mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
rework Mifare simulation flags
This commit is contained in:
parent
e1fa9374d0
commit
838e0adfa7
17 changed files with 185 additions and 215 deletions
|
@ -248,7 +248,8 @@ void RunMod(void) {
|
|||
state = STATE_SEARCH;
|
||||
}
|
||||
} else if (state == STATE_EMUL) {
|
||||
uint16_t flags = FLAG_7B_UID_IN_DATA;
|
||||
uint16_t flags = 0;
|
||||
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||
|
||||
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||
SimulateIso14443aTag(7, flags, card.uid, 0, NULL);
|
||||
|
|
|
@ -297,7 +297,7 @@ static void prepare_emulation(uint8_t *tagType, uint16_t *flags, uint8_t *data,
|
|||
}
|
||||
|
||||
memcpy(data, uidRx.dat, uidRx.len);
|
||||
*flags = (uidRx.len == 10 ? FLAG_10B_UID_IN_DATA : (uidRx.len == 7 ? FLAG_7B_UID_IN_DATA : FLAG_4B_UID_IN_DATA));
|
||||
FLAG_SET_UID_IN_DATA(*flags, uidRx.len);
|
||||
DbpString(_CYAN_("[@]") " UID:");
|
||||
Dbhexdump(uidRx.len, data, false);
|
||||
Dbprintf(_CYAN_("[@]") " Flags: %hu", *flags);
|
||||
|
|
|
@ -717,33 +717,10 @@ readysim:
|
|||
SpinOff(100);
|
||||
LED_C_ON();
|
||||
|
||||
/*
|
||||
uint16_t flags = 0;
|
||||
switch (colin_p_card.uidlen) {
|
||||
case 10:
|
||||
flags = FLAG_10B_UID_IN_DATA;
|
||||
break;
|
||||
case 7:
|
||||
flags = FLAG_7B_UID_IN_DATA;
|
||||
break;
|
||||
case 4:
|
||||
flags = FLAG_4B_UID_IN_DATA;
|
||||
break;
|
||||
default:
|
||||
flags = FLAG_UID_IN_EMUL;
|
||||
break;
|
||||
}
|
||||
// Use UID, SAK, ATQA from EMUL, if uid not defined
|
||||
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
}
|
||||
flags |= FLAG_MF_1K;
|
||||
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
}
|
||||
flags = 0x10;
|
||||
*/
|
||||
uint16_t flags = FLAG_UID_IN_EMUL;
|
||||
// FLAG_SET_UID_IN_DATA(flags, colin_p_card.uidlen);
|
||||
FLAG_SET_UID_IN_EMUL(flags);
|
||||
FLAG_SET_MF_SIZE(flags, MIFARE_1K_MAX_BYTES);
|
||||
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
|
||||
cjSetCursLeft();
|
||||
SpinOff(1000);
|
||||
|
|
|
@ -79,13 +79,8 @@ void RunMod(void) {
|
|||
}
|
||||
} else if (state == STATE_EMUL) {
|
||||
uint16_t flags = 0;
|
||||
if (card.uidlen == 4) {
|
||||
flags |= FLAG_4B_UID_IN_DATA;
|
||||
} else if (card.uidlen == 7) {
|
||||
flags |= FLAG_7B_UID_IN_DATA;
|
||||
} else if (card.uidlen == 10) {
|
||||
flags |= FLAG_10B_UID_IN_DATA;
|
||||
} else {
|
||||
FLAG_SET_UID_IN_DATA(flags, card.uidlen);
|
||||
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
Dbprintf("Unusual UID length, something is wrong. Try again please.");
|
||||
state = STATE_READ;
|
||||
continue;
|
||||
|
|
|
@ -556,19 +556,7 @@ void RunMod(void) {
|
|||
}
|
||||
|
||||
uint16_t simflags = 0;
|
||||
switch (mattyrun_card.uidlen) {
|
||||
case 4:
|
||||
simflags |= FLAG_4B_UID_IN_DATA;
|
||||
break;
|
||||
case 7:
|
||||
simflags |= FLAG_7B_UID_IN_DATA;
|
||||
break;
|
||||
case 10:
|
||||
simflags |= FLAG_10B_UID_IN_DATA;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
FLAG_SET_UID_IN_DATA(simflags, mattyrun_card.uidlen);
|
||||
uint16_t atqa = (uint16_t)bytes_to_num(mattyrun_card.atqa, 2);
|
||||
|
||||
SpinDelay(1000);
|
||||
|
|
|
@ -143,7 +143,9 @@ void RunMod(void) {
|
|||
|
||||
//Start to simulate
|
||||
Dbprintf(_YELLOW_("[Slot: %d] Simulation start, Press button to change next card."), i);
|
||||
uint16_t simflags = FLAG_UID_IN_EMUL | FLAG_MF_1K;
|
||||
uint16_t simflags = 0;
|
||||
FLAG_SET_MF_SIZE(simflags, MIFARE_1K_MAX_BYTES);
|
||||
FLAG_SET_UID_IN_EMUL(simflags);
|
||||
Mifare1ksim(simflags, 0, NULL, 0, 0);
|
||||
Dbprintf(_YELLOW_("[Slot: %d] Simulation end, Write Back to dump file!"), i);
|
||||
|
||||
|
|
|
@ -209,7 +209,8 @@ void RunMod(void) {
|
|||
bool chktoken = false;
|
||||
|
||||
// UID 4 bytes(could be 7 bytes if needed it)
|
||||
uint8_t flags = FLAG_4B_UID_IN_DATA;
|
||||
uint8_t flags = 0;
|
||||
FLAG_SET_UID_IN_DATA(flags, 4);
|
||||
// in case there is a read command received we shouldn't break
|
||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
||||
|
||||
|
|
|
@ -81,7 +81,8 @@ void RunMod() {
|
|||
|
||||
|
||||
// UID 4 bytes(could be 7 bytes if needed it)
|
||||
uint8_t flags = FLAG_4B_UID_IN_DATA;
|
||||
uint8_t flags = 0;
|
||||
FLAG_SET_UID_IN_DATA(flags, 4);
|
||||
// in case there is a read command received we shouldn't break
|
||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
||||
|
||||
|
|
|
@ -110,7 +110,8 @@ void RunMod(void) {
|
|||
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64
|
||||
#define DYNAMIC_MODULATION_BUFFER_SIZE 512
|
||||
|
||||
uint8_t flags = FLAG_7B_UID_IN_DATA; // ST25TA have 7B UID
|
||||
uint8_t flags = 0;
|
||||
FLAG_SET_UID_IN_DATA(flags, 7); // ST25TA have 7B UID
|
||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; // in case there is a read command received we shouldn't break
|
||||
|
||||
// to initialize the emulation
|
||||
|
|
|
@ -236,7 +236,8 @@ void RunMod(void) {
|
|||
int button_pressed = BUTTON_HELD(1000);
|
||||
if (button_pressed == BUTTON_NO_CLICK) { // No button action, proceed with sim
|
||||
|
||||
uint16_t flags = FLAG_4B_UID_IN_DATA;
|
||||
uint16_t flags = 0
|
||||
FLAG_SET_UID_IN_DATA(flags, 4);
|
||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0}; // in case there is a read command received we shouldn't break
|
||||
|
||||
memcpy(data, uids[selected].uid, uids[selected].uidlen);
|
||||
|
@ -244,7 +245,7 @@ void RunMod(void) {
|
|||
uint64_t tmpuid = bytes_to_num(uids[selected].uid, uids[selected].uidlen);
|
||||
|
||||
if (uids[selected].uidlen == 7) {
|
||||
flags = FLAG_7B_UID_IN_DATA;
|
||||
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||
Dbprintf("Simulating ISO14443a tag with uid: %014" PRIx64 " [Bank: %d]", tmpuid, selected);
|
||||
} else {
|
||||
Dbprintf("Simulating ISO14443a tag with uid: %08" PRIx64 " [Bank: %d]", tmpuid, selected);
|
||||
|
|
|
@ -1263,21 +1263,21 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8
|
|||
}
|
||||
|
||||
// if uid not supplied then get from emulator memory
|
||||
if ((memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10) == 0) || ((flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL)) {
|
||||
if ((memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10) == 0) || IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
if (tagType == 2 || tagType == 7) {
|
||||
uint16_t start = MFU_DUMP_PREFIX_LENGTH;
|
||||
uint8_t emdata[8];
|
||||
emlGet(emdata, start, sizeof(emdata));
|
||||
memcpy(data, emdata, 3); // uid bytes 0-2
|
||||
memcpy(data + 3, emdata + 4, 4); // uid bytes 3-7
|
||||
flags |= FLAG_7B_UID_IN_DATA;
|
||||
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||
} else {
|
||||
emlGet(data, 0, 4);
|
||||
flags |= FLAG_4B_UID_IN_DATA;
|
||||
FLAG_SET_UID_IN_DATA(flags, 4);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) {
|
||||
if (IS_FLAG_UID_IN_DATA(flags, 4)) {
|
||||
rUIDc1[0] = data[0];
|
||||
rUIDc1[1] = data[1];
|
||||
rUIDc1[2] = data[2];
|
||||
|
@ -1296,7 +1296,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8
|
|||
AddCrc14A(rSAKc1, sizeof(rSAKc1) - 2);
|
||||
|
||||
*cuid = bytes_to_num(data, 4);
|
||||
} else if ((flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) {
|
||||
} else if (IS_FLAG_UID_IN_DATA(flags, 7)) {
|
||||
rUIDc1[0] = MIFARE_SELECT_CT; // Cascade Tag marker
|
||||
rUIDc1[1] = data[0];
|
||||
rUIDc1[2] = data[1];
|
||||
|
@ -1319,7 +1319,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, uint8
|
|||
|
||||
*cuid = bytes_to_num(data + 3, 4);
|
||||
|
||||
} else if ((flags & FLAG_10B_UID_IN_DATA) == FLAG_10B_UID_IN_DATA) {
|
||||
} else if (IS_FLAG_UID_IN_DATA(flags, 10)) {
|
||||
|
||||
rUIDc1[0] = MIFARE_SELECT_CT; // Cascade Tag marker
|
||||
rUIDc1[1] = data[0];
|
||||
|
@ -2560,7 +2560,7 @@ void iso14443a_antifuzz(uint32_t flags) {
|
|||
resp[0] = 0x04;
|
||||
resp[1] = 0x00;
|
||||
|
||||
if ((flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) {
|
||||
if (IS_FLAG_UID_IN_DATA(flags, 7)) {
|
||||
resp[0] = 0x44;
|
||||
}
|
||||
|
||||
|
@ -2578,7 +2578,7 @@ void iso14443a_antifuzz(uint32_t flags) {
|
|||
resp[4] = resp[0] ^ resp[1] ^ resp[2] ^ resp[3];
|
||||
colpos = 0;
|
||||
|
||||
if ((flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) {
|
||||
if (IS_FLAG_UID_IN_DATA(flags, 7)) {
|
||||
resp[0] = MIFARE_SELECT_CT;
|
||||
colpos = 8;
|
||||
}
|
||||
|
|
|
@ -184,8 +184,9 @@ static bool IsAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
|
||||
static bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
|
||||
|
||||
uint8_t uid_tmp[10] = {0};
|
||||
// SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf
|
||||
// ATQA
|
||||
static uint8_t rATQA_Mini[] = {0x04, 0x00}; // indicate Mifare classic Mini 4Byte UID
|
||||
|
@ -236,84 +237,79 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
|
|||
// Can be set from emulator memory or incoming data
|
||||
// Length: 4,7,or 10 bytes
|
||||
|
||||
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
if (uid == NULL) {
|
||||
uid = uid_tmp;
|
||||
}
|
||||
// Get UID, SAK, ATQA from EMUL
|
||||
if ((flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL) {
|
||||
uint8_t block0[16];
|
||||
emlGet(block0, 0, 16);
|
||||
|
||||
// If uid size defined, copy only uid from EMUL to use, backward compatibility for 'hf_colin.c', 'hf_mattyrun.c'
|
||||
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) != 0) {
|
||||
memcpy(datain, block0, 10); // load 10bytes from EMUL to the datain pointer. to be used below.
|
||||
} else {
|
||||
// Check for 4 bytes uid: bcc corrected and single size uid bits in ATQA
|
||||
if ((block0[0] ^ block0[1] ^ block0[2] ^ block0[3]) == block0[4] && (block0[6] & 0xc0) == 0) {
|
||||
flags |= FLAG_4B_UID_IN_DATA;
|
||||
memcpy(datain, block0, 4);
|
||||
FLAG_SET_UID_IN_DATA(flags, 4);
|
||||
memcpy(uid, block0, 4);
|
||||
rSAK[0] = block0[5];
|
||||
memcpy(rATQA, &block0[6], sizeof(rATQA));
|
||||
}
|
||||
// Check for 7 bytes UID: double size uid bits in ATQA
|
||||
else if ((block0[8] & 0xc0) == 0x40) {
|
||||
flags |= FLAG_7B_UID_IN_DATA;
|
||||
memcpy(datain, block0, 7);
|
||||
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||
memcpy(uid, block0, 7);
|
||||
rSAK[0] = block0[7];
|
||||
memcpy(rATQA, &block0[8], sizeof(rATQA));
|
||||
} else {
|
||||
Dbprintf("ERROR: " _RED_("Invalid dump. UID/SAK/ATQA not found"));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (uid == NULL) {
|
||||
Dbprintf("ERROR: " _RED_("Missing UID"));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Tune tag type, if defined directly
|
||||
// Otherwise use defined by default or extracted from EMUL
|
||||
if ((flags & FLAG_MF_MINI) == FLAG_MF_MINI) {
|
||||
if (IS_FLAG_MF_SIZE(flags, MIFARE_MINI_MAX_BYTES)) {
|
||||
memcpy(rATQA, rATQA_Mini, sizeof(rATQA));
|
||||
rSAK[0] = rSAK_Mini;
|
||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare Mini ATQA/SAK");
|
||||
} else if ((flags & FLAG_MF_1K) == FLAG_MF_1K) {
|
||||
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_1K_MAX_BYTES)) {
|
||||
memcpy(rATQA, rATQA_1k, sizeof(rATQA));
|
||||
rSAK[0] = rSAK_1k;
|
||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 1K ATQA/SAK");
|
||||
} else if ((flags & FLAG_MF_2K) == FLAG_MF_2K) {
|
||||
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_2K_MAX_BYTES)) {
|
||||
memcpy(rATQA, rATQA_2k, sizeof(rATQA));
|
||||
rSAK[0] = rSAK_2k;
|
||||
*rats = rRATS;
|
||||
*rats_len = sizeof(rRATS);
|
||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 2K ATQA/SAK with RATS support");
|
||||
} else if ((flags & FLAG_MF_4K) == FLAG_MF_4K) {
|
||||
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_4K_MAX_BYTES)) {
|
||||
memcpy(rATQA, rATQA_4k, sizeof(rATQA));
|
||||
rSAK[0] = rSAK_4k;
|
||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 4K ATQA/SAK");
|
||||
}
|
||||
|
||||
// Prepare UID arrays
|
||||
if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain
|
||||
memcpy(rUIDBCC1, datain, 4);
|
||||
if (IS_FLAG_UID_IN_DATA(flags, 4)) {
|
||||
memcpy(rUIDBCC1, uid, 4);
|
||||
*uid_len = 4;
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
|
||||
|
||||
// save CUID
|
||||
*cuid = bytes_to_num(rUIDBCC1, 4);
|
||||
// BCC
|
||||
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - Flags: %04X - BCC1: %02X", flags, rUIDBCC1[4]);
|
||||
if (g_dbglevel > DBG_NONE) {
|
||||
Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
|
||||
}
|
||||
|
||||
// Correct uid size bits in ATQA
|
||||
rATQA[0] = (rATQA[0] & 0x3f); // single size uid
|
||||
|
||||
} else if ((flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) {
|
||||
memcpy(&rUIDBCC1[1], datain, 3);
|
||||
memcpy(rUIDBCC2, datain + 3, 4);
|
||||
} else if (IS_FLAG_UID_IN_DATA(flags, 7)) {
|
||||
memcpy(&rUIDBCC1[1], uid, 3);
|
||||
memcpy(rUIDBCC2, uid + 3, 4);
|
||||
*uid_len = 7;
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
|
||||
// save CUID
|
||||
*cuid = bytes_to_num(rUIDBCC2, 4);
|
||||
// CascadeTag, CT
|
||||
|
@ -321,6 +317,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
|
|||
// BCC
|
||||
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
||||
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - Flags: %04X - BCC1: %02X - BCC2: %02X", flags, rUIDBCC1[4], rUIDBCC2[4]);
|
||||
if (g_dbglevel > DBG_NONE) {
|
||||
Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x",
|
||||
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]);
|
||||
|
@ -328,15 +326,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
|
|||
|
||||
// Correct uid size bits in ATQA
|
||||
rATQA[0] = (rATQA[0] & 0x3f) | 0x40; // double size uid
|
||||
|
||||
} else if ((flags & FLAG_10B_UID_IN_DATA) == FLAG_10B_UID_IN_DATA) {
|
||||
memcpy(&rUIDBCC1[1], datain, 3);
|
||||
memcpy(&rUIDBCC2[1], datain + 3, 3);
|
||||
memcpy(rUIDBCC3, datain + 6, 4);
|
||||
} else if (IS_FLAG_UID_IN_DATA(flags, 10)) {
|
||||
memcpy(&rUIDBCC1[1], uid, 3);
|
||||
memcpy(&rUIDBCC2[1], uid + 3, 3);
|
||||
memcpy(rUIDBCC3, uid + 6, 4);
|
||||
*uid_len = 10;
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
|
||||
// save CUID
|
||||
*cuid = bytes_to_num(rUIDBCC3, 4);
|
||||
// CascadeTag, CT
|
||||
|
@ -346,7 +340,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
|
|||
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
||||
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
|
||||
rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3];
|
||||
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - Flags: %04X - BCC1: %02X - BCC2: %02X - BCC3: %02X", flags, rUIDBCC1[4], rUIDBCC2[4], rUIDBCC3[4]);
|
||||
if (g_dbglevel > DBG_NONE) {
|
||||
Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
|
||||
|
@ -361,11 +356,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
|
|||
Dbprintf("ERROR: " _RED_("UID size not defined"));
|
||||
return false;
|
||||
}
|
||||
if (flags & FLAG_FORCED_ATQA) {
|
||||
if (flags & FLAG_ATQA_IN_DATA) {
|
||||
rATQA[0] = atqa >> 8;
|
||||
rATQA[1] = atqa & 0xff;
|
||||
}
|
||||
if (flags & FLAG_FORCED_SAK) {
|
||||
if (flags & FLAG_SAK_IN_DATA) {
|
||||
rSAK[0] = sak;
|
||||
}
|
||||
if (g_dbglevel > DBG_NONE) {
|
||||
|
@ -454,17 +449,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
|
|||
/**
|
||||
*MIFARE 1K simulate.
|
||||
*
|
||||
*@param flags :
|
||||
* FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK
|
||||
* FLAG_4B_UID_IN_DATA - means that there is a 4-byte UID in the data-section, we're expected to use that
|
||||
* FLAG_7B_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that
|
||||
* FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section not finished
|
||||
* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later
|
||||
* FLAG_NESTED_AUTH_ATTACK - means that we support nested authentication attack
|
||||
*@param flags: See pm3_cmd.h for the full definitions
|
||||
*@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ...
|
||||
* (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attempted)
|
||||
*/
|
||||
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak) {
|
||||
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t atqa, uint8_t sak) {
|
||||
tag_response_info_t *responses;
|
||||
uint8_t cardSTATE = MFEMUL_NOFIELD;
|
||||
uint8_t uid_len = 0; // 4, 7, 10
|
||||
|
@ -498,12 +487,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
|||
uint8_t rats_len = 0;
|
||||
|
||||
|
||||
// if fct is called with NULL we need to assign some memory since this pointer is passed around
|
||||
uint8_t datain_tmp[10] = {0};
|
||||
if (datain == NULL) {
|
||||
datain = datain_tmp;
|
||||
}
|
||||
|
||||
//Here, we collect UID,sector,keytype,NT,AR,NR,NT2,AR2,NR2
|
||||
// This will be used in the reader-only attack.
|
||||
|
||||
|
@ -522,7 +505,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
|||
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||
BigBuf_free_keep_EM();
|
||||
|
||||
if (MifareSimInit(flags, datain, atqa, sak, &responses, &cuid, &uid_len, &rats, &rats_len) == false) {
|
||||
if (MifareSimInit(flags, uid, atqa, sak, &responses, &cuid, &uid_len, &rats, &rats_len) == false) {
|
||||
BigBuf_free_keep_EM();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,6 @@
|
|||
#define AUTHKEYB 1
|
||||
#define AUTHKEYNONE 0xff
|
||||
|
||||
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak);
|
||||
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t atqa, uint8_t sak);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -830,17 +830,8 @@ int CmdHF14ASim(const char *Cmd) {
|
|||
bool useUIDfromEML = true;
|
||||
|
||||
if (uid_len > 0) {
|
||||
switch (uid_len) {
|
||||
case 10:
|
||||
flags |= FLAG_10B_UID_IN_DATA;
|
||||
break;
|
||||
case 7:
|
||||
flags |= FLAG_7B_UID_IN_DATA;
|
||||
break;
|
||||
case 4:
|
||||
flags |= FLAG_4B_UID_IN_DATA;
|
||||
break;
|
||||
default:
|
||||
FLAG_SET_UID_IN_DATA(flags, uid_len);
|
||||
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
|
@ -866,7 +857,7 @@ int CmdHF14ASim(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (useUIDfromEML) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
FLAG_SET_UID_IN_EMUL(flags);
|
||||
}
|
||||
|
||||
struct {
|
||||
|
@ -1660,12 +1651,14 @@ static int CmdHF14AAntiFuzz(const char *Cmd) {
|
|||
struct {
|
||||
uint8_t flag;
|
||||
} PACKED param;
|
||||
param.flag = FLAG_4B_UID_IN_DATA;
|
||||
|
||||
if (arg_get_lit(ctx, 2))
|
||||
param.flag = FLAG_7B_UID_IN_DATA;
|
||||
if (arg_get_lit(ctx, 3))
|
||||
param.flag = FLAG_10B_UID_IN_DATA;
|
||||
param.flag = 0;
|
||||
FLAG_SET_UID_IN_DATA(param.flag, 4);
|
||||
if (arg_get_lit(ctx, 2)) {
|
||||
FLAG_SET_UID_IN_DATA(param.flag, 7);
|
||||
}
|
||||
if (arg_get_lit(ctx, 3)) {
|
||||
FLAG_SET_UID_IN_DATA(param.flag, 10);
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
clearCommandBuffer();
|
||||
|
@ -3725,17 +3718,8 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
|||
bool useUIDfromEML = true;
|
||||
|
||||
if (uid_len > 0) {
|
||||
switch (uid_len) {
|
||||
case 10:
|
||||
flags |= FLAG_10B_UID_IN_DATA;
|
||||
break;
|
||||
case 7:
|
||||
flags |= FLAG_7B_UID_IN_DATA;
|
||||
break;
|
||||
case 4:
|
||||
flags |= FLAG_4B_UID_IN_DATA;
|
||||
break;
|
||||
default:
|
||||
FLAG_SET_UID_IN_DATA(flags, uid_len);
|
||||
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
|
@ -3757,7 +3741,7 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (useUIDfromEML) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
FLAG_SET_UID_IN_EMUL(flags);
|
||||
}
|
||||
|
||||
struct {
|
||||
|
|
|
@ -565,7 +565,8 @@ static int CmdHF14AJookiSim(const char *Cmd) {
|
|||
|
||||
// NTAG, 7 byte UID in eloaded data.
|
||||
payload.tagtype = 7;
|
||||
payload.flags = FLAG_UID_IN_EMUL;
|
||||
payload.flags = 0;
|
||||
FLAG_SET_UID_IN_EMUL(payload.flags);
|
||||
payload.exitAfter = 0;
|
||||
memcpy(payload.uid, uid, sizeof(uid));
|
||||
|
||||
|
|
|
@ -4129,25 +4129,15 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
|||
uint8_t uid[10] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||
|
||||
char uidsize[8] = {0};
|
||||
char uidsize[9] = {0};
|
||||
if (uidlen > 0) {
|
||||
switch (uidlen) {
|
||||
case 10:
|
||||
flags |= FLAG_10B_UID_IN_DATA;
|
||||
snprintf(uidsize, sizeof(uidsize), "10 byte");
|
||||
break;
|
||||
case 7:
|
||||
flags |= FLAG_7B_UID_IN_DATA;
|
||||
snprintf(uidsize, sizeof(uidsize), "7 byte");
|
||||
break;
|
||||
case 4:
|
||||
flags |= FLAG_4B_UID_IN_DATA;
|
||||
snprintf(uidsize, sizeof(uidsize), "4 byte");
|
||||
break;
|
||||
default:
|
||||
FLAG_SET_UID_IN_DATA(flags, uidlen);
|
||||
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
PrintAndLogEx(WARNING, "Invalid parameter for UID");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
} else {
|
||||
snprintf(uidsize, sizeof(uidsize), "%i bytes", uidlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4193,7 +4183,7 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
|||
PrintAndLogEx(WARNING, "Wrong ATQA length");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
flags |= FLAG_FORCED_ATQA;
|
||||
flags |= FLAG_ATQA_IN_DATA;
|
||||
}
|
||||
|
||||
if (saklen > 0) {
|
||||
|
@ -4201,12 +4191,7 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
|||
PrintAndLogEx(WARNING, "Wrong SAK length");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
flags |= FLAG_FORCED_SAK;
|
||||
}
|
||||
|
||||
// Use UID, SAK, ATQA from EMUL, if uid not defined
|
||||
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
flags |= FLAG_SAK_IN_DATA;
|
||||
}
|
||||
|
||||
size_t k_sectors_cnt = MIFARE_4K_MAXSECTOR;
|
||||
|
@ -4218,19 +4203,19 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (m0) {
|
||||
flags |= FLAG_MF_MINI;
|
||||
FLAG_SET_MF_SIZE(flags, MIFARE_MINI_MAX_BYTES);
|
||||
snprintf(csize, sizeof(csize), "MINI");
|
||||
k_sectors_cnt = MIFARE_MINI_MAXSECTOR;
|
||||
} else if (m1) {
|
||||
flags |= FLAG_MF_1K;
|
||||
FLAG_SET_MF_SIZE(flags, MIFARE_1K_MAX_BYTES);
|
||||
snprintf(csize, sizeof(csize), "1K");
|
||||
k_sectors_cnt = MIFARE_1K_MAXSECTOR;
|
||||
} else if (m2) {
|
||||
flags |= FLAG_MF_2K;
|
||||
FLAG_SET_MF_SIZE(flags, MIFARE_2K_MAX_BYTES);
|
||||
snprintf(csize, sizeof(csize), "2K with RATS");
|
||||
k_sectors_cnt = MIFARE_2K_MAXSECTOR;
|
||||
} else if (m4) {
|
||||
flags |= FLAG_MF_4K;
|
||||
FLAG_SET_MF_SIZE(flags, MIFARE_4K_MAX_BYTES);
|
||||
snprintf(csize, sizeof(csize), "4K");
|
||||
k_sectors_cnt = MIFARE_4K_MAXSECTOR;
|
||||
} else {
|
||||
|
@ -4262,9 +4247,8 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
|||
, (uidlen == 0) ? "n/a" : sprint_hex(uid, uidlen)
|
||||
);
|
||||
|
||||
PrintAndLogEx(INFO, "Options [ numreads: %d, flags: %d (0x%02x) ]"
|
||||
PrintAndLogEx(INFO, "Options [ numreads: %d, flags: 0x%04x ]"
|
||||
, exitAfterNReads
|
||||
, flags
|
||||
, flags);
|
||||
|
||||
struct {
|
||||
|
|
|
@ -766,21 +766,72 @@ typedef struct {
|
|||
#define CMD_UNKNOWN 0xFFFF
|
||||
|
||||
//Mifare simulation flags
|
||||
#define FLAG_INTERACTIVE 0x01
|
||||
#define FLAG_4B_UID_IN_DATA 0x02
|
||||
#define FLAG_7B_UID_IN_DATA 0x04
|
||||
#define FLAG_10B_UID_IN_DATA 0x08
|
||||
#define FLAG_UID_IN_EMUL 0x10
|
||||
#define FLAG_NR_AR_ATTACK 0x20
|
||||
#define FLAG_MF_MINI 0x80
|
||||
#define FLAG_MF_1K 0x100
|
||||
#define FLAG_MF_2K 0x200
|
||||
#define FLAG_MF_4K 0x400
|
||||
#define FLAG_FORCED_ATQA 0x800
|
||||
#define FLAG_FORCED_SAK 0x1000
|
||||
#define FLAG_CVE21_0430 0x2000
|
||||
#define FLAG_RATS_IN_DATA 0x4000
|
||||
#define FLAG_NESTED_AUTH_ATTACK 0x8000
|
||||
// In interactive mode, we are expected to finish the operation with an ACK
|
||||
#define FLAG_INTERACTIVE 0x0001
|
||||
#define FLAG_ATQA_IN_DATA 0x0002
|
||||
#define FLAG_SAK_IN_DATA 0x0004
|
||||
#define FLAG_RATS_IN_DATA 0x0008
|
||||
|
||||
// internal constants, use the function macros instead
|
||||
#define FLAG_MASK_UID 0x0030
|
||||
#define FLAG_UID_IN_EMUL 0x0000
|
||||
#define FLAG_4B_UID_IN_DATA 0x0010
|
||||
#define FLAG_7B_UID_IN_DATA 0x0020
|
||||
#define FLAG_10B_UID_IN_DATA 0x0030
|
||||
// if there is a UID in the data-section to be used:
|
||||
// note: if UIDLEN is wrong, we default to FLAG_UID_IN_EMUL
|
||||
#define FLAG_SET_UID_IN_DATA(flags, len) {\
|
||||
flags = (flags & (~FLAG_MASK_UID))|\
|
||||
(len == 4 ? FLAG_4B_UID_IN_DATA : \
|
||||
(len == 7 ? FLAG_7B_UID_IN_DATA : \
|
||||
(len == 10 ? FLAG_10B_UID_IN_DATA : \
|
||||
FLAG_UID_IN_EMUL)));\
|
||||
}
|
||||
// else we tell to take UID from block 0:
|
||||
#define FLAG_SET_UID_IN_EMUL(flags) {flags = (flags & (~FLAG_MASK_UID))|FLAG_UID_IN_EMUL;}
|
||||
#define IS_FLAG_UID_IN_DATA(flags, len) (\
|
||||
(flags & FLAG_MASK_UID) == \
|
||||
(len == 4 ? FLAG_4B_UID_IN_DATA : \
|
||||
(len == 7 ? FLAG_7B_UID_IN_DATA : \
|
||||
(len == 10 ? FLAG_10B_UID_IN_DATA : \
|
||||
FLAG_UID_IN_EMUL)))\
|
||||
)
|
||||
#define IS_FLAG_UID_IN_EMUL(flags) ((flags & FLAG_MASK_UID) == FLAG_UID_IN_EMUL)
|
||||
|
||||
// internal constants, use the function macros instead
|
||||
#define MIFARE_4K_MAX_BYTES 4096
|
||||
#define MIFARE_2K_MAX_BYTES 2048
|
||||
#define MIFARE_1K_MAX_BYTES 1024
|
||||
#define MIFARE_MINI_MAX_BYTES 320
|
||||
#define FLAG_MASK_MF_SIZE 0x00C0
|
||||
#define FLAG_MF_MINI 0x0000
|
||||
#define FLAG_MF_1K 0x0040
|
||||
#define FLAG_MF_2K 0x0080
|
||||
#define FLAG_MF_4K 0x00C0
|
||||
#define FLAG_SET_MF_SIZE(flags, size) {\
|
||||
flags = (flags & (~FLAG_MASK_MF_SIZE))|\
|
||||
(size == MIFARE_MINI_MAX_BYTES ? FLAG_MF_MINI : \
|
||||
(size == MIFARE_1K_MAX_BYTES ? FLAG_MF_1K : \
|
||||
(size == MIFARE_2K_MAX_BYTES ? FLAG_MF_2K : \
|
||||
(size == MIFARE_4K_MAX_BYTES ? FLAG_MF_4K : \
|
||||
0))));\
|
||||
}
|
||||
// else we tell to take UID from block 0:
|
||||
#define IS_FLAG_MF_SIZE(flags, size) (\
|
||||
(flags & FLAG_MASK_MF_SIZE) == \
|
||||
(size == MIFARE_MINI_MAX_BYTES ? FLAG_MF_MINI : \
|
||||
(size == MIFARE_1K_MAX_BYTES ? FLAG_MF_1K : \
|
||||
(size == MIFARE_2K_MAX_BYTES ? FLAG_MF_2K : \
|
||||
(size == MIFARE_4K_MAX_BYTES ? FLAG_MF_4K : \
|
||||
0))))\
|
||||
)
|
||||
|
||||
#define FLAG_MF_USE_READ_KEYB 0x0100
|
||||
#define FLAG_CVE21_0430 0x0200
|
||||
// collect NR_AR responses for bruteforcing later
|
||||
#define FLAG_NR_AR_ATTACK 0x0400
|
||||
// support nested authentication attack
|
||||
#define FLAG_NESTED_AUTH_ATTACK 0x0800
|
||||
|
||||
|
||||
#define MODE_SIM_CSN 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue