diff options
| -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 | 
3 files changed, 52 insertions, 21 deletions
| 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) {      if (ntag_file.compability_container != 0xEEFF10F1U) {          return false;      } -    if (amiibo_data.constant_value != 0xA5) { -        return false; -    }      if (amiibo_data.model_info.tag_type != NFC::PackedTagType::Type2) {          return false;      } diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 322bde2ed..e5d4545a8 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) {      memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));      is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data); +    is_write_protected = false; +    device_state = DeviceState::TagFound; +    deactivate_event->GetReadableEvent().Clear(); +    activate_event->Signal(); + +    // Fallback for plain amiibos      if (is_plain_amiibo) { -        encrypted_tag_data = NFP::AmiiboCrypto::EncodedDataToNfcData(tag_data);          LOG_INFO(Service_NFP, "Using plain amiibo"); -    } else { -        tag_data = {}; +        encrypted_tag_data = NFP::AmiiboCrypto::EncodedDataToNfcData(tag_data); +        return true; +    } + +    // Fallback for encrypted amiibos without keys +    if (!NFP::AmiiboCrypto::IsKeyAvailable()) { +        LOG_INFO(Service_NFC, "Loading amiibo without keys");          memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); +        BuildAmiiboWithoutKeys(); +        is_plain_amiibo = true; +        is_write_protected = true; +        return true;      } -    device_state = DeviceState::TagFound; -    deactivate_event->GetReadableEvent().Clear(); -    activate_event->Signal(); +    tag_data = {}; +    memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));      return true;  } @@ -346,23 +359,15 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target          return ResultWrongDeviceState;      } -    // The loaded amiibo is not encrypted -    if (is_plain_amiibo) { -        device_state = DeviceState::TagMounted; -        mount_target = mount_target_; -        return ResultSuccess; -    } -      if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {          LOG_ERROR(Service_NFP, "Not an amiibo");          return ResultNotAnAmiibo;      } -    // Mark amiibos as read only when keys are missing -    if (!NFP::AmiiboCrypto::IsKeyAvailable()) { -        LOG_ERROR(Service_NFP, "No keys detected"); +    // The loaded amiibo is not encrypted +    if (is_plain_amiibo) {          device_state = DeviceState::TagMounted; -        mount_target = NFP::MountTarget::Rom; +        mount_target = mount_target_;          return ResultSuccess;      } @@ -457,6 +462,11 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {          return ResultWrongDeviceState;      } +    if (is_write_protected) { +        LOG_ERROR(Service_NFP, "No keys available skipping write request"); +        return ResultSuccess; +    } +      std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));      if (is_plain_amiibo) {          memcpy(data.data(), &tag_data, sizeof(tag_data)); @@ -1033,7 +1043,6 @@ Result NfcDevice::GetAll(NFP::NfpData& data) const {      }      NFP::CommonInfo common_info{}; -    Service::Mii::MiiManager manager;      const u64 application_id = tag_data.application_id;      GetCommonInfo(common_info); @@ -1249,6 +1258,28 @@ void NfcDevice::UpdateRegisterInfoCrc() {      tag_data.register_info_crc = crc.checksum();  } +void NfcDevice::BuildAmiiboWithoutKeys() { +    Service::Mii::MiiManager manager; +    auto& settings = tag_data.settings; + +    tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_tag_data); + +    // Common info +    tag_data.write_counter = 0; +    tag_data.amiibo_version = 0; +    settings.write_date = GetAmiiboDate(GetCurrentPosixTime()); + +    // Register info +    SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); +    settings.settings.font_region.Assign(0); +    settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); +    tag_data.owner_mii = manager.BuildFromStoreData(manager.BuildDefault(0)); + +    // Admin info +    settings.settings.amiibo_initialized.Assign(1); +    settings.settings.appdata_initialized.Assign(0); +} +  u64 NfcDevice::GetHandle() const {      // Generate a handle based of the npad id      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:      void UpdateSettingsCrc();      void UpdateRegisterInfoCrc(); +    void BuildAmiiboWithoutKeys(); +      bool is_controller_set{};      int callback_key;      const Core::HID::NpadIdType npad_id; @@ -128,6 +130,7 @@ private:      bool is_data_moddified{};      bool is_app_area_open{};      bool is_plain_amiibo{}; +    bool is_write_protected{};      NFP::MountTarget mount_target{NFP::MountTarget::None};      NFP::NTAG215File tag_data{}; | 
