mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	service: nfp: Add plain amiibo support
This commit is contained in:
		@@ -70,6 +70,10 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsAmiiboValid(const NTAG215File& ntag_file) {
 | 
			
		||||
    return IsAmiiboValid(EncodedDataToNfcData(ntag_file));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
 | 
			
		||||
    NTAG215File encoded_data{};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,9 @@ static_assert(sizeof(DerivedKeys) == 0x30, "DerivedKeys is an invalid size");
 | 
			
		||||
/// Validates that the amiibo file is not corrupted
 | 
			
		||||
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
 | 
			
		||||
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,16 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) {
 | 
			
		||||
 | 
			
		||||
    // TODO: Filter by allowed_protocols here
 | 
			
		||||
 | 
			
		||||
    memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
 | 
			
		||||
    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));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    device_state = DeviceState::TagFound;
 | 
			
		||||
    deactivate_event->GetReadableEvent().Clear();
 | 
			
		||||
@@ -232,13 +241,17 @@ Result NfpDevice::Flush() {
 | 
			
		||||
 | 
			
		||||
    tag_data.write_counter++;
 | 
			
		||||
 | 
			
		||||
    if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
 | 
			
		||||
        LOG_ERROR(Service_NFP, "Failed to encode data");
 | 
			
		||||
        return WriteAmiiboFailed;
 | 
			
		||||
    }
 | 
			
		||||
    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)) {
 | 
			
		||||
            LOG_ERROR(Service_NFP, "Failed to encode data");
 | 
			
		||||
            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)) {
 | 
			
		||||
        LOG_ERROR(Service_NFP, "Error writing to file");
 | 
			
		||||
@@ -256,6 +269,13 @@ Result NfpDevice::Mount(MountTarget mount_target_) {
 | 
			
		||||
        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)) {
 | 
			
		||||
        LOG_ERROR(Service_NFP, "Not an amiibo");
 | 
			
		||||
        return NotAnAmiibo;
 | 
			
		||||
 
 | 
			
		||||
@@ -95,6 +95,7 @@ private:
 | 
			
		||||
    bool is_initalized{};
 | 
			
		||||
    bool is_data_moddified{};
 | 
			
		||||
    bool is_app_area_open{};
 | 
			
		||||
    bool is_plain_amiibo{};
 | 
			
		||||
    TagProtocol allowed_protocols{};
 | 
			
		||||
    s64 current_posix_time{};
 | 
			
		||||
    MountTarget mount_target{MountTarget::None};
 | 
			
		||||
 
 | 
			
		||||
@@ -309,7 +309,8 @@ struct EncryptedNTAG215File {
 | 
			
		||||
    u32 CFG1;                        // Defines number of verification attempts
 | 
			
		||||
    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>,
 | 
			
		||||
              "EncryptedNTAG215File must be trivially copyable.");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user