diff options
| author | 2023-11-25 22:19:46 -0600 | |
|---|---|---|
| committer | 2023-11-25 23:40:01 -0600 | |
| commit | 281eb020ea6576e9525e35e4973313c39a553e8d (patch) | |
| tree | 131d570fa1dec936a5a7cb45b0e009b6b92a300b /src | |
| parent | Merge pull request #12153 from liamwhite/deck2 (diff) | |
| download | yuzu-281eb020ea6576e9525e35e4973313c39a553e8d.tar.gz yuzu-281eb020ea6576e9525e35e4973313c39a553e8d.tar.xz yuzu-281eb020ea6576e9525e35e4973313c39a553e8d.zip | |
service: nfc: Validate mii data
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/am/applets/applet_cabinet.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/ver3_store_data.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device.cpp | 68 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device.h | 1 |
4 files changed, 39 insertions, 34 deletions
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index b379dadeb..a88d9d2ce 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp | |||
| @@ -130,7 +130,7 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) | |||
| 130 | nfp_device->DeleteApplicationArea(); | 130 | nfp_device->DeleteApplicationArea(); |
| 131 | break; | 131 | break; |
| 132 | case Service::NFP::CabinetMode::StartRestorer: | 132 | case Service::NFP::CabinetMode::StartRestorer: |
| 133 | nfp_device->RestoreAmiibo(); | 133 | nfp_device->Restore(); |
| 134 | break; | 134 | break; |
| 135 | case Service::NFP::CabinetMode::StartFormatter: | 135 | case Service::NFP::CabinetMode::StartFormatter: |
| 136 | nfp_device->Format(); | 136 | nfp_device->Format(); |
diff --git a/src/core/hle/service/mii/types/ver3_store_data.cpp b/src/core/hle/service/mii/types/ver3_store_data.cpp index a019cc9f7..c27646fcf 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.cpp +++ b/src/core/hle/service/mii/types/ver3_store_data.cpp | |||
| @@ -98,7 +98,7 @@ void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { | 100 | void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { |
| 101 | version = 1; | 101 | version = 3; |
| 102 | mii_information.gender.Assign(static_cast<u8>(store_data.GetGender())); | 102 | mii_information.gender.Assign(static_cast<u8>(store_data.GetGender())); |
| 103 | mii_information.favorite_color.Assign(static_cast<u8>(store_data.GetFavoriteColor())); | 103 | mii_information.favorite_color.Assign(static_cast<u8>(store_data.GetFavoriteColor())); |
| 104 | height = store_data.GetHeight(); | 104 | height = store_data.GetHeight(); |
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index e7a00deb3..47516f883 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp | |||
| @@ -401,6 +401,12 @@ Result NfcDevice::SendCommandByPassThrough(const Time::Clock::TimeSpanType& time | |||
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target_) { | 403 | Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target_) { |
| 404 | bool is_corrupted = false; | ||
| 405 | |||
| 406 | if (model_type != NFP::ModelType::Amiibo) { | ||
| 407 | return ResultInvalidArgument; | ||
| 408 | } | ||
| 409 | |||
| 404 | if (device_state != DeviceState::TagFound) { | 410 | if (device_state != DeviceState::TagFound) { |
| 405 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | 411 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); |
| 406 | return ResultWrongDeviceState; | 412 | return ResultWrongDeviceState; |
| @@ -420,26 +426,32 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target | |||
| 420 | if (is_plain_amiibo) { | 426 | if (is_plain_amiibo) { |
| 421 | std::vector<u8> data(sizeof(NFP::NTAG215File)); | 427 | std::vector<u8> data(sizeof(NFP::NTAG215File)); |
| 422 | memcpy(data.data(), &tag_data, sizeof(tag_data)); | 428 | memcpy(data.data(), &tag_data, sizeof(tag_data)); |
| 423 | WriteBackupData(tag_data.uid, data); | 429 | } |
| 424 | 430 | ||
| 425 | device_state = DeviceState::TagMounted; | 431 | if (!is_plain_amiibo && !NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { |
| 426 | mount_target = mount_target_; | 432 | LOG_ERROR(Service_NFP, "Can't decode amiibo"); |
| 427 | return ResultSuccess; | 433 | is_corrupted = true; |
| 428 | } | 434 | } |
| 429 | 435 | ||
| 430 | if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { | 436 | if (tag_data.settings.settings.amiibo_initialized && !tag_data.owner_mii.IsValid()) { |
| 431 | bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess(); | 437 | LOG_ERROR(Service_NFP, "Invalid mii data"); |
| 432 | LOG_ERROR(Service_NFP, "Can't decode amiibo, has_backup= {}", has_backup); | 438 | is_corrupted = true; |
| 433 | return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData; | ||
| 434 | } | 439 | } |
| 435 | 440 | ||
| 436 | std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); | 441 | if (!is_corrupted) { |
| 437 | memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); | 442 | std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); |
| 438 | WriteBackupData(encrypted_tag_data.uuid, data); | 443 | memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); |
| 444 | WriteBackupData(encrypted_tag_data.uuid, data); | ||
| 445 | } | ||
| 439 | 446 | ||
| 440 | device_state = DeviceState::TagMounted; | 447 | device_state = DeviceState::TagMounted; |
| 441 | mount_target = mount_target_; | 448 | mount_target = mount_target_; |
| 442 | 449 | ||
| 450 | if (is_corrupted) { | ||
| 451 | bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess(); | ||
| 452 | return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData; | ||
| 453 | } | ||
| 454 | |||
| 443 | return ResultSuccess; | 455 | return ResultSuccess; |
| 444 | } | 456 | } |
| 445 | 457 | ||
| @@ -606,6 +618,17 @@ Result NfcDevice::Restore() { | |||
| 606 | } | 618 | } |
| 607 | } | 619 | } |
| 608 | 620 | ||
| 621 | // Restore mii data in case is corrupted by previous instances of yuzu | ||
| 622 | if (tag_data.settings.settings.amiibo_initialized && !tag_data.owner_mii.IsValid()) { | ||
| 623 | LOG_ERROR(Service_NFP, "Regenerating mii data"); | ||
| 624 | Mii::StoreData new_mii{}; | ||
| 625 | new_mii.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All); | ||
| 626 | new_mii.SetNickname({u'y', u'u', u'z', u'u', u'\0'}); | ||
| 627 | |||
| 628 | tag_data.owner_mii.BuildFromStoreData(new_mii); | ||
| 629 | tag_data.mii_extension.SetFromStoreData(new_mii); | ||
| 630 | } | ||
| 631 | |||
| 609 | // Overwrite tag contents with backup and mount the tag | 632 | // Overwrite tag contents with backup and mount the tag |
| 610 | tag_data = temporary_tag_data; | 633 | tag_data = temporary_tag_data; |
| 611 | encrypted_tag_data = temporary_encrypted_tag_data; | 634 | encrypted_tag_data = temporary_encrypted_tag_data; |
| @@ -851,25 +874,6 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe | |||
| 851 | return Flush(); | 874 | return Flush(); |
| 852 | } | 875 | } |
| 853 | 876 | ||
| 854 | Result NfcDevice::RestoreAmiibo() { | ||
| 855 | if (device_state != DeviceState::TagMounted) { | ||
| 856 | LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | ||
| 857 | if (device_state == DeviceState::TagRemoved) { | ||
| 858 | return ResultTagRemoved; | ||
| 859 | } | ||
| 860 | return ResultWrongDeviceState; | ||
| 861 | } | ||
| 862 | |||
| 863 | if (mount_target == NFP::MountTarget::None || mount_target == NFP::MountTarget::Rom) { | ||
| 864 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | ||
| 865 | return ResultWrongDeviceState; | ||
| 866 | } | ||
| 867 | |||
| 868 | // TODO: Load amiibo from backup on system | ||
| 869 | LOG_ERROR(Service_NFP, "Not Implemented"); | ||
| 870 | return ResultSuccess; | ||
| 871 | } | ||
| 872 | |||
| 873 | Result NfcDevice::Format() { | 877 | Result NfcDevice::Format() { |
| 874 | Result result = ResultSuccess; | 878 | Result result = ResultSuccess; |
| 875 | 879 | ||
| @@ -877,7 +881,9 @@ Result NfcDevice::Format() { | |||
| 877 | result = Mount(NFP::ModelType::Amiibo, NFP::MountTarget::All); | 881 | result = Mount(NFP::ModelType::Amiibo, NFP::MountTarget::All); |
| 878 | } | 882 | } |
| 879 | 883 | ||
| 880 | if (result.IsError()) { | 884 | // We are formatting all data. Corruption is not an issue. |
| 885 | if (result.IsError() && | ||
| 886 | (result != ResultCorruptedData && result != ResultCorruptedDataWithBackup)) { | ||
| 881 | return result; | 887 | return result; |
| 882 | } | 888 | } |
| 883 | 889 | ||
diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h index 0ed1ff34c..d8efe25ec 100644 --- a/src/core/hle/service/nfc/common/device.h +++ b/src/core/hle/service/nfc/common/device.h | |||
| @@ -68,7 +68,6 @@ public: | |||
| 68 | 68 | ||
| 69 | Result DeleteRegisterInfo(); | 69 | Result DeleteRegisterInfo(); |
| 70 | Result SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& register_info); | 70 | Result SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& register_info); |
| 71 | Result RestoreAmiibo(); | ||
| 72 | Result Format(); | 71 | Result Format(); |
| 73 | 72 | ||
| 74 | Result OpenApplicationArea(u32 access_id); | 73 | Result OpenApplicationArea(u32 access_id); |