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_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap
;
164 UINT32 ActivePcrBanks
;
166 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePcrBanks
);
167 ASSERT_EFI_ERROR (Status
);
169 switch (CommandCode
) {
170 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
171 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
172 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
173 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
174 Status
= Tpm2CommandClear (PlatformAuth
);
175 if (EFI_ERROR (Status
)) {
176 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
178 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
181 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE
:
182 PpiFlags
->PPFlags
|= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
;
183 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
185 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
186 PpiFlags
->PPFlags
&= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
;
187 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
189 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
190 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, CommandParameter
);
191 if (EFI_ERROR (Status
)) {
192 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
194 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
197 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
198 Status
= Tpm2CommandChangeEps (PlatformAuth
);
199 if (EFI_ERROR (Status
)) {
200 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
202 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
205 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
206 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, TpmHashAlgorithmBitmap
);
207 if (EFI_ERROR (Status
)) {
208 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
210 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
214 if (CommandCode
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
215 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
217 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
224 Read the specified key for user confirmation.
226 @param[in] CautionKey If true, F12 is used as confirm key;
227 If false, F10 is used as confirm key.
229 @retval TRUE User confirmed the changes by input.
230 @retval FALSE User discarded the changes.
234 IN BOOLEAN CautionKey
243 Status
= gBS
->CheckEvent (gST
->ConIn
->WaitForKey
);
244 if (!EFI_ERROR (Status
)) {
245 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
246 if (Key
.ScanCode
== SCAN_ESC
) {
247 InputKey
= Key
.ScanCode
;
249 if ((Key
.ScanCode
== SCAN_F10
) && !CautionKey
) {
250 InputKey
= Key
.ScanCode
;
252 if ((Key
.ScanCode
== SCAN_F12
) && CautionKey
) {
253 InputKey
= Key
.ScanCode
;
256 } while (InputKey
== 0);
258 if (InputKey
!= SCAN_ESC
) {
266 Fill Buffer With BootHashAlg.
268 @param[in] Buffer Buffer to be filled.
269 @param[in] BufferSize Size of buffer.
270 @param[in] BootHashAlg BootHashAlg.
274 Tcg2FillBufferWithBootHashAlg (
277 IN UINT32 BootHashAlg
281 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
282 if (Buffer
[0] != 0) {
283 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
285 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA1", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
287 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
288 if (Buffer
[0] != 0) {
289 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
291 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
293 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
294 if (Buffer
[0] != 0) {
295 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
297 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA384", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
299 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
300 if (Buffer
[0] != 0) {
301 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
303 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA512", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
305 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
306 if (Buffer
[0] != 0) {
307 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
309 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SM3_256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
314 Display the confirm text and get user confirmation.
316 @param[in] TpmPpCommand The requested TPM physical presence command.
317 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
319 @retval TRUE The user has confirmed the changes.
320 @retval FALSE The user doesn't confirm the changes.
324 IN UINT32 TpmPpCommand
,
325 IN UINT32 TpmPpCommandParameter
336 CHAR16 TempBuffer
[1024];
337 CHAR16 TempBuffer2
[1024];
338 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
339 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability
;
340 UINT32 CurrentPCRBanks
;
343 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
344 ASSERT_EFI_ERROR (Status
);
346 ProtocolCapability
.Size
= sizeof(ProtocolCapability
);
347 Status
= Tcg2Protocol
->GetCapability (
351 ASSERT_EFI_ERROR (Status
);
353 Status
= Tcg2Protocol
->GetActivePcrBanks (
357 ASSERT_EFI_ERROR (Status
);
362 BufSize
= CONFIRM_BUFFER_SIZE
;
363 ConfirmText
= AllocateZeroPool (BufSize
);
364 ASSERT (ConfirmText
!= NULL
);
366 switch (TpmPpCommand
) {
368 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
369 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
370 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
371 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
373 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
375 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
376 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
379 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
380 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
381 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
386 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
389 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
391 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR
));
392 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
395 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR
));
396 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
399 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
400 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
401 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
406 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
408 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS
));
410 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
411 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
414 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1
));
415 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
418 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2
));
419 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
422 Tcg2FillBufferWithBootHashAlg (TempBuffer
, sizeof(TempBuffer
), TpmPpCommandParameter
);
423 Tcg2FillBufferWithBootHashAlg (TempBuffer2
, sizeof(TempBuffer2
), CurrentPCRBanks
);
425 TmpStr1
= AllocateZeroPool (BufSize
);
426 ASSERT (TmpStr1
!= NULL
);
427 UnicodeSPrint (TmpStr1
, BufSize
, L
"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks
, TempBuffer2
, TpmPpCommandParameter
, TempBuffer
);
429 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
430 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
435 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
437 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS
));
439 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
440 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
443 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1
));
444 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
447 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2
));
448 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
458 if (TmpStr2
== NULL
) {
459 FreePool (ConfirmText
);
463 if (TpmPpCommand
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) {
465 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
467 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY
));
469 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
473 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO
));
474 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
478 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY
));
481 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY
));
483 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY
));
485 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
489 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO
));
490 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
494 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY
));
496 BufSize
-= StrSize (ConfirmText
);
497 UnicodeSPrint (ConfirmText
+ StrLen (ConfirmText
), BufSize
, TmpStr1
, TmpStr2
);
500 for (Index
= 0; Index
< StrLen (ConfirmText
); Index
+= 80) {
501 StrnCpyS (DstStr
, sizeof (DstStr
) / sizeof (CHAR16
), ConfirmText
+ Index
, sizeof (DstStr
) / sizeof (CHAR16
) - 1);
507 FreePool (ConfirmText
);
509 if (Tcg2ReadUserKey (CautionKey
)) {
517 Check if there is a valid physical presence command request. Also updates parameter value
518 to whether the requested physical presence command already confirmed by user
520 @param[in] TcgPpData EFI Tcg2 Physical Presence request data.
521 @param[in] Flags The physical presence interface flags.
522 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
523 True, it indicates the command doesn't require user confirm, or already confirmed
524 in last boot cycle by user.
525 False, it indicates the command need user confirm from UI.
527 @retval TRUE Physical Presence operation command is valid.
528 @retval FALSE Physical Presence operation command is invalid.
532 Tcg2HaveValidTpmRequest (
533 IN EFI_TCG2_PHYSICAL_PRESENCE
*TcgPpData
,
534 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
,
535 OUT BOOLEAN
*RequestConfirmed
538 BOOLEAN IsRequestValid
;
540 *RequestConfirmed
= FALSE
;
542 switch (TcgPpData
->PPRequest
) {
543 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
544 *RequestConfirmed
= TRUE
;
547 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
548 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
549 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
550 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
551 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
) == 0) {
552 *RequestConfirmed
= TRUE
;
556 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE
:
557 *RequestConfirmed
= TRUE
;
560 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
563 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
564 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS
) == 0) {
565 *RequestConfirmed
= TRUE
;
569 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
570 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS
) == 0) {
571 *RequestConfirmed
= TRUE
;
575 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
576 *RequestConfirmed
= TRUE
;
580 if (TcgPpData
->PPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
581 IsRequestValid
= Tcg2PpVendorLibHasValidRequest (TcgPpData
->PPRequest
, Flags
.PPFlags
, RequestConfirmed
);
582 if (!IsRequestValid
) {
589 // Wrong Physical Presence command
595 if ((Flags
.PPFlags
& TCG2_LIB_PP_FLAG_RESET_TRACK
) != 0) {
597 // It had been confirmed in last boot, it doesn't need confirm again.
599 *RequestConfirmed
= TRUE
;
603 // Physical Presence command is correct
610 Check and execute the requested physical presence command.
612 Caution: This function may receive untrusted input.
613 TcgPpData variable is external input, so this function will validate
614 its data structure to be valid value.
616 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
617 @param[in] TcgPpData Point to the physical presence NV variable.
618 @param[in] Flags The physical presence interface flags.
621 Tcg2ExecutePendingTpmRequest (
622 IN TPM2B_AUTH
*PlatformAuth
, OPTIONAL
623 IN EFI_TCG2_PHYSICAL_PRESENCE
*TcgPpData
,
624 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
629 BOOLEAN RequestConfirmed
;
630 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags
;
631 BOOLEAN ResetRequired
;
634 if (TcgPpData
->PPRequest
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
636 // No operation request
641 if (!Tcg2HaveValidTpmRequest(TcgPpData
, Flags
, &RequestConfirmed
)) {
643 // Invalid operation request.
645 if (TcgPpData
->PPRequest
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
646 TcgPpData
->PPResponse
= TCG_PP_OPERATION_RESPONSE_SUCCESS
;
648 TcgPpData
->PPResponse
= TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
650 TcgPpData
->LastPPRequest
= TcgPpData
->PPRequest
;
651 TcgPpData
->PPRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
652 TcgPpData
->PPRequestParameter
= 0;
654 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
655 Status
= gRT
->SetVariable (
656 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
657 &gEfiTcg2PhysicalPresenceGuid
,
658 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
665 ResetRequired
= FALSE
;
666 if (TcgPpData
->PPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
668 NewPPFlags
= NewFlags
.PPFlags
;
669 TcgPpData
->PPResponse
= Tcg2PpVendorLibExecutePendingRequest (PlatformAuth
, TcgPpData
->PPRequest
, &NewPPFlags
, &ResetRequired
);
670 NewFlags
.PPFlags
= NewPPFlags
;
672 if (!RequestConfirmed
) {
674 // Print confirm text and wait for approval.
676 RequestConfirmed
= Tcg2UserConfirm (TcgPpData
->PPRequest
, TcgPpData
->PPRequestParameter
);
680 // Execute requested physical presence command
682 TcgPpData
->PPResponse
= TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
684 if (RequestConfirmed
) {
685 TcgPpData
->PPResponse
= Tcg2ExecutePhysicalPresence (
687 TcgPpData
->PPRequest
,
688 TcgPpData
->PPRequestParameter
,
695 // Save the flags if it is updated.
697 if (CompareMem (&Flags
, &NewFlags
, sizeof(EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
)) != 0) {
698 Status
= gRT
->SetVariable (
699 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
700 &gEfiTcg2PhysicalPresenceGuid
,
701 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
702 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
),
710 if ((NewFlags
.PPFlags
& TCG2_LIB_PP_FLAG_RESET_TRACK
) == 0) {
711 TcgPpData
->LastPPRequest
= TcgPpData
->PPRequest
;
712 TcgPpData
->PPRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
713 TcgPpData
->PPRequestParameter
= 0;
719 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
720 Status
= gRT
->SetVariable (
721 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
722 &gEfiTcg2PhysicalPresenceGuid
,
723 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
727 if (EFI_ERROR (Status
)) {
731 if (TcgPpData
->PPResponse
== TCG_PP_OPERATION_RESPONSE_USER_ABORT
) {
736 // Reset system to make new TPM settings in effect
738 switch (TcgPpData
->LastPPRequest
) {
739 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
740 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
741 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
742 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
743 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
744 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
745 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
749 if (TcgPpData
->LastPPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
756 if (TcgPpData
->PPRequest
!= TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
762 Print (L
"Rebooting system to make TPM2 settings in effect\n");
763 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
768 Check and execute the pending TPM request.
770 The TPM request may come from OS or BIOS. This API will display request information and wait
771 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
772 the TPM request is confirmed, and one or more reset may be required to make TPM request to
775 This API should be invoked after console in and console out are all ready as they are required
776 to display request information and get user input to confirm the request.
778 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
782 Tcg2PhysicalPresenceLibProcessRequest (
783 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
788 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData
;
789 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
790 EDKII_VARIABLE_LOCK_PROTOCOL
*VariableLockProtocol
;
791 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags
;
793 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
794 if (EFI_ERROR (Status
)) {
801 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
802 DEBUG ((EFI_D_INFO
, "S4 Resume, Skip TPM PP process!\n"));
806 mTcg2PpStringPackHandle
= HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid
, gImageHandle
, DxeTcg2PhysicalPresenceLibStrings
, NULL
);
807 ASSERT (mTcg2PpStringPackHandle
!= NULL
);
810 // Initialize physical presence flags.
812 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
813 Status
= gRT
->GetVariable (
814 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
815 &gEfiTcg2PhysicalPresenceGuid
,
820 if (EFI_ERROR (Status
)) {
821 PpiFlags
.PPFlags
= TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT
;
822 Status
= gRT
->SetVariable (
823 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
824 &gEfiTcg2PhysicalPresenceGuid
,
825 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
826 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
),
829 if (EFI_ERROR (Status
)) {
830 DEBUG ((EFI_D_ERROR
, "[TPM2] Set physical presence flag failed, Status = %r\n", Status
));
834 DEBUG ((EFI_D_INFO
, "[TPM2] PpiFlags = %x\n", PpiFlags
.PPFlags
));
837 // This flags variable controls whether physical presence is required for TPM command.
838 // It should be protected from malicious software. We set it as read-only variable here.
840 Status
= gBS
->LocateProtocol (&gEdkiiVariableLockProtocolGuid
, NULL
, (VOID
**)&VariableLockProtocol
);
841 if (!EFI_ERROR (Status
)) {
842 Status
= VariableLockProtocol
->RequestToLock (
843 VariableLockProtocol
,
844 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
845 &gEfiTcg2PhysicalPresenceGuid
847 if (EFI_ERROR (Status
)) {
848 DEBUG ((EFI_D_ERROR
, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
, Status
));
849 ASSERT_EFI_ERROR (Status
);
854 // Initialize physical presence variable.
856 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
857 Status
= gRT
->GetVariable (
858 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
859 &gEfiTcg2PhysicalPresenceGuid
,
864 if (EFI_ERROR (Status
)) {
865 ZeroMem ((VOID
*)&TcgPpData
, sizeof (TcgPpData
));
866 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
867 Status
= gRT
->SetVariable (
868 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
869 &gEfiTcg2PhysicalPresenceGuid
,
870 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
874 if (EFI_ERROR (Status
)) {
875 DEBUG ((EFI_D_ERROR
, "[TPM2] Set physical presence variable failed, Status = %r\n", Status
));
880 DEBUG ((EFI_D_INFO
, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags
.PPFlags
, TcgPpData
.PPRequest
, TcgPpData
.LastPPRequest
));
883 // Execute pending TPM request.
885 Tcg2ExecutePendingTpmRequest (PlatformAuth
, &TcgPpData
, PpiFlags
);
886 DEBUG ((EFI_D_INFO
, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData
.PPResponse
, TcgPpData
.LastPPRequest
, PpiFlags
.PPFlags
));
891 Check if the pending TPM request needs user input to confirm.
893 The TPM request may come from OS. This API will check if TPM request exists and need user
894 input to confirmation.
896 @retval TRUE TPM needs input to confirm user physical presence.
897 @retval FALSE TPM doesn't need input to confirm user physical presence.
902 Tcg2PhysicalPresenceLibNeedUserConfirm(
907 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData
;
909 BOOLEAN RequestConfirmed
;
910 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
911 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags
;
913 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
914 if (EFI_ERROR (Status
)) {
921 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
922 DEBUG ((EFI_D_INFO
, "S4 Resume, Skip TPM PP process!\n"));
927 // Check Tpm requests
929 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
930 Status
= gRT
->GetVariable (
931 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
932 &gEfiTcg2PhysicalPresenceGuid
,
937 if (EFI_ERROR (Status
)) {
941 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
942 Status
= gRT
->GetVariable (
943 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
944 &gEfiTcg2PhysicalPresenceGuid
,
949 if (EFI_ERROR (Status
)) {
953 if (TcgPpData
.PPRequest
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
955 // No operation request
960 if (!Tcg2HaveValidTpmRequest(&TcgPpData
, PpiFlags
, &RequestConfirmed
)) {
962 // Invalid operation request.
967 if (!RequestConfirmed
) {
969 // Need UI to confirm
979 The handler for TPM physical presence function:
980 Return TPM Operation Response to OS Environment.
982 @param[out] MostRecentRequest Most recent operation request.
983 @param[out] Response Response to the most recent operation request.
985 @return Return Code for Return TPM Operation Response to OS Environment.
989 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
990 OUT UINT32
*MostRecentRequest
,
996 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
998 DEBUG ((EFI_D_INFO
, "[TPM2] ReturnOperationResponseToOsFunction\n"));
1001 // Get the Physical Presence variable
1003 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
1004 Status
= gRT
->GetVariable (
1005 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
1006 &gEfiTcg2PhysicalPresenceGuid
,
1011 if (EFI_ERROR (Status
)) {
1012 *MostRecentRequest
= 0;
1014 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
1015 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
1018 *MostRecentRequest
= PpData
.LastPPRequest
;
1019 *Response
= PpData
.PPResponse
;
1021 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
1025 The handler for TPM physical presence function:
1026 Submit TPM Operation Request to Pre-OS Environment and
1027 Submit TPM Operation Request to Pre-OS Environment 2.
1029 Caution: This function may receive untrusted input.
1031 @param[in] OperationRequest TPM physical presence operation request.
1032 @param[in] RequestParameter TPM physical presence operation request parameter.
1034 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
1035 Submit TPM Operation Request to Pre-OS Environment 2.
1039 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
1040 IN UINT32 OperationRequest
,
1041 IN UINT32 RequestParameter
1046 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
1047 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
1049 DEBUG ((EFI_D_INFO
, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest
, RequestParameter
));
1052 // Get the Physical Presence variable
1054 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
1055 Status
= gRT
->GetVariable (
1056 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
1057 &gEfiTcg2PhysicalPresenceGuid
,
1062 if (EFI_ERROR (Status
)) {
1063 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
1064 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
1067 if ((OperationRequest
> TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) &&
1068 (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) ) {
1070 // This command requires UI to prompt user for Auth data.
1072 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
;
1075 if ((PpData
.PPRequest
!= OperationRequest
) ||
1076 (PpData
.PPRequestParameter
!= RequestParameter
)) {
1077 PpData
.PPRequest
= (UINT8
)OperationRequest
;
1078 PpData
.PPRequestParameter
= RequestParameter
;
1079 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
1080 Status
= gRT
->SetVariable (
1081 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
1082 &gEfiTcg2PhysicalPresenceGuid
,
1083 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1089 if (EFI_ERROR (Status
)) {
1090 DEBUG ((EFI_D_ERROR
, "[TPM2] Set PP variable failure! Status = %r\n", Status
));
1091 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
1094 if (OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
1095 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
1096 Status
= gRT
->GetVariable (
1097 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
1098 &gEfiTcg2PhysicalPresenceGuid
,
1103 if (EFI_ERROR (Status
)) {
1104 Flags
.PPFlags
= TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT
;
1106 return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest
, Flags
.PPFlags
, RequestParameter
);
1109 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;