backward compatibility, on load converter for old mfu dump format

This commit is contained in:
Eloff 2019-04-23 17:07:20 +03:00
commit a8c1fa7a3b
6 changed files with 96 additions and 10 deletions

View file

@ -1318,6 +1318,9 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
p_response = NULL; p_response = NULL;
} }
} }
} else if (receivedCmd[0] == MIFARE_ULEV1_VCSL) {
EmSend4bit(CARD_NACK_NA);
p_response = NULL;
} else { } else {
// Check for ISO 14443A-4 compliant commands, look at left nibble // Check for ISO 14443A-4 compliant commands, look at left nibble
switch (receivedCmd[0]) { switch (receivedCmd[0]) {
@ -1371,8 +1374,10 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
default: { default: {
// Never seen this command before // 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); 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) {
Dbprintf("Received unknown command (len=%d):", len); Dbprintf("Received unknown command (len=%d):", len);
Dbhexdump(len, receivedCmd, false); Dbhexdump(len, receivedCmd, false);
}
// Do not respond // Do not respond
dynamic_response_info.response_n = 0; 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; dynamic_response_info.response_n += 2;
if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) { 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); LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
break; break;
} }

View file

@ -2590,6 +2590,16 @@ int CmdHF14AMfELoad(const char *Cmd) {
return 2; 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"); PrintAndLogEx(INFO, "Copying to emulator memory");
blockNum = 0; blockNum = 0;

View file

@ -1973,7 +1973,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
fptr += sprintf(fptr, "hf-mfu-"); fptr += sprintf(fptr, "hf-mfu-");
FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); 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); saveFile(filename, "bin", (uint8_t *)&dump_file_data, datalen);
saveFileJSON(filename, "json", jsfMfuMemory, (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 // read all data
size_t bytes_read = fread(dump, 1, fsize, f); size_t bytes_read = fread(dump, 1, fsize, f);
fclose(f); fclose(f);
if (bytes_read < DUMP_PREFIX_LENGTH) { if (bytes_read < MFU_DUMP_PREFIX_LENGTH) {
PrintAndLogEx(WARNING, "Error, dump file is too small"); PrintAndLogEx(WARNING, "Error, dump file is too small");
free(dump); free(dump);
return 1; 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; 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) { if (pages - 1 != mem->pages) {
PrintAndLogEx(WARNING, "Error, invalid dump, wrong page count"); PrintAndLogEx(WARNING, "Error, invalid dump, wrong page count");
@ -2142,7 +2150,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
if (read_key) { if (read_key) {
// try reading key from dump and use. // 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 { } else {
memcpy(c.d.asBytes, p_authkey, 4); memcpy(c.d.asBytes, p_authkey, 4);
} }
@ -2160,7 +2168,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
// pack now stored in dump // pack now stored in dump
c.arg[0] = MFU_NTAG_SPECIAL_PACK; 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[2] = 0;
c.d.asBytes[3] = 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)); PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(c.d.asBytes, 4));

View file

@ -12,8 +12,10 @@
#include "comms.h" #include "comms.h"
#include "loclass/fileutils.h" #include "loclass/fileutils.h"
// New Ultralight/NTAG dump file format
// Length must be aligned to 4 bytes (UL/NTAG page) // Length must be aligned to 4 bytes (UL/NTAG page)
#define DUMP_PREFIX_LENGTH 56 #define MFU_DUMP_PREFIX_LENGTH 56
typedef struct { typedef struct {
uint8_t version[8]; uint8_t version[8];
@ -25,6 +27,22 @@ typedef struct {
uint8_t data[1024]; uint8_t data[1024];
} mfu_dump_t; } 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); uint32_t GetHF14AMfU_Type(void);
int ul_print_type(uint32_t tagtype, uint8_t spaces); int ul_print_type(uint32_t tagtype, uint8_t spaces);

View file

@ -233,7 +233,7 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty
} }
// size of header 56b // 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++) { for (size_t i = 0; i < len; i++) {
sprintf(path, "$.blocks.%zu", i); sprintf(path, "$.blocks.%zu", i);
@ -568,6 +568,41 @@ out:
return retval; 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 #else //if we're on ARM
#endif #endif

View file

@ -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); 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) #define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
#else #else
@ -171,6 +180,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data
#define PrintAndLogDevice(level, format, args...) { } #define PrintAndLogDevice(level, format, args...) { }
#endif //ON_DEVICE #endif //ON_DEVICE
#endif // FILEUTILS_H #endif // FILEUTILS_H