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 Tcg2ExecutePendingTpmRequest() will receive untrusted input and do validation.
10 Copyright (C) 2018, Red Hat, Inc.
11 Copyright (c) 2018, IBM Corporation. All rights reserved.<BR>
12 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
13 SPDX-License-Identifier: BSD-2-Clause-Patent
19 #include <Guid/Tcg2PhysicalPresenceData.h>
20 #include <IndustryStandard/QemuTpm.h>
21 #include <Protocol/Tcg2Protocol.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/DxeServicesTableLib.h>
26 #include <Library/HiiLib.h>
27 #include <Library/HobLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/PrintLib.h>
30 #include <Library/QemuFwCfgLib.h>
31 #include <Library/Tpm2CommandLib.h>
32 #include <Library/UefiBootServicesTableLib.h>
33 #include <Library/UefiLib.h>
34 #include <Library/UefiRuntimeServicesTableLib.h>
35 #include <Library/UefiBootManagerLib.h>
37 #include <Library/Tcg2PhysicalPresenceLib.h>
39 #define CONFIRM_BUFFER_SIZE 4096
41 EFI_HII_HANDLE mTcg2PpStringPackHandle
;
43 #define TPM_PPI_FLAGS (QEMU_TPM_PPI_FUNC_ALLOWED_USR_REQ)
45 STATIC
volatile QEMU_TPM_PPI
*mPpi
;
48 Reads QEMU PPI config from fw_cfg.
50 @param[out] The Config structure to read to.
52 @retval EFI_SUCCESS Operation completed successfully.
53 @retval EFI_PROTOCOL_ERROR Invalid fw_cfg entry size.
58 OUT QEMU_FWCFG_TPM_CONFIG
*Config
62 FIRMWARE_CONFIG_ITEM FwCfgItem
;
65 Status
= QemuFwCfgFindFile ("etc/tpm/config", &FwCfgItem
, &FwCfgSize
);
66 if (EFI_ERROR (Status
)) {
70 if (FwCfgSize
!= sizeof (*Config
)) {
71 return EFI_PROTOCOL_ERROR
;
74 QemuFwCfgSelectItem (FwCfgItem
);
75 QemuFwCfgReadBytes (sizeof (*Config
), Config
);
80 Initializes QEMU PPI memory region.
82 @retval EFI_SUCCESS Operation completed successfully.
83 @retval EFI_PROTOCOL_ERROR PPI address is invalid.
92 QEMU_FWCFG_TPM_CONFIG Config
;
93 EFI_PHYSICAL_ADDRESS PpiAddress64
;
94 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
101 Status
= QemuTpmReadConfig (&Config
);
102 if (EFI_ERROR (Status
)) {
106 mPpi
= (QEMU_TPM_PPI
*)(UINTN
)Config
.PpiAddress
;
108 return EFI_PROTOCOL_ERROR
;
111 DEBUG ((DEBUG_INFO
, "[TPM2PP] mPpi=%p version=%d\n", mPpi
, Config
.TpmVersion
));
113 PpiAddress64
= (UINTN
)mPpi
;
114 if ((PpiAddress64
& ~(UINT64
)EFI_PAGE_MASK
) !=
115 ((PpiAddress64
+ sizeof *mPpi
- 1) & ~(UINT64
)EFI_PAGE_MASK
))
117 DEBUG ((DEBUG_ERROR
, "[TPM2PP] mPpi crosses a page boundary\n"));
118 goto InvalidPpiAddress
;
121 Status
= gDS
->GetMemorySpaceDescriptor (PpiAddress64
, &Descriptor
);
122 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
123 ASSERT_EFI_ERROR (Status
);
124 goto InvalidPpiAddress
;
127 if (!EFI_ERROR (Status
) &&
128 ((Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeMemoryMappedIo
) &&
129 (Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeNonExistent
)))
131 DEBUG ((DEBUG_ERROR
, "[TPM2PP] mPpi has an invalid memory type\n"));
132 goto InvalidPpiAddress
;
135 for (Idx
= 0; Idx
< ARRAY_SIZE (mPpi
->Func
); Idx
++) {
139 if (Config
.TpmVersion
== QEMU_TPM_VERSION_2
) {
140 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_NO_ACTION
] = TPM_PPI_FLAGS
;
141 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CLEAR
] = TPM_PPI_FLAGS
;
142 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
] = TPM_PPI_FLAGS
;
143 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
] = TPM_PPI_FLAGS
;
144 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
] = TPM_PPI_FLAGS
;
145 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
] = TPM_PPI_FLAGS
;
146 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
] = TPM_PPI_FLAGS
;
147 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
] = TPM_PPI_FLAGS
;
148 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
149 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
154 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
155 mPpi
->LastRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
156 mPpi
->NextStep
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
163 return EFI_PROTOCOL_ERROR
;
167 Get string by string id from HII Interface.
169 @param[in] Id String ID.
171 @retval CHAR16 * String from ID.
172 @retval NULL If error occurs.
177 Tcg2PhysicalPresenceGetStringById (
181 return HiiGetString (mTcg2PpStringPackHandle
, Id
, NULL
);
185 Send ClearControl and Clear command to TPM.
187 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
189 @retval EFI_SUCCESS Operation completed successfully.
190 @retval EFI_TIMEOUT The register can't run into the expected status in time.
191 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
192 @retval EFI_DEVICE_ERROR Unexpected device behavior.
198 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
202 TPMS_AUTH_COMMAND
*AuthSession
;
203 TPMS_AUTH_COMMAND LocalAuthSession
;
205 if (PlatformAuth
== NULL
) {
208 AuthSession
= &LocalAuthSession
;
209 ZeroMem (&LocalAuthSession
, sizeof (LocalAuthSession
));
210 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
211 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
212 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
215 DEBUG ((DEBUG_INFO
, "Tpm2ClearControl ... \n"));
216 Status
= Tpm2ClearControl (TPM_RH_PLATFORM
, AuthSession
, NO
);
217 DEBUG ((DEBUG_INFO
, "Tpm2ClearControl - %r\n", Status
));
218 if (EFI_ERROR (Status
)) {
222 DEBUG ((DEBUG_INFO
, "Tpm2Clear ... \n"));
223 Status
= Tpm2Clear (TPM_RH_PLATFORM
, AuthSession
);
224 DEBUG ((DEBUG_INFO
, "Tpm2Clear - %r\n", Status
));
227 ZeroMem (&LocalAuthSession
.hmac
, sizeof (LocalAuthSession
.hmac
));
234 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
236 @retval EFI_SUCCESS Operation completed successfully.
240 Tpm2CommandChangeEps (
241 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
245 TPMS_AUTH_COMMAND
*AuthSession
;
246 TPMS_AUTH_COMMAND LocalAuthSession
;
248 if (PlatformAuth
== NULL
) {
251 AuthSession
= &LocalAuthSession
;
252 ZeroMem (&LocalAuthSession
, sizeof (LocalAuthSession
));
253 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
254 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
255 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
258 Status
= Tpm2ChangeEPS (TPM_RH_PLATFORM
, AuthSession
);
259 DEBUG ((DEBUG_INFO
, "Tpm2ChangeEPS - %r\n", Status
));
261 ZeroMem (&LocalAuthSession
.hmac
, sizeof (LocalAuthSession
.hmac
));
266 Execute physical presence operation requested by the OS.
268 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
269 @param[in] CommandCode Physical presence operation value.
270 @param[in] CommandParameter Physical presence operation parameter.
272 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
273 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
274 receiving response from TPM.
275 @retval Others Return code from the TPM device after command execution.
279 Tcg2ExecutePhysicalPresence (
280 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
,
281 IN UINT32 CommandCode
,
282 IN UINT32 CommandParameter
286 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap
;
287 UINT32 ActivePcrBanks
;
289 switch (CommandCode
) {
290 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
291 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
292 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
293 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
294 Status
= Tpm2CommandClear (PlatformAuth
);
295 if (EFI_ERROR (Status
)) {
296 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
298 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
301 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
302 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePcrBanks
);
303 ASSERT_EFI_ERROR (Status
);
306 // PP spec requirements:
307 // Firmware should check that all requested (set) hashing algorithms are supported with respective PCR banks.
308 // Firmware has to ensure that at least one PCR banks is active.
309 // If not, an error is returned and no action is taken.
311 if ((CommandParameter
== 0) || ((CommandParameter
& (~TpmHashAlgorithmBitmap
)) != 0)) {
312 DEBUG ((DEBUG_ERROR
, "PCR banks %x to allocate are not supported by TPM. Skip operation\n", CommandParameter
));
313 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
316 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, CommandParameter
);
317 if (EFI_ERROR (Status
)) {
318 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
320 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
323 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
324 Status
= Tpm2CommandChangeEps (PlatformAuth
);
325 if (EFI_ERROR (Status
)) {
326 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
328 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
331 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
332 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePcrBanks
);
333 ASSERT_EFI_ERROR (Status
);
334 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, TpmHashAlgorithmBitmap
);
335 if (EFI_ERROR (Status
)) {
336 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
338 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
342 if (CommandCode
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
343 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
345 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
351 Read the specified key for user confirmation.
353 @param[in] CautionKey If true, F12 is used as confirm key;
354 If false, F10 is used as confirm key.
356 @retval TRUE User confirmed the changes by input.
357 @retval FALSE User discarded the changes.
362 IN BOOLEAN CautionKey
371 Status
= gBS
->CheckEvent (gST
->ConIn
->WaitForKey
);
372 if (!EFI_ERROR (Status
)) {
373 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
374 if (Key
.ScanCode
== SCAN_ESC
) {
375 InputKey
= Key
.ScanCode
;
378 if ((Key
.ScanCode
== SCAN_F10
) && !CautionKey
) {
379 InputKey
= Key
.ScanCode
;
382 if ((Key
.ScanCode
== SCAN_F12
) && CautionKey
) {
383 InputKey
= Key
.ScanCode
;
386 } while (InputKey
== 0);
388 if (InputKey
!= SCAN_ESC
) {
396 Fill Buffer With BootHashAlg.
398 @param[in] Buffer Buffer to be filled.
399 @param[in] BufferSize Size of buffer.
400 @param[in] BootHashAlg BootHashAlg.
405 Tcg2FillBufferWithBootHashAlg (
408 IN UINT32 BootHashAlg
412 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
413 if (Buffer
[0] != 0) {
414 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
417 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA1", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
420 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
421 if (Buffer
[0] != 0) {
422 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
425 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
428 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
429 if (Buffer
[0] != 0) {
430 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
433 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA384", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
436 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
437 if (Buffer
[0] != 0) {
438 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
441 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA512", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
444 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
445 if (Buffer
[0] != 0) {
446 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
449 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SM3_256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
454 Display the confirm text and get user confirmation.
456 @param[in] TpmPpCommand The requested TPM physical presence command.
457 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
459 @retval TRUE The user has confirmed the changes.
460 @retval FALSE The user doesn't confirm the changes.
465 IN UINT32 TpmPpCommand
,
466 IN UINT32 TpmPpCommandParameter
477 CHAR16 TempBuffer
[1024];
478 CHAR16 TempBuffer2
[1024];
479 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
480 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability
;
481 UINT32 CurrentPCRBanks
;
487 BufSize
= CONFIRM_BUFFER_SIZE
;
488 ConfirmText
= AllocateZeroPool (BufSize
);
489 ASSERT (ConfirmText
!= NULL
);
491 mTcg2PpStringPackHandle
= HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid
, gImageHandle
, Tcg2PhysicalPresenceLibQemuStrings
, NULL
);
492 ASSERT (mTcg2PpStringPackHandle
!= NULL
);
494 switch (TpmPpCommand
) {
495 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
496 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
497 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
498 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
500 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
502 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
503 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
506 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
507 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
508 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
513 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
514 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**)&Tcg2Protocol
);
515 ASSERT_EFI_ERROR (Status
);
517 ProtocolCapability
.Size
= sizeof (ProtocolCapability
);
518 Status
= Tcg2Protocol
->GetCapability (
522 ASSERT_EFI_ERROR (Status
);
524 Status
= Tcg2Protocol
->GetActivePcrBanks (
528 ASSERT_EFI_ERROR (Status
);
531 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS
));
533 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
534 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
537 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1
));
538 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
541 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2
));
542 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
545 Tcg2FillBufferWithBootHashAlg (TempBuffer
, sizeof (TempBuffer
), TpmPpCommandParameter
);
546 Tcg2FillBufferWithBootHashAlg (TempBuffer2
, sizeof (TempBuffer2
), CurrentPCRBanks
);
548 TmpStr1
= AllocateZeroPool (BufSize
);
549 ASSERT (TmpStr1
!= NULL
);
550 UnicodeSPrint (TmpStr1
, BufSize
, L
"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks
, TempBuffer2
, TpmPpCommandParameter
, TempBuffer
);
552 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
553 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
558 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
560 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS
));
562 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
563 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
566 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1
));
567 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
570 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2
));
571 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
576 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
577 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID
));
579 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
580 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
584 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
585 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID
));
587 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
588 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
596 if (TmpStr2
== NULL
) {
597 FreePool (ConfirmText
);
601 // Console for user interaction
602 // We need to connect all trusted consoles for TCG PP. Here we treat all consoles in OVMF to be trusted consoles.
603 EfiBootManagerConnectAllDefaultConsoles ();
605 if (TpmPpCommand
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) {
607 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
609 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY
));
612 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
616 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO
));
617 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
621 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY
));
624 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY
));
626 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY
));
629 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
633 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO
));
634 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
638 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY
));
641 BufSize
-= StrSize (ConfirmText
);
642 UnicodeSPrint (ConfirmText
+ StrLen (ConfirmText
), BufSize
, TmpStr1
, TmpStr2
);
645 for (Index
= 0; Index
< StrLen (ConfirmText
); Index
+= 80) {
646 StrnCpyS (DstStr
, sizeof (DstStr
) / sizeof (CHAR16
), ConfirmText
+ Index
, sizeof (DstStr
) / sizeof (CHAR16
) - 1);
652 FreePool (ConfirmText
);
653 HiiRemovePackages (mTcg2PpStringPackHandle
);
655 if (Tcg2ReadUserKey (CautionKey
)) {
663 Check if there is a valid physical presence command request. Also updates parameter value
664 to whether the requested physical presence command already confirmed by user
666 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
667 True, it indicates the command doesn't require user confirm, or already confirmed
668 in last boot cycle by user.
669 False, it indicates the command need user confirm from UI.
671 @retval TRUE Physical Presence operation command is valid.
672 @retval FALSE Physical Presence operation command is invalid.
677 Tcg2HaveValidTpmRequest (
678 OUT BOOLEAN
*RequestConfirmed
681 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
684 *RequestConfirmed
= FALSE
;
686 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
688 // Need TCG2 protocol.
690 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**)&Tcg2Protocol
);
691 if (EFI_ERROR (Status
)) {
696 switch (mPpi
->Request
) {
697 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
698 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
699 *RequestConfirmed
= TRUE
;
702 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
703 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
704 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
705 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
706 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
707 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
708 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
709 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
714 // Wrong Physical Presence command
720 // Physical Presence command is correct
726 Check and execute the requested physical presence command.
728 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
732 Tcg2ExecutePendingTpmRequest (
733 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
736 BOOLEAN RequestConfirmed
;
738 if (mPpi
->Request
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
740 // No operation request
745 if (!Tcg2HaveValidTpmRequest (&RequestConfirmed
)) {
747 // Invalid operation request.
749 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
750 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_SUCCESS
;
752 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
755 mPpi
->LastRequest
= mPpi
->Request
;
756 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
757 mPpi
->RequestParameter
= 0;
761 if (!RequestConfirmed
) {
763 // Print confirm text and wait for approval.
765 RequestConfirmed
= Tcg2UserConfirm (mPpi
->Request
, mPpi
->RequestParameter
);
769 // Execute requested physical presence command
771 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
772 if (RequestConfirmed
) {
773 mPpi
->Response
= Tcg2ExecutePhysicalPresence (
776 mPpi
->RequestParameter
783 mPpi
->LastRequest
= mPpi
->Request
;
784 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
785 mPpi
->RequestParameter
= 0;
787 if (mPpi
->Response
== TCG_PP_OPERATION_RESPONSE_USER_ABORT
) {
792 // Reset system to make new TPM settings in effect
794 switch (mPpi
->LastRequest
) {
795 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
796 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
797 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
798 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
799 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
800 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
801 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
804 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
805 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
809 if (mPpi
->Request
!= TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
816 Print (L
"Rebooting system to make TPM2 settings in effect\n");
817 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
822 Check and execute the pending TPM request.
824 The TPM request may come from OS or BIOS. This API will display request information and wait
825 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
826 the TPM request is confirmed, and one or more reset may be required to make TPM request to
829 This API should be invoked after console in and console out are all ready as they are required
830 to display request information and get user input to confirm the request.
832 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
836 Tcg2PhysicalPresenceLibProcessRequest (
837 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
842 Status
= QemuTpmInitPPI ();
843 if (EFI_ERROR (Status
)) {
844 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
851 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
852 DEBUG ((DEBUG_INFO
, "S4 Resume, Skip TPM PP process!\n"));
856 DEBUG ((DEBUG_INFO
, "[TPM2PP] PPRequest=%x (PPRequestParameter=%x)\n", mPpi
->Request
, mPpi
->RequestParameter
));
857 Tcg2ExecutePendingTpmRequest (PlatformAuth
);
861 The handler for TPM physical presence function:
862 Return TPM Operation Response to OS Environment.
864 @param[out] MostRecentRequest Most recent operation request.
865 @param[out] Response Response to the most recent operation request.
867 @return Return Code for Return TPM Operation Response to OS Environment.
871 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
872 OUT UINT32
*MostRecentRequest
,
878 DEBUG ((DEBUG_INFO
, "[TPM2PP] ReturnOperationResponseToOsFunction\n"));
880 Status
= QemuTpmInitPPI ();
881 if (EFI_ERROR (Status
)) {
882 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
883 *MostRecentRequest
= 0;
885 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
888 *MostRecentRequest
= mPpi
->LastRequest
;
889 *Response
= mPpi
->Response
;
891 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
895 The handler for TPM physical presence function:
896 Submit TPM Operation Request to Pre-OS Environment and
897 Submit TPM Operation Request to Pre-OS Environment 2.
899 Caution: This function may receive untrusted input.
901 @param[in] OperationRequest TPM physical presence operation request.
902 @param[in] RequestParameter TPM physical presence operation request parameter.
904 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
905 Submit TPM Operation Request to Pre-OS Environment 2.
909 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
910 IN UINT32 OperationRequest
,
911 IN UINT32 RequestParameter
916 DEBUG ((DEBUG_INFO
, "[TPM2PP] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest
, RequestParameter
));
918 Status
= QemuTpmInitPPI ();
919 if (EFI_ERROR (Status
)) {
920 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
921 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
924 mPpi
->Request
= OperationRequest
;
925 mPpi
->RequestParameter
= RequestParameter
;
927 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;