diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index e002a5bc6..f0f9453d6 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -898,6 +898,11 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { response1[0] = 0x02; sak = 0x18; } break; + case 9 : { // FM11RF005SH (Shanghai Metro) + response1[0] = 0x03; + response1[1] = 0x00; + sak = 0x0A; + } default: { Dbprintf("Error: unkown tagtype (%d)",tagType); return; @@ -951,6 +956,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { uint8_t response5[4]; uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS: + // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1 // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us) @@ -1045,7 +1051,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) p_response = &responses[3]; order = 3; } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) - p_response = &responses[4]; order = 30; + p_response = &responses[4]; order = 30; } else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { // Received a (plain) READ uint8_t block = receivedCmd[1]; // if Ultralight or NTAG (4 byte blocks) @@ -1058,6 +1064,11 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { 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 ) { + // FM11005SH. 16blocks, 4bytes / block. + // block0 = 2byte Customer ID (CID), 2byte Manufacture ID (MID) + // block1 = 4byte UID. + p_response = &responses[1]; } else { // all other tags (16 byte block tags) uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; emlGetMemBt( emdata, block, 16); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 4f6f217d8..98a2135cf 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -119,6 +119,7 @@ int usage_hf_14a_sim(void) { PrintAndLogEx(NORMAL, " 6 = MIFARE Mini"); PrintAndLogEx(NORMAL, " 7 = AMIIBO (NTAG 215), pack 0x8080"); PrintAndLogEx(NORMAL, " 8 = MIFARE Classic 4k"); + PrintAndLogEx(NORMAL, " 9 = FM11RF005SH Shanghai Metro"); // PrintAndLogEx(NORMAL, " u : 4, 7 or 10 byte UID"); PrintAndLogEx(NORMAL, " u : 4, 7 byte UID"); PrintAndLogEx(NORMAL, " x : (Optional) Performs the 'reader attack', nr/ar attack against a reader"); @@ -233,51 +234,52 @@ int CmdHF14AReader(const char *Cmd) { SendCommand(&c); if (ISO14A_CONNECT & cm) { - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { - if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed"); - DropField(); - return 1; - } + UsbCommand resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { + if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed"); + DropField(); + return 1; + } - iso14a_card_select_t card; - memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); + iso14a_card_select_t card; + memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); + + /* + 0: couldn't read + 1: OK, with ATS + 2: OK, no ATS + 3: proprietary Anticollision + */ + uint64_t select_status = resp.arg[0]; + + if (select_status == 0) { + if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed"); + DropField(); + return 1; + } - /* - 0: couldn't read - 1: OK, with ATS - 2: OK, no ATS - 3: proprietary Anticollision - */ - uint64_t select_status = resp.arg[0]; - - if (select_status == 0) { - if (!silent) PrintAndLogEx(WARNING, "iso14443a card select failed"); - DropField(); - return 1; - } + if (select_status == 3) { + PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision"); + PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + DropField(); + return 1; + } - if (select_status == 3) { - PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision"); + PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen)); PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); - DropField(); - return 1; - } - - PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]); - PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.arg[0]); + PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.arg[0]); - if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes - PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len)); - } + if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes + PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len)); + } + if (!disconnectAfter) { if (!silent) PrintAndLogEx(SUCCESS, "Card is selected. You can now start sending commands"); } } if (disconnectAfter) { - if (!silent) PrintAndLogEx(SUCCESS, "field dropped."); + if (!silent) PrintAndLogEx(SUCCESS, "field dropped."); } return 0; @@ -364,6 +366,7 @@ int CmdHF14AInfo(const char *Cmd) { case 0x04: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); isMifareClassic = false; break; case 0x08: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); break; case 0x09: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k"); break; + case 0x0A: PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)"); break; case 0x10: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2"); break; case 0x11: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2"); break; case 0x18: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); break; @@ -568,7 +571,6 @@ int CmdHF14ACUIDs(const char *Cmd) { } // ## simulate iso14443a tag -// ## greg - added ability to specify tag UID int CmdHF14ASim(const char *Cmd) { bool errors = false; uint8_t flags = 0; diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index bc58914db..5ecde14b0 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -32,6 +32,7 @@ ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance" ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)" ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k" ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k" +ISO14443a_TYPES[0x0A} = "FM11RF005SH (Shanghai Metro)") ISO14443a_TYPES[0x10] = "NXP MIFARE Plus 2k" ISO14443a_TYPES[0x11] = "NXP MIFARE Plus 4k" ISO14443a_TYPES[0x18] = "NXP MIFARE Classic 4k | Plus 4k"