diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.cpp b/src/core/hle/service/nfc/common/amiibo_crypto.cpp
index b2bcb68c3..bc232c334 100644
--- a/src/core/hle/service/nfc/common/amiibo_crypto.cpp
+++ b/src/core/hle/service/nfc/common/amiibo_crypto.cpp
@@ -36,12 +36,12 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
 
     // Validate UUID
     constexpr u8 CT = 0x88; // As defined in `ISO / IEC 14443 - 3`
-    if ((CT ^ ntag_file.uuid.uid[0] ^ ntag_file.uuid.uid[1] ^ ntag_file.uuid.uid[2]) !=
-        ntag_file.uuid.uid[3]) {
+    if ((CT ^ ntag_file.uuid.part1[0] ^ ntag_file.uuid.part1[1] ^ ntag_file.uuid.part1[2]) !=
+        ntag_file.uuid.crc_check1) {
         return false;
     }
-    if ((ntag_file.uuid.uid[4] ^ ntag_file.uuid.uid[5] ^ ntag_file.uuid.uid[6] ^
-         ntag_file.uuid.nintendo_id) != ntag_file.uuid.lock_bytes[0]) {
+    if ((ntag_file.uuid.part2[0] ^ ntag_file.uuid.part2[1] ^ ntag_file.uuid.part2[2] ^
+         ntag_file.uuid.nintendo_id) != ntag_file.uuid_crc_check2) {
         return false;
     }
 
@@ -74,8 +74,9 @@ bool IsAmiiboValid(const NTAG215File& ntag_file) {
 NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
     NTAG215File encoded_data{};
 
-    encoded_data.uid = nfc_data.uuid.uid;
-    encoded_data.nintendo_id = nfc_data.uuid.nintendo_id;
+    encoded_data.uid = nfc_data.uuid;
+    encoded_data.uid_crc_check2 = nfc_data.uuid_crc_check2;
+    encoded_data.internal_number = nfc_data.internal_number;
     encoded_data.static_lock = nfc_data.static_lock;
     encoded_data.compability_container = nfc_data.compability_container;
     encoded_data.hmac_data = nfc_data.user_memory.hmac_data;
@@ -94,7 +95,6 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
     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;
     encoded_data.model_info = nfc_data.user_memory.model_info;
     encoded_data.keygen_salt = nfc_data.user_memory.keygen_salt;
     encoded_data.dynamic_lock = nfc_data.dynamic_lock;
@@ -108,9 +108,9 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
 EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
     EncryptedNTAG215File nfc_data{};
 
-    nfc_data.uuid.uid = encoded_data.uid;
-    nfc_data.uuid.nintendo_id = encoded_data.nintendo_id;
-    nfc_data.uuid.lock_bytes = encoded_data.lock_bytes;
+    nfc_data.uuid = encoded_data.uid;
+    nfc_data.uuid_crc_check2 = encoded_data.uid_crc_check2;
+    nfc_data.internal_number = encoded_data.internal_number;
     nfc_data.static_lock = encoded_data.static_lock;
     nfc_data.compability_container = encoded_data.compability_container;
     nfc_data.user_memory.hmac_data = encoded_data.hmac_data;
@@ -139,23 +139,12 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
     return nfc_data;
 }
 
-u32 GetTagPassword(const TagUuid& uuid) {
-    // Verify that the generated password is correct
-    u32 password = 0xAA ^ (uuid.uid[1] ^ uuid.uid[3]);
-    password &= (0x55 ^ (uuid.uid[2] ^ uuid.uid[4])) << 8;
-    password &= (0xAA ^ (uuid.uid[3] ^ uuid.uid[5])) << 16;
-    password &= (0x55 ^ (uuid.uid[4] ^ uuid.uid[6])) << 24;
-    return password;
-}
-
 HashSeed GetSeed(const NTAG215File& data) {
     HashSeed seed{
         .magic = data.write_counter,
         .padding = {},
         .uid_1 = data.uid,
-        .nintendo_id_1 = data.nintendo_id,
         .uid_2 = data.uid,
-        .nintendo_id_2 = data.nintendo_id,
         .keygen_salt = data.keygen_salt,
     };
 
@@ -177,10 +166,11 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
     output.insert(output.end(), key.magic_bytes.begin(),
                   key.magic_bytes.begin() + key.magic_length);
 
-    output.insert(output.end(), seed.uid_1.begin(), seed.uid_1.end());
-    output.emplace_back(seed.nintendo_id_1);
-    output.insert(output.end(), seed.uid_2.begin(), seed.uid_2.end());
-    output.emplace_back(seed.nintendo_id_2);
+    std::array<u8, sizeof(NFP::TagUuid)> seed_uuid{};
+    memcpy(seed_uuid.data(), &seed.uid_1, sizeof(NFP::TagUuid));
+    output.insert(output.end(), seed_uuid.begin(), seed_uuid.end());
+    memcpy(seed_uuid.data(), &seed.uid_2, sizeof(NFP::TagUuid));
+    output.insert(output.end(), seed_uuid.begin(), seed_uuid.end());
 
     for (std::size_t i = 0; i < sizeof(seed.keygen_salt); i++) {
         output.emplace_back(static_cast<u8>(seed.keygen_salt[i] ^ key.xor_pad[i]));
@@ -264,8 +254,8 @@ void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& ou
 
     // Copy the rest of the data directly
     out_data.uid = in_data.uid;
-    out_data.nintendo_id = in_data.nintendo_id;
-    out_data.lock_bytes = in_data.lock_bytes;
+    out_data.uid_crc_check2 = in_data.uid_crc_check2;
+    out_data.internal_number = in_data.internal_number;
     out_data.static_lock = in_data.static_lock;
     out_data.compability_container = in_data.compability_container;
 
diff --git a/src/core/hle/service/nfc/common/amiibo_crypto.h b/src/core/hle/service/nfc/common/amiibo_crypto.h
index bf3044ed9..6a3e0841e 100644
--- a/src/core/hle/service/nfc/common/amiibo_crypto.h
+++ b/src/core/hle/service/nfc/common/amiibo_crypto.h
@@ -24,10 +24,8 @@ using DrgbOutput = std::array<u8, 0x20>;
 struct HashSeed {
     u16_be magic;
     std::array<u8, 0xE> padding;
-    NFC::UniqueSerialNumber uid_1;
-    u8 nintendo_id_1;
-    NFC::UniqueSerialNumber uid_2;
-    u8 nintendo_id_2;
+    TagUuid uid_1;
+    TagUuid uid_2;
     std::array<u8, 0x20> keygen_salt;
 };
 static_assert(sizeof(HashSeed) == 0x40, "HashSeed is an invalid size");
@@ -69,9 +67,6 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data);
 /// Converts from encoded file format to encrypted file format
 EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data);
 
-/// Returns password needed to allow write access to protected memory
-u32 GetTagPassword(const TagUuid& uuid);
-
 // Generates Seed needed for key derivation
 HashSeed GetSeed(const NTAG215File& data);
 
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index b14f682b5..f4b180b06 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -242,34 +242,39 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const {
         return ResultWrongDeviceState;
     }
 
-    UniqueSerialNumber uuid = encrypted_tag_data.uuid.uid;
-
-    // Generate random UUID to bypass amiibo load limits
-    if (Settings::values.random_amiibo_id) {
-        Common::TinyMT rng{};
-        rng.Initialize(static_cast<u32>(GetCurrentPosixTime()));
-        rng.GenerateRandomBytes(uuid.data(), sizeof(UniqueSerialNumber));
-        uuid[3] = 0x88 ^ uuid[0] ^ uuid[1] ^ uuid[2];
-    }
+    UniqueSerialNumber uuid{};
+    u8 uuid_length{};
+    NfcProtocol protocol{NfcProtocol::TypeA};
+    TagType tag_type{TagType::Type2};
 
     if (is_mifare) {
-        tag_info = {
-            .uuid = uuid,
-            .uuid_extension = {},
-            .uuid_length = static_cast<u8>(uuid.size()),
-            .protocol = NfcProtocol::TypeA,
-            .tag_type = TagType::Type4,
+        tag_type = TagType::Mifare;
+        uuid_length = sizeof(NFP::NtagTagUuid);
+        memcpy(uuid.data(), mifare_data.data(), uuid_length);
+    } else {
+        tag_type = TagType::Type2;
+        uuid_length = sizeof(NFP::NtagTagUuid);
+        NFP::NtagTagUuid nUuid{
+            .part1 = encrypted_tag_data.uuid.part1,
+            .part2 = encrypted_tag_data.uuid.part2,
+            .nintendo_id = encrypted_tag_data.uuid.nintendo_id,
         };
-        return ResultSuccess;
+        memcpy(uuid.data(), &nUuid, uuid_length);
+
+        // Generate random UUID to bypass amiibo load limits
+        if (Settings::values.random_amiibo_id) {
+            Common::TinyMT rng{};
+            rng.Initialize(static_cast<u32>(GetCurrentPosixTime()));
+            rng.GenerateRandomBytes(uuid.data(), uuid_length);
+        }
     }
 
     // Protocol and tag type may change here
     tag_info = {
         .uuid = uuid,
-        .uuid_extension = {},
-        .uuid_length = static_cast<u8>(uuid.size()),
-        .protocol = NfcProtocol::TypeA,
-        .tag_type = TagType::Type2,
+        .uuid_length = uuid_length,
+        .protocol = protocol,
+        .tag_type = tag_type,
     };
 
     return ResultSuccess;
@@ -277,8 +282,38 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const {
 
 Result NfcDevice::ReadMifare(std::span<const MifareReadBlockParameter> parameters,
                              std::span<MifareReadBlockData> read_block_data) const {
+    if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) {
+        LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
+        if (device_state == DeviceState::TagRemoved) {
+            return ResultTagRemoved;
+        }
+        return ResultWrongDeviceState;
+    }
+
     Result result = ResultSuccess;
 
+    TagInfo tag_info{};
+    result = GetTagInfo(tag_info, true);
+
+    if (result.IsError()) {
+        return result;
+    }
+
+    if (tag_info.protocol != NfcProtocol::TypeA || tag_info.tag_type != TagType::Mifare) {
+        return ResultInvalidTagType;
+    }
+
+    if (parameters.size() == 0) {
+        return ResultInvalidArgument;
+    }
+
+    const auto unknown = parameters[0].sector_key.unknown;
+    for (std::size_t i = 0; i < parameters.size(); i++) {
+        if (unknown != parameters[i].sector_key.unknown) {
+            return ResultInvalidArgument;
+        }
+    }
+
     for (std::size_t i = 0; i < parameters.size(); i++) {
         result = ReadMifare(parameters[i], read_block_data[i]);
         if (result.IsError()) {
@@ -293,17 +328,8 @@ Result NfcDevice::ReadMifare(const MifareReadBlockParameter& parameter,
                              MifareReadBlockData& read_block_data) const {
     const std::size_t sector_index = parameter.sector_number * sizeof(DataBlock);
     read_block_data.sector_number = parameter.sector_number;
-
-    if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) {
-        LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
-        if (device_state == DeviceState::TagRemoved) {
-            return ResultTagRemoved;
-        }
-        return ResultWrongDeviceState;
-    }
-
     if (mifare_data.size() < sector_index + sizeof(DataBlock)) {
-        return Mifare::ResultReadError;
+        return ResultMifareError288;
     }
 
     // TODO: Use parameter.sector_key to read encrypted data
@@ -315,6 +341,28 @@ Result NfcDevice::ReadMifare(const MifareReadBlockParameter& parameter,
 Result NfcDevice::WriteMifare(std::span<const MifareWriteBlockParameter> parameters) {
     Result result = ResultSuccess;
 
+    TagInfo tag_info{};
+    result = GetTagInfo(tag_info, true);
+
+    if (result.IsError()) {
+        return result;
+    }
+
+    if (tag_info.protocol != NfcProtocol::TypeA || tag_info.tag_type != TagType::Mifare) {
+        return ResultInvalidTagType;
+    }
+
+    if (parameters.size() == 0) {
+        return ResultInvalidArgument;
+    }
+
+    const auto unknown = parameters[0].sector_key.unknown;
+    for (std::size_t i = 0; i < parameters.size(); i++) {
+        if (unknown != parameters[i].sector_key.unknown) {
+            return ResultInvalidArgument;
+        }
+    }
+
     for (std::size_t i = 0; i < parameters.size(); i++) {
         result = WriteMifare(parameters[i]);
         if (result.IsError()) {
@@ -324,7 +372,7 @@ Result NfcDevice::WriteMifare(std::span<const MifareWriteBlockParameter> paramet
 
     if (!npad_device->WriteNfc(mifare_data)) {
         LOG_ERROR(Service_NFP, "Error writing to file");
-        return Mifare::ResultReadError;
+        return ResultMifareError288;
     }
 
     return result;
@@ -342,7 +390,7 @@ Result NfcDevice::WriteMifare(const MifareWriteBlockParameter& parameter) {
     }
 
     if (mifare_data.size() < sector_index + sizeof(DataBlock)) {
-        return Mifare::ResultReadError;
+        return ResultMifareError288;
     }
 
     // TODO: Use parameter.sector_key to encrypt the data
@@ -366,7 +414,7 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target
 
     if (!NFP::AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {
         LOG_ERROR(Service_NFP, "Not an amiibo");
-        return ResultNotAnAmiibo;
+        return ResultInvalidTagType;
     }
 
     // The loaded amiibo is not encrypted
@@ -381,14 +429,14 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target
     }
 
     if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) {
-        bool has_backup = HasBackup(encrypted_tag_data.uuid.uid).IsSuccess();
+        bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess();
         LOG_ERROR(Service_NFP, "Can't decode amiibo, has_backup= {}", has_backup);
         return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData;
     }
 
     std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
     memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
-    WriteBackupData(encrypted_tag_data.uuid.uid, data);
+    WriteBackupData(encrypted_tag_data.uuid, data);
 
     device_state = DeviceState::TagMounted;
     mount_target = mount_target_;
@@ -492,7 +540,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {
         }
 
         memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
-        WriteBackupData(encrypted_tag_data.uuid.uid, data);
+        WriteBackupData(encrypted_tag_data.uuid, data);
     }
 
     if (!npad_device->WriteNfc(data)) {
@@ -520,7 +568,7 @@ Result NfcDevice::Restore() {
         return result;
     }
 
-    result = ReadBackupData(tag_info.uuid, data);
+    result = ReadBackupData(tag_info.uuid, tag_info.uuid_length, data);
 
     if (result.IsError()) {
         return result;
@@ -548,7 +596,7 @@ Result NfcDevice::Restore() {
     }
 
     if (!NFP::AmiiboCrypto::IsAmiiboValid(temporary_encrypted_tag_data)) {
-        return ResultNotAnAmiibo;
+        return ResultInvalidTagType;
     }
 
     if (!is_plain_amiibo) {
@@ -1194,10 +1242,12 @@ Result NfcDevice::BreakTag(NFP::BreakType break_type) {
     return FlushWithBreak(break_type);
 }
 
-Result NfcDevice::HasBackup(const NFC::UniqueSerialNumber& uid) const {
+Result NfcDevice::HasBackup(const UniqueSerialNumber& uid, std::size_t uuid_size) const {
+    ASSERT_MSG(uuid_size < sizeof(UniqueSerialNumber), "Invalid UUID size");
     constexpr auto backup_dir = "backup";
     const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir);
-    const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, ""));
+    const auto file_name =
+        fmt::format("{0:02x}.bin", fmt::join(uid.begin(), uid.begin() + uuid_size, ""));
 
     if (!Common::FS::Exists(yuzu_amiibo_dir / backup_dir / file_name)) {
         return ResultUnableToAccessBackupFile;
@@ -1206,10 +1256,19 @@ Result NfcDevice::HasBackup(const NFC::UniqueSerialNumber& uid) const {
     return ResultSuccess;
 }
 
-Result NfcDevice::ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u8> data) const {
+Result NfcDevice::HasBackup(const NFP::TagUuid& tag_uid) const {
+    UniqueSerialNumber uuid{};
+    memcpy(uuid.data(), &tag_uid, sizeof(NFP::TagUuid));
+    return HasBackup(uuid, sizeof(NFP::TagUuid));
+}
+
+Result NfcDevice::ReadBackupData(const UniqueSerialNumber& uid, std::size_t uuid_size,
+                                 std::span<u8> data) const {
+    ASSERT_MSG(uuid_size < sizeof(UniqueSerialNumber), "Invalid UUID size");
     constexpr auto backup_dir = "backup";
     const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir);
-    const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, ""));
+    const auto file_name =
+        fmt::format("{0:02x}.bin", fmt::join(uid.begin(), uid.begin() + uuid_size, ""));
 
     const Common::FS::IOFile keys_file{yuzu_amiibo_dir / backup_dir / file_name,
                                        Common::FS::FileAccessMode::Read,
@@ -1228,12 +1287,21 @@ Result NfcDevice::ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u
     return ResultSuccess;
 }
 
-Result NfcDevice::WriteBackupData(const NFC::UniqueSerialNumber& uid, std::span<const u8> data) {
+Result NfcDevice::ReadBackupData(const NFP::TagUuid& tag_uid, std::span<u8> data) const {
+    UniqueSerialNumber uuid{};
+    memcpy(uuid.data(), &tag_uid, sizeof(NFP::TagUuid));
+    return ReadBackupData(uuid, sizeof(NFP::TagUuid), data);
+}
+
+Result NfcDevice::WriteBackupData(const UniqueSerialNumber& uid, std::size_t uuid_size,
+                                  std::span<const u8> data) {
+    ASSERT_MSG(uuid_size < sizeof(UniqueSerialNumber), "Invalid UUID size");
     constexpr auto backup_dir = "backup";
     const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir);
-    const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, ""));
+    const auto file_name =
+        fmt::format("{0:02x}.bin", fmt::join(uid.begin(), uid.begin() + uuid_size, ""));
 
-    if (HasBackup(uid).IsError()) {
+    if (HasBackup(uid, uuid_size).IsError()) {
         if (!Common::FS::CreateDir(yuzu_amiibo_dir / backup_dir)) {
             return ResultBackupPathAlreadyExist;
         }
@@ -1260,6 +1328,12 @@ Result NfcDevice::WriteBackupData(const NFC::UniqueSerialNumber& uid, std::span<
     return ResultSuccess;
 }
 
+Result NfcDevice::WriteBackupData(const NFP::TagUuid& tag_uid, std::span<const u8> data) {
+    UniqueSerialNumber uuid{};
+    memcpy(uuid.data(), &tag_uid, sizeof(NFP::TagUuid));
+    return WriteBackupData(uuid, sizeof(NFP::TagUuid), data);
+}
+
 Result NfcDevice::WriteNtf(std::span<const u8> data) {
     if (device_state != DeviceState::TagMounted) {
         LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h
index 6f049b687..7560210d6 100644
--- a/src/core/hle/service/nfc/common/device.h
+++ b/src/core/hle/service/nfc/common/device.h
@@ -86,9 +86,14 @@ public:
     Result GetAll(NFP::NfpData& data) const;
     Result SetAll(const NFP::NfpData& data);
     Result BreakTag(NFP::BreakType break_type);
-    Result HasBackup(const NFC::UniqueSerialNumber& uid) const;
-    Result ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u8> data) const;
-    Result WriteBackupData(const NFC::UniqueSerialNumber& uid, std::span<const u8> data);
+    Result HasBackup(const UniqueSerialNumber& uid, std::size_t uuid_size) const;
+    Result HasBackup(const NFP::TagUuid& tag_uid) const;
+    Result ReadBackupData(const UniqueSerialNumber& uid, std::size_t uuid_size,
+                          std::span<u8> data) const;
+    Result ReadBackupData(const NFP::TagUuid& tag_uid, std::span<u8> data) const;
+    Result WriteBackupData(const UniqueSerialNumber& uid, std::size_t uuid_size,
+                           std::span<const u8> data);
+    Result WriteBackupData(const NFP::TagUuid& tag_uid, std::span<const u8> data);
     Result WriteNtf(std::span<const u8> data);
 
     u64 GetHandle() const;
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index cffd602df..b0456508e 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -550,7 +550,7 @@ Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) cons
     }
 
     if (result.IsSuccess()) {
-        result = device->ReadBackupData(tag_info.uuid, data);
+        result = device->ReadBackupData(tag_info.uuid, tag_info.uuid_length, data);
         result = VerifyDeviceResult(device, result);
     }
 
@@ -569,7 +569,7 @@ Result DeviceManager::WriteBackupData(u64 device_handle, std::span<const u8> dat
     }
 
     if (result.IsSuccess()) {
-        result = device->WriteBackupData(tag_info.uuid, data);
+        result = device->WriteBackupData(tag_info.uuid, tag_info.uuid_length, data);
         result = VerifyDeviceResult(device, result);
     }
 
diff --git a/src/core/hle/service/nfc/mifare_result.h b/src/core/hle/service/nfc/mifare_result.h
index 4b60048a5..16a9171e6 100644
--- a/src/core/hle/service/nfc/mifare_result.h
+++ b/src/core/hle/service/nfc/mifare_result.h
@@ -12,6 +12,6 @@ constexpr Result ResultInvalidArgument(ErrorModule::NFCMifare, 65);
 constexpr Result ResultWrongDeviceState(ErrorModule::NFCMifare, 73);
 constexpr Result ResultNfcDisabled(ErrorModule::NFCMifare, 80);
 constexpr Result ResultTagRemoved(ErrorModule::NFCMifare, 97);
-constexpr Result ResultReadError(ErrorModule::NFCMifare, 288);
+constexpr Result ResultNotAMifare(ErrorModule::NFCMifare, 288);
 
 } // namespace Service::NFC::Mifare
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp
index 198d0f2b9..48405f6f2 100644
--- a/src/core/hle/service/nfc/nfc_interface.cpp
+++ b/src/core/hle/service/nfc/nfc_interface.cpp
@@ -355,7 +355,7 @@ Result NfcInterface::TranslateResultToNfp(Result result) const {
     if (result == ResultApplicationAreaExist) {
         return NFP::ResultApplicationAreaExist;
     }
-    if (result == ResultNotAnAmiibo) {
+    if (result == ResultInvalidTagType) {
         return NFP::ResultNotAnAmiibo;
     }
     if (result == ResultUnableToAccessBackupFile) {
@@ -381,6 +381,9 @@ Result NfcInterface::TranslateResultToMifare(Result result) const {
     if (result == ResultTagRemoved) {
         return Mifare::ResultTagRemoved;
     }
+    if (result == ResultInvalidTagType) {
+        return Mifare::ResultNotAMifare;
+    }
     LOG_WARNING(Service_NFC, "Result conversion not handled");
     return result;
 }
diff --git a/src/core/hle/service/nfc/nfc_result.h b/src/core/hle/service/nfc/nfc_result.h
index 59a808740..715c0e80c 100644
--- a/src/core/hle/service/nfc/nfc_result.h
+++ b/src/core/hle/service/nfc/nfc_result.h
@@ -24,7 +24,8 @@ constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);
 constexpr Result ResultCorruptedData(ErrorModule::NFC, 144);
 constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFC, 152);
 constexpr Result ResultApplicationAreaExist(ErrorModule::NFC, 168);
-constexpr Result ResultNotAnAmiibo(ErrorModule::NFC, 178);
+constexpr Result ResultInvalidTagType(ErrorModule::NFC, 178);
 constexpr Result ResultBackupPathAlreadyExist(ErrorModule::NFC, 216);
+constexpr Result ResultMifareError288(ErrorModule::NFC, 288);
 
 } // namespace Service::NFC
diff --git a/src/core/hle/service/nfc/nfc_types.h b/src/core/hle/service/nfc/nfc_types.h
index c7ebd1fdb..1a0866e78 100644
--- a/src/core/hle/service/nfc/nfc_types.h
+++ b/src/core/hle/service/nfc/nfc_types.h
@@ -35,21 +35,27 @@ enum class State : u32 {
 
 // This is nn::nfc::TagType
 enum class TagType : u32 {
-    None,
-    Type1, // ISO14443A RW 96-2k bytes 106kbit/s
-    Type2, // ISO14443A RW/RO 540 bytes 106kbit/s
-    Type3, // Sony FeliCa RW/RO 2k bytes 212kbit/s
-    Type4, // ISO14443A RW/RO 4k-32k bytes 424kbit/s
-    Type5, // ISO15693 RW/RO 540 bytes 106kbit/s
+    None = 0,
+    Type1 = 1U << 0,  // ISO14443A RW. Topaz
+    Type2 = 1U << 1,  // ISO14443A RW. Ultralight, NTAGX, ST25TN
+    Type3 = 1U << 2,  // ISO14443A RW/RO. Sony FeliCa
+    Type4A = 1U << 3, // ISO14443A RW/RO. DESFire
+    Type4B = 1U << 4, // ISO14443B RW/RO. DESFire
+    Type5 = 1U << 5,  // ISO15693 RW/RO. SLI, SLIX, ST25TV
+    Mifare = 1U << 6, // Mifare classic. Skylanders
+    All = 0xFFFFFFFF,
 };
 
 enum class PackedTagType : u8 {
-    None,
-    Type1, // ISO14443A RW 96-2k bytes 106kbit/s
-    Type2, // ISO14443A RW/RO 540 bytes 106kbit/s
-    Type3, // Sony FeliCa RW/RO 2k bytes 212kbit/s
-    Type4, // ISO14443A RW/RO 4k-32k bytes 424kbit/s
-    Type5, // ISO15693 RW/RO 540 bytes 106kbit/s
+    None = 0,
+    Type1 = 1U << 0,  // ISO14443A RW. Topaz
+    Type2 = 1U << 1,  // ISO14443A RW. Ultralight, NTAGX, ST25TN
+    Type3 = 1U << 2,  // ISO14443A RW/RO. Sony FeliCa
+    Type4A = 1U << 3, // ISO14443A RW/RO. DESFire
+    Type4B = 1U << 4, // ISO14443B RW/RO. DESFire
+    Type5 = 1U << 5,  // ISO15693 RW/RO. SLI, SLIX, ST25TV
+    Mifare = 1U << 6, // Mifare classic. Skylanders
+    All = 0xFF,
 };
 
 // This is nn::nfc::NfcProtocol
@@ -69,8 +75,7 @@ enum class TestWaveType : u32 {
     Unknown,
 };
 
-using UniqueSerialNumber = std::array<u8, 7>;
-using UniqueSerialNumberExtension = std::array<u8, 3>;
+using UniqueSerialNumber = std::array<u8, 10>;
 
 // This is nn::nfc::DeviceHandle
 using DeviceHandle = u64;
@@ -78,7 +83,6 @@ using DeviceHandle = u64;
 // This is nn::nfc::TagInfo
 struct TagInfo {
     UniqueSerialNumber uuid;
-    UniqueSerialNumberExtension uuid_extension;
     u8 uuid_length;
     INSERT_PADDING_BYTES(0x15);
     NfcProtocol protocol;
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h
index 7d36d5ee6..aed12a7f8 100644
--- a/src/core/hle/service/nfp/nfp_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -85,7 +85,7 @@ enum class CabinetMode : u8 {
     StartFormatter,
 };
 
-using LockBytes = std::array<u8, 2>;
+using UuidPart = std::array<u8, 3>;
 using HashData = std::array<u8, 0x20>;
 using ApplicationArea = std::array<u8, 0xD8>;
 using AmiiboName = std::array<char, (amiibo_name_length * 4) + 1>;
@@ -93,12 +93,20 @@ using AmiiboName = std::array<char, (amiibo_name_length * 4) + 1>;
 // This is nn::nfp::TagInfo
 using TagInfo = NFC::TagInfo;
 
-struct TagUuid {
-    NFC::UniqueSerialNumber uid;
+struct NtagTagUuid {
+    UuidPart part1;
+    UuidPart part2;
     u8 nintendo_id;
-    LockBytes lock_bytes;
 };
-static_assert(sizeof(TagUuid) == 10, "TagUuid is an invalid size");
+static_assert(sizeof(NtagTagUuid) == 7, "NtagTagUuid is an invalid size");
+
+struct TagUuid {
+    UuidPart part1;
+    u8 crc_check1;
+    UuidPart part2;
+    u8 nintendo_id;
+};
+static_assert(sizeof(TagUuid) == 8, "TagUuid is an invalid size");
 
 struct WriteDate {
     u16 year;
@@ -231,7 +239,8 @@ struct EncryptedAmiiboFile {
 static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size");
 
 struct NTAG215File {
-    LockBytes lock_bytes;      // Tag UUID
+    u8 uid_crc_check2;
+    u8 internal_number;
     u16 static_lock;           // Set defined pages as read only
     u32 compability_container; // Defines available memory
     HashData hmac_data;        // Hash
@@ -250,8 +259,7 @@ struct NTAG215File {
     u32_be register_info_crc;
     ApplicationArea application_area; // Encrypted Game data
     HashData hmac_tag;                // Hash
-    NFC::UniqueSerialNumber uid;      // Unique serial number
-    u8 nintendo_id;                   // Tag UUID
+    TagUuid uid;
     AmiiboModelInfo model_info;
     HashData keygen_salt;     // Salt
     u32 dynamic_lock;         // Dynamic lock
@@ -264,7 +272,9 @@ static_assert(std::is_trivially_copyable_v<NTAG215File>, "NTAG215File must be tr
 #pragma pack()
 
 struct EncryptedNTAG215File {
-    TagUuid uuid;                    // Unique serial number
+    TagUuid uuid;
+    u8 uuid_crc_check2;
+    u8 internal_number;
     u16 static_lock;                 // Set defined pages as read only
     u32 compability_container;       // Defines available memory
     EncryptedAmiiboFile user_memory; // Writable data