From db3103b531cf146dc13ac2b883cd13fb6e86976e Mon Sep 17 00:00:00 2001 From: Eloff Date: Sun, 21 Apr 2019 03:18:00 +0300 Subject: [PATCH 1/4] UL/NTAG new dump file format. Added counters support, simulation --- CHANGELOG.md | 1 + armsrc/iso14443a.c | 103 +++++++++++++++++------------- armsrc/iso14443a.h | 12 ++++ armsrc/util.c | 6 ++ armsrc/util.h | 1 + client/cmdhfmfu.c | 45 +++++++------ client/cmdhfmfu.h | 8 +-- client/loclass/fileutils.c | 11 ++-- client/scripts/dumptoemul-mfu.lua | 10 +-- 9 files changed, 123 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b768a5cd7..54323e4d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Change/Add new dump format for Ultralight/NTAG, counters support, simulation (@mceloff) - Fix/Add 'hf mf sim' bugs fix, RATS support, etc (@mceloff) - Fix serial of FPC. (@ryan) - Fix 'data shiftgraphzero' corrupting end of GraphBuffer (@doegox) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 4dde7846a..154d621d6 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -832,8 +832,6 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { // PACK response to PWD AUTH for EV1/NTAG uint8_t response8[4] = {0, 0, 0, 0}; - // Counter for EV1/NTAG - uint32_t counters[] = {0, 0, 0}; // The first response contains the ATQA (note: bytes are transmitted in reverse order). uint8_t response1[] = {0, 0}; @@ -848,6 +846,9 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { memset(ar_nr_nonces, 0x00, sizeof(ar_nr_nonces)); uint8_t moebius_count = 0; + // some first pages of UL/NTAG dump is special data + mfu_dump_prefix_t *mfu_header = tagType == 2 || tagType == 7 ? (mfu_dump_prefix_t *) BigBuf_get_EM_addr() : NULL; + switch (tagType) { case 1: { // MIFARE Classic 1k response1[0] = 0x04; @@ -884,13 +885,12 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { case 7: { // NTAG response1[0] = 0x44; sak = 0x00; - // PACK - response8[0] = 0x80; - response8[1] = 0x80; + // PACK, from last page of dump + emlGetMemBt(response8, MFU_DUMP_PREFIX_LENGTH + mfu_header->pages * 4, 2); compute_crc(CRC_14443_A, response8, 2, &response8[2], &response8[3]); // uid not supplied then get from emulator memory if (data[0] == 0) { - uint16_t start = 4 * (0 + 12); + uint16_t start = MFU_DUMP_PREFIX_LENGTH; uint8_t emdata[8]; emlGetMemBt(emdata, start, sizeof(emdata)); memcpy(data, emdata, 3); // uid bytes 0-2 @@ -1086,12 +1086,17 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { uint8_t block = receivedCmd[1]; // if Ultralight or NTAG (4 byte blocks) if (tagType == 7 || tagType == 2) { - // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] - uint16_t start = 4 * (block + 12); - uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; - emlGetMemBt(emdata, start, 16); - AddCrc14A(emdata, 16); - EmSendCmd(emdata, sizeof(emdata)); + if (block > mfu_header->pages) { + // send NACK 0x0 == invalid argument + EmSend4bit(CARD_NACK_IV); + } else { + // first blocks of emu are header + uint16_t start = block * 4 + MFU_DUMP_PREFIX_LENGTH; + uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; + emlGetMemBt(emdata, start, 16); + AddCrc14A(emdata, 16); + EmSendCmd(emdata, sizeof(emdata)); + } // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below p_response = NULL; } else if (tagType == 9 && block == 1) { @@ -1110,23 +1115,36 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { p_response = NULL; } } else if (receivedCmd[0] == MIFARE_ULEV1_FASTREAD) { // Received a FAST READ (ranged read) - uint8_t emdata[MAX_FRAME_SIZE]; - // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] - int start = (receivedCmd[1] + 12) * 4; - len = (receivedCmd[2] - receivedCmd[1] + 1) * 4; - emlGetMemBt(emdata, start, len); - AddCrc14A(emdata, len); - EmSendCmd(emdata, len + 2); + uint8_t block1 = receivedCmd[1]; + uint8_t block2 = receivedCmd[2]; + if (block1 > mfu_header->pages) { + // send NACK 0x0 == invalid argument + EmSend4bit(CARD_NACK_IV); + } else { + uint8_t emdata[MAX_FRAME_SIZE]; + // first blocks of emu are header + int start = block1 * 4 + MFU_DUMP_PREFIX_LENGTH; + len = (block2 - block1 + 1) * 4; + emlGetMemBt(emdata, start, len); + AddCrc14A(emdata, len); + EmSendCmd(emdata, len + 2); + } p_response = NULL; } else if ((receivedCmd[0] == MIFARE_ULC_WRITE || receivedCmd[0] == MIFARE_ULC_COMP_WRITE) && (tagType == 2 || tagType == 7)) { // Received a WRITE // cmd + block + 4/16 bytes data + 2 bytes crc if (len == 8 || len == 20) { bool isCrcCorrect = CheckCrc14A(receivedCmd, len); if (isCrcCorrect) { - int block = receivedCmd[1] + 12; // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] - emlSetMem_xt(&receivedCmd[2], block, 1, 4); - // send ACK - EmSend4bit(CARD_ACK); + uint8_t block = receivedCmd[1]; + if (block > mfu_header->pages) { + // send NACK 0x0 == invalid argument + EmSend4bit(CARD_NACK_IV); + } else { + // first blocks of emu are header + emlSetMem_xt(&receivedCmd[2], block + MFU_DUMP_PREFIX_LENGTH / 4, 1, 4); + // send ACK + EmSend4bit(CARD_ACK); + } } else { // send NACK 0x1 == crc/parity error EmSend4bit(CARD_NACK_PA); @@ -1137,10 +1155,9 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { } p_response = NULL; } else if (receivedCmd[0] == MIFARE_ULEV1_READSIG && tagType == 7) { // Received a READ SIGNATURE -- - // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] - uint16_t start = 4 * 4; + // first blocks of emu are header uint8_t emdata[34]; - emlGetMemBt(emdata, start, 32); + memcpy(emdata, mfu_header->signature, 32); AddCrc14A(emdata, 32); EmSendCmd(emdata, sizeof(emdata)); p_response = NULL; @@ -1151,7 +1168,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { EmSend4bit(0x00); } else { uint8_t cmd[] = {0x00, 0x00, 0x00, 0x14, 0xa5}; - num_to_bytes(counters[index], 3, cmd); + memcpy(cmd, mfu_header->counter_tearing[index], 3); AddCrc14A(cmd, sizeof(cmd) - 2); EmSendCmd(cmd, sizeof(cmd)); } @@ -1162,15 +1179,13 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { // send NACK 0x0 == invalid argument EmSend4bit(0x00); } else { - - uint32_t val = bytes_to_num(receivedCmd + 2, 4); - + uint32_t val = le24toh(receivedCmd + 2) + le24toh(mfu_header->counter_tearing[index]); // if new value + old value is bigger 24bits, fail - if (val + counters[index] > 0xFFFFFF) { + if (val > 0xFFFFFF) { // send NACK 0x4 == counter overflow EmSend4bit(CARD_NACK_NA); } else { - counters[index] = val; + htole24(val, mfu_header->counter_tearing[index]); // send ACK EmSend4bit(CARD_ACK); } @@ -1184,7 +1199,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { // send NACK 0x0 == invalid argument EmSend4bit(0x00); } else { - emlGetMemBt(emdata, 10 + index, 1); + emdata[0] = mfu_header->counter_tearing[index][3]; AddCrc14A(emdata, sizeof(emdata) - 2); EmSendCmd(emdata, sizeof(emdata)); } @@ -1195,7 +1210,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { } else if (receivedCmd[0] == MIFARE_AUTH_KEYA || receivedCmd[0] == MIFARE_AUTH_KEYB) { // Received an authentication request if (tagType == 7) { // IF NTAG /EV1 0x60 == GET_VERSION, not a authentication request. uint8_t emdata[10]; - emlGetMemBt(emdata, 0, 8); + memcpy(emdata, mfu_header->version, 8); AddCrc14A(emdata, sizeof(emdata) - 2); EmSendCmd(emdata, sizeof(emdata)); p_response = NULL; @@ -1291,15 +1306,17 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { } else if (receivedCmd[0] == MIFARE_ULC_AUTH_1) { // ULC authentication, or Desfire Authentication } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH) { // NTAG / EV-1 authentication if (tagType == 7) { - uint16_t start = 13; // first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00] - uint8_t emdata[4]; - emlGetMemBt(emdata, start, 2); - AddCrc14A(emdata, 2); - EmSendCmd(emdata, sizeof(emdata)); - p_response = NULL; - uint32_t pwd = bytes_to_num(receivedCmd + 1, 4); - - if (MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd); + // PWD stored in dump now + uint8_t pwd[4]; + emlGetMemBt(pwd, (mfu_header->pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd)); + if (memcmp(receivedCmd + 1, pwd, 4) == 0) { + p_response = &responses[7]; // precompiled PACK + } else { + EmSend4bit(CARD_NACK_NA); + uint32_t pwd = bytes_to_num(receivedCmd + 1, 4); + if (MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd); + p_response = NULL; + } } } else { // Check for ISO 14443A-4 compliant commands, look at left nibble diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index f2a1c6120..27b6b8afe 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -95,6 +95,18 @@ typedef struct { uint8_t *parity; } tUart; +// Length must be aligned to 4 bytes (UL/NTAG page) +#define MFU_DUMP_PREFIX_LENGTH 56 + +typedef struct { + uint8_t version[8]; + uint8_t tbo[2]; + uint8_t tbo1[1]; + uint8_t pages; // max page number in dump + uint8_t signature[32]; + uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag +} mfu_dump_prefix_t; + #ifndef AddCrc14A # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) #endif diff --git a/armsrc/util.c b/armsrc/util.c index 8ee91b464..ce6a62d22 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -91,6 +91,12 @@ int32_t le24toh(uint8_t data[3]) { return (data[2] << 16) | (data[1] << 8) | data[0]; } +void htole24(uint32_t val, uint8_t data[3]) { + data[0] = (uint8_t) val; + data[1] = (uint8_t)(val >> 8); + data[2] = (uint8_t)(val >> 16); +} + //convert hex digit to integer uint8_t hex2int(char hexchar) { switch (hexchar) { diff --git a/armsrc/util.h b/armsrc/util.h index fc519fe43..f592f1ff3 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -93,6 +93,7 @@ uint64_t bytes_to_num(uint8_t *src, size_t len); void rol(uint8_t *data, const size_t len); void lsl(uint8_t *data, size_t len); int32_t le24toh(uint8_t data[3]); +void htole24(uint32_t val, uint8_t data[3]); uint8_t hex2int(char hexchar); void LED(int led, int ms); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 38b01bd71..47fb487f9 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1619,11 +1619,15 @@ void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage) { PrintAndLogEx(NORMAL, "----------+-------------------------+---------"); PrintAndLogEx(NORMAL, "Version | %s| %s", sprint_hex(card->version, sizeof(card->version)), sprint_ascii(card->version, sizeof(card->version))); PrintAndLogEx(NORMAL, "TBD | %-24s| %s", sprint_hex(card->tbo, sizeof(card->tbo)), sprint_ascii(card->tbo, sizeof(card->tbo))); - PrintAndLogEx(NORMAL, "Tearing | %-24s| %s", sprint_hex(card->tearing, sizeof(card->tearing)), sprint_ascii(card->tearing, sizeof(card->tearing))); - PrintAndLogEx(NORMAL, "Pack | %-24s| %s", sprint_hex(card->pack, sizeof(card->pack)), sprint_ascii(card->pack, sizeof(card->pack))); PrintAndLogEx(NORMAL, "TBD | %-24s| %s", sprint_hex(card->tbo1, sizeof(card->tbo1)), sprint_ascii(card->tbo1, sizeof(card->tbo1))); PrintAndLogEx(NORMAL, "Signature1| %s| %s", sprint_hex(card->signature, 16), sprint_ascii(card->signature, 16)); PrintAndLogEx(NORMAL, "Signature2| %s| %s", sprint_hex(card->signature + 16, 16), sprint_ascii(card->signature + 16, 16)); + PrintAndLogEx(NORMAL, "Counter0 | %-24s| %s", sprint_hex(card->counter_tearing[0], 3), sprint_ascii(card->counter_tearing[0], 3)); + PrintAndLogEx(NORMAL, "Tearing0 | %-24s| %s", sprint_hex(card->counter_tearing[0] + 3, 1), sprint_ascii(card->counter_tearing[0] + 3, 1)); + PrintAndLogEx(NORMAL, "Counter1 | %-24s| %s", sprint_hex(card->counter_tearing[1], 3), sprint_ascii(card->counter_tearing[1], 3)); + PrintAndLogEx(NORMAL, "Tearing1 | %-24s| %s", sprint_hex(card->counter_tearing[1] + 3, 1), sprint_ascii(card->counter_tearing[1] + 3, 1)); + PrintAndLogEx(NORMAL, "Counter2 | %-24s| %s", sprint_hex(card->counter_tearing[2], 3), sprint_ascii(card->counter_tearing[2], 3)); + PrintAndLogEx(NORMAL, "Tearing3 | %-24s| %s", sprint_hex(card->counter_tearing[2] + 3, 1), sprint_ascii(card->counter_tearing[2] + 3, 1)); PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, "\nBlock# | Data |lck| Ascii"); PrintAndLogEx(NORMAL, "---------+-------------+---+------"); @@ -1889,8 +1893,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { mfu_dump_t dump_file_data; uint8_t get_pack[] = {0, 0}; uint8_t get_version[] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t get_tearing[] = {0, 0, 0}; - uint8_t get_counter[] = {0, 0, 0}; + uint8_t get_counter_tearing[][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; uint8_t dummy_pack[] = {0, 0}; uint8_t get_signature[32]; memset(get_signature, 0, sizeof(get_signature)); @@ -1920,8 +1923,8 @@ static int CmdHF14AMfUDump(const char *Cmd) { ulev1_getVersion(get_version, sizeof(get_version)); for (uint8_t n = 0; n < 3; ++n) { - ulev1_readTearing(n, get_tearing + n, 1); - ulev1_readCounter(n, get_counter, sizeof(get_counter)); + ulev1_readTearing(n, &get_counter_tearing[n][3], 1); + ulev1_readCounter(n, &get_counter_tearing[n][0], 3); } DropField(); @@ -1935,7 +1938,8 @@ static int CmdHF14AMfUDump(const char *Cmd) { } // format and add keys to block dump output - if (hasAuthKey) { + // only add keys if not partial read, and complete pages read + if (!is_partial && pages == card_mem_size && hasAuthKey) { // if we didn't swapendian before - do it now for the sprint_hex call // NOTE: default entry is bigendian (unless swapped), sprint_hex outputs little endian // need to swap to keep it the same @@ -1954,11 +1958,11 @@ static int CmdHF14AMfUDump(const char *Cmd) { } //add *special* blocks to dump - //iceman: need to add counters and pwd values to the dump format + // pack and pwd saved into last pages of dump, if was not partial read + dump_file_data.pages = pages - 1; memcpy(dump_file_data.version, get_version, sizeof(dump_file_data.version)); - memcpy(dump_file_data.tearing, get_tearing, sizeof(dump_file_data.tearing)); - memcpy(dump_file_data.pack, get_pack, sizeof(dump_file_data.pack)); memcpy(dump_file_data.signature, get_signature, sizeof(dump_file_data.signature)); + memcpy(dump_file_data.counter_tearing, get_counter_tearing, sizeof(dump_file_data.counter_tearing)); memcpy(dump_file_data.data, data, pages * 4); printMFUdumpEx(&dump_file_data, pages, startPage); @@ -2092,16 +2096,22 @@ static int CmdHF14AMfURestore(const char *Cmd) { // read all data size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); - if (bytes_read < 48) { + if (bytes_read < DUMP_PREFIX_LENGTH) { PrintAndLogEx(WARNING, "Error, dump file is too small"); free(dump); return 1; } - PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", filename); - mfu_dump_t *mem = (mfu_dump_t *)dump; - uint8_t pages = (bytes_read - 48) / 4; + uint8_t pages = (bytes_read - DUMP_PREFIX_LENGTH) / 4; + + if (pages - 1 != mem->pages) { + PrintAndLogEx(WARNING, "Error, invalid dump, wrong page count"); + free(dump); + return 1; + } + + PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", filename); // print dump printMFUdumpEx(mem, pages, 0); @@ -2134,7 +2144,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { if (read_key) { // try reading key from dump and use. - memcpy(c.d.asBytes, mem->data + (bytes_read - 48 - 8), 4); + memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 8), 4); } else { memcpy(c.d.asBytes, p_authkey, 4); } @@ -2150,10 +2160,9 @@ static int CmdHF14AMfURestore(const char *Cmd) { memcpy(c.d.asBytes + 4, authkey, 4); } - // pack + // pack now stored in dump c.arg[0] = MFU_NTAG_SPECIAL_PACK; - c.d.asBytes[0] = mem->pack[0]; - c.d.asBytes[1] = mem->pack[1]; + memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 4), 2); c.d.asBytes[2] = 0; c.d.asBytes[3] = 0; PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(c.d.asBytes, 4)); diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index 444a55ea6..ea631b171 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -12,16 +12,16 @@ #include "comms.h" #include "loclass/fileutils.h" -#define DUMP_PREFIX_LENGTH 48 +// Length must be aligned to 4 bytes (UL/NTAG page) +#define DUMP_PREFIX_LENGTH 56 typedef struct { uint8_t version[8]; uint8_t tbo[2]; - uint8_t tearing[3]; - uint8_t pack[2]; uint8_t tbo1[1]; + uint8_t pages; // max page number in dump uint8_t signature[32]; - //uint8_t counter[3]; + uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag uint8_t data[1024]; } mfu_dump_t; diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 72d3e26af..1aa11cfd6 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -221,13 +221,16 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); JsonSaveBufAsHexCompact(root, "$.Card.Version", tmp->version, sizeof(tmp->version)); JsonSaveBufAsHexCompact(root, "$.Card.TBO_0", tmp->tbo, sizeof(tmp->tbo)); - JsonSaveBufAsHexCompact(root, "$.Card.Tearing", tmp->tearing, sizeof(tmp->tearing)); - JsonSaveBufAsHexCompact(root, "$.Card.Pack", tmp->pack, sizeof(tmp->pack)); JsonSaveBufAsHexCompact(root, "$.Card.TBO_1", tmp->tbo1, sizeof(tmp->tbo1)); JsonSaveBufAsHexCompact(root, "$.Card.Signature", tmp->signature, sizeof(tmp->signature)); - JsonSaveStr(root, "$.Card.Counter", "N/A"); + JsonSaveBufAsHexCompact(root, "$.Card.Counter0", tmp->counter_tearing[0], 3); + JsonSaveBufAsHexCompact(root, "$.Card.Tearing0", tmp->counter_tearing[0] + 3, 1); + JsonSaveBufAsHexCompact(root, "$.Card.Counter1", tmp->counter_tearing[1], 3); + JsonSaveBufAsHexCompact(root, "$.Card.Tearing1", tmp->counter_tearing[1] + 3, 1); + JsonSaveBufAsHexCompact(root, "$.Card.Counter2", tmp->counter_tearing[2], 3); + JsonSaveBufAsHexCompact(root, "$.Card.Tearing2", tmp->counter_tearing[2] + 3, 1); - // size of header 48b + // size of header 56b size_t len = (datalen - DUMP_PREFIX_LENGTH) / 4; for (size_t i = 0; i < len; i++) { diff --git a/client/scripts/dumptoemul-mfu.lua b/client/scripts/dumptoemul-mfu.lua index 34fbdc1d0..fb14077d5 100644 --- a/client/scripts/dumptoemul-mfu.lua +++ b/client/scripts/dumptoemul-mfu.lua @@ -104,11 +104,11 @@ local function main(args) -- lua uses start index and endindex, not count. -- UID is 3three skip bcc0 then 4bytes. -- 1 lua is one-index. - -- 1 + 96 (48*2) new dump format has version/signature/counter data here - -- 97,98,99,100,101,102 UID first three bytes - -- 103,104 bcc0 - -- 105--- UID last four bytes - local uid = string.sub(dumpdata, 97, 97+5)..string.sub(dumpdata, 97+8, 97+8+7) + -- 1 + 112 (56*2) new dump format has version/signature/counter data here + -- 113,114,115,116,117,118 UID first three bytes + -- 119,120 bcc0 + -- 121--- UID last four bytes + local uid = string.sub(dumpdata, 113, 113+5)..string.sub(dumpdata, 113+8, 113+8+7) output = output or (uid .. ".eml") -- Format some linebreaks From 4161779083d31c4722bcfe38493a63467dd5d4af Mon Sep 17 00:00:00 2001 From: Eloff Date: Mon, 22 Apr 2019 23:20:35 +0300 Subject: [PATCH 2/4] loops for counters output --- client/cmdhfmfu.c | 10 ++++------ client/loclass/fileutils.c | 15 ++++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 47fb487f9..5ba989584 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1622,12 +1622,10 @@ void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage) { PrintAndLogEx(NORMAL, "TBD | %-24s| %s", sprint_hex(card->tbo1, sizeof(card->tbo1)), sprint_ascii(card->tbo1, sizeof(card->tbo1))); PrintAndLogEx(NORMAL, "Signature1| %s| %s", sprint_hex(card->signature, 16), sprint_ascii(card->signature, 16)); PrintAndLogEx(NORMAL, "Signature2| %s| %s", sprint_hex(card->signature + 16, 16), sprint_ascii(card->signature + 16, 16)); - PrintAndLogEx(NORMAL, "Counter0 | %-24s| %s", sprint_hex(card->counter_tearing[0], 3), sprint_ascii(card->counter_tearing[0], 3)); - PrintAndLogEx(NORMAL, "Tearing0 | %-24s| %s", sprint_hex(card->counter_tearing[0] + 3, 1), sprint_ascii(card->counter_tearing[0] + 3, 1)); - PrintAndLogEx(NORMAL, "Counter1 | %-24s| %s", sprint_hex(card->counter_tearing[1], 3), sprint_ascii(card->counter_tearing[1], 3)); - PrintAndLogEx(NORMAL, "Tearing1 | %-24s| %s", sprint_hex(card->counter_tearing[1] + 3, 1), sprint_ascii(card->counter_tearing[1] + 3, 1)); - PrintAndLogEx(NORMAL, "Counter2 | %-24s| %s", sprint_hex(card->counter_tearing[2], 3), sprint_ascii(card->counter_tearing[2], 3)); - PrintAndLogEx(NORMAL, "Tearing3 | %-24s| %s", sprint_hex(card->counter_tearing[2] + 3, 1), sprint_ascii(card->counter_tearing[2] + 3, 1)); + for (uint8_t i = 0; i < 3; i ++) { + PrintAndLogEx(NORMAL, "Counter%d | %-24s| %s", i, sprint_hex(card->counter_tearing[i], 3), sprint_ascii(card->counter_tearing[i], 3)); + PrintAndLogEx(NORMAL, "Tearing%d | %-24s| %s", i, sprint_hex(card->counter_tearing[i] + 3, 1), sprint_ascii(card->counter_tearing[i] + 3, 1)); + } PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, "\nBlock# | Data |lck| Ascii"); PrintAndLogEx(NORMAL, "---------+-------------+---+------"); diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 1aa11cfd6..4ce49f2b2 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -218,23 +218,24 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty memcpy(uid, tmp->data, 3); memcpy(uid + 3, tmp->data + 4, 4); + char path[PATH_MAX_LENGTH] = {0}; + JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid)); JsonSaveBufAsHexCompact(root, "$.Card.Version", tmp->version, sizeof(tmp->version)); JsonSaveBufAsHexCompact(root, "$.Card.TBO_0", tmp->tbo, sizeof(tmp->tbo)); JsonSaveBufAsHexCompact(root, "$.Card.TBO_1", tmp->tbo1, sizeof(tmp->tbo1)); JsonSaveBufAsHexCompact(root, "$.Card.Signature", tmp->signature, sizeof(tmp->signature)); - JsonSaveBufAsHexCompact(root, "$.Card.Counter0", tmp->counter_tearing[0], 3); - JsonSaveBufAsHexCompact(root, "$.Card.Tearing0", tmp->counter_tearing[0] + 3, 1); - JsonSaveBufAsHexCompact(root, "$.Card.Counter1", tmp->counter_tearing[1], 3); - JsonSaveBufAsHexCompact(root, "$.Card.Tearing1", tmp->counter_tearing[1] + 3, 1); - JsonSaveBufAsHexCompact(root, "$.Card.Counter2", tmp->counter_tearing[2], 3); - JsonSaveBufAsHexCompact(root, "$.Card.Tearing2", tmp->counter_tearing[2] + 3, 1); + for (uint8_t i = 0; i < 3; i ++) { + sprintf(path, "$.Card.Counter%d", i); + JsonSaveBufAsHexCompact(root, path, tmp->counter_tearing[i], 3); + sprintf(path, "$.Card.Tearing%d", i); + JsonSaveBufAsHexCompact(root, path, tmp->counter_tearing[i] + 3, 1); + } // size of header 56b size_t len = (datalen - DUMP_PREFIX_LENGTH) / 4; for (size_t i = 0; i < len; i++) { - char path[PATH_MAX_LENGTH] = {0}; sprintf(path, "$.blocks.%zu", i); JsonSaveBufAsHexCompact(root, path, tmp->data + (i * 4), 4); } From a8c1fa7a3bd4ba8c537aea196e51268bc527af47 Mon Sep 17 00:00:00 2001 From: Eloff Date: Tue, 23 Apr 2019 17:07:20 +0300 Subject: [PATCH 3/4] backward compatibility, on load converter for old mfu dump format --- armsrc/iso14443a.c | 11 ++++++++--- client/cmdhfmf.c | 10 ++++++++++ client/cmdhfmfu.c | 18 +++++++++++++----- client/cmdhfmfu.h | 20 +++++++++++++++++++- client/loclass/fileutils.c | 37 ++++++++++++++++++++++++++++++++++++- client/loclass/fileutils.h | 10 ++++++++++ 6 files changed, 96 insertions(+), 10 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 154d621d6..63acc2cb9 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1318,6 +1318,9 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { p_response = NULL; } } + } else if (receivedCmd[0] == MIFARE_ULEV1_VCSL) { + EmSend4bit(CARD_NACK_NA); + p_response = NULL; } else { // Check for ISO 14443A-4 compliant commands, look at left nibble switch (receivedCmd[0]) { @@ -1371,8 +1374,10 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { default: { // Never seen this command before LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - Dbprintf("Received unknown command (len=%d):", len); - Dbhexdump(len, receivedCmd, false); + if (MF_DBGLEVEL >= 3) { + Dbprintf("Received unknown command (len=%d):", len); + Dbhexdump(len, receivedCmd, false); + } // Do not respond dynamic_response_info.response_n = 0; } @@ -1388,7 +1393,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { dynamic_response_info.response_n += 2; if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) { - DbpString("Error preparing tag response"); + if (MF_DBGLEVEL >= 3) DbpString("Error preparing tag response"); LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); break; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a64c40fe1..810a9b009 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -2590,6 +2590,16 @@ int CmdHF14AMfELoad(const char *Cmd) { return 2; } + // convert old mfu format to new + if (blockWidth == 4) { + res = convertOldMfuDump(&data, &datalen); + if (res) { + PrintAndLogEx(FAILED, "Failed convert on load to new Ultralight/NTAG format"); + free(data); + return res; + } + } + PrintAndLogEx(INFO, "Copying to emulator memory"); blockNum = 0; diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 5ba989584..39ee6a6b0 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1973,7 +1973,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { fptr += sprintf(fptr, "hf-mfu-"); FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); } - uint16_t datalen = pages * 4 + DUMP_PREFIX_LENGTH; + uint16_t datalen = pages * 4 + MFU_DUMP_PREFIX_LENGTH; saveFile(filename, "bin", (uint8_t *)&dump_file_data, datalen); saveFileJSON(filename, "json", jsfMfuMemory, (uint8_t *)&dump_file_data, datalen); @@ -2094,14 +2094,22 @@ static int CmdHF14AMfURestore(const char *Cmd) { // read all data size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); - if (bytes_read < DUMP_PREFIX_LENGTH) { + if (bytes_read < MFU_DUMP_PREFIX_LENGTH) { PrintAndLogEx(WARNING, "Error, dump file is too small"); free(dump); return 1; } + // convert old format to new format, if need + int res = convertOldMfuDump(&dump, &bytes_read); + if (res) { + PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format"); + free(dump); + return res; + } + mfu_dump_t *mem = (mfu_dump_t *)dump; - uint8_t pages = (bytes_read - DUMP_PREFIX_LENGTH) / 4; + uint8_t pages = (bytes_read - MFU_DUMP_PREFIX_LENGTH) / 4; if (pages - 1 != mem->pages) { PrintAndLogEx(WARNING, "Error, invalid dump, wrong page count"); @@ -2142,7 +2150,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { if (read_key) { // try reading key from dump and use. - memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 8), 4); + memcpy(c.d.asBytes, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 8), 4); } else { memcpy(c.d.asBytes, p_authkey, 4); } @@ -2160,7 +2168,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { // pack now stored in dump c.arg[0] = MFU_NTAG_SPECIAL_PACK; - memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 4), 2); + memcpy(c.d.asBytes, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 4), 2); c.d.asBytes[2] = 0; c.d.asBytes[3] = 0; PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(c.d.asBytes, 4)); diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index ea631b171..4294939b6 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -12,8 +12,10 @@ #include "comms.h" #include "loclass/fileutils.h" + +// New Ultralight/NTAG dump file format // Length must be aligned to 4 bytes (UL/NTAG page) -#define DUMP_PREFIX_LENGTH 56 +#define MFU_DUMP_PREFIX_LENGTH 56 typedef struct { uint8_t version[8]; @@ -25,6 +27,22 @@ typedef struct { uint8_t data[1024]; } mfu_dump_t; +// Old Ultralight/NTAG dump file format +// It is used only for converting +#define OLD_MFU_DUMP_PREFIX_LENGTH 48 + +typedef struct { + uint8_t version[8]; + uint8_t tbo[2]; + uint8_t tearing[3]; + uint8_t pack[2]; + uint8_t tbo1[1]; + uint8_t signature[32]; + //uint8_t counter[3]; + uint8_t data[1024]; +} old_mfu_dump_t; + + uint32_t GetHF14AMfU_Type(void); int ul_print_type(uint32_t tagtype, uint8_t spaces); diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 4ce49f2b2..ef3ec2417 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -233,7 +233,7 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty } // size of header 56b - size_t len = (datalen - DUMP_PREFIX_LENGTH) / 4; + size_t len = (datalen - MFU_DUMP_PREFIX_LENGTH) / 4; for (size_t i = 0; i < len; i++) { sprintf(path, "$.blocks.%zu", i); @@ -568,6 +568,41 @@ out: return retval; } +int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { + if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH) + return 1; + // try to check new file format + mfu_dump_t *mfu_dump = (mfu_dump_t *) *dump; + if ((*dumplen - MFU_DUMP_PREFIX_LENGTH) / 4 - 1 == mfu_dump->pages) + return 0; + // convert old format + old_mfu_dump_t *old_mfu_dump = (old_mfu_dump_t *) *dump; + + size_t old_data_len = *dumplen - OLD_MFU_DUMP_PREFIX_LENGTH; + size_t new_dump_len = old_data_len + MFU_DUMP_PREFIX_LENGTH; + + mfu_dump = (mfu_dump_t *) calloc(new_dump_len, sizeof(uint8_t)); + + memcpy(mfu_dump->version, old_mfu_dump->version, 8); + mfu_dump->tbo[0] = old_mfu_dump->tbo[0]; + mfu_dump->tbo[1] = old_mfu_dump->tbo[1]; + mfu_dump->tbo1[0] = old_mfu_dump->tbo1[0]; + memcpy(mfu_dump->signature, old_mfu_dump->signature, 32); + mfu_dump->counter_tearing[0][3] = old_mfu_dump->tearing[0]; + mfu_dump->counter_tearing[1][3] = old_mfu_dump->tearing[1]; + mfu_dump->counter_tearing[2][3] = old_mfu_dump->tearing[2]; + + memcpy(mfu_dump->data, old_mfu_dump->data, old_data_len); + mfu_dump->pages = old_data_len / 4 - 1; + // free old buffer, return new buffer + *dumplen = new_dump_len; + free(*dump); + *dump = (uint8_t *) mfu_dump; + PrintAndLogDevice(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1); + return 0; +} + + #else //if we're on ARM #endif diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h index ddc906725..57dfbebc8 100644 --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@ -158,6 +158,15 @@ int loadFileJSON(const char *preferredName, const char *suffix, void *data, size */ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); +/** + * @brief Utility function to check and convert old mfu dump format to new + * + * @param dump pointer to loaded dump to check and convert format + * @param dumplen the number of bytes loaded dump and converted + * @return 0 for ok, 1 for fails +*/ +int convertOldMfuDump(uint8_t **dump, size_t *dumplen); + #define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args) #else @@ -171,6 +180,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data #define PrintAndLogDevice(level, format, args...) { } + #endif //ON_DEVICE #endif // FILEUTILS_H From 66ee8dc09edd9ad553d1c4370d06192bb0ea20fb Mon Sep 17 00:00:00 2001 From: Eloff Date: Tue, 23 Apr 2019 21:14:20 +0300 Subject: [PATCH 4/4] used predefined constants, common types moved to common header files --- armsrc/iso14443a.c | 40 +++++++++++++++++++------------------- armsrc/iso14443a.h | 12 ------------ client/cmdhfmfu.h | 14 ------------- client/loclass/fileutils.c | 8 +++----- include/mifare.h | 17 ++++++++++++++++ 5 files changed, 40 insertions(+), 51 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 63acc2cb9..a87415919 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -624,7 +624,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { } } // end main loop - if (MF_DBGLEVEL >= 1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) { Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len); Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]); } @@ -847,7 +847,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { uint8_t moebius_count = 0; // some first pages of UL/NTAG dump is special data - mfu_dump_prefix_t *mfu_header = tagType == 2 || tagType == 7 ? (mfu_dump_prefix_t *) BigBuf_get_EM_addr() : NULL; + mfu_dump_t *mfu_header = tagType == 2 || tagType == 7 ? (mfu_dump_t *) BigBuf_get_EM_addr() : NULL; switch (tagType) { case 1: { // MIFARE Classic 1k @@ -1314,7 +1314,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { } else { EmSend4bit(CARD_NACK_NA); uint32_t pwd = bytes_to_num(receivedCmd + 1, 4); - if (MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd); + if (MF_DBGLEVEL >= MF_DBG_DEBUG) Dbprintf("Auth attempt: %08x", pwd); p_response = NULL; } } @@ -1374,7 +1374,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { default: { // Never seen this command before LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - if (MF_DBGLEVEL >= 3) { + if (MF_DBGLEVEL >= MF_DBG_DEBUG) { Dbprintf("Received unknown command (len=%d):", len); Dbhexdump(len, receivedCmd, false); } @@ -1393,7 +1393,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { dynamic_response_info.response_n += 2; if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) { - if (MF_DBGLEVEL >= 3) DbpString("Error preparing tag response"); + if (MF_DBGLEVEL >= MF_DBG_DEBUG) DbpString("Error preparing tag response"); LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); break; } @@ -1420,7 +1420,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { set_tracing(false); BigBuf_free_keep_EM(); - if (MF_DBGLEVEL >= 4) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { Dbprintf("-[ Wake ups after halt [%d]", happened); Dbprintf("-[ Messages after halt [%d]", happened2); Dbprintf("-[ Num of received cmd [%d]", cmdsRecvd); @@ -1470,7 +1470,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing else PrepareDelayedTransfer(*timing & 0x00000007); // Delay transfer (fine tuning - up to 7 MF clock ticks) - if (MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) + if (MF_DBGLEVEL >= MF_DBG_EXTENDED && GetCountSspClk() >= (*timing & 0xfffffff8)) Dbprintf("TransmitFor14443a: Missed timing"); while (GetCountSspClk() < (*timing & 0xfffffff8)) {}; // Delay transfer (multiple of 8 MF clock ticks) LastTimeProxToAirStart = *timing; @@ -1952,12 +1952,12 @@ void iso14443a_antifuzz(uint32_t flags) { } EmSendCmdEx(resp, 5, true); - if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT %x", received[1]); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("ANTICOLL or SELECT %x", received[1]); LED_D_INV(); continue; } else if (received[1] == 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) - if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT_2"); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("ANTICOLL or SELECT_2"); } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) } else { @@ -2575,7 +2575,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (ALL)"); + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Mifare: Can't select card (ALL)"); continue; } switch (card_info.uidlen) { @@ -2594,7 +2594,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { have_uid = true; } else { // no need for anticollision. We can directly select the card if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (UID)"); + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Mifare: Can't select card (UID)"); continue; } } @@ -2666,7 +2666,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { sync_time = GetCountSspClk() & 0xfffffff8; } - if (MF_DBGLEVEL >= 4) + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles); LED_B_OFF(); @@ -2693,13 +2693,13 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { } if (consecutive_resyncs < 3) { - if (MF_DBGLEVEL >= 4) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs); } } else { sync_cycles += catch_up_cycles; - if (MF_DBGLEVEL >= 4) + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles); last_catch_up = 0; @@ -2749,7 +2749,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) { mf_nr_ar[3] &= 0x1F; - if (MF_DBGLEVEL >= 4) Dbprintf("Number of sent auth requestes: %u", i); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Number of sent auth requestes: %u", i); uint8_t buf[32] = {0x00}; memset(buf, 0x00, sizeof(buf)); @@ -2824,7 +2824,7 @@ void DetectNACKbug() { if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (ALL)"); + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Mifare: Can't select card (ALL)"); continue; } switch (card_info.uidlen) { @@ -2843,7 +2843,7 @@ void DetectNACKbug() { have_uid = true; } else { // no need for anticollision. We can directly select the card if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (UID)"); + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Mifare: Can't select card (UID)"); continue; } } @@ -2921,7 +2921,7 @@ void DetectNACKbug() { break; } - if (MF_DBGLEVEL >= 4) + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles); continue; @@ -2948,13 +2948,13 @@ void DetectNACKbug() { } if (consecutive_resyncs < 3) { - if (MF_DBGLEVEL >= 4) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs); } } else { sync_cycles += catch_up_cycles; - if (MF_DBGLEVEL >= 4) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles); Dbprintf("nt [%08x] attacted [%08x]", nt, nt_attacked); } diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 27b6b8afe..f2a1c6120 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -95,18 +95,6 @@ typedef struct { uint8_t *parity; } tUart; -// Length must be aligned to 4 bytes (UL/NTAG page) -#define MFU_DUMP_PREFIX_LENGTH 56 - -typedef struct { - uint8_t version[8]; - uint8_t tbo[2]; - uint8_t tbo1[1]; - uint8_t pages; // max page number in dump - uint8_t signature[32]; - uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag -} mfu_dump_prefix_t; - #ifndef AddCrc14A # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) #endif diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index 4294939b6..6587cd538 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -13,20 +13,6 @@ #include "loclass/fileutils.h" -// New Ultralight/NTAG dump file format -// Length must be aligned to 4 bytes (UL/NTAG page) -#define MFU_DUMP_PREFIX_LENGTH 56 - -typedef struct { - uint8_t version[8]; - uint8_t tbo[2]; - uint8_t tbo1[1]; - uint8_t pages; // max page number in dump - uint8_t signature[32]; - uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag - uint8_t data[1024]; -} mfu_dump_t; - // Old Ultralight/NTAG dump file format // It is used only for converting #define OLD_MFU_DUMP_PREFIX_LENGTH 48 diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index ef3ec2417..da86f68da 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -584,13 +584,11 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { mfu_dump = (mfu_dump_t *) calloc(new_dump_len, sizeof(uint8_t)); memcpy(mfu_dump->version, old_mfu_dump->version, 8); - mfu_dump->tbo[0] = old_mfu_dump->tbo[0]; - mfu_dump->tbo[1] = old_mfu_dump->tbo[1]; + memcpy(mfu_dump->tbo, old_mfu_dump->tbo, 2); mfu_dump->tbo1[0] = old_mfu_dump->tbo1[0]; memcpy(mfu_dump->signature, old_mfu_dump->signature, 32); - mfu_dump->counter_tearing[0][3] = old_mfu_dump->tearing[0]; - mfu_dump->counter_tearing[1][3] = old_mfu_dump->tearing[1]; - mfu_dump->counter_tearing[2][3] = old_mfu_dump->tearing[2]; + for (int i = 0; i < 3; i++) + mfu_dump->counter_tearing[i][3] = old_mfu_dump->tearing[i]; memcpy(mfu_dump->data, old_mfu_dump->data, old_data_len); mfu_dump->pages = old_data_len / 4 - 1; diff --git a/include/mifare.h b/include/mifare.h index 410250593..87ba3a74e 100644 --- a/include/mifare.h +++ b/include/mifare.h @@ -19,6 +19,23 @@ #define MF_MAD1_SECTOR 0x00 #define MF_MAD2_SECTOR 0x10 +//----------------------------------------------------------------------------- +// Common types, used by client and ARM +//----------------------------------------------------------------------------- +// New Ultralight/NTAG dump file format +// Length must be aligned to 4 bytes (UL/NTAG page) +#define MFU_DUMP_PREFIX_LENGTH 56 + +typedef struct { + uint8_t version[8]; + uint8_t tbo[2]; + uint8_t tbo1[1]; + uint8_t pages; // max page number in dump + uint8_t signature[32]; + uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag + uint8_t data[1024]; +} mfu_dump_t; + //----------------------------------------------------------------------------- // ISO 14443A //-----------------------------------------------------------------------------