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
;
49 Reads QEMU PPI config from fw_cfg.
51 @param[out] The Config structure to read to.
53 @retval EFI_SUCCESS Operation completed successfully.
54 @retval EFI_PROTOCOL_ERROR Invalid fw_cfg entry size.
59 OUT QEMU_FWCFG_TPM_CONFIG
*Config
63 FIRMWARE_CONFIG_ITEM FwCfgItem
;
66 Status
= QemuFwCfgFindFile ("etc/tpm/config", &FwCfgItem
, &FwCfgSize
);
67 if (EFI_ERROR (Status
)) {
71 if (FwCfgSize
!= sizeof (*Config
)) {
72 return EFI_PROTOCOL_ERROR
;
75 QemuFwCfgSelectItem (FwCfgItem
);
76 QemuFwCfgReadBytes (sizeof (*Config
), Config
);
82 Initializes QEMU PPI memory region.
84 @retval EFI_SUCCESS Operation completed successfully.
85 @retval EFI_PROTOCOL_ERROR PPI address is invalid.
94 QEMU_FWCFG_TPM_CONFIG Config
;
95 EFI_PHYSICAL_ADDRESS PpiAddress64
;
96 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
103 Status
= QemuTpmReadConfig (&Config
);
104 if (EFI_ERROR (Status
)) {
108 mPpi
= (QEMU_TPM_PPI
*)(UINTN
)Config
.PpiAddress
;
110 return EFI_PROTOCOL_ERROR
;
113 DEBUG ((DEBUG_INFO
, "[TPM2PP] mPpi=%p version=%d\n", mPpi
, Config
.TpmVersion
));
115 PpiAddress64
= (UINTN
)mPpi
;
116 if ((PpiAddress64
& ~(UINT64
)EFI_PAGE_MASK
) !=
117 ((PpiAddress64
+ sizeof *mPpi
- 1) & ~(UINT64
)EFI_PAGE_MASK
)) {
118 DEBUG ((DEBUG_ERROR
, "[TPM2PP] mPpi crosses a page boundary\n"));
119 goto InvalidPpiAddress
;
122 Status
= gDS
->GetMemorySpaceDescriptor (PpiAddress64
, &Descriptor
);
123 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
124 ASSERT_EFI_ERROR (Status
);
125 goto InvalidPpiAddress
;
127 if (!EFI_ERROR (Status
) &&
128 (Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeMemoryMappedIo
&&
129 Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeNonExistent
)) {
130 DEBUG ((DEBUG_ERROR
, "[TPM2PP] mPpi has an invalid memory type\n"));
131 goto InvalidPpiAddress
;
134 for (Idx
= 0; Idx
< ARRAY_SIZE (mPpi
->Func
); Idx
++) {
137 if (Config
.TpmVersion
== QEMU_TPM_VERSION_2
) {
138 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_NO_ACTION
] = TPM_PPI_FLAGS
;
139 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CLEAR
] = TPM_PPI_FLAGS
;
140 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
] = TPM_PPI_FLAGS
;
141 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
] = TPM_PPI_FLAGS
;
142 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
] = TPM_PPI_FLAGS
;
143 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
] = TPM_PPI_FLAGS
;
144 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
] = TPM_PPI_FLAGS
;
145 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
] = TPM_PPI_FLAGS
;
146 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
147 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
152 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
153 mPpi
->LastRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
154 mPpi
->NextStep
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
161 return EFI_PROTOCOL_ERROR
;
166 Get string by string id from HII Interface.
168 @param[in] Id String ID.
170 @retval CHAR16 * String from ID.
171 @retval NULL If error occurs.
176 Tcg2PhysicalPresenceGetStringById (
180 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
)) {
221 DEBUG ((DEBUG_INFO
, "Tpm2Clear ... \n"));
222 Status
= Tpm2Clear (TPM_RH_PLATFORM
, AuthSession
);
223 DEBUG ((DEBUG_INFO
, "Tpm2Clear - %r\n", Status
));
226 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
));
267 Execute physical presence operation requested by the OS.
269 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
270 @param[in] CommandCode Physical presence operation value.
271 @param[in] CommandParameter Physical presence operation parameter.
273 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
274 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
275 receiving response from TPM.
276 @retval Others Return code from the TPM device after command execution.
280 Tcg2ExecutePhysicalPresence (
281 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
,
282 IN UINT32 CommandCode
,
283 IN UINT32 CommandParameter
287 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap
;
288 UINT32 ActivePcrBanks
;
290 switch (CommandCode
) {
291 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
292 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
293 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
294 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
295 Status
= Tpm2CommandClear (PlatformAuth
);
296 if (EFI_ERROR (Status
)) {
297 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
299 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
302 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
303 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePcrBanks
);
304 ASSERT_EFI_ERROR (Status
);
307 // PP spec requirements:
308 // Firmware should check that all requested (set) hashing algorithms are supported with respective PCR banks.
309 // Firmware has to ensure that at least one PCR banks is active.
310 // If not, an error is returned and no action is taken.
312 if (CommandParameter
== 0 || (CommandParameter
& (~TpmHashAlgorithmBitmap
)) != 0) {
313 DEBUG((DEBUG_ERROR
, "PCR banks %x to allocate are not supported by TPM. Skip operation\n", CommandParameter
));
314 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
317 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, CommandParameter
);
318 if (EFI_ERROR (Status
)) {
319 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
321 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
324 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
325 Status
= Tpm2CommandChangeEps (PlatformAuth
);
326 if (EFI_ERROR (Status
)) {
327 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
329 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
332 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
333 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePcrBanks
);
334 ASSERT_EFI_ERROR (Status
);
335 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, TpmHashAlgorithmBitmap
);
336 if (EFI_ERROR (Status
)) {
337 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
339 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
343 if (CommandCode
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
344 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
346 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
353 Read the specified key for user confirmation.
355 @param[in] CautionKey If true, F12 is used as confirm key;
356 If false, F10 is used as confirm key.
358 @retval TRUE User confirmed the changes by input.
359 @retval FALSE User discarded the changes.
364 IN BOOLEAN CautionKey
373 Status
= gBS
->CheckEvent (gST
->ConIn
->WaitForKey
);
374 if (!EFI_ERROR (Status
)) {
375 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
376 if (Key
.ScanCode
== SCAN_ESC
) {
377 InputKey
= Key
.ScanCode
;
379 if ((Key
.ScanCode
== SCAN_F10
) && !CautionKey
) {
380 InputKey
= Key
.ScanCode
;
382 if ((Key
.ScanCode
== SCAN_F12
) && CautionKey
) {
383 InputKey
= Key
.ScanCode
;
386 } while (InputKey
== 0);
388 if (InputKey
!= SCAN_ESC
) {
397 Fill Buffer With BootHashAlg.
399 @param[in] Buffer Buffer to be filled.
400 @param[in] BufferSize Size of buffer.
401 @param[in] BootHashAlg BootHashAlg.
406 Tcg2FillBufferWithBootHashAlg (
409 IN UINT32 BootHashAlg
413 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
414 if (Buffer
[0] != 0) {
415 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);
419 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
420 if (Buffer
[0] != 0) {
421 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
423 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
425 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
426 if (Buffer
[0] != 0) {
427 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
429 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA384", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
431 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
432 if (Buffer
[0] != 0) {
433 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
435 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA512", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
437 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
438 if (Buffer
[0] != 0) {
439 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
441 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SM3_256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
447 Display the confirm text and get user confirmation.
449 @param[in] TpmPpCommand The requested TPM physical presence command.
450 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
452 @retval TRUE The user has confirmed the changes.
453 @retval FALSE The user doesn't confirm the changes.
458 IN UINT32 TpmPpCommand
,
459 IN UINT32 TpmPpCommandParameter
470 CHAR16 TempBuffer
[1024];
471 CHAR16 TempBuffer2
[1024];
472 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
473 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability
;
474 UINT32 CurrentPCRBanks
;
480 BufSize
= CONFIRM_BUFFER_SIZE
;
481 ConfirmText
= AllocateZeroPool (BufSize
);
482 ASSERT (ConfirmText
!= NULL
);
484 mTcg2PpStringPackHandle
= HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid
, gImageHandle
, Tcg2PhysicalPresenceLibQemuStrings
, NULL
);
485 ASSERT (mTcg2PpStringPackHandle
!= NULL
);
487 switch (TpmPpCommand
) {
489 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
490 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
491 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
492 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
494 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
496 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
497 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
500 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
501 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
502 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
507 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
508 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
509 ASSERT_EFI_ERROR (Status
);
511 ProtocolCapability
.Size
= sizeof(ProtocolCapability
);
512 Status
= Tcg2Protocol
->GetCapability (
516 ASSERT_EFI_ERROR (Status
);
518 Status
= Tcg2Protocol
->GetActivePcrBanks (
522 ASSERT_EFI_ERROR (Status
);
525 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS
));
527 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
528 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
531 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1
));
532 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
535 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2
));
536 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
539 Tcg2FillBufferWithBootHashAlg (TempBuffer
, sizeof(TempBuffer
), TpmPpCommandParameter
);
540 Tcg2FillBufferWithBootHashAlg (TempBuffer2
, sizeof(TempBuffer2
), CurrentPCRBanks
);
542 TmpStr1
= AllocateZeroPool (BufSize
);
543 ASSERT (TmpStr1
!= NULL
);
544 UnicodeSPrint (TmpStr1
, BufSize
, L
"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks
, TempBuffer2
, TpmPpCommandParameter
, TempBuffer
);
546 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
547 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
552 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
554 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS
));
556 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
557 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
560 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1
));
561 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
564 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2
));
565 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
570 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
571 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID
));
573 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
574 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
578 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
579 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID
));
581 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
582 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
590 if (TmpStr2
== NULL
) {
591 FreePool (ConfirmText
);
595 // Console for user interaction
596 // We need to connect all trusted consoles for TCG PP. Here we treat all consoles in OVMF to be trusted consoles.
597 EfiBootManagerConnectAllDefaultConsoles ();
599 if (TpmPpCommand
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) {
601 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
603 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY
));
605 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
609 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO
));
610 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
614 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY
));
617 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY
));
619 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY
));
621 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
625 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO
));
626 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
630 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY
));
632 BufSize
-= StrSize (ConfirmText
);
633 UnicodeSPrint (ConfirmText
+ StrLen (ConfirmText
), BufSize
, TmpStr1
, TmpStr2
);
636 for (Index
= 0; Index
< StrLen (ConfirmText
); Index
+= 80) {
637 StrnCpyS (DstStr
, sizeof (DstStr
) / sizeof (CHAR16
), ConfirmText
+ Index
, sizeof (DstStr
) / sizeof (CHAR16
) - 1);
643 FreePool (ConfirmText
);
644 HiiRemovePackages (mTcg2PpStringPackHandle
);
646 if (Tcg2ReadUserKey (CautionKey
)) {
655 Check if there is a valid physical presence command request. Also updates parameter value
656 to whether the requested physical presence command already confirmed by user
658 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
659 True, it indicates the command doesn't require user confirm, or already confirmed
660 in last boot cycle by user.
661 False, it indicates the command need user confirm from UI.
663 @retval TRUE Physical Presence operation command is valid.
664 @retval FALSE Physical Presence operation command is invalid.
669 Tcg2HaveValidTpmRequest (
670 OUT BOOLEAN
*RequestConfirmed
673 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
676 *RequestConfirmed
= FALSE
;
678 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
680 // Need TCG2 protocol.
682 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
683 if (EFI_ERROR (Status
)) {
688 switch (mPpi
->Request
) {
689 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
690 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
691 *RequestConfirmed
= TRUE
;
694 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
695 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
696 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
697 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
698 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
699 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
700 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
701 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
706 // Wrong Physical Presence command
712 // Physical Presence command is correct
719 Check and execute the requested physical presence command.
721 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
725 Tcg2ExecutePendingTpmRequest (
726 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
729 BOOLEAN RequestConfirmed
;
731 if (mPpi
->Request
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
733 // No operation request
738 if (!Tcg2HaveValidTpmRequest (&RequestConfirmed
)) {
740 // Invalid operation request.
742 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
743 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_SUCCESS
;
745 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
747 mPpi
->LastRequest
= mPpi
->Request
;
748 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
749 mPpi
->RequestParameter
= 0;
753 if (!RequestConfirmed
) {
755 // Print confirm text and wait for approval.
757 RequestConfirmed
= Tcg2UserConfirm (mPpi
->Request
, mPpi
->RequestParameter
);
761 // Execute requested physical presence command
763 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
764 if (RequestConfirmed
) {
765 mPpi
->Response
= Tcg2ExecutePhysicalPresence (
768 mPpi
->RequestParameter
775 mPpi
->LastRequest
= mPpi
->Request
;
776 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
777 mPpi
->RequestParameter
= 0;
779 if (mPpi
->Response
== TCG_PP_OPERATION_RESPONSE_USER_ABORT
) {
784 // Reset system to make new TPM settings in effect
786 switch (mPpi
->LastRequest
) {
787 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
788 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
789 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
790 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
791 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
792 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
793 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
796 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
797 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
801 if (mPpi
->Request
!= TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
807 Print (L
"Rebooting system to make TPM2 settings in effect\n");
808 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
814 Check and execute the pending TPM request.
816 The TPM request may come from OS or BIOS. This API will display request information and wait
817 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
818 the TPM request is confirmed, and one or more reset may be required to make TPM request to
821 This API should be invoked after console in and console out are all ready as they are required
822 to display request information and get user input to confirm the request.
824 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
828 Tcg2PhysicalPresenceLibProcessRequest (
829 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
834 Status
= QemuTpmInitPPI ();
835 if (EFI_ERROR (Status
)) {
836 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
843 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
844 DEBUG ((DEBUG_INFO
, "S4 Resume, Skip TPM PP process!\n"));
848 DEBUG ((DEBUG_INFO
, "[TPM2PP] PPRequest=%x (PPRequestParameter=%x)\n", mPpi
->Request
, mPpi
->RequestParameter
));
849 Tcg2ExecutePendingTpmRequest (PlatformAuth
);
854 The handler for TPM physical presence function:
855 Return TPM Operation Response to OS Environment.
857 @param[out] MostRecentRequest Most recent operation request.
858 @param[out] Response Response to the most recent operation request.
860 @return Return Code for Return TPM Operation Response to OS Environment.
864 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
865 OUT UINT32
*MostRecentRequest
,
871 DEBUG ((DEBUG_INFO
, "[TPM2PP] ReturnOperationResponseToOsFunction\n"));
873 Status
= QemuTpmInitPPI ();
874 if (EFI_ERROR (Status
)) {
875 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
876 *MostRecentRequest
= 0;
878 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
881 *MostRecentRequest
= mPpi
->LastRequest
;
882 *Response
= mPpi
->Response
;
884 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
889 The handler for TPM physical presence function:
890 Submit TPM Operation Request to Pre-OS Environment and
891 Submit TPM Operation Request to Pre-OS Environment 2.
893 Caution: This function may receive untrusted input.
895 @param[in] OperationRequest TPM physical presence operation request.
896 @param[in] RequestParameter TPM physical presence operation request parameter.
898 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
899 Submit TPM Operation Request to Pre-OS Environment 2.
903 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
904 IN UINT32 OperationRequest
,
905 IN UINT32 RequestParameter
910 DEBUG ((DEBUG_INFO
, "[TPM2PP] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest
, RequestParameter
));
912 Status
= QemuTpmInitPPI ();
913 if (EFI_ERROR (Status
)) {
914 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
915 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
918 mPpi
->Request
= OperationRequest
;
919 mPpi
->RequestParameter
= RequestParameter
;
921 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;