diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/kernel/k_memory_block_manager.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/amiibo_crypto.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device.cpp | 67 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device.h | 3 |
4 files changed, 54 insertions, 27 deletions
diff --git a/src/core/hle/kernel/k_memory_block_manager.h b/src/core/hle/kernel/k_memory_block_manager.h index 7c0bd16f0..96496e990 100644 --- a/src/core/hle/kernel/k_memory_block_manager.h +++ b/src/core/hle/kernel/k_memory_block_manager.h | |||
| @@ -144,14 +144,10 @@ private: | |||
| 144 | 144 | ||
| 145 | class KScopedMemoryBlockManagerAuditor { | 145 | class KScopedMemoryBlockManagerAuditor { |
| 146 | public: | 146 | public: |
| 147 | explicit KScopedMemoryBlockManagerAuditor(KMemoryBlockManager* m) : m_manager(m) { | 147 | explicit KScopedMemoryBlockManagerAuditor(KMemoryBlockManager* m) : m_manager(m) {} |
| 148 | ASSERT(m_manager->CheckState()); | ||
| 149 | } | ||
| 150 | explicit KScopedMemoryBlockManagerAuditor(KMemoryBlockManager& m) | 148 | explicit KScopedMemoryBlockManagerAuditor(KMemoryBlockManager& m) |
| 151 | : KScopedMemoryBlockManagerAuditor(std::addressof(m)) {} | 149 | : KScopedMemoryBlockManagerAuditor(std::addressof(m)) {} |
| 152 | ~KScopedMemoryBlockManagerAuditor() { | 150 | ~KScopedMemoryBlockManagerAuditor() = default; |
| 153 | ASSERT(m_manager->CheckState()); | ||
| 154 | } | ||
| 155 | 151 | ||
| 156 | private: | 152 | private: |
| 157 | KMemoryBlockManager* m_manager; | 153 | KMemoryBlockManager* m_manager; |
diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.cpp b/src/core/hle/service/nfc/common/amiibo_crypto.cpp index f3901ee8d..b2bcb68c3 100644 --- a/src/core/hle/service/nfc/common/amiibo_crypto.cpp +++ b/src/core/hle/service/nfc/common/amiibo_crypto.cpp | |||
| @@ -52,9 +52,6 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) { | |||
| 52 | if (ntag_file.compability_container != 0xEEFF10F1U) { | 52 | if (ntag_file.compability_container != 0xEEFF10F1U) { |
| 53 | return false; | 53 | return false; |
| 54 | } | 54 | } |
| 55 | if (amiibo_data.constant_value != 0xA5) { | ||
| 56 | return false; | ||
| 57 | } | ||
| 58 | if (amiibo_data.model_info.tag_type != NFC::PackedTagType::Type2) { | 55 | if (amiibo_data.model_info.tag_type != NFC::PackedTagType::Type2) { |
| 59 | return false; | 56 | return false; |
| 60 | } | 57 | } |
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 8a7e9edac..0bd7900e1 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp | |||
| @@ -119,18 +119,31 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) { | |||
| 119 | 119 | ||
| 120 | memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); | 120 | memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); |
| 121 | is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data); | 121 | is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data); |
| 122 | is_write_protected = false; | ||
| 122 | 123 | ||
| 124 | device_state = DeviceState::TagFound; | ||
| 125 | deactivate_event->GetReadableEvent().Clear(); | ||
| 126 | activate_event->Signal(); | ||
| 127 | |||
| 128 | // Fallback for plain amiibos | ||
| 123 | if (is_plain_amiibo) { | 129 | if (is_plain_amiibo) { |
| 124 | encrypted_tag_data = NFP::AmiiboCrypto::EncodedDataToNfcData(tag_data); | ||
| 125 | LOG_INFO(Service_NFP, "Using plain amiibo"); | 130 | LOG_INFO(Service_NFP, "Using plain amiibo"); |
| 126 | } else { | 131 | encrypted_tag_data = NFP::AmiiboCrypto::EncodedDataToNfcData(tag_data); |
| 127 | tag_data = {}; | 132 | return true; |
| 133 | } | ||
| 134 | |||
| 135 | // Fallback for encrypted amiibos without keys | ||
| 136 | if (!NFP::AmiiboCrypto::IsKeyAvailable()) { | ||
| 137 | LOG_INFO(Service_NFC, "Loading amiibo without keys"); | ||
| 128 | memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); | 138 | memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); |
| 139 | BuildAmiiboWithoutKeys(); | ||
| 140 | is_plain_amiibo = true; | ||
| 141 | is_write_protected = true; | ||
| 142 | return true; | ||
| 129 | } | 143 | } |
| 130 | 144 | ||
| 131 | device_state = DeviceState::TagFound; | 145 | tag_data = {}; |
| 132 | deactivate_event->GetReadableEvent().Clear(); | 146 | memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); |
| 133 | activate_event->Signal(); | ||
| 134 | return true; | 147 | return true; |
| 135 | } | 148 | } |
| 136 | 149 | ||
| @@ -346,23 +359,15 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target | |||
| 346 | return ResultWrongDeviceState; | 359 | return ResultWrongDeviceState; |
| 347 | } | 360 | } |
| 348 | 361 | ||
| 349 | // The loaded amiibo is not encrypted | ||
| 350 | if (is_plain_amiibo) { | ||
| 351 | device_state = DeviceState::TagMounted; | ||
| 352 | mount_target = mount_target_; | ||
| 353 | return ResultSuccess; | ||
| 354 | } | ||
| 355 | |||
| 356 | if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { | 362 | if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { |
| 357 | LOG_ERROR(Service_NFP, "Not an amiibo"); | 363 | LOG_ERROR(Service_NFP, "Not an amiibo"); |
| 358 | return ResultNotAnAmiibo; | 364 | return ResultNotAnAmiibo; |
| 359 | } | 365 | } |
| 360 | 366 | ||
| 361 | // Mark amiibos as read only when keys are missing | 367 | // The loaded amiibo is not encrypted |
| 362 | if (!NFP::AmiiboCrypto::IsKeyAvailable()) { | 368 | if (is_plain_amiibo) { |
| 363 | LOG_ERROR(Service_NFP, "No keys detected"); | ||
| 364 | device_state = DeviceState::TagMounted; | 369 | device_state = DeviceState::TagMounted; |
| 365 | mount_target = NFP::MountTarget::Rom; | 370 | mount_target = mount_target_; |
| 366 | return ResultSuccess; | 371 | return ResultSuccess; |
| 367 | } | 372 | } |
| 368 | 373 | ||
| @@ -457,6 +462,11 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) { | |||
| 457 | return ResultWrongDeviceState; | 462 | return ResultWrongDeviceState; |
| 458 | } | 463 | } |
| 459 | 464 | ||
| 465 | if (is_write_protected) { | ||
| 466 | LOG_ERROR(Service_NFP, "No keys available skipping write request"); | ||
| 467 | return ResultSuccess; | ||
| 468 | } | ||
| 469 | |||
| 460 | std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); | 470 | std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); |
| 461 | if (is_plain_amiibo) { | 471 | if (is_plain_amiibo) { |
| 462 | memcpy(data.data(), &tag_data, sizeof(tag_data)); | 472 | memcpy(data.data(), &tag_data, sizeof(tag_data)); |
| @@ -1033,7 +1043,6 @@ Result NfcDevice::GetAll(NFP::NfpData& data) const { | |||
| 1033 | } | 1043 | } |
| 1034 | 1044 | ||
| 1035 | NFP::CommonInfo common_info{}; | 1045 | NFP::CommonInfo common_info{}; |
| 1036 | Service::Mii::MiiManager manager; | ||
| 1037 | const u64 application_id = tag_data.application_id; | 1046 | const u64 application_id = tag_data.application_id; |
| 1038 | 1047 | ||
| 1039 | GetCommonInfo(common_info); | 1048 | GetCommonInfo(common_info); |
| @@ -1249,6 +1258,28 @@ void NfcDevice::UpdateRegisterInfoCrc() { | |||
| 1249 | tag_data.register_info_crc = crc.checksum(); | 1258 | tag_data.register_info_crc = crc.checksum(); |
| 1250 | } | 1259 | } |
| 1251 | 1260 | ||
| 1261 | void NfcDevice::BuildAmiiboWithoutKeys() { | ||
| 1262 | Service::Mii::MiiManager manager; | ||
| 1263 | auto& settings = tag_data.settings; | ||
| 1264 | |||
| 1265 | tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_tag_data); | ||
| 1266 | |||
| 1267 | // Common info | ||
| 1268 | tag_data.write_counter = 0; | ||
| 1269 | tag_data.amiibo_version = 0; | ||
| 1270 | settings.write_date = GetAmiiboDate(GetCurrentPosixTime()); | ||
| 1271 | |||
| 1272 | // Register info | ||
| 1273 | SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); | ||
| 1274 | settings.settings.font_region.Assign(0); | ||
| 1275 | settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); | ||
| 1276 | tag_data.owner_mii = manager.BuildFromStoreData(manager.BuildDefault(0)); | ||
| 1277 | |||
| 1278 | // Admin info | ||
| 1279 | settings.settings.amiibo_initialized.Assign(1); | ||
| 1280 | settings.settings.appdata_initialized.Assign(0); | ||
| 1281 | } | ||
| 1282 | |||
| 1252 | u64 NfcDevice::GetHandle() const { | 1283 | u64 NfcDevice::GetHandle() const { |
| 1253 | // Generate a handle based of the npad id | 1284 | // Generate a handle based of the npad id |
| 1254 | return static_cast<u64>(npad_id); | 1285 | return static_cast<u64>(npad_id); |
diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h index 98e1945c1..6a37e8458 100644 --- a/src/core/hle/service/nfc/common/device.h +++ b/src/core/hle/service/nfc/common/device.h | |||
| @@ -110,6 +110,8 @@ private: | |||
| 110 | void UpdateSettingsCrc(); | 110 | void UpdateSettingsCrc(); |
| 111 | void UpdateRegisterInfoCrc(); | 111 | void UpdateRegisterInfoCrc(); |
| 112 | 112 | ||
| 113 | void BuildAmiiboWithoutKeys(); | ||
| 114 | |||
| 113 | bool is_controller_set{}; | 115 | bool is_controller_set{}; |
| 114 | int callback_key; | 116 | int callback_key; |
| 115 | const Core::HID::NpadIdType npad_id; | 117 | const Core::HID::NpadIdType npad_id; |
| @@ -128,6 +130,7 @@ private: | |||
| 128 | bool is_data_moddified{}; | 130 | bool is_data_moddified{}; |
| 129 | bool is_app_area_open{}; | 131 | bool is_app_area_open{}; |
| 130 | bool is_plain_amiibo{}; | 132 | bool is_plain_amiibo{}; |
| 133 | bool is_write_protected{}; | ||
| 131 | NFP::MountTarget mount_target{NFP::MountTarget::None}; | 134 | NFP::MountTarget mount_target{NFP::MountTarget::None}; |
| 132 | 135 | ||
| 133 | NFP::NTAG215File tag_data{}; | 136 | NFP::NTAG215File tag_data{}; |