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 This program and the accompanying materials
14 are licensed and made available under the terms and conditions of the BSD License
15 which accompanies this distribution. The full text of the license may be found at
16 http://opensource.org/licenses/bsd-license.php
18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 #include <Guid/Tcg2PhysicalPresenceData.h>
26 #include <IndustryStandard/QemuTpm.h>
27 #include <Protocol/Tcg2Protocol.h>
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/DxeServicesTableLib.h>
32 #include <Library/HiiLib.h>
33 #include <Library/HobLib.h>
34 #include <Library/MemoryAllocationLib.h>
35 #include <Library/PrintLib.h>
36 #include <Library/QemuFwCfgLib.h>
37 #include <Library/Tpm2CommandLib.h>
38 #include <Library/UefiBootServicesTableLib.h>
39 #include <Library/UefiLib.h>
40 #include <Library/UefiRuntimeServicesTableLib.h>
42 #include <Library/Tcg2PhysicalPresenceLib.h>
44 #define CONFIRM_BUFFER_SIZE 4096
46 EFI_HII_HANDLE mTcg2PpStringPackHandle
;
48 #define TPM_PPI_FLAGS (QEMU_TPM_PPI_FUNC_ALLOWED_USR_REQ)
50 STATIC
volatile QEMU_TPM_PPI
*mPpi
;
54 Reads QEMU PPI config from fw_cfg.
56 @param[out] The Config structure to read to.
58 @retval EFI_SUCCESS Operation completed successfully.
59 @retval EFI_PROTOCOL_ERROR Invalid fw_cfg entry size.
64 OUT QEMU_FWCFG_TPM_CONFIG
*Config
68 FIRMWARE_CONFIG_ITEM FwCfgItem
;
71 Status
= QemuFwCfgFindFile ("etc/tpm/config", &FwCfgItem
, &FwCfgSize
);
72 if (EFI_ERROR (Status
)) {
76 if (FwCfgSize
!= sizeof (*Config
)) {
77 return EFI_PROTOCOL_ERROR
;
80 QemuFwCfgSelectItem (FwCfgItem
);
81 QemuFwCfgReadBytes (sizeof (*Config
), Config
);
87 Initializes QEMU PPI memory region.
89 @retval EFI_SUCCESS Operation completed successfully.
90 @retval EFI_PROTOCOL_ERROR PPI address is invalid.
99 QEMU_FWCFG_TPM_CONFIG Config
;
100 EFI_PHYSICAL_ADDRESS PpiAddress64
;
101 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
108 Status
= QemuTpmReadConfig (&Config
);
109 if (EFI_ERROR (Status
)) {
113 mPpi
= (QEMU_TPM_PPI
*)(UINTN
)Config
.PpiAddress
;
115 return EFI_PROTOCOL_ERROR
;
118 DEBUG ((DEBUG_INFO
, "[TPM2PP] mPpi=%p version=%d\n", mPpi
, Config
.TpmVersion
));
120 PpiAddress64
= (UINTN
)mPpi
;
121 if ((PpiAddress64
& ~(UINT64
)EFI_PAGE_MASK
) !=
122 ((PpiAddress64
+ sizeof *mPpi
- 1) & ~(UINT64
)EFI_PAGE_MASK
)) {
123 DEBUG ((DEBUG_ERROR
, "[TPM2PP] mPpi crosses a page boundary\n"));
124 goto InvalidPpiAddress
;
127 Status
= gDS
->GetMemorySpaceDescriptor (PpiAddress64
, &Descriptor
);
128 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
129 ASSERT_EFI_ERROR (Status
);
130 goto InvalidPpiAddress
;
132 if (!EFI_ERROR (Status
) &&
133 (Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeMemoryMappedIo
&&
134 Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeNonExistent
)) {
135 DEBUG ((DEBUG_ERROR
, "[TPM2PP] mPpi has an invalid memory type\n"));
136 goto InvalidPpiAddress
;
139 for (Idx
= 0; Idx
< ARRAY_SIZE (mPpi
->Func
); Idx
++) {
142 if (Config
.TpmVersion
== QEMU_TPM_VERSION_2
) {
143 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_NO_ACTION
] = TPM_PPI_FLAGS
;
144 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CLEAR
] = TPM_PPI_FLAGS
;
145 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
] = TPM_PPI_FLAGS
;
146 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
] = TPM_PPI_FLAGS
;
147 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
] = TPM_PPI_FLAGS
;
148 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
] = TPM_PPI_FLAGS
;
149 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
] = TPM_PPI_FLAGS
;
150 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
] = TPM_PPI_FLAGS
;
151 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
152 mPpi
->Func
[TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
] = TPM_PPI_FLAGS
;
157 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
158 mPpi
->LastRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
159 mPpi
->NextStep
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
166 return EFI_PROTOCOL_ERROR
;
171 Get string by string id from HII Interface.
173 @param[in] Id String ID.
175 @retval CHAR16 * String from ID.
176 @retval NULL If error occurs.
181 Tcg2PhysicalPresenceGetStringById (
185 return HiiGetString (mTcg2PpStringPackHandle
, Id
, NULL
);
190 Send ClearControl and Clear command to TPM.
192 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
194 @retval EFI_SUCCESS Operation completed successfully.
195 @retval EFI_TIMEOUT The register can't run into the expected status in time.
196 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
197 @retval EFI_DEVICE_ERROR Unexpected device behavior.
203 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
207 TPMS_AUTH_COMMAND
*AuthSession
;
208 TPMS_AUTH_COMMAND LocalAuthSession
;
210 if (PlatformAuth
== NULL
) {
213 AuthSession
= &LocalAuthSession
;
214 ZeroMem (&LocalAuthSession
, sizeof (LocalAuthSession
));
215 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
216 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
217 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
220 DEBUG ((DEBUG_INFO
, "Tpm2ClearControl ... \n"));
221 Status
= Tpm2ClearControl (TPM_RH_PLATFORM
, AuthSession
, NO
);
222 DEBUG ((DEBUG_INFO
, "Tpm2ClearControl - %r\n", Status
));
223 if (EFI_ERROR (Status
)) {
226 DEBUG ((DEBUG_INFO
, "Tpm2Clear ... \n"));
227 Status
= Tpm2Clear (TPM_RH_PLATFORM
, AuthSession
);
228 DEBUG ((DEBUG_INFO
, "Tpm2Clear - %r\n", Status
));
231 ZeroMem (&LocalAuthSession
.hmac
, sizeof (LocalAuthSession
.hmac
));
239 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
241 @retval EFI_SUCCESS Operation completed successfully.
245 Tpm2CommandChangeEps (
246 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
250 TPMS_AUTH_COMMAND
*AuthSession
;
251 TPMS_AUTH_COMMAND LocalAuthSession
;
253 if (PlatformAuth
== NULL
) {
256 AuthSession
= &LocalAuthSession
;
257 ZeroMem (&LocalAuthSession
, sizeof (LocalAuthSession
));
258 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
259 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
260 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
263 Status
= Tpm2ChangeEPS (TPM_RH_PLATFORM
, AuthSession
);
264 DEBUG ((DEBUG_INFO
, "Tpm2ChangeEPS - %r\n", Status
));
266 ZeroMem (&LocalAuthSession
.hmac
, sizeof(LocalAuthSession
.hmac
));
272 Execute physical presence operation requested by the OS.
274 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
275 @param[in] CommandCode Physical presence operation value.
276 @param[in] CommandParameter Physical presence operation parameter.
278 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
279 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
280 receiving response from TPM.
281 @retval Others Return code from the TPM device after command execution.
285 Tcg2ExecutePhysicalPresence (
286 IN TPM2B_AUTH
*PlatformAuth
, OPTIONAL
287 IN UINT32 CommandCode
,
288 IN UINT32 CommandParameter
292 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap
;
293 UINT32 ActivePcrBanks
;
295 switch (CommandCode
) {
296 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
297 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
298 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
299 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
300 Status
= Tpm2CommandClear (PlatformAuth
);
301 if (EFI_ERROR (Status
)) {
302 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
304 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
307 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
308 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePcrBanks
);
309 ASSERT_EFI_ERROR (Status
);
312 // PP spec requirements:
313 // Firmware should check that all requested (set) hashing algorithms are supported with respective PCR banks.
314 // Firmware has to ensure that at least one PCR banks is active.
315 // If not, an error is returned and no action is taken.
317 if (CommandParameter
== 0 || (CommandParameter
& (~TpmHashAlgorithmBitmap
)) != 0) {
318 DEBUG((DEBUG_ERROR
, "PCR banks %x to allocate are not supported by TPM. Skip operation\n", CommandParameter
));
319 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
322 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, CommandParameter
);
323 if (EFI_ERROR (Status
)) {
324 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
326 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
329 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
330 Status
= Tpm2CommandChangeEps (PlatformAuth
);
331 if (EFI_ERROR (Status
)) {
332 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
334 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
337 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
338 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap
, &ActivePcrBanks
);
339 ASSERT_EFI_ERROR (Status
);
340 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, TpmHashAlgorithmBitmap
, TpmHashAlgorithmBitmap
);
341 if (EFI_ERROR (Status
)) {
342 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
344 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
348 if (CommandCode
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
349 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
351 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
358 Read the specified key for user confirmation.
360 @param[in] CautionKey If true, F12 is used as confirm key;
361 If false, F10 is used as confirm key.
363 @retval TRUE User confirmed the changes by input.
364 @retval FALSE User discarded the changes.
369 IN BOOLEAN CautionKey
378 Status
= gBS
->CheckEvent (gST
->ConIn
->WaitForKey
);
379 if (!EFI_ERROR (Status
)) {
380 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
381 if (Key
.ScanCode
== SCAN_ESC
) {
382 InputKey
= Key
.ScanCode
;
384 if ((Key
.ScanCode
== SCAN_F10
) && !CautionKey
) {
385 InputKey
= Key
.ScanCode
;
387 if ((Key
.ScanCode
== SCAN_F12
) && CautionKey
) {
388 InputKey
= Key
.ScanCode
;
391 } while (InputKey
== 0);
393 if (InputKey
!= SCAN_ESC
) {
402 Fill Buffer With BootHashAlg.
404 @param[in] Buffer Buffer to be filled.
405 @param[in] BufferSize Size of buffer.
406 @param[in] BootHashAlg BootHashAlg.
411 Tcg2FillBufferWithBootHashAlg (
414 IN UINT32 BootHashAlg
418 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 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
"SHA1", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
424 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 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
"SHA256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
430 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 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
"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);
440 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA512", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
442 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
443 if (Buffer
[0] != 0) {
444 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
446 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SM3_256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
452 Display the confirm text and get user confirmation.
454 @param[in] TpmPpCommand The requested TPM physical presence command.
455 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
457 @retval TRUE The user has confirmed the changes.
458 @retval FALSE The user doesn't confirm the changes.
463 IN UINT32 TpmPpCommand
,
464 IN UINT32 TpmPpCommandParameter
475 CHAR16 TempBuffer
[1024];
476 CHAR16 TempBuffer2
[1024];
477 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
478 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability
;
479 UINT32 CurrentPCRBanks
;
485 BufSize
= CONFIRM_BUFFER_SIZE
;
486 ConfirmText
= AllocateZeroPool (BufSize
);
487 ASSERT (ConfirmText
!= NULL
);
489 mTcg2PpStringPackHandle
= HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid
, gImageHandle
, Tcg2PhysicalPresenceLibQemuStrings
, NULL
);
490 ASSERT (mTcg2PpStringPackHandle
!= NULL
);
492 switch (TpmPpCommand
) {
494 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
495 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
496 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
497 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
499 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
501 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
502 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
505 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
506 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
507 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
512 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
513 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
514 ASSERT_EFI_ERROR (Status
);
516 ProtocolCapability
.Size
= sizeof(ProtocolCapability
);
517 Status
= Tcg2Protocol
->GetCapability (
521 ASSERT_EFI_ERROR (Status
);
523 Status
= Tcg2Protocol
->GetActivePcrBanks (
527 ASSERT_EFI_ERROR (Status
);
530 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS
));
532 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
533 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
536 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1
));
537 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
540 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2
));
541 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
544 Tcg2FillBufferWithBootHashAlg (TempBuffer
, sizeof(TempBuffer
), TpmPpCommandParameter
);
545 Tcg2FillBufferWithBootHashAlg (TempBuffer2
, sizeof(TempBuffer2
), CurrentPCRBanks
);
547 TmpStr1
= AllocateZeroPool (BufSize
);
548 ASSERT (TmpStr1
!= NULL
);
549 UnicodeSPrint (TmpStr1
, BufSize
, L
"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks
, TempBuffer2
, TpmPpCommandParameter
, TempBuffer
);
551 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
552 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
557 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
559 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS
));
561 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
562 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
565 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1
));
566 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
569 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2
));
570 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
575 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
576 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID
));
578 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
579 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
583 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
584 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID
));
586 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR
));
587 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
595 if (TmpStr2
== NULL
) {
596 FreePool (ConfirmText
);
600 if (TpmPpCommand
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) {
602 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
604 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY
));
606 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
610 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO
));
611 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
615 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY
));
618 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY
));
620 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY
));
622 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
626 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO
));
627 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
631 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY
));
633 BufSize
-= StrSize (ConfirmText
);
634 UnicodeSPrint (ConfirmText
+ StrLen (ConfirmText
), BufSize
, TmpStr1
, TmpStr2
);
637 for (Index
= 0; Index
< StrLen (ConfirmText
); Index
+= 80) {
638 StrnCpyS (DstStr
, sizeof (DstStr
) / sizeof (CHAR16
), ConfirmText
+ Index
, sizeof (DstStr
) / sizeof (CHAR16
) - 1);
644 FreePool (ConfirmText
);
645 HiiRemovePackages (mTcg2PpStringPackHandle
);
647 if (Tcg2ReadUserKey (CautionKey
)) {
656 Check if there is a valid physical presence command request. Also updates parameter value
657 to whether the requested physical presence command already confirmed by user
659 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
660 True, it indicates the command doesn't require user confirm, or already confirmed
661 in last boot cycle by user.
662 False, it indicates the command need user confirm from UI.
664 @retval TRUE Physical Presence operation command is valid.
665 @retval FALSE Physical Presence operation command is invalid.
670 Tcg2HaveValidTpmRequest (
671 OUT BOOLEAN
*RequestConfirmed
674 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
677 *RequestConfirmed
= FALSE
;
679 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
681 // Need TCG2 protocol.
683 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
684 if (EFI_ERROR (Status
)) {
689 switch (mPpi
->Request
) {
690 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
691 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
692 *RequestConfirmed
= TRUE
;
695 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
696 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
697 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
698 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
699 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
700 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
701 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
702 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
707 // Wrong Physical Presence command
713 // Physical Presence command is correct
720 Check and execute the requested physical presence command.
722 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
726 Tcg2ExecutePendingTpmRequest (
727 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
730 BOOLEAN RequestConfirmed
;
732 if (mPpi
->Request
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
734 // No operation request
739 if (!Tcg2HaveValidTpmRequest (&RequestConfirmed
)) {
741 // Invalid operation request.
743 if (mPpi
->Request
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
744 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_SUCCESS
;
746 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
748 mPpi
->LastRequest
= mPpi
->Request
;
749 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
750 mPpi
->RequestParameter
= 0;
754 if (!RequestConfirmed
) {
756 // Print confirm text and wait for approval.
758 RequestConfirmed
= Tcg2UserConfirm (mPpi
->Request
, mPpi
->RequestParameter
);
762 // Execute requested physical presence command
764 mPpi
->Response
= TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
765 if (RequestConfirmed
) {
766 mPpi
->Response
= Tcg2ExecutePhysicalPresence (
769 mPpi
->RequestParameter
776 mPpi
->LastRequest
= mPpi
->Request
;
777 mPpi
->Request
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
778 mPpi
->RequestParameter
= 0;
780 if (mPpi
->Response
== TCG_PP_OPERATION_RESPONSE_USER_ABORT
) {
785 // Reset system to make new TPM settings in effect
787 switch (mPpi
->LastRequest
) {
788 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
789 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
790 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
791 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
792 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
793 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
794 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
797 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
798 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
802 if (mPpi
->Request
!= TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
808 Print (L
"Rebooting system to make TPM2 settings in effect\n");
809 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
815 Check and execute the pending TPM request.
817 The TPM request may come from OS or BIOS. This API will display request information and wait
818 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
819 the TPM request is confirmed, and one or more reset may be required to make TPM request to
822 This API should be invoked after console in and console out are all ready as they are required
823 to display request information and get user input to confirm the request.
825 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
829 Tcg2PhysicalPresenceLibProcessRequest (
830 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
835 Status
= QemuTpmInitPPI ();
836 if (EFI_ERROR (Status
)) {
837 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
844 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
845 DEBUG ((DEBUG_INFO
, "S4 Resume, Skip TPM PP process!\n"));
849 DEBUG ((DEBUG_INFO
, "[TPM2PP] PPRequest=%x (PPRequestParameter=%x)\n", mPpi
->Request
, mPpi
->RequestParameter
));
850 Tcg2ExecutePendingTpmRequest (PlatformAuth
);
855 The handler for TPM physical presence function:
856 Return TPM Operation Response to OS Environment.
858 @param[out] MostRecentRequest Most recent operation request.
859 @param[out] Response Response to the most recent operation request.
861 @return Return Code for Return TPM Operation Response to OS Environment.
865 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
866 OUT UINT32
*MostRecentRequest
,
872 DEBUG ((DEBUG_INFO
, "[TPM2PP] ReturnOperationResponseToOsFunction\n"));
874 Status
= QemuTpmInitPPI ();
875 if (EFI_ERROR (Status
)) {
876 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
877 *MostRecentRequest
= 0;
879 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
882 *MostRecentRequest
= mPpi
->LastRequest
;
883 *Response
= mPpi
->Response
;
885 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
890 The handler for TPM physical presence function:
891 Submit TPM Operation Request to Pre-OS Environment and
892 Submit TPM Operation Request to Pre-OS Environment 2.
894 Caution: This function may receive untrusted input.
896 @param[in] OperationRequest TPM physical presence operation request.
897 @param[in] RequestParameter TPM physical presence operation request parameter.
899 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
900 Submit TPM Operation Request to Pre-OS Environment 2.
904 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
905 IN UINT32 OperationRequest
,
906 IN UINT32 RequestParameter
911 DEBUG ((DEBUG_INFO
, "[TPM2PP] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest
, RequestParameter
));
913 Status
= QemuTpmInitPPI ();
914 if (EFI_ERROR (Status
)) {
915 DEBUG ((DEBUG_INFO
, "[TPM2PP] no PPI\n"));
916 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
919 mPpi
->Request
= OperationRequest
;
920 mPpi
->RequestParameter
= RequestParameter
;
922 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;