1 /** @file 2 Execute pending TPM2 requests from OS or BIOS. 3 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. 7 8 Tpm2ExecutePendingTpmRequest() will receive untrusted input and do validation. 9 10 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR> 11 This program and the accompanying materials 12 are licensed and made available under the terms and conditions of the BSD License 13 which accompanies this distribution. The full text of the license may be found at 14 http://opensource.org/licenses/bsd-license.php 15 16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 18 19 **/ 20 21 #include <PiDxe.h> 22 23 #include <Protocol/Tcg2Protocol.h> 24 #include <Protocol/VariableLock.h> 25 #include <Library/DebugLib.h> 26 #include <Library/BaseMemoryLib.h> 27 #include <Library/UefiRuntimeServicesTableLib.h> 28 #include <Library/UefiDriverEntryPoint.h> 29 #include <Library/UefiBootServicesTableLib.h> 30 #include <Library/UefiLib.h> 31 #include <Library/MemoryAllocationLib.h> 32 #include <Library/PrintLib.h> 33 #include <Library/HiiLib.h> 34 #include <Library/HobLib.h> 35 #include <Guid/EventGroup.h> 36 #include <Guid/Tcg2PhysicalPresenceData.h> 37 #include <Library/Tpm2CommandLib.h> 38 #include <Library/Tcg2PhysicalPresenceLib.h> 39 #include <Library/Tcg2PpVendorLib.h> 40 41 #define CONFIRM_BUFFER_SIZE 4096 42 43 EFI_HII_HANDLE mTcg2PpStringPackHandle; 44 45 /** 46 Get string by string id from HII Interface. 47 48 @param[in] Id String ID. 49 50 @retval CHAR16 * String from ID. 51 @retval NULL If error occurs. 52 53 **/ 54 CHAR16 * 55 Tcg2PhysicalPresenceGetStringById ( 56 IN EFI_STRING_ID Id 57 ) 58 { 59 return HiiGetString (mTcg2PpStringPackHandle, Id, NULL); 60 } 61 62 /** 63 Send ClearControl and Clear command to TPM. 64 65 @param[in] PlatformAuth platform auth value. NULL means no platform auth change. 66 67 @retval EFI_SUCCESS Operation completed successfully. 68 @retval EFI_TIMEOUT The register can't run into the expected status in time. 69 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. 70 @retval EFI_DEVICE_ERROR Unexpected device behavior. 71 72 **/ 73 EFI_STATUS 74 EFIAPI 75 Tpm2CommandClear ( 76 IN TPM2B_AUTH *PlatformAuth OPTIONAL 77 ) 78 { 79 EFI_STATUS Status; 80 TPMS_AUTH_COMMAND *AuthSession; 81 TPMS_AUTH_COMMAND LocalAuthSession; 82 83 if (PlatformAuth == NULL) { 84 AuthSession = NULL; 85 } else { 86 AuthSession = &LocalAuthSession; 87 ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession)); 88 LocalAuthSession.sessionHandle = TPM_RS_PW; 89 LocalAuthSession.hmac.size = PlatformAuth->size; 90 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size); 91 } 92 93 DEBUG ((EFI_D_INFO, "Tpm2ClearControl ... \n")); 94 Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO); 95 DEBUG ((EFI_D_INFO, "Tpm2ClearControl - %r\n", Status)); 96 if (EFI_ERROR (Status)) { 97 goto Done; 98 } 99 DEBUG ((EFI_D_INFO, "Tpm2Clear ... \n")); 100 Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession); 101 DEBUG ((EFI_D_INFO, "Tpm2Clear - %r\n", Status)); 102 103 Done: 104 ZeroMem (&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac)); 105 return Status; 106 } 107 108 /** 109 Change EPS. 110 111 @param[in] PlatformAuth platform auth value. NULL means no platform auth change. 112 113 @retval EFI_SUCCESS Operation completed successfully. 114 **/ 115 EFI_STATUS 116 Tpm2CommandChangeEps ( 117 IN TPM2B_AUTH *PlatformAuth OPTIONAL 118 ) 119 { 120 EFI_STATUS Status; 121 TPMS_AUTH_COMMAND *AuthSession; 122 TPMS_AUTH_COMMAND LocalAuthSession; 123 124 if (PlatformAuth == NULL) { 125 AuthSession = NULL; 126 } else { 127 AuthSession = &LocalAuthSession; 128 ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession)); 129 LocalAuthSession.sessionHandle = TPM_RS_PW; 130 LocalAuthSession.hmac.size = PlatformAuth->size; 131 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size); 132 } 133 134 Status = Tpm2ChangeEPS (TPM_RH_PLATFORM, AuthSession); 135 DEBUG ((EFI_D_INFO, "Tpm2ChangeEPS - %r\n", Status)); 136 137 ZeroMem(&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac)); 138 return Status; 139 } 140 141 /** 142 Execute physical presence operation requested by the OS. 143 144 @param[in] PlatformAuth platform auth value. NULL means no platform auth change. 145 @param[in] CommandCode Physical presence operation value. 146 @param[in] CommandParameter Physical presence operation parameter. 147 @param[in, out] PpiFlags The physical presence interface flags. 148 149 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation. 150 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or 151 receiving response from TPM. 152 @retval Others Return code from the TPM device after command execution. 153 **/ 154 UINT32 155 Tcg2ExecutePhysicalPresence ( 156 IN TPM2B_AUTH *PlatformAuth, OPTIONAL 157 IN UINT32 CommandCode, 158 IN UINT32 CommandParameter, 159 IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *PpiFlags 160 ) 161 { 162 EFI_STATUS Status; 163 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap; 164 UINT32 ActivePcrBanks; 165 166 switch (CommandCode) { 167 case TCG2_PHYSICAL_PRESENCE_CLEAR: 168 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: 169 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: 170 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: 171 Status = Tpm2CommandClear (PlatformAuth); 172 if (EFI_ERROR (Status)) { 173 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; 174 } else { 175 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 176 } 177 178 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE: 179 PpiFlags->PPFlags |= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR; 180 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 181 182 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE: 183 PpiFlags->PPFlags &= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR; 184 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 185 186 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: 187 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks); 188 ASSERT_EFI_ERROR (Status); 189 Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, CommandParameter); 190 if (EFI_ERROR (Status)) { 191 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; 192 } else { 193 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 194 } 195 196 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: 197 Status = Tpm2CommandChangeEps (PlatformAuth); 198 if (EFI_ERROR (Status)) { 199 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; 200 } else { 201 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 202 } 203 204 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS: 205 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks); 206 ASSERT_EFI_ERROR (Status); 207 Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, TpmHashAlgorithmBitmap); 208 if (EFI_ERROR (Status)) { 209 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; 210 } else { 211 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 212 } 213 214 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: 215 PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID; 216 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 217 218 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: 219 PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID; 220 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 221 222 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE: 223 PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID; 224 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 225 226 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE: 227 PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID; 228 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 229 230 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE: 231 PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID; 232 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 233 234 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE: 235 PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID; 236 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 237 238 default: 239 if (CommandCode <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) { 240 return TCG_PP_OPERATION_RESPONSE_SUCCESS; 241 } else { 242 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; 243 } 244 } 245 } 246 247 248 /** 249 Read the specified key for user confirmation. 250 251 @param[in] CautionKey If true, F12 is used as confirm key; 252 If false, F10 is used as confirm key. 253 254 @retval TRUE User confirmed the changes by input. 255 @retval FALSE User discarded the changes. 256 **/ 257 BOOLEAN 258 Tcg2ReadUserKey ( 259 IN BOOLEAN CautionKey 260 ) 261 { 262 EFI_STATUS Status; 263 EFI_INPUT_KEY Key; 264 UINT16 InputKey; 265 266 InputKey = 0; 267 do { 268 Status = gBS->CheckEvent (gST->ConIn->WaitForKey); 269 if (!EFI_ERROR (Status)) { 270 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); 271 if (Key.ScanCode == SCAN_ESC) { 272 InputKey = Key.ScanCode; 273 } 274 if ((Key.ScanCode == SCAN_F10) && !CautionKey) { 275 InputKey = Key.ScanCode; 276 } 277 if ((Key.ScanCode == SCAN_F12) && CautionKey) { 278 InputKey = Key.ScanCode; 279 } 280 } 281 } while (InputKey == 0); 282 283 if (InputKey != SCAN_ESC) { 284 return TRUE; 285 } 286 287 return FALSE; 288 } 289 290 /** 291 Fill Buffer With BootHashAlg. 292 293 @param[in] Buffer Buffer to be filled. 294 @param[in] BufferSize Size of buffer. 295 @param[in] BootHashAlg BootHashAlg. 296 297 **/ 298 VOID 299 Tcg2FillBufferWithBootHashAlg ( 300 IN UINT16 *Buffer, 301 IN UINTN BufferSize, 302 IN UINT32 BootHashAlg 303 ) 304 { 305 Buffer[0] = 0; 306 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) { 307 if (Buffer[0] != 0) { 308 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 309 } 310 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 311 } 312 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) { 313 if (Buffer[0] != 0) { 314 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 315 } 316 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 317 } 318 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) { 319 if (Buffer[0] != 0) { 320 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 321 } 322 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 323 } 324 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) { 325 if (Buffer[0] != 0) { 326 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 327 } 328 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 329 } 330 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) { 331 if (Buffer[0] != 0) { 332 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 333 } 334 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1); 335 } 336 } 337 338 /** 339 Display the confirm text and get user confirmation. 340 341 @param[in] TpmPpCommand The requested TPM physical presence command. 342 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter. 343 344 @retval TRUE The user has confirmed the changes. 345 @retval FALSE The user doesn't confirm the changes. 346 **/ 347 BOOLEAN 348 Tcg2UserConfirm ( 349 IN UINT32 TpmPpCommand, 350 IN UINT32 TpmPpCommandParameter 351 ) 352 { 353 CHAR16 *ConfirmText; 354 CHAR16 *TmpStr1; 355 CHAR16 *TmpStr2; 356 UINTN BufSize; 357 BOOLEAN CautionKey; 358 BOOLEAN NoPpiInfo; 359 UINT16 Index; 360 CHAR16 DstStr[81]; 361 CHAR16 TempBuffer[1024]; 362 CHAR16 TempBuffer2[1024]; 363 EFI_TCG2_PROTOCOL *Tcg2Protocol; 364 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability; 365 UINT32 CurrentPCRBanks; 366 EFI_STATUS Status; 367 368 TmpStr2 = NULL; 369 CautionKey = FALSE; 370 NoPpiInfo = FALSE; 371 BufSize = CONFIRM_BUFFER_SIZE; 372 ConfirmText = AllocateZeroPool (BufSize); 373 ASSERT (ConfirmText != NULL); 374 375 mTcg2PpStringPackHandle = HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL); 376 ASSERT (mTcg2PpStringPackHandle != NULL); 377 378 switch (TpmPpCommand) { 379 380 case TCG2_PHYSICAL_PRESENCE_CLEAR: 381 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: 382 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: 383 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: 384 CautionKey = TRUE; 385 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); 386 387 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); 388 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 389 FreePool (TmpStr1); 390 391 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); 392 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 393 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 394 FreePool (TmpStr1); 395 396 break; 397 398 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE: 399 CautionKey = TRUE; 400 NoPpiInfo = TRUE; 401 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); 402 403 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR)); 404 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 405 FreePool (TmpStr1); 406 407 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR)); 408 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 409 FreePool (TmpStr1); 410 411 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); 412 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 413 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 414 FreePool (TmpStr1); 415 416 break; 417 418 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: 419 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol); 420 ASSERT_EFI_ERROR (Status); 421 422 ProtocolCapability.Size = sizeof(ProtocolCapability); 423 Status = Tcg2Protocol->GetCapability ( 424 Tcg2Protocol, 425 &ProtocolCapability 426 ); 427 ASSERT_EFI_ERROR (Status); 428 429 Status = Tcg2Protocol->GetActivePcrBanks ( 430 Tcg2Protocol, 431 &CurrentPCRBanks 432 ); 433 ASSERT_EFI_ERROR (Status); 434 435 CautionKey = TRUE; 436 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS)); 437 438 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); 439 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 440 FreePool (TmpStr1); 441 442 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1)); 443 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 444 FreePool (TmpStr1); 445 446 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2)); 447 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 448 FreePool (TmpStr1); 449 450 Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), TpmPpCommandParameter); 451 Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof(TempBuffer2), CurrentPCRBanks); 452 453 TmpStr1 = AllocateZeroPool (BufSize); 454 ASSERT (TmpStr1 != NULL); 455 UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandParameter, TempBuffer); 456 457 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 458 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 459 FreePool (TmpStr1); 460 461 break; 462 463 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: 464 CautionKey = TRUE; 465 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS)); 466 467 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); 468 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 469 FreePool (TmpStr1); 470 471 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1)); 472 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 473 FreePool (TmpStr1); 474 475 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2)); 476 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 477 FreePool (TmpStr1); 478 479 break; 480 481 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: 482 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID)); 483 484 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR)); 485 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 486 FreePool (TmpStr1); 487 break; 488 489 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: 490 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID)); 491 492 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR)); 493 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 494 FreePool (TmpStr1); 495 break; 496 497 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE: 498 NoPpiInfo = TRUE; 499 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_ENABLE_BLOCK_SID)); 500 501 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PPI_HEAD_STR)); 502 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 503 FreePool (TmpStr1); 504 break; 505 506 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE: 507 NoPpiInfo = TRUE; 508 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_DISABLE_BLOCK_SID)); 509 510 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PPI_HEAD_STR)); 511 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); 512 FreePool (TmpStr1); 513 break; 514 515 default: 516 ; 517 } 518 519 if (TmpStr2 == NULL) { 520 FreePool (ConfirmText); 521 return FALSE; 522 } 523 524 if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) { 525 if (CautionKey) { 526 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); 527 } else { 528 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); 529 } 530 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 531 FreePool (TmpStr1); 532 533 if (NoPpiInfo) { 534 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO)); 535 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 536 FreePool (TmpStr1); 537 } 538 539 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY)); 540 } else { 541 if (CautionKey) { 542 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY)); 543 } else { 544 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY)); 545 } 546 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 547 FreePool (TmpStr1); 548 549 if (NoPpiInfo) { 550 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO)); 551 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); 552 FreePool (TmpStr1); 553 } 554 555 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY)); 556 } 557 BufSize -= StrSize (ConfirmText); 558 UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2); 559 560 DstStr[80] = L'\0'; 561 for (Index = 0; Index < StrLen (ConfirmText); Index += 80) { 562 StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1); 563 Print (DstStr); 564 } 565 566 FreePool (TmpStr1); 567 FreePool (TmpStr2); 568 FreePool (ConfirmText); 569 HiiRemovePackages (mTcg2PpStringPackHandle); 570 571 if (Tcg2ReadUserKey (CautionKey)) { 572 return TRUE; 573 } 574 575 return FALSE; 576 } 577 578 /** 579 Check if there is a valid physical presence command request. Also updates parameter value 580 to whether the requested physical presence command already confirmed by user 581 582 @param[in] TcgPpData EFI Tcg2 Physical Presence request data. 583 @param[in] Flags The physical presence interface flags. 584 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI. 585 True, it indicates the command doesn't require user confirm, or already confirmed 586 in last boot cycle by user. 587 False, it indicates the command need user confirm from UI. 588 589 @retval TRUE Physical Presence operation command is valid. 590 @retval FALSE Physical Presence operation command is invalid. 591 592 **/ 593 BOOLEAN 594 Tcg2HaveValidTpmRequest ( 595 IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData, 596 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags, 597 OUT BOOLEAN *RequestConfirmed 598 ) 599 { 600 EFI_TCG2_PROTOCOL *Tcg2Protocol; 601 EFI_STATUS Status; 602 BOOLEAN IsRequestValid; 603 604 *RequestConfirmed = FALSE; 605 606 if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) { 607 // 608 // Need TCG2 protocol. 609 // 610 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol); 611 if (EFI_ERROR (Status)) { 612 return FALSE; 613 } 614 } 615 616 switch (TcgPpData->PPRequest) { 617 case TCG2_PHYSICAL_PRESENCE_NO_ACTION: 618 *RequestConfirmed = TRUE; 619 return TRUE; 620 621 case TCG2_PHYSICAL_PRESENCE_CLEAR: 622 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: 623 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: 624 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: 625 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) { 626 *RequestConfirmed = TRUE; 627 } 628 break; 629 630 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE: 631 *RequestConfirmed = TRUE; 632 break; 633 634 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE: 635 break; 636 637 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: 638 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) { 639 *RequestConfirmed = TRUE; 640 } 641 break; 642 643 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: 644 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) { 645 *RequestConfirmed = TRUE; 646 } 647 break; 648 649 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS: 650 *RequestConfirmed = TRUE; 651 break; 652 653 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: 654 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) { 655 *RequestConfirmed = TRUE; 656 } 657 break; 658 659 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: 660 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) { 661 *RequestConfirmed = TRUE; 662 } 663 break; 664 665 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE: 666 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE: 667 *RequestConfirmed = TRUE; 668 break; 669 670 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE: 671 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE: 672 break; 673 674 default: 675 if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) { 676 IsRequestValid = Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed); 677 if (!IsRequestValid) { 678 return FALSE; 679 } else { 680 break; 681 } 682 } else { 683 // 684 // Wrong Physical Presence command 685 // 686 return FALSE; 687 } 688 } 689 690 if ((Flags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) != 0) { 691 // 692 // It had been confirmed in last boot, it doesn't need confirm again. 693 // 694 *RequestConfirmed = TRUE; 695 } 696 697 // 698 // Physical Presence command is correct 699 // 700 return TRUE; 701 } 702 703 704 /** 705 Check and execute the requested physical presence command. 706 707 Caution: This function may receive untrusted input. 708 TcgPpData variable is external input, so this function will validate 709 its data structure to be valid value. 710 711 @param[in] PlatformAuth platform auth value. NULL means no platform auth change. 712 @param[in, out] TcgPpData Pointer to the physical presence NV variable. 713 @param[in, out] Flags Pointer to the physical presence interface flags. 714 **/ 715 VOID 716 Tcg2ExecutePendingTpmRequest ( 717 IN TPM2B_AUTH *PlatformAuth, OPTIONAL 718 IN OUT EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData, 719 IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *Flags 720 ) 721 { 722 EFI_STATUS Status; 723 UINTN DataSize; 724 BOOLEAN RequestConfirmed; 725 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags; 726 BOOLEAN ResetRequired; 727 UINT32 NewPPFlags; 728 729 if (TcgPpData->PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) { 730 // 731 // No operation request 732 // 733 return; 734 } 735 736 if (!Tcg2HaveValidTpmRequest(TcgPpData, *Flags, &RequestConfirmed)) { 737 // 738 // Invalid operation request. 739 // 740 if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) { 741 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_SUCCESS; 742 } else { 743 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; 744 } 745 TcgPpData->LastPPRequest = TcgPpData->PPRequest; 746 TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION; 747 TcgPpData->PPRequestParameter = 0; 748 749 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 750 Status = gRT->SetVariable ( 751 TCG2_PHYSICAL_PRESENCE_VARIABLE, 752 &gEfiTcg2PhysicalPresenceGuid, 753 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 754 DataSize, 755 TcgPpData 756 ); 757 return; 758 } 759 760 ResetRequired = FALSE; 761 if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) { 762 NewFlags = *Flags; 763 NewPPFlags = NewFlags.PPFlags; 764 TcgPpData->PPResponse = Tcg2PpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired); 765 NewFlags.PPFlags = NewPPFlags; 766 } else { 767 if (!RequestConfirmed) { 768 // 769 // Print confirm text and wait for approval. 770 // 771 RequestConfirmed = Tcg2UserConfirm (TcgPpData->PPRequest, TcgPpData->PPRequestParameter); 772 } 773 774 // 775 // Execute requested physical presence command 776 // 777 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT; 778 NewFlags = *Flags; 779 if (RequestConfirmed) { 780 TcgPpData->PPResponse = Tcg2ExecutePhysicalPresence ( 781 PlatformAuth, 782 TcgPpData->PPRequest, 783 TcgPpData->PPRequestParameter, 784 &NewFlags 785 ); 786 } 787 } 788 789 // 790 // Save the flags if it is updated. 791 // 792 if (CompareMem (Flags, &NewFlags, sizeof(EFI_TCG2_PHYSICAL_PRESENCE_FLAGS)) != 0) { 793 *Flags = NewFlags; 794 Status = gRT->SetVariable ( 795 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, 796 &gEfiTcg2PhysicalPresenceGuid, 797 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 798 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS), 799 &NewFlags 800 ); 801 } 802 803 // 804 // Clear request 805 // 806 if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) == 0) { 807 TcgPpData->LastPPRequest = TcgPpData->PPRequest; 808 TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION; 809 TcgPpData->PPRequestParameter = 0; 810 } 811 812 // 813 // Save changes 814 // 815 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 816 Status = gRT->SetVariable ( 817 TCG2_PHYSICAL_PRESENCE_VARIABLE, 818 &gEfiTcg2PhysicalPresenceGuid, 819 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 820 DataSize, 821 TcgPpData 822 ); 823 if (EFI_ERROR (Status)) { 824 return; 825 } 826 827 if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) { 828 return; 829 } 830 831 // 832 // Reset system to make new TPM settings in effect 833 // 834 switch (TcgPpData->LastPPRequest) { 835 case TCG2_PHYSICAL_PRESENCE_CLEAR: 836 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: 837 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: 838 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: 839 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: 840 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: 841 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS: 842 break; 843 844 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: 845 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: 846 break; 847 848 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE: 849 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE: 850 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE: 851 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE: 852 return; 853 854 default: 855 if (TcgPpData->LastPPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) { 856 if (ResetRequired) { 857 break; 858 } else { 859 return ; 860 } 861 } 862 if (TcgPpData->PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) { 863 break; 864 } 865 return; 866 } 867 868 Print (L"Rebooting system to make TPM2 settings in effect\n"); 869 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); 870 ASSERT (FALSE); 871 } 872 873 /** 874 Check and execute the pending TPM request. 875 876 The TPM request may come from OS or BIOS. This API will display request information and wait 877 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after 878 the TPM request is confirmed, and one or more reset may be required to make TPM request to 879 take effect. 880 881 This API should be invoked after console in and console out are all ready as they are required 882 to display request information and get user input to confirm the request. 883 884 @param[in] PlatformAuth platform auth value. NULL means no platform auth change. 885 **/ 886 VOID 887 EFIAPI 888 Tcg2PhysicalPresenceLibProcessRequest ( 889 IN TPM2B_AUTH *PlatformAuth OPTIONAL 890 ) 891 { 892 EFI_STATUS Status; 893 UINTN DataSize; 894 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData; 895 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol; 896 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags; 897 898 // 899 // This flags variable controls whether physical presence is required for TPM command. 900 // It should be protected from malicious software. We set it as read-only variable here. 901 // 902 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol); 903 if (!EFI_ERROR (Status)) { 904 Status = VariableLockProtocol->RequestToLock ( 905 VariableLockProtocol, 906 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, 907 &gEfiTcg2PhysicalPresenceGuid 908 ); 909 if (EFI_ERROR (Status)) { 910 DEBUG ((EFI_D_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status)); 911 ASSERT_EFI_ERROR (Status); 912 } 913 } 914 915 // 916 // Check S4 resume 917 // 918 if (GetBootModeHob () == BOOT_ON_S4_RESUME) { 919 DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n")); 920 return ; 921 } 922 923 // 924 // Initialize physical presence flags. 925 // 926 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); 927 Status = gRT->GetVariable ( 928 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, 929 &gEfiTcg2PhysicalPresenceGuid, 930 NULL, 931 &DataSize, 932 &PpiFlags 933 ); 934 if (EFI_ERROR (Status)) { 935 PpiFlags.PPFlags = PcdGet32(PcdTcg2PhysicalPresenceFlags); 936 Status = gRT->SetVariable ( 937 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, 938 &gEfiTcg2PhysicalPresenceGuid, 939 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 940 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS), 941 &PpiFlags 942 ); 943 if (EFI_ERROR (Status)) { 944 DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status)); 945 return ; 946 } 947 DEBUG((DEBUG_INFO, "[TPM2] Initial physical presence flags value is 0x%x\n", PpiFlags.PPFlags)); 948 } 949 950 // 951 // Initialize physical presence variable. 952 // 953 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 954 Status = gRT->GetVariable ( 955 TCG2_PHYSICAL_PRESENCE_VARIABLE, 956 &gEfiTcg2PhysicalPresenceGuid, 957 NULL, 958 &DataSize, 959 &TcgPpData 960 ); 961 if (EFI_ERROR (Status)) { 962 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData)); 963 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 964 Status = gRT->SetVariable ( 965 TCG2_PHYSICAL_PRESENCE_VARIABLE, 966 &gEfiTcg2PhysicalPresenceGuid, 967 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 968 DataSize, 969 &TcgPpData 970 ); 971 if (EFI_ERROR (Status)) { 972 DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status)); 973 return ; 974 } 975 } 976 977 DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest)); 978 979 // 980 // Execute pending TPM request. 981 // 982 Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, &PpiFlags); 983 DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags)); 984 985 } 986 987 /** 988 Check if the pending TPM request needs user input to confirm. 989 990 The TPM request may come from OS. This API will check if TPM request exists and need user 991 input to confirmation. 992 993 @retval TRUE TPM needs input to confirm user physical presence. 994 @retval FALSE TPM doesn't need input to confirm user physical presence. 995 996 **/ 997 BOOLEAN 998 EFIAPI 999 Tcg2PhysicalPresenceLibNeedUserConfirm( 1000 VOID 1001 ) 1002 { 1003 EFI_STATUS Status; 1004 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData; 1005 UINTN DataSize; 1006 BOOLEAN RequestConfirmed; 1007 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags; 1008 1009 // 1010 // Check S4 resume 1011 // 1012 if (GetBootModeHob () == BOOT_ON_S4_RESUME) { 1013 DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n")); 1014 return FALSE; 1015 } 1016 1017 // 1018 // Check Tpm requests 1019 // 1020 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 1021 Status = gRT->GetVariable ( 1022 TCG2_PHYSICAL_PRESENCE_VARIABLE, 1023 &gEfiTcg2PhysicalPresenceGuid, 1024 NULL, 1025 &DataSize, 1026 &TcgPpData 1027 ); 1028 if (EFI_ERROR (Status)) { 1029 return FALSE; 1030 } 1031 1032 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); 1033 Status = gRT->GetVariable ( 1034 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, 1035 &gEfiTcg2PhysicalPresenceGuid, 1036 NULL, 1037 &DataSize, 1038 &PpiFlags 1039 ); 1040 if (EFI_ERROR (Status)) { 1041 return FALSE; 1042 } 1043 1044 if (TcgPpData.PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) { 1045 // 1046 // No operation request 1047 // 1048 return FALSE; 1049 } 1050 1051 if (!Tcg2HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) { 1052 // 1053 // Invalid operation request. 1054 // 1055 return FALSE; 1056 } 1057 1058 if (!RequestConfirmed) { 1059 // 1060 // Need UI to confirm 1061 // 1062 return TRUE; 1063 } 1064 1065 return FALSE; 1066 } 1067 1068 1069 /** 1070 The handler for TPM physical presence function: 1071 Return TPM Operation Response to OS Environment. 1072 1073 @param[out] MostRecentRequest Most recent operation request. 1074 @param[out] Response Response to the most recent operation request. 1075 1076 @return Return Code for Return TPM Operation Response to OS Environment. 1077 **/ 1078 UINT32 1079 EFIAPI 1080 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction ( 1081 OUT UINT32 *MostRecentRequest, 1082 OUT UINT32 *Response 1083 ) 1084 { 1085 EFI_STATUS Status; 1086 UINTN DataSize; 1087 EFI_TCG2_PHYSICAL_PRESENCE PpData; 1088 1089 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n")); 1090 1091 // 1092 // Get the Physical Presence variable 1093 // 1094 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 1095 Status = gRT->GetVariable ( 1096 TCG2_PHYSICAL_PRESENCE_VARIABLE, 1097 &gEfiTcg2PhysicalPresenceGuid, 1098 NULL, 1099 &DataSize, 1100 &PpData 1101 ); 1102 if (EFI_ERROR (Status)) { 1103 *MostRecentRequest = 0; 1104 *Response = 0; 1105 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status)); 1106 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE; 1107 } 1108 1109 *MostRecentRequest = PpData.LastPPRequest; 1110 *Response = PpData.PPResponse; 1111 1112 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS; 1113 } 1114 1115 /** 1116 The handler for TPM physical presence function: 1117 Submit TPM Operation Request to Pre-OS Environment and 1118 Submit TPM Operation Request to Pre-OS Environment 2. 1119 1120 Caution: This function may receive untrusted input. 1121 1122 @param[in] OperationRequest TPM physical presence operation request. 1123 @param[in] RequestParameter TPM physical presence operation request parameter. 1124 1125 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and 1126 Submit TPM Operation Request to Pre-OS Environment 2. 1127 **/ 1128 UINT32 1129 EFIAPI 1130 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction ( 1131 IN UINT32 OperationRequest, 1132 IN UINT32 RequestParameter 1133 ) 1134 { 1135 EFI_STATUS Status; 1136 UINTN DataSize; 1137 EFI_TCG2_PHYSICAL_PRESENCE PpData; 1138 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags; 1139 1140 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter)); 1141 1142 // 1143 // Get the Physical Presence variable 1144 // 1145 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 1146 Status = gRT->GetVariable ( 1147 TCG2_PHYSICAL_PRESENCE_VARIABLE, 1148 &gEfiTcg2PhysicalPresenceGuid, 1149 NULL, 1150 &DataSize, 1151 &PpData 1152 ); 1153 if (EFI_ERROR (Status)) { 1154 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status)); 1155 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE; 1156 } 1157 1158 if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) && 1159 (OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) ) { 1160 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED; 1161 } 1162 1163 if ((PpData.PPRequest != OperationRequest) || 1164 (PpData.PPRequestParameter != RequestParameter)) { 1165 PpData.PPRequest = (UINT8)OperationRequest; 1166 PpData.PPRequestParameter = RequestParameter; 1167 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE); 1168 Status = gRT->SetVariable ( 1169 TCG2_PHYSICAL_PRESENCE_VARIABLE, 1170 &gEfiTcg2PhysicalPresenceGuid, 1171 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 1172 DataSize, 1173 &PpData 1174 ); 1175 if (EFI_ERROR (Status)) { 1176 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status)); 1177 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE; 1178 } 1179 } 1180 1181 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) { 1182 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); 1183 Status = gRT->GetVariable ( 1184 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, 1185 &gEfiTcg2PhysicalPresenceGuid, 1186 NULL, 1187 &DataSize, 1188 &Flags 1189 ); 1190 if (EFI_ERROR (Status)) { 1191 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT | TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT; 1192 } 1193 return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter); 1194 } 1195 1196 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS; 1197 } 1198 1199 /** 1200 Return TPM2 ManagementFlags set by PP interface. 1201 1202 @retval ManagementFlags TPM2 Management Flags. 1203 **/ 1204 UINT32 1205 EFIAPI 1206 Tcg2PhysicalPresenceLibGetManagementFlags ( 1207 VOID 1208 ) 1209 { 1210 EFI_STATUS Status; 1211 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags; 1212 UINTN DataSize; 1213 1214 DEBUG ((EFI_D_INFO, "[TPM2] GetManagementFlags\n")); 1215 1216 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); 1217 Status = gRT->GetVariable ( 1218 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, 1219 &gEfiTcg2PhysicalPresenceGuid, 1220 NULL, 1221 &DataSize, 1222 &PpiFlags 1223 ); 1224 if (EFI_ERROR (Status)) { 1225 PpiFlags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT | TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT; 1226 } 1227 return PpiFlags.PPFlags; 1228 } 1229