From 026fe2e4f4128f4c81a07e25cb646620f7643a75 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Tue, 14 Mar 2023 22:00:38 -0600 Subject: [PATCH] service: nfp: Actually write correct crc --- src/core/hle/service/mii/mii_manager.cpp | 2 + src/core/hle/service/mii/types.h | 3 +- src/core/hle/service/nfp/amiibo_crypto.cpp | 4 +- src/core/hle/service/nfp/nfp_device.cpp | 53 ++++++++++++++-------- src/core/hle/service/nfp/nfp_device.h | 1 + src/core/hle/service/nfp/nfp_types.h | 4 +- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 3a2fe938f..9d31a080c 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -585,6 +585,8 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const { mii_v3.appearance_bits11.mole_x_position.Assign(mii.mole_x); mii_v3.appearance_bits11.mole_y_position.Assign(mii.mole_y); + mii_v3.crc = GenerateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16)); + // TODO: Validate mii_v3 data return mii_v3; diff --git a/src/core/hle/service/mii/types.h b/src/core/hle/service/mii/types.h index 9e3247397..1f53e6af3 100644 --- a/src/core/hle/service/mii/types.h +++ b/src/core/hle/service/mii/types.h @@ -365,7 +365,8 @@ struct Ver3StoreData { } appearance_bits11; std::array author_name; - INSERT_PADDING_BYTES(0x4); + INSERT_PADDING_BYTES(0x2); + u16_be crc; }; static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size"); diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp index ad73edbda..66773d26c 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.cpp +++ b/src/core/hle/service/nfp/amiibo_crypto.cpp @@ -89,7 +89,7 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { encoded_data.application_id_byte = nfc_data.user_memory.application_id_byte; encoded_data.unknown = nfc_data.user_memory.unknown; encoded_data.unknown2 = nfc_data.user_memory.unknown2; - encoded_data.application_area_crc = nfc_data.user_memory.application_area_crc; + encoded_data.register_info_crc = nfc_data.user_memory.register_info_crc; encoded_data.application_area = nfc_data.user_memory.application_area; encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag; encoded_data.lock_bytes = nfc_data.uuid.lock_bytes; @@ -123,7 +123,7 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) { nfc_data.user_memory.application_id_byte = encoded_data.application_id_byte; nfc_data.user_memory.unknown = encoded_data.unknown; nfc_data.user_memory.unknown2 = encoded_data.unknown2; - nfc_data.user_memory.application_area_crc = encoded_data.application_area_crc; + nfc_data.user_memory.register_info_crc = encoded_data.register_info_crc; nfc_data.user_memory.application_area = encoded_data.application_area; nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag; nfc_data.user_memory.model_info = encoded_data.model_info; diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index ddff90d6a..53bc56814 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp @@ -448,7 +448,7 @@ Result NfpDevice::DeleteRegisterInfo() { rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8)); rng.GenerateRandomBytes(&tag_data.unknown2[0], sizeof(u32)); rng.GenerateRandomBytes(&tag_data.unknown2[1], sizeof(u32)); - rng.GenerateRandomBytes(&tag_data.application_area_crc, sizeof(u32)); + rng.GenerateRandomBytes(&tag_data.register_info_crc, sizeof(u32)); rng.GenerateRandomBytes(&tag_data.settings.init_date, sizeof(u32)); tag_data.settings.settings.font_region.Assign(0); tag_data.settings.settings.amiibo_initialized.Assign(0); @@ -486,9 +486,7 @@ Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) { settings.settings.font_region.Assign(0); settings.settings.amiibo_initialized.Assign(1); - // TODO: this is a mix of tag.file input - std::array unknown_input{}; - tag_data.application_area_crc = CalculateCrc(unknown_input); + UpdateRegisterInfoCrc(); return Flush(); } @@ -716,9 +714,7 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span dat tag_data.application_area_id = access_id; tag_data.unknown = {}; - // TODO: this is a mix of tag_data input - std::array unknown_input{}; - tag_data.application_area_crc = CalculateCrc(unknown_input); + UpdateRegisterInfoCrc(); return Flush(); } @@ -838,6 +834,29 @@ void NfpDevice::UpdateSettingsCrc() { settings.crc = CalculateCrc(unknown_input); } +void NfpDevice::UpdateRegisterInfoCrc() { +#pragma pack(push, 1) + struct CrcData { + Mii::Ver3StoreData mii; + u8 application_id_byte; + u8 unknown; + std::array unknown2; + }; + static_assert(sizeof(CrcData) == 0x7e, "CrcData is an invalid size"); +#pragma pack(pop) + + const CrcData crc_data{ + .mii = tag_data.owner_mii, + .application_id_byte = tag_data.application_id_byte, + .unknown = tag_data.unknown, + .unknown2 = tag_data.unknown2, + }; + + std::array data{}; + memcpy(data.data(), &crc_data, sizeof(CrcData)); + tag_data.register_info_crc = CalculateCrc(data); +} + u32 NfpDevice::CalculateCrc(std::span data) { constexpr u32 magic = 0xedb88320; u32 crc = 0xffffffff; @@ -847,17 +866,15 @@ u32 NfpDevice::CalculateCrc(std::span data) { } for (u8 input : data) { - u32 temp = (crc ^ input) >> 1; - if (((crc ^ input) & 1) != 0) { - temp = temp ^ magic; - } - - for (std::size_t step = 0; step < 7; ++step) { - crc = temp >> 1; - if ((temp & 1) != 0) { - crc = temp >> 1 ^ magic; - } - } + crc ^= input; + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); + crc = crc >> 1 ^ ((crc & 1) ? magic : 0x0); } return ~crc; diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index 06386401d..fc7fbd578 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h @@ -80,6 +80,7 @@ private: AmiiboDate GetAmiiboDate(s64 posix_time) const; u64 RemoveVersionByte(u64 application_id) const; void UpdateSettingsCrc(); + void UpdateRegisterInfoCrc(); u32 CalculateCrc(std::span); bool is_controller_set{}; diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index 142343d6e..5f4a5d7f9 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h @@ -260,7 +260,7 @@ struct EncryptedAmiiboFile { u8 application_id_byte; u8 unknown; std::array unknown2; - u32_be application_area_crc; + u32_be register_info_crc; ApplicationArea application_area; // Encrypted Game data }; static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size"); @@ -281,7 +281,7 @@ struct NTAG215File { u8 application_id_byte; u8 unknown; std::array unknown2; - u32_be application_area_crc; + u32_be register_info_crc; ApplicationArea application_area; // Encrypted Game data HashData hmac_tag; // Hash UniqueSerialNumber uid; // Unique serial number