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>
36 #include <Library/Tcg2PhysicalPresenceLib.h>
38 #define CONFIRM_BUFFER_SIZE 4096
40 EFI_HII_HANDLE mTcg2PpStringPackHandle
;
42 #define TPM_PPI_FLAGS (QEMU_TPM_PPI_FUNC_ALLOWED_USR_REQ)
44 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
);
81 Initializes QEMU PPI memory region.
83 @retval EFI_SUCCESS Operation completed successfully.
84 @retval EFI_PROTOCOL_ERROR PPI address is invalid.
93 QEMU_FWCFG_TPM_CONFIG Config
;
94 EFI_PHYSICAL_ADDRESS PpiAddress64
;
95 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
102 Status
= QemuTpmReadConfig (&Config
);
103 if (EFI_ERROR (Status
)) {
107 mPpi
= (QEMU_TPM_PPI
*)(UINTN
)Config
.PpiAddress
;
109 return EFI_PROTOCOL_ERROR
;
112 DEBUG ((DEBUG_INFO
, "[TPM2PP] mPpi=%p version=%d\n", mPpi
, Config
.TpmVersion
));
114 PpiAddress64
= (UINTN
)mPpi
;
115 if ((PpiAddress64
& ~(UINT64
)EFI_PAGE_MASK
) !=
116 ((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
;
126 if (!EFI_ERROR (Status
) &&
127 (Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeMemoryMappedIo
&&
128 Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeNonExistent
)) {
129 DEBUG ((DEBUG_ERROR
, "[TPM2PP] mPpi has an invalid memory type\n"));
130 goto InvalidPpiAddress
;
133 for (Idx
= 0; Idx
< ARRAY_SIZE (mPpi
->Func
); Idx
++) {
136 if (Config
.TpmVersion
== QEMU_TPM_VERSION_2
) {
137 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_NO_ACTION
] = TPM_PPI_FLAGS
;
138 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CLEAR
] = TPM_PPI_FLAGS
;
139 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
] = TPM_PPI_FLAGS
;
140 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
] = TPM_PPI_FLAGS
;
141 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
] = TPM_PPI_FLAGS
;
142 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
] = TPM_PPI_FLAGS
;
143 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
] = TPM_PPI_FLAGS
;
144 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
] = TPM_PPI_FLAGS
;
145 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
146 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
151 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
152 mPpi
->LastRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
153 mPpi
->NextStep
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
160 return EFI_PROTOCOL_ERROR
;
165 Get string by string id from HII Interface.
167 @param[in] Id String ID.
169 @retval CHAR16 * String from ID.
170 @retval NULL If error occurs.
175 Tcg2PhysicalPresenceGetStringById (
179 return HiiGetString (mTcg2PpStringPackHandle
, Id
, NULL
);
184 Send ClearControl and Clear command to TPM.
186 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
188 @retval EFI_SUCCESS Operation completed successfully.
189 @retval EFI_TIMEOUT The register can't run into the expected status in time.
190 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
191 @retval EFI_DEVICE_ERROR Unexpected device behavior.
197 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
201 TPMS_AUTH_COMMAND
*AuthSession
;
202 TPMS_AUTH_COMMAND LocalAuthSession
;
204 if (PlatformAuth
== NULL
) {
207 AuthSession
= &LocalAuthSession
;
208 ZeroMem (&LocalAuthSession
, sizeof (LocalAuthSession
));
209 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
210 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
211 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
214 DEBUG ((DEBUG_INFO
, "Tpm2ClearControl ... \n"));
215 Status
= Tpm2ClearControl (TPM_RH_PLATFORM
, AuthSession
, NO
);
216 DEBUG ((DEBUG_INFO
, "Tpm2ClearControl - %r\n", Status
));
217 if (EFI_ERROR (Status
)) {
220 DEBUG ((DEBUG_INFO
, "Tpm2Clear ... \n"));
221 Status
= Tpm2Clear (TPM_RH_PLATFORM
, AuthSession
);
222 DEBUG ((DEBUG_INFO
, "Tpm2Clear - %r\n", Status
));
225 ZeroMem (&LocalAuthSession
.hmac
, sizeof (LocalAuthSession
.hmac
));
233 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
235 @retval EFI_SUCCESS Operation completed successfully.
239 Tpm2CommandChangeEps (
240 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
244 TPMS_AUTH_COMMAND
*AuthSession
;
245 TPMS_AUTH_COMMAND LocalAuthSession
;
247 if (PlatformAuth
== NULL
) {
250 AuthSession
= &LocalAuthSession
;
251 ZeroMem (&LocalAuthSession
, sizeof (LocalAuthSession
));
252 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
253 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
254 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
257 Status
= Tpm2ChangeEPS (TPM_RH_PLATFORM
, AuthSession
);
258 DEBUG ((DEBUG_INFO
, "Tpm2ChangeEPS - %r\n", Status
));
260 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
;
352 Read the specified key for user confirmation.
354 @param[in] CautionKey If true, F12 is used as confirm key;
355 If false, F10 is used as confirm key.
357 @retval TRUE User confirmed the changes by input.
358 @retval FALSE User discarded the changes.
363 IN BOOLEAN CautionKey
372 Status
= gBS
->CheckEvent (gST
->ConIn
->WaitForKey
);
373 if (!EFI_ERROR (Status
)) {
374 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
375 if (Key
.ScanCode
== SCAN_ESC
) {
376 InputKey
= Key
.ScanCode
;
378 if ((Key
.ScanCode
== SCAN_F10
) && !CautionKey
) {
379 InputKey
= Key
.ScanCode
;
381 if ((Key
.ScanCode
== SCAN_F12
) && CautionKey
) {
382 InputKey
= Key
.ScanCode
;
385 } while (InputKey
== 0);
387 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);
416 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA1", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
418 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
419 if (Buffer
[0] != 0) {
420 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
422 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
424 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
425 if (Buffer
[0] != 0) {
426 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
428 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA384", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
430 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
431 if (Buffer
[0] != 0) {
432 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
434 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA512", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
436 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
437 if (Buffer
[0] != 0) {
438 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
440 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SM3_256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
446 Display the confirm text and get user confirmation.
448 @param[in] TpmPpCommand The requested TPM physical presence command.
449 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
451 @retval TRUE The user has confirmed the changes.
452 @retval FALSE The user doesn't confirm the changes.
457 IN UINT32 TpmPpCommand
,
458 IN UINT32 TpmPpCommandParameter
469 CHAR16 TempBuffer
[1024];
470 CHAR16 TempBuffer2
[1024];
471 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
472 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability
;
473 UINT32 CurrentPCRBanks
;
479 BufSize
= CONFIRM_BUFFER_SIZE
;
480 ConfirmText
= AllocateZeroPool (BufSize
);
481 ASSERT (ConfirmText
!= NULL
);
483 mTcg2PpStringPackHandle
= HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid
, gImageHandle
, Tcg2PhysicalPresenceLibQemuStrings
, NULL
);
484 ASSERT (mTcg2PpStringPackHandle
!= NULL
);
486 switch (TpmPpCommand
) {
488 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
489 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
490 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
491 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
493 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
495 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
496 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
499 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
500 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
501 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
506 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
507 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
508 ASSERT_EFI_ERROR (Status
);
510 ProtocolCapability
.Size
= sizeof(ProtocolCapability
);
511 Status
= Tcg2Protocol
->GetCapability (
515 ASSERT_EFI_ERROR (Status
);
517 Status
= Tcg2Protocol
->GetActivePcrBanks (
521 ASSERT_EFI_ERROR (Status
);
524 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS
));
526 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
527 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
530 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1
));
531 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
534 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2
));
535 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
538 Tcg2FillBufferWithBootHashAlg (TempBuffer
, sizeof(TempBuffer
), TpmPpCommandParameter
);
539 Tcg2FillBufferWithBootHashAlg (TempBuffer2
, sizeof(TempBuffer2
), CurrentPCRBanks
);
541 TmpStr1
= AllocateZeroPool (BufSize
);
542 ASSERT (TmpStr1
!= NULL
);
543 UnicodeSPrint (TmpStr1
, BufSize
, L
"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks
, TempBuffer2
, TpmPpCommandParameter
, TempBuffer
);
545 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
546 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
551 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
553 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS
));
555 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
556 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
559 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1
));
560 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
563 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2
));
564 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
569 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
570 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID
));
572 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
573 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
577 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
578 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID
));
580 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
581 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
589 if (TmpStr2
== NULL
) {
590 FreePool (ConfirmText
);
594 if (TpmPpCommand
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) {
596 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
598 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY
));
600 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
604 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO
));
605 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
609 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY
));
612 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY
));
614 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY
));
616 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
620 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO
));
621 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
625 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY
));
627 BufSize
-= StrSize (ConfirmText
);
628 UnicodeSPrint (ConfirmText
+ StrLen (ConfirmText
), BufSize
, TmpStr1
, TmpStr2
);
631 for (Index
= 0; Index
< StrLen (ConfirmText
); Index
+= 80) {
632 StrnCpyS (DstStr
, sizeof (DstStr
) / sizeof (CHAR16
), ConfirmText
+ Index
, sizeof (DstStr
) / sizeof (CHAR16
) - 1);
638 FreePool (ConfirmText
);
639 HiiRemovePackages (mTcg2PpStringPackHandle
);
641 if (Tcg2ReadUserKey (CautionKey
)) {
650 Check if there is a valid physical presence command request. Also updates parameter value
651 to whether the requested physical presence command already confirmed by user
653 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
654 True, it indicates the command doesn't require user confirm, or already confirmed
655 in last boot cycle by user.
656 False, it indicates the command need user confirm from UI.
658 @retval TRUE Physical Presence operation command is valid.
659 @retval FALSE Physical Presence operation command is invalid.
664 Tcg2HaveValidTpmRequest (
665 OUT BOOLEAN
*RequestConfirmed
668 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
671 *RequestConfirmed
= FALSE
;
673 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
675 // Need TCG2 protocol.
677 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
678 if (EFI_ERROR (Status
)) {
683 switch (mPpi
->Request
) {
684 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
685 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
686 *RequestConfirmed
= TRUE
;
689 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
690 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
691 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
692 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
693 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
694 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
695 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
696 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
701 // Wrong Physical Presence command
707 // Physical Presence command is correct
714 Check and execute the requested physical presence command.
716 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
720 Tcg2ExecutePendingTpmRequest (
721 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
724 BOOLEAN RequestConfirmed
;
726 if (mPpi
->Request
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
728 // No operation request
733 if (!Tcg2HaveValidTpmRequest (&RequestConfirmed
)) {
735 // Invalid operation request.
737 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
738 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_SUCCESS
;
740 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
742 mPpi
->LastRequest
= mPpi
->Request
;
743 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
744 mPpi
->RequestParameter
= 0;
748 if (!RequestConfirmed
) {
750 // Print confirm text and wait for approval.
752 RequestConfirmed
= Tcg2UserConfirm (mPpi
->Request
, mPpi
->RequestParameter
);
756 // Execute requested physical presence command
758 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
759 if (RequestConfirmed
) {
760 mPpi
->Response
= Tcg2ExecutePhysicalPresence (
763 mPpi
->RequestParameter
770 mPpi
->LastRequest
= mPpi
->Request
;
771 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
772 mPpi
->RequestParameter
= 0;
774 if (mPpi
->Response
== TCG_PP_OPERATION_RESPONSE_USER_ABORT
) {
779 // Reset system to make new TPM settings in effect
781 switch (mPpi
->LastRequest
) {
782 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
783 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
784 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
785 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
786 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
787 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
788 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
791 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
792 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
796 if (mPpi
->Request
!= TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
802 Print (L
"Rebooting system to make TPM2 settings in effect\n");
803 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
809 Check and execute the pending TPM request.
811 The TPM request may come from OS or BIOS. This API will display request information and wait
812 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
813 the TPM request is confirmed, and one or more reset may be required to make TPM request to
816 This API should be invoked after console in and console out are all ready as they are required
817 to display request information and get user input to confirm the request.
819 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
823 Tcg2PhysicalPresenceLibProcessRequest (
824 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
829 Status
= QemuTpmInitPPI ();
830 if (EFI_ERROR (Status
)) {
831 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
838 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
839 DEBUG ((DEBUG_INFO
, "S4 Resume, Skip TPM PP process!\n"));
843 DEBUG ((DEBUG_INFO
, "[TPM2PP] PPRequest=%x (PPRequestParameter=%x)\n", mPpi
->Request
, mPpi
->RequestParameter
));
844 Tcg2ExecutePendingTpmRequest (PlatformAuth
);
849 The handler for TPM physical presence function:
850 Return TPM Operation Response to OS Environment.
852 @param[out] MostRecentRequest Most recent operation request.
853 @param[out] Response Response to the most recent operation request.
855 @return Return Code for Return TPM Operation Response to OS Environment.
859 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
860 OUT UINT32
*MostRecentRequest
,
866 DEBUG ((DEBUG_INFO
, "[TPM2PP] ReturnOperationResponseToOsFunction\n"));
868 Status
= QemuTpmInitPPI ();
869 if (EFI_ERROR (Status
)) {
870 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
871 *MostRecentRequest
= 0;
873 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
876 *MostRecentRequest
= mPpi
->LastRequest
;
877 *Response
= mPpi
->Response
;
879 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
884 The handler for TPM physical presence function:
885 Submit TPM Operation Request to Pre-OS Environment and
886 Submit TPM Operation Request to Pre-OS Environment 2.
888 Caution: This function may receive untrusted input.
890 @param[in] OperationRequest TPM physical presence operation request.
891 @param[in] RequestParameter TPM physical presence operation request parameter.
893 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
894 Submit TPM Operation Request to Pre-OS Environment 2.
898 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
899 IN UINT32 OperationRequest
,
900 IN UINT32 RequestParameter
905 DEBUG ((DEBUG_INFO
, "[TPM2PP] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest
, RequestParameter
));
907 Status
= QemuTpmInitPPI ();
908 if (EFI_ERROR (Status
)) {
909 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
910 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
913 mPpi
->Request
= OperationRequest
;
914 mPpi
->RequestParameter
= RequestParameter
;
916 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;