mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -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;
|
state = STATE_SEARCH;
|
||||||
}
|
}
|
||||||
} else if (state == STATE_EMUL) {
|
} 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.");
|
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||||
SimulateIso14443aTag(7, flags, card.uid, 0, NULL);
|
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);
|
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:");
|
DbpString(_CYAN_("[@]") " UID:");
|
||||||
Dbhexdump(uidRx.len, data, false);
|
Dbhexdump(uidRx.len, data, false);
|
||||||
Dbprintf(_CYAN_("[@]") " Flags: %hu", *flags);
|
Dbprintf(_CYAN_("[@]") " Flags: %hu", *flags);
|
||||||
|
|
|
@ -717,33 +717,10 @@ readysim:
|
||||||
SpinOff(100);
|
SpinOff(100);
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
/*
|
|
||||||
uint16_t flags = 0;
|
uint16_t flags = 0;
|
||||||
switch (colin_p_card.uidlen) {
|
// FLAG_SET_UID_IN_DATA(flags, colin_p_card.uidlen);
|
||||||
case 10:
|
FLAG_SET_UID_IN_EMUL(flags);
|
||||||
flags = FLAG_10B_UID_IN_DATA;
|
FLAG_SET_MF_SIZE(flags, MIFARE_1K_MAX_BYTES);
|
||||||
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;
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
|
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
SpinOff(1000);
|
SpinOff(1000);
|
||||||
|
|
|
@ -79,13 +79,8 @@ void RunMod(void) {
|
||||||
}
|
}
|
||||||
} else if (state == STATE_EMUL) {
|
} else if (state == STATE_EMUL) {
|
||||||
uint16_t flags = 0;
|
uint16_t flags = 0;
|
||||||
if (card.uidlen == 4) {
|
FLAG_SET_UID_IN_DATA(flags, card.uidlen);
|
||||||
flags |= FLAG_4B_UID_IN_DATA;
|
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||||
} else if (card.uidlen == 7) {
|
|
||||||
flags |= FLAG_7B_UID_IN_DATA;
|
|
||||||
} else if (card.uidlen == 10) {
|
|
||||||
flags |= FLAG_10B_UID_IN_DATA;
|
|
||||||
} else {
|
|
||||||
Dbprintf("Unusual UID length, something is wrong. Try again please.");
|
Dbprintf("Unusual UID length, something is wrong. Try again please.");
|
||||||
state = STATE_READ;
|
state = STATE_READ;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -556,19 +556,7 @@ void RunMod(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t simflags = 0;
|
uint16_t simflags = 0;
|
||||||
switch (mattyrun_card.uidlen) {
|
FLAG_SET_UID_IN_DATA(simflags, 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;
|
|
||||||
}
|
|
||||||
uint16_t atqa = (uint16_t)bytes_to_num(mattyrun_card.atqa, 2);
|
uint16_t atqa = (uint16_t)bytes_to_num(mattyrun_card.atqa, 2);
|
||||||
|
|
||||||
SpinDelay(1000);
|
SpinDelay(1000);
|
||||||
|
|
|
@ -143,7 +143,9 @@ void RunMod(void) {
|
||||||
|
|
||||||
//Start to simulate
|
//Start to simulate
|
||||||
Dbprintf(_YELLOW_("[Slot: %d] Simulation start, Press button to change next card."), i);
|
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);
|
Mifare1ksim(simflags, 0, NULL, 0, 0);
|
||||||
Dbprintf(_YELLOW_("[Slot: %d] Simulation end, Write Back to dump file!"), i);
|
Dbprintf(_YELLOW_("[Slot: %d] Simulation end, Write Back to dump file!"), i);
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,8 @@ void RunMod(void) {
|
||||||
bool chktoken = false;
|
bool chktoken = false;
|
||||||
|
|
||||||
// UID 4 bytes(could be 7 bytes if needed it)
|
// 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
|
// in case there is a read command received we shouldn't break
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,8 @@ void RunMod() {
|
||||||
|
|
||||||
|
|
||||||
// UID 4 bytes(could be 7 bytes if needed it)
|
// 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
|
// in case there is a read command received we shouldn't break
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,8 @@ void RunMod(void) {
|
||||||
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64
|
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64
|
||||||
#define DYNAMIC_MODULATION_BUFFER_SIZE 512
|
#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
|
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; // in case there is a read command received we shouldn't break
|
||||||
|
|
||||||
// to initialize the emulation
|
// to initialize the emulation
|
||||||
|
|
|
@ -236,7 +236,8 @@ void RunMod(void) {
|
||||||
int button_pressed = BUTTON_HELD(1000);
|
int button_pressed = BUTTON_HELD(1000);
|
||||||
if (button_pressed == BUTTON_NO_CLICK) { // No button action, proceed with sim
|
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
|
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);
|
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);
|
uint64_t tmpuid = bytes_to_num(uids[selected].uid, uids[selected].uidlen);
|
||||||
|
|
||||||
if (uids[selected].uidlen == 7) {
|
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);
|
Dbprintf("Simulating ISO14443a tag with uid: %014" PRIx64 " [Bank: %d]", tmpuid, selected);
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Simulating ISO14443a tag with uid: %08" PRIx64 " [Bank: %d]", tmpuid, selected);
|
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 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) {
|
if (tagType == 2 || tagType == 7) {
|
||||||
uint16_t start = MFU_DUMP_PREFIX_LENGTH;
|
uint16_t start = MFU_DUMP_PREFIX_LENGTH;
|
||||||
uint8_t emdata[8];
|
uint8_t emdata[8];
|
||||||
emlGet(emdata, start, sizeof(emdata));
|
emlGet(emdata, start, sizeof(emdata));
|
||||||
memcpy(data, emdata, 3); // uid bytes 0-2
|
memcpy(data, emdata, 3); // uid bytes 0-2
|
||||||
memcpy(data + 3, emdata + 4, 4); // uid bytes 3-7
|
memcpy(data + 3, emdata + 4, 4); // uid bytes 3-7
|
||||||
flags |= FLAG_7B_UID_IN_DATA;
|
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||||
} else {
|
} else {
|
||||||
emlGet(data, 0, 4);
|
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[0] = data[0];
|
||||||
rUIDc1[1] = data[1];
|
rUIDc1[1] = data[1];
|
||||||
rUIDc1[2] = data[2];
|
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);
|
AddCrc14A(rSAKc1, sizeof(rSAKc1) - 2);
|
||||||
|
|
||||||
*cuid = bytes_to_num(data, 4);
|
*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[0] = MIFARE_SELECT_CT; // Cascade Tag marker
|
||||||
rUIDc1[1] = data[0];
|
rUIDc1[1] = data[0];
|
||||||
rUIDc1[2] = data[1];
|
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);
|
*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[0] = MIFARE_SELECT_CT; // Cascade Tag marker
|
||||||
rUIDc1[1] = data[0];
|
rUIDc1[1] = data[0];
|
||||||
|
@ -2560,7 +2560,7 @@ void iso14443a_antifuzz(uint32_t flags) {
|
||||||
resp[0] = 0x04;
|
resp[0] = 0x04;
|
||||||
resp[1] = 0x00;
|
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;
|
resp[0] = 0x44;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2578,7 +2578,7 @@ void iso14443a_antifuzz(uint32_t flags) {
|
||||||
resp[4] = resp[0] ^ resp[1] ^ resp[2] ^ resp[3];
|
resp[4] = resp[0] ^ resp[1] ^ resp[2] ^ resp[3];
|
||||||
colpos = 0;
|
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;
|
resp[0] = MIFARE_SELECT_CT;
|
||||||
colpos = 8;
|
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
|
// SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf
|
||||||
// ATQA
|
// ATQA
|
||||||
static uint8_t rATQA_Mini[] = {0x04, 0x00}; // indicate Mifare classic Mini 4Byte UID
|
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
|
// Can be set from emulator memory or incoming data
|
||||||
// Length: 4,7,or 10 bytes
|
// 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
|
// Get UID, SAK, ATQA from EMUL
|
||||||
if ((flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL) {
|
|
||||||
uint8_t block0[16];
|
uint8_t block0[16];
|
||||||
emlGet(block0, 0, 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
|
// 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) {
|
if ((block0[0] ^ block0[1] ^ block0[2] ^ block0[3]) == block0[4] && (block0[6] & 0xc0) == 0) {
|
||||||
flags |= FLAG_4B_UID_IN_DATA;
|
FLAG_SET_UID_IN_DATA(flags, 4);
|
||||||
memcpy(datain, block0, 4);
|
memcpy(uid, block0, 4);
|
||||||
rSAK[0] = block0[5];
|
rSAK[0] = block0[5];
|
||||||
memcpy(rATQA, &block0[6], sizeof(rATQA));
|
memcpy(rATQA, &block0[6], sizeof(rATQA));
|
||||||
}
|
}
|
||||||
// Check for 7 bytes UID: double size uid bits in ATQA
|
// Check for 7 bytes UID: double size uid bits in ATQA
|
||||||
else if ((block0[8] & 0xc0) == 0x40) {
|
else if ((block0[8] & 0xc0) == 0x40) {
|
||||||
flags |= FLAG_7B_UID_IN_DATA;
|
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||||
memcpy(datain, block0, 7);
|
memcpy(uid, block0, 7);
|
||||||
rSAK[0] = block0[7];
|
rSAK[0] = block0[7];
|
||||||
memcpy(rATQA, &block0[8], sizeof(rATQA));
|
memcpy(rATQA, &block0[8], sizeof(rATQA));
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("ERROR: " _RED_("Invalid dump. UID/SAK/ATQA not found"));
|
Dbprintf("ERROR: " _RED_("Invalid dump. UID/SAK/ATQA not found"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (uid == NULL) {
|
||||||
|
Dbprintf("ERROR: " _RED_("Missing UID"));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tune tag type, if defined directly
|
// Tune tag type, if defined directly
|
||||||
// Otherwise use defined by default or extracted from EMUL
|
// 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));
|
memcpy(rATQA, rATQA_Mini, sizeof(rATQA));
|
||||||
rSAK[0] = rSAK_Mini;
|
rSAK[0] = rSAK_Mini;
|
||||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare Mini ATQA/SAK");
|
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));
|
memcpy(rATQA, rATQA_1k, sizeof(rATQA));
|
||||||
rSAK[0] = rSAK_1k;
|
rSAK[0] = rSAK_1k;
|
||||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 1K ATQA/SAK");
|
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));
|
memcpy(rATQA, rATQA_2k, sizeof(rATQA));
|
||||||
rSAK[0] = rSAK_2k;
|
rSAK[0] = rSAK_2k;
|
||||||
*rats = rRATS;
|
*rats = rRATS;
|
||||||
*rats_len = sizeof(rRATS);
|
*rats_len = sizeof(rRATS);
|
||||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 2K ATQA/SAK with RATS support");
|
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));
|
memcpy(rATQA, rATQA_4k, sizeof(rATQA));
|
||||||
rSAK[0] = rSAK_4k;
|
rSAK[0] = rSAK_4k;
|
||||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 4K ATQA/SAK");
|
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 4K ATQA/SAK");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare UID arrays
|
// Prepare UID arrays
|
||||||
if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain
|
if (IS_FLAG_UID_IN_DATA(flags, 4)) {
|
||||||
memcpy(rUIDBCC1, datain, 4);
|
memcpy(rUIDBCC1, uid, 4);
|
||||||
*uid_len = 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
|
// save CUID
|
||||||
*cuid = bytes_to_num(rUIDBCC1, 4);
|
*cuid = bytes_to_num(rUIDBCC1, 4);
|
||||||
// BCC
|
// BCC
|
||||||
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
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) {
|
if (g_dbglevel > DBG_NONE) {
|
||||||
Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
|
Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Correct uid size bits in ATQA
|
// Correct uid size bits in ATQA
|
||||||
rATQA[0] = (rATQA[0] & 0x3f); // single size uid
|
rATQA[0] = (rATQA[0] & 0x3f); // single size uid
|
||||||
|
} else if (IS_FLAG_UID_IN_DATA(flags, 7)) {
|
||||||
} else if ((flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) {
|
memcpy(&rUIDBCC1[1], uid, 3);
|
||||||
memcpy(&rUIDBCC1[1], datain, 3);
|
memcpy(rUIDBCC2, uid + 3, 4);
|
||||||
memcpy(rUIDBCC2, datain + 3, 4);
|
|
||||||
*uid_len = 7;
|
*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
|
// save CUID
|
||||||
*cuid = bytes_to_num(rUIDBCC2, 4);
|
*cuid = bytes_to_num(rUIDBCC2, 4);
|
||||||
// CascadeTag, CT
|
// CascadeTag, CT
|
||||||
|
@ -321,6 +317,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
|
||||||
// BCC
|
// BCC
|
||||||
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
||||||
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[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) {
|
if (g_dbglevel > DBG_NONE) {
|
||||||
Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x",
|
Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x",
|
||||||
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]);
|
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
|
// Correct uid size bits in ATQA
|
||||||
rATQA[0] = (rATQA[0] & 0x3f) | 0x40; // double size uid
|
rATQA[0] = (rATQA[0] & 0x3f) | 0x40; // double size uid
|
||||||
|
} else if (IS_FLAG_UID_IN_DATA(flags, 10)) {
|
||||||
} else if ((flags & FLAG_10B_UID_IN_DATA) == FLAG_10B_UID_IN_DATA) {
|
memcpy(&rUIDBCC1[1], uid, 3);
|
||||||
memcpy(&rUIDBCC1[1], datain, 3);
|
memcpy(&rUIDBCC2[1], uid + 3, 3);
|
||||||
memcpy(&rUIDBCC2[1], datain + 3, 3);
|
memcpy(rUIDBCC3, uid + 6, 4);
|
||||||
memcpy(rUIDBCC3, datain + 6, 4);
|
|
||||||
*uid_len = 10;
|
*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
|
// save CUID
|
||||||
*cuid = bytes_to_num(rUIDBCC3, 4);
|
*cuid = bytes_to_num(rUIDBCC3, 4);
|
||||||
// CascadeTag, CT
|
// 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];
|
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
||||||
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
|
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
|
||||||
rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[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) {
|
if (g_dbglevel > DBG_NONE) {
|
||||||
Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
|
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"));
|
Dbprintf("ERROR: " _RED_("UID size not defined"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (flags & FLAG_FORCED_ATQA) {
|
if (flags & FLAG_ATQA_IN_DATA) {
|
||||||
rATQA[0] = atqa >> 8;
|
rATQA[0] = atqa >> 8;
|
||||||
rATQA[1] = atqa & 0xff;
|
rATQA[1] = atqa & 0xff;
|
||||||
}
|
}
|
||||||
if (flags & FLAG_FORCED_SAK) {
|
if (flags & FLAG_SAK_IN_DATA) {
|
||||||
rSAK[0] = sak;
|
rSAK[0] = sak;
|
||||||
}
|
}
|
||||||
if (g_dbglevel > DBG_NONE) {
|
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.
|
*MIFARE 1K simulate.
|
||||||
*
|
*
|
||||||
*@param flags :
|
*@param flags: See pm3_cmd.h for the full definitions
|
||||||
* 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 exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ...
|
*@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)
|
* (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;
|
tag_response_info_t *responses;
|
||||||
uint8_t cardSTATE = MFEMUL_NOFIELD;
|
uint8_t cardSTATE = MFEMUL_NOFIELD;
|
||||||
uint8_t uid_len = 0; // 4, 7, 10
|
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;
|
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
|
//Here, we collect UID,sector,keytype,NT,AR,NR,NT2,AR2,NR2
|
||||||
// This will be used in the reader-only attack.
|
// 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
|
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||||
BigBuf_free_keep_EM();
|
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();
|
BigBuf_free_keep_EM();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,6 @@
|
||||||
#define AUTHKEYB 1
|
#define AUTHKEYB 1
|
||||||
#define AUTHKEYNONE 0xff
|
#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
|
#endif
|
||||||
|
|
|
@ -830,17 +830,8 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
bool useUIDfromEML = true;
|
bool useUIDfromEML = true;
|
||||||
|
|
||||||
if (uid_len > 0) {
|
if (uid_len > 0) {
|
||||||
switch (uid_len) {
|
FLAG_SET_UID_IN_DATA(flags, uid_len);
|
||||||
case 10:
|
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||||
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:
|
|
||||||
PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID");
|
PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
@ -866,7 +857,7 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useUIDfromEML) {
|
if (useUIDfromEML) {
|
||||||
flags |= FLAG_UID_IN_EMUL;
|
FLAG_SET_UID_IN_EMUL(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -1660,12 +1651,14 @@ static int CmdHF14AAntiFuzz(const char *Cmd) {
|
||||||
struct {
|
struct {
|
||||||
uint8_t flag;
|
uint8_t flag;
|
||||||
} PACKED param;
|
} PACKED param;
|
||||||
param.flag = FLAG_4B_UID_IN_DATA;
|
param.flag = 0;
|
||||||
|
FLAG_SET_UID_IN_DATA(param.flag, 4);
|
||||||
if (arg_get_lit(ctx, 2))
|
if (arg_get_lit(ctx, 2)) {
|
||||||
param.flag = FLAG_7B_UID_IN_DATA;
|
FLAG_SET_UID_IN_DATA(param.flag, 7);
|
||||||
if (arg_get_lit(ctx, 3))
|
}
|
||||||
param.flag = FLAG_10B_UID_IN_DATA;
|
if (arg_get_lit(ctx, 3)) {
|
||||||
|
FLAG_SET_UID_IN_DATA(param.flag, 10);
|
||||||
|
}
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -3725,17 +3718,8 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
||||||
bool useUIDfromEML = true;
|
bool useUIDfromEML = true;
|
||||||
|
|
||||||
if (uid_len > 0) {
|
if (uid_len > 0) {
|
||||||
switch (uid_len) {
|
FLAG_SET_UID_IN_DATA(flags, uid_len);
|
||||||
case 10:
|
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||||
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:
|
|
||||||
PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID");
|
PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
@ -3757,7 +3741,7 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useUIDfromEML) {
|
if (useUIDfromEML) {
|
||||||
flags |= FLAG_UID_IN_EMUL;
|
FLAG_SET_UID_IN_EMUL(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -565,7 +565,8 @@ static int CmdHF14AJookiSim(const char *Cmd) {
|
||||||
|
|
||||||
// NTAG, 7 byte UID in eloaded data.
|
// NTAG, 7 byte UID in eloaded data.
|
||||||
payload.tagtype = 7;
|
payload.tagtype = 7;
|
||||||
payload.flags = FLAG_UID_IN_EMUL;
|
payload.flags = 0;
|
||||||
|
FLAG_SET_UID_IN_EMUL(payload.flags);
|
||||||
payload.exitAfter = 0;
|
payload.exitAfter = 0;
|
||||||
memcpy(payload.uid, uid, sizeof(uid));
|
memcpy(payload.uid, uid, sizeof(uid));
|
||||||
|
|
||||||
|
|
|
@ -4129,25 +4129,15 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
||||||
uint8_t uid[10] = {0};
|
uint8_t uid[10] = {0};
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
|
||||||
char uidsize[8] = {0};
|
char uidsize[9] = {0};
|
||||||
if (uidlen > 0) {
|
if (uidlen > 0) {
|
||||||
switch (uidlen) {
|
FLAG_SET_UID_IN_DATA(flags, uidlen);
|
||||||
case 10:
|
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||||
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:
|
|
||||||
PrintAndLogEx(WARNING, "Invalid parameter for UID");
|
PrintAndLogEx(WARNING, "Invalid parameter for UID");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
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");
|
PrintAndLogEx(WARNING, "Wrong ATQA length");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
flags |= FLAG_FORCED_ATQA;
|
flags |= FLAG_ATQA_IN_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (saklen > 0) {
|
if (saklen > 0) {
|
||||||
|
@ -4201,12 +4191,7 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
||||||
PrintAndLogEx(WARNING, "Wrong SAK length");
|
PrintAndLogEx(WARNING, "Wrong SAK length");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
flags |= FLAG_FORCED_SAK;
|
flags |= FLAG_SAK_IN_DATA;
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t k_sectors_cnt = MIFARE_4K_MAXSECTOR;
|
size_t k_sectors_cnt = MIFARE_4K_MAXSECTOR;
|
||||||
|
@ -4218,19 +4203,19 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m0) {
|
if (m0) {
|
||||||
flags |= FLAG_MF_MINI;
|
FLAG_SET_MF_SIZE(flags, MIFARE_MINI_MAX_BYTES);
|
||||||
snprintf(csize, sizeof(csize), "MINI");
|
snprintf(csize, sizeof(csize), "MINI");
|
||||||
k_sectors_cnt = MIFARE_MINI_MAXSECTOR;
|
k_sectors_cnt = MIFARE_MINI_MAXSECTOR;
|
||||||
} else if (m1) {
|
} else if (m1) {
|
||||||
flags |= FLAG_MF_1K;
|
FLAG_SET_MF_SIZE(flags, MIFARE_1K_MAX_BYTES);
|
||||||
snprintf(csize, sizeof(csize), "1K");
|
snprintf(csize, sizeof(csize), "1K");
|
||||||
k_sectors_cnt = MIFARE_1K_MAXSECTOR;
|
k_sectors_cnt = MIFARE_1K_MAXSECTOR;
|
||||||
} else if (m2) {
|
} else if (m2) {
|
||||||
flags |= FLAG_MF_2K;
|
FLAG_SET_MF_SIZE(flags, MIFARE_2K_MAX_BYTES);
|
||||||
snprintf(csize, sizeof(csize), "2K with RATS");
|
snprintf(csize, sizeof(csize), "2K with RATS");
|
||||||
k_sectors_cnt = MIFARE_2K_MAXSECTOR;
|
k_sectors_cnt = MIFARE_2K_MAXSECTOR;
|
||||||
} else if (m4) {
|
} else if (m4) {
|
||||||
flags |= FLAG_MF_4K;
|
FLAG_SET_MF_SIZE(flags, MIFARE_4K_MAX_BYTES);
|
||||||
snprintf(csize, sizeof(csize), "4K");
|
snprintf(csize, sizeof(csize), "4K");
|
||||||
k_sectors_cnt = MIFARE_4K_MAXSECTOR;
|
k_sectors_cnt = MIFARE_4K_MAXSECTOR;
|
||||||
} else {
|
} else {
|
||||||
|
@ -4262,9 +4247,8 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
||||||
, (uidlen == 0) ? "n/a" : sprint_hex(uid, uidlen)
|
, (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
|
, exitAfterNReads
|
||||||
, flags
|
|
||||||
, flags);
|
, flags);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -766,21 +766,72 @@ typedef struct {
|
||||||
#define CMD_UNKNOWN 0xFFFF
|
#define CMD_UNKNOWN 0xFFFF
|
||||||
|
|
||||||
//Mifare simulation flags
|
//Mifare simulation flags
|
||||||
#define FLAG_INTERACTIVE 0x01
|
// In interactive mode, we are expected to finish the operation with an ACK
|
||||||
#define FLAG_4B_UID_IN_DATA 0x02
|
#define FLAG_INTERACTIVE 0x0001
|
||||||
#define FLAG_7B_UID_IN_DATA 0x04
|
#define FLAG_ATQA_IN_DATA 0x0002
|
||||||
#define FLAG_10B_UID_IN_DATA 0x08
|
#define FLAG_SAK_IN_DATA 0x0004
|
||||||
#define FLAG_UID_IN_EMUL 0x10
|
#define FLAG_RATS_IN_DATA 0x0008
|
||||||
#define FLAG_NR_AR_ATTACK 0x20
|
|
||||||
#define FLAG_MF_MINI 0x80
|
// internal constants, use the function macros instead
|
||||||
#define FLAG_MF_1K 0x100
|
#define FLAG_MASK_UID 0x0030
|
||||||
#define FLAG_MF_2K 0x200
|
#define FLAG_UID_IN_EMUL 0x0000
|
||||||
#define FLAG_MF_4K 0x400
|
#define FLAG_4B_UID_IN_DATA 0x0010
|
||||||
#define FLAG_FORCED_ATQA 0x800
|
#define FLAG_7B_UID_IN_DATA 0x0020
|
||||||
#define FLAG_FORCED_SAK 0x1000
|
#define FLAG_10B_UID_IN_DATA 0x0030
|
||||||
#define FLAG_CVE21_0430 0x2000
|
// if there is a UID in the data-section to be used:
|
||||||
#define FLAG_RATS_IN_DATA 0x4000
|
// note: if UIDLEN is wrong, we default to FLAG_UID_IN_EMUL
|
||||||
#define FLAG_NESTED_AUTH_ATTACK 0x8000
|
#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
|
#define MODE_SIM_CSN 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue