Merge pull request #10415 from german77/amiibo-no-key
service: nfc: Remove encryption key requirement
This commit is contained in:
commit
e264ab4ad0
|
@ -52,9 +52,6 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
|
||||||
if (ntag_file.compability_container != 0xEEFF10F1U) {
|
if (ntag_file.compability_container != 0xEEFF10F1U) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (amiibo_data.constant_value != 0xA5) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (amiibo_data.model_info.tag_type != NFC::PackedTagType::Type2) {
|
if (amiibo_data.model_info.tag_type != NFC::PackedTagType::Type2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,18 +119,31 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) {
|
||||||
|
|
||||||
memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
|
memcpy(&tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
|
||||||
is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data);
|
is_plain_amiibo = NFP::AmiiboCrypto::IsAmiiboValid(tag_data);
|
||||||
|
is_write_protected = false;
|
||||||
if (is_plain_amiibo) {
|
|
||||||
encrypted_tag_data = NFP::AmiiboCrypto::EncodedDataToNfcData(tag_data);
|
|
||||||
LOG_INFO(Service_NFP, "Using plain amiibo");
|
|
||||||
} else {
|
|
||||||
tag_data = {};
|
|
||||||
memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
|
|
||||||
}
|
|
||||||
|
|
||||||
device_state = DeviceState::TagFound;
|
device_state = DeviceState::TagFound;
|
||||||
deactivate_event->GetReadableEvent().Clear();
|
deactivate_event->GetReadableEvent().Clear();
|
||||||
activate_event->Signal();
|
activate_event->Signal();
|
||||||
|
|
||||||
|
// Fallback for plain amiibos
|
||||||
|
if (is_plain_amiibo) {
|
||||||
|
LOG_INFO(Service_NFP, "Using plain amiibo");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_data = {};
|
||||||
|
memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,23 +359,15 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target
|
||||||
return ResultWrongDeviceState;
|
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)) {
|
if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {
|
||||||
LOG_ERROR(Service_NFP, "Not an amiibo");
|
LOG_ERROR(Service_NFP, "Not an amiibo");
|
||||||
return ResultNotAnAmiibo;
|
return ResultNotAnAmiibo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark amiibos as read only when keys are missing
|
// The loaded amiibo is not encrypted
|
||||||
if (!NFP::AmiiboCrypto::IsKeyAvailable()) {
|
if (is_plain_amiibo) {
|
||||||
LOG_ERROR(Service_NFP, "No keys detected");
|
|
||||||
device_state = DeviceState::TagMounted;
|
device_state = DeviceState::TagMounted;
|
||||||
mount_target = NFP::MountTarget::Rom;
|
mount_target = mount_target_;
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,6 +462,11 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {
|
||||||
return ResultWrongDeviceState;
|
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));
|
std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
|
||||||
if (is_plain_amiibo) {
|
if (is_plain_amiibo) {
|
||||||
memcpy(data.data(), &tag_data, sizeof(tag_data));
|
memcpy(data.data(), &tag_data, sizeof(tag_data));
|
||||||
|
@ -1033,7 +1043,6 @@ Result NfcDevice::GetAll(NFP::NfpData& data) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
NFP::CommonInfo common_info{};
|
NFP::CommonInfo common_info{};
|
||||||
Service::Mii::MiiManager manager;
|
|
||||||
const u64 application_id = tag_data.application_id;
|
const u64 application_id = tag_data.application_id;
|
||||||
|
|
||||||
GetCommonInfo(common_info);
|
GetCommonInfo(common_info);
|
||||||
|
@ -1249,6 +1258,28 @@ void NfcDevice::UpdateRegisterInfoCrc() {
|
||||||
tag_data.register_info_crc = crc.checksum();
|
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 {
|
u64 NfcDevice::GetHandle() const {
|
||||||
// Generate a handle based of the npad id
|
// Generate a handle based of the npad id
|
||||||
return static_cast<u64>(npad_id);
|
return static_cast<u64>(npad_id);
|
||||||
|
|
|
@ -110,6 +110,8 @@ private:
|
||||||
void UpdateSettingsCrc();
|
void UpdateSettingsCrc();
|
||||||
void UpdateRegisterInfoCrc();
|
void UpdateRegisterInfoCrc();
|
||||||
|
|
||||||
|
void BuildAmiiboWithoutKeys();
|
||||||
|
|
||||||
bool is_controller_set{};
|
bool is_controller_set{};
|
||||||
int callback_key;
|
int callback_key;
|
||||||
const Core::HID::NpadIdType npad_id;
|
const Core::HID::NpadIdType npad_id;
|
||||||
|
@ -128,6 +130,7 @@ private:
|
||||||
bool is_data_moddified{};
|
bool is_data_moddified{};
|
||||||
bool is_app_area_open{};
|
bool is_app_area_open{};
|
||||||
bool is_plain_amiibo{};
|
bool is_plain_amiibo{};
|
||||||
|
bool is_write_protected{};
|
||||||
NFP::MountTarget mount_target{NFP::MountTarget::None};
|
NFP::MountTarget mount_target{NFP::MountTarget::None};
|
||||||
|
|
||||||
NFP::NTAG215File tag_data{};
|
NFP::NTAG215File tag_data{};
|
||||||
|
|
Reference in New Issue