default type of ENUM in C is INT. the tagtype enum broke it. Converted to DEFINES since you cant change type of an ENUM

This commit is contained in:
iceman1001 2023-11-03 15:39:28 +01:00
parent b7028bb798
commit b09c3ac67c
4 changed files with 193 additions and 183 deletions

View file

@ -2010,8 +2010,8 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
// ******** is card of the MFU type (UL/ULC/NTAG/ etc etc)
DropField();
uint32_t tagT = GetHF14AMfU_Type();
if (tagT != UL_ERROR) {
uint64_t tagT = GetHF14AMfU_Type();
if (tagT != MFU_TT_UL_ERROR) {
ul_print_type(tagT, 0);
isMifareUltralight = true;
printTag("MIFARE Ultralight/C/NTAG Compatible");

View file

@ -2485,8 +2485,8 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
// ------------------------------
uint32_t tagT = GetHF14AMfU_Type();
if (tagT != UL_ERROR) {
uint64_t tagT = GetHF14AMfU_Type();
if (tagT != MFU_TT_UL_ERROR) {
PrintAndLogEx(ERR, "Detected a MIFARE Ultralight/C/NTAG Compatible card.");
PrintAndLogEx(ERR, "This command targets " _YELLOW_("MIFARE Classic"));
return PM3_ESOFT;

View file

@ -69,16 +69,24 @@ static uint8_t default_pwd_pack[][4] = {
{0x4E, 0x45, 0x78, 0x54}, // NExT
};
static uint32_t UL_TYPES_ARRAY[] = {
UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128,
NTAG, NTAG_203, NTAG_210, NTAG_212,
NTAG_213, NTAG_215, NTAG_216,
MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC, MY_D_MOVE_LEAN,
NTAG_I2C_1K, NTAG_I2C_2K, NTAG_I2C_1K_PLUS, NTAG_I2C_2K_PLUS,
FUDAN_UL, NTAG_213_F, NTAG_216_F, UL_EV1, UL_NANO_40,
NTAG_213_TT, NTAG_213_C,
MAGIC_1A, MAGIC_1B, MAGIC_NTAG,
NTAG_210u, UL_MAGIC, UL_C_MAGIC
static uint64_t UL_TYPES_ARRAY[] = {
MFU_TT_UNKNOWN, MFU_TT_UL,
MFU_TT_UL_C, MFU_TT_UL_EV1_48,
MFU_TT_UL_EV1_128, MFU_TT_NTAG,
MFU_TT_NTAG_203, MFU_TT_NTAG_210,
MFU_TT_NTAG_212, MFU_TT_NTAG_213,
MFU_TT_NTAG_215, MFU_TT_NTAG_216,
MFU_TT_MY_D, MFU_TT_MY_D_NFC,
MFU_TT_MY_D_MOVE, MFU_TT_MY_D_MOVE_NFC,
MFU_TT_MY_D_MOVE_LEAN, MFU_TT_NTAG_I2C_1K,
MFU_TT_NTAG_I2C_2K, MFU_TT_NTAG_I2C_1K_PLUS,
MFU_TT_NTAG_I2C_2K_PLUS, MFU_TT_FUDAN_UL,
MFU_TT_NTAG_213_F, MFU_TT_NTAG_216_F,
MFU_TT_UL_EV1, MFU_TT_UL_NANO_40,
MFU_TT_NTAG_213_TT, MFU_TT_NTAG_213_C,
MFU_TT_MAGIC_1A, MFU_TT_MAGIC_1B,
MFU_TT_MAGIC_NTAG, MFU_TT_NTAG_210u,
MFU_TT_UL_MAGIC, MFU_TT_UL_C_MAGIC
};
static uint8_t UL_MEMORY_ARRAY[ARRAYLEN(UL_TYPES_ARRAY)] = {
@ -372,8 +380,8 @@ static int ulev1_requestAuthentication(uint8_t *pwd, uint8_t *pack, uint16_t pac
return len;
}
static int ul_auth_select(iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authkey, uint8_t *pack, uint8_t packSize) {
if (hasAuthKey && (tagtype & UL_C)) {
static int ul_auth_select(iso14a_card_select_t *card, uint64_t tagtype, bool hasAuthKey, uint8_t *authkey, uint8_t *pack, uint8_t packSize) {
if (hasAuthKey && (tagtype & MFU_TT_UL_C)) {
//will select card automatically and close connection on error
if (!ulc_authentication(authkey, false)) {
PrintAndLogEx(WARNING, "Authentication Failed UL-C");
@ -442,16 +450,16 @@ static int ulev1_readSignature(uint8_t *response, uint16_t responseLength) {
static int ul_fudan_check(void) {
iso14a_card_select_t card;
if (!ul_select(&card))
return UL_ERROR;
return MFU_TT_UL_ERROR;
uint8_t cmd[4] = {ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa7}; //wrong crc on purpose should be 0xa8
clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 4, 0, cmd, sizeof(cmd));
PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return UL_ERROR;
if (resp.oldarg[0] != 1) return UL_ERROR;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return MFU_TT_UL_ERROR;
if (resp.oldarg[0] != 1) return MFU_TT_UL_ERROR;
return (!resp.data.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP
return (!resp.data.asBytes[0]) ? MFU_TT_FUDAN_UL : MFU_TT_UL; //if response == 0x00 then Fudan, else Genuine NXP
}
static int ul_print_default(uint8_t *data, uint8_t *real_uid) {
@ -623,7 +631,7 @@ static int ndef_print_CC(uint8_t *data) {
return PM3_SUCCESS;
}
int ul_print_type(uint32_t tagtype, uint8_t spaces) {
int ul_print_type(uint64_t tagtype, uint8_t spaces) {
if (spaces > 10)
spaces = 10;
@ -631,73 +639,73 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) {
char typestr[100];
memset(typestr, 0x00, sizeof(typestr));
if (tagtype & UL)
if (tagtype & MFU_TT_UL)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("MIFARE Ultralight (MF0ICU1)"), spaces, "");
else if (tagtype & UL_C)
else if (tagtype & MFU_TT_UL_C)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("MIFARE Ultralight C (MF0ULC)"), spaces, "");
else if (tagtype & UL_NANO_40)
else if (tagtype & MFU_TT_UL_NANO_40)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("MIFARE Ultralight Nano 40bytes (MF0UNH00)"), spaces, "");
else if (tagtype & UL_EV1_48)
else if (tagtype & MFU_TT_UL_EV1_48)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("MIFARE Ultralight EV1 48bytes (MF0UL1101)"), spaces, "");
else if (tagtype & UL_EV1_128)
else if (tagtype & MFU_TT_UL_EV1_128)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("MIFARE Ultralight EV1 128bytes (MF0UL2101)"), spaces, "");
else if (tagtype & UL_EV1)
else if (tagtype & MFU_TT_UL_EV1)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("MIFARE Ultralight EV1 UNKNOWN"), spaces, "");
else if (tagtype & NTAG)
else if (tagtype & MFU_TT_NTAG)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG UNKNOWN"), spaces, "");
else if (tagtype & NTAG_203)
else if (tagtype & MFU_TT_NTAG_203)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 203 144bytes (NT2H0301F0DT)"), spaces, "");
else if (tagtype & NTAG_210u)
else if (tagtype & MFU_TT_NTAG_210u)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 210u (micro) 48bytes (NT2L1001G0DU)"), spaces, "");
else if (tagtype & NTAG_210)
else if (tagtype & MFU_TT_NTAG_210)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 210 48bytes (NT2L1011G0DU)"), spaces, "");
else if (tagtype & NTAG_212)
else if (tagtype & MFU_TT_NTAG_212)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 212 128bytes (NT2L1211G0DU)"), spaces, "");
else if (tagtype & NTAG_213)
else if (tagtype & MFU_TT_NTAG_213)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 213 144bytes (NT2H1311G0DU)"), spaces, "");
else if (tagtype & NTAG_213_F)
else if (tagtype & MFU_TT_NTAG_213_F)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spaces, "");
else if (tagtype & NTAG_213_C)
else if (tagtype & MFU_TT_NTAG_213_C)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 213C 144bytes (NT2H1311C1DTL)"), spaces, "");
else if (tagtype & NTAG_213_TT)
else if (tagtype & MFU_TT_NTAG_213_TT)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 213TT 144bytes (NT2H1311TTDU)"), spaces, "");
else if (tagtype & NTAG_215)
else if (tagtype & MFU_TT_NTAG_215)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 215 504bytes (NT2H1511G0DU)"), spaces, "");
else if (tagtype & NTAG_216)
else if (tagtype & MFU_TT_NTAG_216)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 216 888bytes (NT2H1611G0DU)"), spaces, "");
else if (tagtype & NTAG_216_F)
else if (tagtype & MFU_TT_NTAG_216_F)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG 216F 888bytes (NT2H1611F0DTL)"), spaces, "");
else if (tagtype & NTAG_I2C_1K)
else if (tagtype & MFU_TT_NTAG_I2C_1K)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG I2C 888bytes (NT3H1101FHK)"), spaces, "");
else if (tagtype & NTAG_I2C_2K)
else if (tagtype & MFU_TT_NTAG_I2C_2K)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG I2C 1904bytes (NT3H1201FHK)"), spaces, "");
else if (tagtype & NTAG_I2C_1K_PLUS)
else if (tagtype & MFU_TT_NTAG_I2C_1K_PLUS)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG I2C plus 888bytes (NT3H2111FHK)"), spaces, "");
else if (tagtype & NTAG_I2C_2K_PLUS)
else if (tagtype & MFU_TT_NTAG_I2C_2K_PLUS)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("NTAG I2C plus 1912bytes (NT3H2211FHK)"), spaces, "");
else if (tagtype & MY_D)
else if (tagtype & MFU_TT_MY_D)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 (SLE 66RxxS)"), spaces, "");
else if (tagtype & MY_D_NFC)
else if (tagtype & MFU_TT_MY_D_NFC)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 NFC (SLE 66RxxP)"), spaces, "");
else if (tagtype & MY_D_MOVE)
else if (tagtype & MFU_TT_MY_D_MOVE)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 move (SLE 66R01P)"), spaces, "");
else if (tagtype & MY_D_MOVE_NFC)
else if (tagtype & MFU_TT_MY_D_MOVE_NFC)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 move NFC (SLE 66R01P)"), spaces, "");
else if (tagtype & MY_D_MOVE_LEAN)
else if (tagtype & MFU_TT_MY_D_MOVE_LEAN)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("INFINEON my-d\x99 move lean (SLE 66R01L)"), spaces, "");
else if (tagtype & FUDAN_UL)
else if (tagtype & MFU_TT_FUDAN_UL)
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("FUDAN Ultralight Compatible (or other compatible)"), spaces, "");
else
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("Unknown %06x"), spaces, "", tagtype);
snprintf(typestr, sizeof(typestr), "%*sTYPE: " _YELLOW_("Unknown %06" PRIx64), spaces, "", tagtype);
bool ismagic = ((tagtype & MAGIC) == MAGIC);
bool ismagic = ((tagtype & MFU_TT_MAGIC) == MFU_TT_MAGIC);
if (ismagic)
snprintf(typestr + strlen(typestr), 4, " (");
snprintf(typestr + strlen(typestr), sizeof(typestr) - strlen(typestr), " %s ", (tagtype & MAGIC) ? _GREEN_("magic") : "");
tagtype &= ~(MAGIC);
snprintf(typestr + strlen(typestr), sizeof(typestr) - strlen(typestr), "%s", (tagtype & MAGIC_1A) ? _GREEN_("Gen 1a") : "");
snprintf(typestr + strlen(typestr), sizeof(typestr) - strlen(typestr), "%s", (tagtype & MAGIC_1B) ? _GREEN_("Gen 1b") : "");
snprintf(typestr + strlen(typestr), sizeof(typestr) - strlen(typestr), " %s ", (tagtype & MFU_TT_MAGIC) ? _GREEN_("magic") : "");
tagtype &= ~(MFU_TT_MAGIC);
snprintf(typestr + strlen(typestr), sizeof(typestr) - strlen(typestr), "%s", (tagtype & MFU_TT_MAGIC_1A) ? _GREEN_("Gen 1a") : "");
snprintf(typestr + strlen(typestr), sizeof(typestr) - strlen(typestr), "%s", (tagtype & MFU_TT_MAGIC_1B) ? _GREEN_("Gen 1b") : "");
if (ismagic)
snprintf(typestr + strlen(typestr), 4, " )");
@ -738,7 +746,7 @@ static int ulc_print_configuration(uint8_t *data) {
return PM3_SUCCESS;
}
static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t startPage) {
static int ulev1_print_configuration(uint64_t tagtype, uint8_t *data, uint8_t startPage) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Configuration"));
@ -756,7 +764,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4));
//NTAG213TT has different ASCII mirroring options and config bytes interpretation from other ulev1 class tags
if (tagtype & NTAG_213_TT) {
if (tagtype & MFU_TT_NTAG_213_TT) {
uint8_t mirror_conf = ((data[0] & 0xE0) >> 5);
uint8_t mirror_byte = ((data[0] & 0x18) >> 3);
uint8_t mirror_page = data[2];
@ -822,7 +830,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
PrintAndLogEx(INFO, " mirror start page %02X | byte pos %02X - %s", mirror_page, mirror_byte, (mirror_page >= 0x4 && ((mirror_user_mem_start_byte + bytes_required_for_mirror_data) <= 144)) ? _GREEN_("OK") : _YELLOW_("Invalid value"));
}
} else if (tagtype & (NTAG_213_F | NTAG_216_F)) {
} else if (tagtype & (MFU_TT_NTAG_213_F | MFU_TT_NTAG_216_F)) {
uint8_t mirror_conf = ((data[0] & 0xC0) >> 6);
uint8_t mirror_byte = (data[0] & 0x30);
bool sleep_en = (data[0] & 0x08);
@ -865,7 +873,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
break;
}
// valid mirror start page and byte position within start page.
if (tagtype & NTAG_213_F) {
if (tagtype & MFU_TT_NTAG_213_F) {
switch (mirror_conf) {
case 1:
{ PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;}
@ -876,7 +884,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
default:
break;
}
} else if (tagtype & NTAG_216_F) {
} else if (tagtype & MFU_TT_NTAG_216_F) {
switch (mirror_conf) {
case 1:
{ PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xDE) ? "OK" : "Invalid value"); break;}
@ -901,7 +909,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
uint8_t tt_msg_resp_len = 0;
uint8_t tt_status_resp[5] = {0x00};
if (tagtype & NTAG_213_TT) {
if (tagtype & MFU_TT_NTAG_213_TT) {
tt_enabled = (data[1] & 0x02);
tt_msg_resp_len = ul_read(45, tt_message, 4);
@ -941,7 +949,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2));
PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2));
if (tagtype & NTAG_213_TT) {
if (tagtype & MFU_TT_NTAG_213_TT) {
if (data[1] & 0x06) {
PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s- (cannot be read)", sprint_hex(tt_message, tt_msg_resp_len));
PrintAndLogEx(INFO, " - tamper message is masked in memory");
@ -952,7 +960,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
}
//The NTAG213TT only returns meaningful information for the fields below if the tamper feature is enabled
if ((tagtype & NTAG_213_TT) && tt_enabled) {
if ((tagtype & MFU_TT_NTAG_213_TT) && tt_enabled) {
uint8_t tt_status_len = ntagtt_getTamperStatus(tt_status_resp, 5);
@ -1012,7 +1020,7 @@ static int ulev1_print_counters(void) {
return len;
}
static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *signature, size_t signature_len) {
static int ulev1_print_signature(uint64_t tagtype, uint8_t *uid, uint8_t *signature, size_t signature_len) {
#define PUBLIC_ECDA_KEYLEN 33
// known public keys for the originality check (source: https://github.com/alexbatalov/node-nxp-originality-verifier)
@ -1152,14 +1160,14 @@ static int ulc_magic_test(){
uint8_t nonce1[11] = {0x00};
uint8_t nonce2[11] = {0x00};
if ( !ul_select(&card) ){
return UL_ERROR;
return MFU_TT_UL_ERROR;
}
int status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
if ( status > 0 ) {
status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
returnValue = ( !memcmp(nonce1, nonce2, 11) ) ? UL_C_MAGIC : UL_C;
returnValue = ( !memcmp(nonce1, nonce2, 11) ) ? MFU_TT_UL_C_MAGIC : MFU_TT_UL_C;
} else {
returnValue = UL;
returnValue = MFU_TT_UL;
}
DropField();
return returnValue;
@ -1172,12 +1180,12 @@ static int ul_magic_test(void) {
iso14a_card_select_t card;
if (ul_select(&card) == false)
return UL_ERROR;
return MFU_TT_UL_ERROR;
int status = ul_comp_write(0, NULL, 0);
DropField();
if (status == 0)
return MAGIC;
return MFU_TT_MAGIC;
// check for GEN1A, GEN1B and NTAG21x
uint8_t is_generation = 0;
@ -1191,11 +1199,11 @@ static int ul_magic_test(void) {
}
switch (is_generation) {
case MAGIC_GEN_1A:
return MAGIC_1A;
return MFU_TT_MAGIC_1A;
case MAGIC_GEN_1B:
return MAGIC_1B;
return MFU_TT_MAGIC_1B;
case MAGIC_NTAG21X:
return MAGIC_NTAG;
return MFU_TT_MAGIC_NTAG;
default:
break;
}
@ -1461,7 +1469,7 @@ static int mfu_get_version_uid(uint8_t *version, uint8_t *uid) {
return PM3_SUCCESS;
}
static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authkey, int ak_len) {
static int mfu_fingerprint(uint64_t tagtype, bool hasAuthKey, uint8_t *authkey, int ak_len) {
uint8_t *data = NULL;
int res = PM3_SUCCESS;
@ -1486,7 +1494,7 @@ static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authke
uint8_t keytype = 0;
if (hasAuthKey) {
if (tagtype & UL_C)
if (tagtype & MFU_TT_UL_C)
keytype = 1; //UL_C auth
else
keytype = 2; //UL_EV1/NTAG auth
@ -1567,17 +1575,17 @@ out:
uint32_t GetHF14AMfU_Type(void) {
TagTypeUL_t tagtype = UNKNOWN;
uint64_t tagtype = MFU_TT_UNKNOWN;
iso14a_card_select_t card;
if (ul_select(&card) == false)
return UL_ERROR;
return MFU_TT_UL_ERROR;
// Ultralight - ATQA / SAK
if (card.atqa[1] != 0x00 || card.atqa[0] != 0x44 || card.sak != 0x00) {
//PrintAndLogEx(NORMAL, "Tag is not Ultralight | NTAG | MY-D [ATQA: %02X %02X SAK: %02X]\n", card.atqa[1], card.atqa[0], card.sak);
DropField();
return UL_ERROR;
return MFU_TT_UL_ERROR;
}
if (card.uid[0] != 0x05) {
@ -1628,79 +1636,79 @@ uint32_t GetHF14AMfU_Type(void) {
Feiju NTAG 0053040201000F03
*/
if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0B", 7) == 0) { tagtype = UL_EV1_48; break; }
else if (memcmp(version, "\x00\x04\x03\x01\x02\x00\x0B", 7) == 0) { tagtype = UL_NANO_40; break; }
else if (memcmp(version, "\x00\x04\x03\x02\x01\x00\x0B", 7) == 0) { tagtype = UL_EV1_48; break; }
else if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0E", 7) == 0) { tagtype = UL_EV1_128; break; }
else if (memcmp(version, "\x00\x04\x03\x02\x01\x00\x0E", 7) == 0) { tagtype = UL_EV1_128; break; }
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { tagtype = UL_EV1_128; break; } // Mikron JSC Russia EV1 41 pages tag
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0B", 7) == 0) { tagtype = NTAG_210; break; }
else if (memcmp(version, "\x00\x04\x04\x01\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; }
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0E", 7) == 0) { tagtype = NTAG_212; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; }
else if (memcmp(version, "\x00\x53\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; } //Shanghai Feiju Microelectronics Co. Ltd. China (Xiaomi Air Purifier filter)
else if (memcmp(version, "\x00\x04\x04\x02\x01\x01\x0F", 7) == 0) { tagtype = NTAG_213_C; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x11", 7) == 0) { tagtype = NTAG_215; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x13", 7) == 0) { tagtype = NTAG_216; break; }
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213_F; break; }
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x13", 7) == 0) { tagtype = NTAG_216_F; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x03\x00\x0F", 7) == 0) { tagtype = NTAG_213_TT; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x13", 7) == 0) { tagtype = NTAG_I2C_1K; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x15", 7) == 0) { tagtype = NTAG_I2C_2K; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x13", 7) == 0) { tagtype = NTAG_I2C_1K_PLUS; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x15", 7) == 0) { tagtype = NTAG_I2C_2K_PLUS; break; }
else if (version[2] == 0x04) { tagtype = NTAG; break; }
else if (version[2] == 0x03) { tagtype = UL_EV1; }
if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0B", 7) == 0) { tagtype = MFU_TT_UL_EV1_48; break; }
else if (memcmp(version, "\x00\x04\x03\x01\x02\x00\x0B", 7) == 0) { tagtype = MFU_TT_UL_NANO_40; break; }
else if (memcmp(version, "\x00\x04\x03\x02\x01\x00\x0B", 7) == 0) { tagtype = MFU_TT_UL_EV1_48; break; }
else if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0E", 7) == 0) { tagtype = MFU_TT_UL_EV1_128; break; }
else if (memcmp(version, "\x00\x04\x03\x02\x01\x00\x0E", 7) == 0) { tagtype = MFU_TT_UL_EV1_128; break; }
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { tagtype = MFU_TT_UL_EV1_128; break; } // Mikron JSC Russia EV1 41 pages tag
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0B", 7) == 0) { tagtype = MFU_TT_NTAG_210; break; }
else if (memcmp(version, "\x00\x04\x04\x01\x02\x00\x0B", 7) == 0) { tagtype = MFU_TT_NTAG_210u; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x02\x00\x0B", 7) == 0) { tagtype = MFU_TT_NTAG_210u; break; }
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0E", 7) == 0) { tagtype = MFU_TT_NTAG_212; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = MFU_TT_NTAG_213; break; }
else if (memcmp(version, "\x00\x53\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = MFU_TT_NTAG_213; break; } //Shanghai Feiju Microelectronics Co. Ltd. China (Xiaomi Air Purifier filter)
else if (memcmp(version, "\x00\x04\x04\x02\x01\x01\x0F", 7) == 0) { tagtype = MFU_TT_NTAG_213_C; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x11", 7) == 0) { tagtype = MFU_TT_NTAG_215; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x13", 7) == 0) { tagtype = MFU_TT_NTAG_216; break; }
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x0F", 7) == 0) { tagtype = MFU_TT_NTAG_213_F; break; }
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x13", 7) == 0) { tagtype = MFU_TT_NTAG_216_F; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x03\x00\x0F", 7) == 0) { tagtype = MFU_TT_NTAG_213_TT; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x13", 7) == 0) { tagtype = MFU_TT_NTAG_I2C_1K; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x15", 7) == 0) { tagtype = MFU_TT_NTAG_I2C_2K; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x13", 7) == 0) { tagtype = MFU_TT_NTAG_I2C_1K_PLUS; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x15", 7) == 0) { tagtype = MFU_TT_NTAG_I2C_2K_PLUS; break; }
else if (version[2] == 0x04) { tagtype = MFU_TT_NTAG; break; }
else if (version[2] == 0x03) { tagtype = MFU_TT_UL_EV1; }
break;
}
case 0x01:
tagtype = UL_C;
tagtype = MFU_TT_UL_C;
break;
case 0x00:
tagtype = UL;
tagtype = MFU_TT_UL;
break;
case -1 :
tagtype = (UL | UL_C | NTAG_203);
tagtype = (MFU_TT_UL | MFU_TT_UL_C | MFU_TT_NTAG_203);
break; // could be UL | UL_C magic tags
default :
tagtype = UNKNOWN;
tagtype = MFU_TT_UNKNOWN;
break;
}
// UL vs UL-C vs ntag203 test
if (tagtype & (UL | UL_C | NTAG_203)) {
if (!ul_select(&card)) return UL_ERROR;
if (tagtype & (MFU_TT_UL | MFU_TT_UL_C | MFU_TT_NTAG_203)) {
if (!ul_select(&card)) return MFU_TT_UL_ERROR;
// do UL_C check first...
uint8_t nonce[11] = {0x00};
int status = ulc_requestAuthentication(nonce, sizeof(nonce));
DropField();
if (status > 1) {
tagtype = UL_C;
tagtype = MFU_TT_UL_C;
} else {
// need to re-select after authentication error
if (ul_select(&card) == false)
return UL_ERROR;
return MFU_TT_UL_ERROR;
uint8_t data[16] = {0x00};
// read page 0x26-0x29 (last valid ntag203 page)
status = ul_read(0x26, data, sizeof(data));
if (status <= 1) {
tagtype = UL;
tagtype = MFU_TT_UL;
} else {
// read page 0x30 (should error if it is a ntag203)
status = ul_read(0x30, data, sizeof(data));
if (status <= 1) {
tagtype = NTAG_203;
tagtype = MFU_TT_NTAG_203;
} else {
tagtype = UNKNOWN;
tagtype = MFU_TT_UNKNOWN;
}
}
DropField();
}
}
if (tagtype & UL) {
if (tagtype & MFU_TT_UL) {
tagtype = ul_fudan_check();
DropField();
}
@ -1711,23 +1719,23 @@ uint32_t GetHF14AMfU_Type(void) {
switch (nib) {
// case 0: tagtype = SLE66R35E7; break; //or SLE 66R35E7 - mifare compat... should have different sak/atqa for mf 1k
case 1:
tagtype = MY_D;
tagtype = MFU_TT_MY_D;
break; // or SLE 66RxxS ... up to 512 pages of 8 user bytes...
case 2:
tagtype = (MY_D_NFC);
tagtype = MFU_TT_MY_D_NFC;
break; // or SLE 66RxxP ... up to 512 pages of 8 user bytes... (or in nfc mode FF pages of 4 bytes)
case 3:
tagtype = (MY_D_MOVE | MY_D_MOVE_NFC);
tagtype = (MFU_TT_MY_D_MOVE | MFU_TT_MY_D_MOVE_NFC);
break; // or SLE 66R01P // 38 pages of 4 bytes //notice: we can not currently distinguish between these two
case 7:
tagtype = MY_D_MOVE_LEAN;
tagtype = MFU_TT_MY_D_MOVE_LEAN;
break; // or SLE 66R01L // 16 pages of 4 bytes
}
}
tagtype |= ul_magic_test();
if (tagtype == (UNKNOWN | MAGIC)) {
tagtype = (UL_MAGIC);
if (tagtype == (MFU_TT_UNKNOWN | MFU_TT_MAGIC)) {
tagtype = (MFU_TT_UL_MAGIC);
}
return tagtype;
}
@ -1780,8 +1788,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
uint8_t pack[4] = {0, 0, 0, 0};
int len;
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR)
uint64_t tagtype = GetHF14AMfU_Type();
if (tagtype == MFU_TT_UL_ERROR)
return PM3_ESOFT;
PrintAndLogEx(NORMAL, "");
@ -1812,7 +1820,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
}
// UL_C Specific
if ((tagtype & UL_C)) {
if ((tagtype & MFU_TT_UL_C)) {
// read pages 0x28, 0x29, 0x2A, 0x2B
uint8_t ulc_conf[16] = {0x00};
@ -1829,7 +1837,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
mfu_fingerprint(tagtype, has_auth_key, authkeyptr, ak_len);
if ((tagtype & MAGIC)) {
if ((tagtype & MFU_TT_MAGIC)) {
//just read key
uint8_t ulc_deskey[16] = {0x00};
status = ul_read(0x2C, ulc_deskey, sizeof(ulc_deskey));
@ -1863,7 +1871,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
// do counters and signature first (don't neet auth)
// ul counters are different than ntag counters
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1))) {
if ((tagtype & (MFU_TT_UL_EV1_48 | MFU_TT_UL_EV1_128 | MFU_TT_UL_EV1))) {
if (ulev1_print_counters() != 3) {
// failed - re-select
if (ul_auth_select(&card, tagtype, has_auth_key, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) {
@ -1873,7 +1881,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
}
// NTAG counters?
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_C | NTAG_213_TT | NTAG_215 | NTAG_216))) {
if ((tagtype & (MFU_TT_NTAG_213 | MFU_TT_NTAG_213_F | MFU_TT_NTAG_213_C | MFU_TT_NTAG_213_TT | MFU_TT_NTAG_215 | MFU_TT_NTAG_216))) {
if (ntag_print_counter()) {
// failed - re-select
if (ul_auth_select(&card, tagtype, has_auth_key, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) {
@ -1883,7 +1891,10 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
}
// Read signature
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_210u | NTAG_213 | NTAG_213_F | NTAG_213_C | NTAG_213_TT | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) {
if ((tagtype & (MFU_TT_UL_EV1_48 | MFU_TT_UL_EV1_128 | MFU_TT_UL_EV1 | MFU_TT_UL_NANO_40 |
MFU_TT_NTAG_210u | MFU_TT_NTAG_213 | MFU_TT_NTAG_213_F | MFU_TT_NTAG_213_C |
MFU_TT_NTAG_213_TT | MFU_TT_NTAG_215 | MFU_TT_NTAG_216 | MFU_TT_NTAG_216_F |
MFU_TT_NTAG_I2C_1K | MFU_TT_NTAG_I2C_2K | MFU_TT_NTAG_I2C_1K_PLUS | MFU_TT_NTAG_I2C_2K_PLUS))) {
uint8_t ulev1_signature[32] = {0x00};
status = ulev1_readSignature(ulev1_signature, sizeof(ulev1_signature));
if (status == -1) {
@ -2096,8 +2107,8 @@ static int CmdHF14AMfUWrBl(const char *Cmd) {
uint8_t *authKeyPtr = authenticationkey;
// starting with getting tagtype
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR)
uint64_t tagtype = GetHF14AMfU_Type();
if (tagtype == MFU_TT_UL_ERROR)
return PM3_ESOFT;
uint8_t maxblockno = 0;
@ -2217,8 +2228,8 @@ static int CmdHF14AMfURdBl(const char *Cmd) {
uint8_t *authKeyPtr = authenticationkey;
// start with getting tagtype
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR)
uint64_t tagtype = GetHF14AMfU_Type();
if (tagtype == MFU_TT_UL_ERROR)
return PM3_ESOFT;
uint8_t maxblockno = 0;
@ -2506,8 +2517,8 @@ static int CmdHF14AMfUDump(const char *Cmd) {
authKeyPtr = SwapEndian64(authenticationkey, ak_len, 4);
}
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR)
uint64_t tagtype = GetHF14AMfU_Type();
if (tagtype == MFU_TT_UL_ERROR)
return PM3_ESOFT;
//get number of pages to read
@ -2524,7 +2535,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
PrintAndLogEx(SUCCESS, "Reading tag memory...");
uint8_t keytype = 0;
if (has_auth_key || has_pwd) {
if (tagtype & UL_C)
if (tagtype & MFU_TT_UL_C)
keytype = 1; //UL_C auth
else
keytype = 2; //UL_EV1/NTAG auth
@ -2574,7 +2585,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
// not ul_c and not std ul then attempt to collect info like
// VERSION, SIGNATURE, COUNTERS, TEARING, PACK,
if (!(tagtype & UL_C || tagtype & UL || tagtype & MY_D_MOVE || tagtype & MY_D_MOVE_LEAN)) {
if (!(tagtype & MFU_TT_UL_C || tagtype & MFU_TT_UL || tagtype & MFU_TT_MY_D_MOVE || tagtype & MFU_TT_MY_D_MOVE_LEAN)) {
//attempt to read pack
uint8_t get_pack[] = {0, 0};
if (ul_auth_select(&card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack)) != PM3_SUCCESS) {
@ -2604,7 +2615,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
uint8_t n = 0;
// NTAG has 1 counter, at 0x02
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_C | NTAG_213_TT | NTAG_215 | NTAG_216))) {
if ((tagtype & (MFU_TT_NTAG_213 | MFU_TT_NTAG_213_F | MFU_TT_NTAG_213_C | MFU_TT_NTAG_213_TT | MFU_TT_NTAG_215 | MFU_TT_NTAG_216))) {
n = 2;
}
@ -2652,7 +2663,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
authKeyPtr = authenticationkey;
}
if (tagtype & UL_C) { //add 4 pages
if (tagtype & MFU_TT_UL_C) { //add 4 pages
memcpy(data + pages * 4, authKeyPtr, ak_len);
pages += ak_len / 4;
} else { // 2nd page from end
@ -2751,13 +2762,13 @@ int CmdHF14MfUTamper(const char *Cmd) {
bool disable = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR) {
uint64_t tagtype = GetHF14AMfU_Type();
if (tagtype == MFU_TT_UL_ERROR) {
PrintAndLogEx(WARNING, "Tag type not detected");
DropField();
return PM3_ESOFT;
}
if (tagtype != NTAG_213_TT) {
if (tagtype != MFU_TT_NTAG_213_TT) {
PrintAndLogEx(WARNING, "Tag type not NTAG 213TT");
DropField();
return PM3_ESOFT;
@ -2775,7 +2786,7 @@ int CmdHF14MfUTamper(const char *Cmd) {
if (use_msg) {
if (ul_select(&card) == false) {
DropField();
return UL_ERROR;
return MFU_TT_UL_ERROR;
}
PrintAndLogEx(INFO, "Trying to write tamper message\n");
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, tt_msg_page, 0, 0, msg_data, 4);
@ -2798,7 +2809,7 @@ int CmdHF14MfUTamper(const char *Cmd) {
if (ul_select(&card) == false) {
PrintAndLogEx(ERR, "Unable to select tag");
DropField();
return UL_ERROR;
return MFU_TT_UL_ERROR;
}
uint8_t cfg_page[4] = {0x00};
@ -4384,8 +4395,8 @@ int CmdHF14MfuNDEFRead(const char *Cmd) {
}
// Get tag type
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR) {
uint64_t tagtype = GetHF14AMfU_Type();
if (tagtype == MFU_TT_UL_ERROR) {
PrintAndLogEx(WARNING, "No Ultralight / NTAG based tag found");
return PM3_ESOFT;
}

View file

@ -43,7 +43,7 @@ typedef struct {
} PACKED old_mfu_dump_t;
uint32_t GetHF14AMfU_Type(void);
int ul_print_type(uint32_t tagtype, uint8_t spaces);
int ul_print_type(uint64_t tagtype, uint8_t spaces);
void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage);
int ul_read_uid(uint8_t *uid);
int trace_mfuc_try_default_3des_keys(uint8_t **correct_key, int state, uint8_t (*authdata)[16]);
@ -55,44 +55,43 @@ int CmdHF14MfUTamper(const char *Cmd);
uint16_t ul_ev1_packgen_VCNEW(uint8_t *uid, uint32_t pwd);
uint32_t ul_ev1_otpgenA(uint8_t *uid);
typedef enum TAGTYPE_UL {
UNKNOWN = 0x000000,
UL = 0x1,
UL_C = 0x2,
UL_EV1_48 = 0x4,
UL_EV1_128 = 0x8,
NTAG = 0x10,
NTAG_203 = 0x20,
NTAG_210 = 0x40,
NTAG_212 = 0x80,
NTAG_213 = 0x100,
NTAG_215 = 0x200,
NTAG_216 = 0x400,
MY_D = 0x800,
MY_D_NFC = 0x1000,
MY_D_MOVE = 0x2000,
MY_D_MOVE_NFC = 0x4000,
MY_D_MOVE_LEAN = 0x8000,
NTAG_I2C_1K = 0x10000,
NTAG_I2C_2K = 0x20000,
NTAG_I2C_1K_PLUS = 0x40000,
NTAG_I2C_2K_PLUS = 0x80000,
FUDAN_UL = 0x100000,
MAGIC = 0x200000,
NTAG_213_F = 0x400000,
NTAG_216_F = 0x800000,
UL_EV1 = 0x1000000,
UL_NANO_40 = 0x2000000,
NTAG_213_TT = 0x4000000,
NTAG_213_C = 0x8000000,
MAGIC_1A = 0x10000000 | MAGIC,
MAGIC_1B = 0x20000000 | MAGIC,
MAGIC_NTAG = 0x40000000 | MAGIC,
NTAG_210u = 0x80000000,
UL_MAGIC = UL | MAGIC,
UL_C_MAGIC = UL_C | MAGIC,
// Don't forget to fill UL_TYPES_ARRAY and UL_MEMORY_ARRAY if new types are added
UL_ERROR = 0xFFFFFF,
} TagTypeUL_t;
#define MFU_TT_UNKNOWN 0x0ULL
#define MFU_TT_UL 0x1ULL
#define MFU_TT_UL_C 0x2ULL
#define MFU_TT_UL_EV1_48 0x4ULL
#define MFU_TT_UL_EV1_128 0x8ULL
#define MFU_TT_NTAG 0x10ULL
#define MFU_TT_NTAG_203 0x20ULL
#define MFU_TT_NTAG_210 0x40ULL
#define MFU_TT_NTAG_212 0x80ULL
#define MFU_TT_NTAG_213 0x100ULL
#define MFU_TT_NTAG_215 0x200ULL
#define MFU_TT_NTAG_216 0x400ULL
#define MFU_TT_MY_D 0x800ULL
#define MFU_TT_MY_D_NFC 0x1000ULL
#define MFU_TT_MY_D_MOVE 0x2000ULL
#define MFU_TT_MY_D_MOVE_NFC 0x4000ULL
#define MFU_TT_MY_D_MOVE_LEAN 0x8000ULL
#define MFU_TT_NTAG_I2C_1K 0x10000ULL
#define MFU_TT_NTAG_I2C_2K 0x20000ULL
#define MFU_TT_NTAG_I2C_1K_PLUS 0x40000ULL
#define MFU_TT_NTAG_I2C_2K_PLUS 0x80000ULL
#define MFU_TT_FUDAN_UL 0x100000ULL
#define MFU_TT_MAGIC 0x200000ULL
#define MFU_TT_NTAG_213_F 0x400000ULL
#define MFU_TT_NTAG_216_F 0x800000ULL
#define MFU_TT_UL_EV1 0x1000000ULL
#define MFU_TT_UL_NANO_40 0x2000000ULL
#define MFU_TT_NTAG_213_TT 0x4000000ULL
#define MFU_TT_NTAG_213_C 0x8000000ULL
#define MFU_TT_MAGIC_1A (0x10000000ULL | MFU_TT_MAGIC)
#define MFU_TT_MAGIC_1B (0x20000000ULL | MFU_TT_MAGIC)
#define MFU_TT_MAGIC_NTAG (0x40000000ULL | MFU_TT_MAGIC)
#define MFU_TT_NTAG_210u 0x80000000ULL
#define MFU_TT_UL_MAGIC (MFU_TT_UL | MFU_TT_MAGIC)
#define MFU_TT_UL_C_MAGIC (MFU_TT_UL_C | MFU_TT_MAGIC)
// Don't forget to fill UL_TYPES_ARRAY and UL_MEMORY_ARRAY if new types are added
#define MFU_TT_UL_ERROR 0x7FFFFFFFULL
#endif