/** Check and execute the requested physical presence command. Caution: This function may receive untrusted input. TcgPpData variable is external input, so this function will validate its data structure to be valid value. @param[in] TcgProtocol EFI TCG Protocol instance. @param[in] TcgPpData Point to the physical presence NV variable. @param[in] Flags The physical presence interface flags. **/ VOID ExecutePendingTpmRequest ( IN EFI_TCG_PROTOCOL *TcgProtocol, IN EFI_PHYSICAL_PRESENCE *TcgPpData, IN UINT8 Flags ) { EFI_STATUS Status; UINTN DataSize; BOOLEAN RequestConfirmed; UINT8 NewFlags; if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) { // // Invalid operation request. // TcgPpData->PPResponse = TPM_PP_BIOS_FAILURE; TcgPpData->LastPPRequest = TcgPpData->PPRequest; TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; DataSize = sizeof (EFI_PHYSICAL_PRESENCE); Status = gRT->SetVariable ( PHYSICAL_PRESENCE_VARIABLE, &gEfiPhysicalPresenceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, DataSize, TcgPpData ); return; } if (!RequestConfirmed) { // // Print confirm text and wait for approval. // RequestConfirmed = UserConfirm (TcgPpData->PPRequest); } // // Execute requested physical presence command // TcgPpData->PPResponse = TPM_PP_USER_ABORT; NewFlags = Flags; if (RequestConfirmed) { TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &NewFlags); } // // Save the flags if it is updated. // if (Flags != NewFlags) { Status = gRT->SetVariable ( PHYSICAL_PRESENCE_FLAGS_VARIABLE, &gEfiPhysicalPresenceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (UINT8), &NewFlags ); if (EFI_ERROR (Status)) { return; } } // // Clear request // if ((NewFlags & FLAG_RESET_TRACK) == 0) { TcgPpData->LastPPRequest = TcgPpData->PPRequest; TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; } // // Save changes // DataSize = sizeof (EFI_PHYSICAL_PRESENCE); Status = gRT->SetVariable ( PHYSICAL_PRESENCE_VARIABLE, &gEfiPhysicalPresenceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, DataSize, TcgPpData ); if (EFI_ERROR (Status)) { return; } if (TcgPpData->PPResponse == TPM_PP_USER_ABORT) { return; } // // Reset system to make new TPM settings in effect // switch (TcgPpData->LastPPRequest) { case PHYSICAL_PRESENCE_ACTIVATE: case PHYSICAL_PRESENCE_DEACTIVATE: case PHYSICAL_PRESENCE_CLEAR: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: break; default: if (TcgPpData->PPRequest != PHYSICAL_PRESENCE_NO_ACTION) { break; } return; } Print (L"Rebooting system to make TPM settings in effect\n"); gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); ASSERT (FALSE); }
/** Check and execute the requested physical presence command. Caution: This function may receive untrusted input. TcgPpData variable is external input, so this function will validate its data structure to be valid value. @param[in] TcgProtocol EFI TCG Protocol instance. @param[in] TcgPpData Point to the physical presence NV variable. **/ VOID ExecutePendingTpmRequest ( IN EFI_TCG_PROTOCOL *TcgProtocol, IN EFI_PHYSICAL_PRESENCE *TcgPpData ) { EFI_STATUS Status; UINTN DataSize; UINT8 Flags; BOOLEAN RequestConfirmed; Flags = TcgPpData->Flags; RequestConfirmed = FALSE; switch (TcgPpData->PPRequest) { case PHYSICAL_PRESENCE_NO_ACTION: return; case PHYSICAL_PRESENCE_ENABLE: case PHYSICAL_PRESENCE_DISABLE: case PHYSICAL_PRESENCE_ACTIVATE: case PHYSICAL_PRESENCE_DEACTIVATE: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: if ((Flags & FLAG_NO_PPI_PROVISION) != 0) { RequestConfirmed = TRUE; } break; case PHYSICAL_PRESENCE_CLEAR: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: if ((Flags & FLAG_NO_PPI_CLEAR) != 0) { RequestConfirmed = TRUE; } break; case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: if ((Flags & FLAG_NO_PPI_MAINTENANCE) != 0) { RequestConfirmed = TRUE; } break; case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: if ((Flags & FLAG_NO_PPI_CLEAR) != 0 && (Flags & FLAG_NO_PPI_PROVISION) != 0) { RequestConfirmed = TRUE; } break; case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE: case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE: case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE: RequestConfirmed = TRUE; break; default: // // Invalid operation request. // TcgPpData->PPResponse = TPM_PP_BIOS_FAILURE; TcgPpData->LastPPRequest = TcgPpData->PPRequest; TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; DataSize = sizeof (EFI_PHYSICAL_PRESENCE); Status = gRT->SetVariable ( PHYSICAL_PRESENCE_VARIABLE, &gEfiPhysicalPresenceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, DataSize, TcgPpData ); return; } if ((Flags & FLAG_RESET_TRACK) != 0) { // // It had been confirmed in last boot, it doesn't need confirm again. // RequestConfirmed = TRUE; } if (!RequestConfirmed) { // // Print confirm text and wait for approval. // RequestConfirmed = UserConfirm (TcgPpData->PPRequest); } // // Execute requested physical presence command // TcgPpData->PPResponse = TPM_PP_USER_ABORT; if (RequestConfirmed) { TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &TcgPpData->Flags); } // // Clear request // if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) { TcgPpData->LastPPRequest = TcgPpData->PPRequest; TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; } // // Save changes // DataSize = sizeof (EFI_PHYSICAL_PRESENCE); Status = gRT->SetVariable ( PHYSICAL_PRESENCE_VARIABLE, &gEfiPhysicalPresenceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, DataSize, TcgPpData ); if (EFI_ERROR (Status)) { return; } if (TcgPpData->PPResponse == TPM_PP_USER_ABORT) { return; } // // Reset system to make new TPM settings in effect // switch (TcgPpData->LastPPRequest) { case PHYSICAL_PRESENCE_ACTIVATE: case PHYSICAL_PRESENCE_DEACTIVATE: case PHYSICAL_PRESENCE_CLEAR: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: break; default: if (TcgPpData->PPRequest != PHYSICAL_PRESENCE_NO_ACTION) { break; } return; } Print (L"Rebooting system to make TPM settings in effect\n"); gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); ASSERT (FALSE); }