service: nfp: Add plain amiibo support

This commit is contained in:
german77 2023-03-26 14:26:21 -06:00
parent 568d523746
commit 8802646730
5 changed files with 37 additions and 8 deletions

View File

@ -70,6 +70,10 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
return true; return true;
} }
bool IsAmiiboValid(const NTAG215File& ntag_file) {
return IsAmiiboValid(EncodedDataToNfcData(ntag_file));
}
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
NTAG215File encoded_data{}; NTAG215File encoded_data{};

View File

@ -60,6 +60,9 @@ static_assert(sizeof(DerivedKeys) == 0x30, "DerivedKeys is an invalid size");
/// Validates that the amiibo file is not corrupted /// Validates that the amiibo file is not corrupted
bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file); bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file);
/// Validates that the amiibo file is not corrupted
bool IsAmiiboValid(const NTAG215File& ntag_file);
/// Converts from encrypted file format to encoded file format /// Converts from encrypted file format to encoded file format
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data); NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data);

View File

@ -121,7 +121,16 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) {
// TODO: Filter by allowed_protocols here // TODO: Filter by allowed_protocols here
memcpy(&tag_data, data.data(), sizeof(EncryptedNTAG215File));
is_plain_amiibo = AmiiboCrypto::IsAmiiboValid(tag_data);
if (is_plain_amiibo) {
encrypted_tag_data = AmiiboCrypto::EncodedDataToNfcData(tag_data);
LOG_INFO(Service_NFP, "Using plain amiibo");
} else {
tag_data = {};
memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
}
device_state = DeviceState::TagFound; device_state = DeviceState::TagFound;
deactivate_event->GetReadableEvent().Clear(); deactivate_event->GetReadableEvent().Clear();
@ -232,13 +241,17 @@ Result NfpDevice::Flush() {
tag_data.write_counter++; tag_data.write_counter++;
std::vector<u8> data(sizeof(EncryptedNTAG215File));
if (is_plain_amiibo) {
memcpy(data.data(), &tag_data, sizeof(tag_data));
} else {
if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
LOG_ERROR(Service_NFP, "Failed to encode data"); LOG_ERROR(Service_NFP, "Failed to encode data");
return WriteAmiiboFailed; return WriteAmiiboFailed;
} }
std::vector<u8> data(sizeof(encrypted_tag_data));
memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
}
if (!npad_device->WriteNfc(data)) { if (!npad_device->WriteNfc(data)) {
LOG_ERROR(Service_NFP, "Error writing to file"); LOG_ERROR(Service_NFP, "Error writing to file");
@ -256,6 +269,13 @@ Result NfpDevice::Mount(MountTarget mount_target_) {
return WrongDeviceState; return WrongDeviceState;
} }
// The loaded amiibo is not encrypted
if (is_plain_amiibo) {
device_state = DeviceState::TagMounted;
mount_target = mount_target_;
return ResultSuccess;
}
if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) { if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {
LOG_ERROR(Service_NFP, "Not an amiibo"); LOG_ERROR(Service_NFP, "Not an amiibo");
return NotAnAmiibo; return NotAnAmiibo;

View File

@ -95,6 +95,7 @@ private:
bool is_initalized{}; bool is_initalized{};
bool is_data_moddified{}; bool is_data_moddified{};
bool is_app_area_open{}; bool is_app_area_open{};
bool is_plain_amiibo{};
TagProtocol allowed_protocols{}; TagProtocol allowed_protocols{};
s64 current_posix_time{}; s64 current_posix_time{};
MountTarget mount_target{MountTarget::None}; MountTarget mount_target{MountTarget::None};

View File

@ -309,7 +309,8 @@ struct EncryptedNTAG215File {
u32 CFG1; // Defines number of verification attempts u32 CFG1; // Defines number of verification attempts
NTAG215Password password; // Password data NTAG215Password password; // Password data
}; };
static_assert(sizeof(EncryptedNTAG215File) == 0x21C, "EncryptedNTAG215File is an invalid size"); static_assert(sizeof(EncryptedNTAG215File) == sizeof(NTAG215File),
"EncryptedNTAG215File is an invalid size");
static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>, static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>,
"EncryptedNTAG215File must be trivially copyable."); "EncryptedNTAG215File must be trivially copyable.");