Don't do iso14443-4 select for mifare emulations on processor cards (IDPrime, SmartMX...
authorpwpiwi <pwpiwi@users.noreply.github.com>
Sun, 1 Oct 2017 15:52:10 +0000 (17:52 +0200)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Sun, 1 Oct 2017 15:52:10 +0000 (17:52 +0200)
armsrc/appmain.c
armsrc/epa.c
armsrc/iso14443a.c
armsrc/iso14443a.h
armsrc/mifarecmd.c
client/cmdhf14a.c
client/cmdhfmfu.c
client/mifarehost.c
include/mifare.h

index b375c3ced2e4a54322cc6dec516c96b83140b18d..e292483b80b5a6634151a11ad5243bf0ff77cf49 100644 (file)
@@ -450,7 +450,7 @@ void StandAloneMode14a()
                                                SpinDelay(300);
                                        }
                                }
-                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0))
+                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0, true))
                                        continue;
                                else
                                {
index f434aa3422421c0bdc872c5fc98068b180a548f7..fd71430bf04ba1906a75c3cae42988079d1844c2 100644 (file)
@@ -530,7 +530,7 @@ int EPA_Setup()
        // power up the field
        iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
        // select the card
-       return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0);
+       return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0, false);
        if (return_code == 1) {
                // send the PPS request
                ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
index 29b23833cd875065c26a1aa06f9981391941c86f..e9ad25355b4c498c46c2f5f8fe6c1a534df2e66b 100644 (file)
@@ -1733,7 +1733,8 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
 // fills the card info record unless NULL
 // if anticollision is false, then the UID must be provided in uid_ptr[] 
 // and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
-int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades) {
+// requests ATS unless no_rats is true
+int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) {
        uint8_t wupa[]       = { 0x52 };  // 0x26 - REQA  0x52 - WAKE-UP
        uint8_t sel_all[]    = { 0x93,0x20 };
        uint8_t sel_uid[]    = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
@@ -1868,24 +1869,24 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
        // non iso14443a compliant tag
        if( (sak & 0x20) == 0) return 2; 
 
-       // Request for answer to select
-       AppendCrc14443a(rats, 2);
-       ReaderTransmit(rats, sizeof(rats), NULL);
+       if (!no_rats) {
+               // Request for answer to select
+               AppendCrc14443a(rats, 2);
+               ReaderTransmit(rats, sizeof(rats), NULL);
 
-       if (!(len = ReaderReceive(resp, resp_par))) return 0;
+               if (!(len = ReaderReceive(resp, resp_par))) return 0;
 
-       
-       if(p_hi14a_card) {
-               memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
-               p_hi14a_card->ats_len = len;
-       }
-
-       // reset the PCB block number
-       iso14_pcb_blocknum = 0;
+               if(p_hi14a_card) {
+                       memcpy(p_hi14a_card->ats, resp, len);
+                       p_hi14a_card->ats_len = len;
+               }
 
-       // set default timeout based on ATS
-       iso14a_set_ATS_timeout(resp);
+               // reset the PCB block number
+               iso14_pcb_blocknum = 0;
 
+               // set default timeout based on ATS
+               iso14a_set_ATS_timeout(resp);
+       }
        return 1;       
 }
 
@@ -1971,7 +1972,7 @@ void ReaderIso14443a(UsbCommand *c)
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
                if(!(param & ISO14A_NO_SELECT)) {
                        iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
-                       arg0 = iso14443a_select_card(NULL, card, NULL, true, 0);
+                       arg0 = iso14443a_select_card(NULL, card, NULL, true, 0, param & ISO14A_NO_RATS);
                        cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
                }
        }
@@ -2168,7 +2169,7 @@ void ReaderMifare(bool first_try)
                        SpinDelay(100);
                }
                
-               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
+               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Mifare: Can't select card");
                        continue;
                }
index 658216e72461b44a8dfea9d08434dc203658100a..10e50e0fbc10f7cd161ce8ef5413487bfd57cea2 100644 (file)
@@ -27,6 +27,6 @@ extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
 
 extern void iso14443a_setup(uint8_t fpga_minor_mode);
 extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
-extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
+extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
 extern void iso14a_set_trigger(bool enable);
 #endif /* __ISO14443A_H */
index 60a85c80117c571f14132084f915b9a745317e78..a3f0d374430ce9c9c7786f3853b76c7f017b5441 100644 (file)
@@ -59,7 +59,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_C_OFF();\r
 \r
        while (true) {\r
-               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+               if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                        break;\r
                };\r
@@ -106,7 +106,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
 \r
        clear_trace();\r
 \r
-       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
+       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
                OnError(0);\r
                return;\r
@@ -141,7 +141,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 \r
        clear_trace();\r
 \r
-       int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);\r
+       int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);\r
        if(!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);\r
                OnError(1);\r
@@ -217,7 +217,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_C_OFF();\r
 \r
        isOK = 1;\r
-       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
                isOK = 0;\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
        }\r
@@ -281,7 +281,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
                return;\r
        }\r
 \r
-       int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);\r
+       int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);\r
        if (!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);\r
                OnError(1);\r
@@ -383,7 +383,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_C_OFF();\r
 \r
        while (true) {\r
-                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                        break;\r
                };\r
@@ -483,7 +483,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 \r
        clear_trace();\r
 \r
-       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
+       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {\r
                if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
                OnError(0);\r
                return;\r
@@ -542,7 +542,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
 \r
        clear_trace();\r
 \r
-       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
+       if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {\r
                if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
                OnError(0);\r
                return;\r
@@ -662,7 +662,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 \r
                if (!have_uid) { // need a full select cycle to get the uid first\r
                        iso14a_card_select_t card_info;\r
-                       if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
+                       if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Can't select card (ALL)");\r
                                continue;\r
                        }\r
@@ -674,7 +674,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
                        }\r
                        have_uid = true;\r
                } else { // no need for anticollision. We can directly select the card\r
-                       if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
+                       if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("AcquireNonces: Can't select card (UID)");\r
                                continue;\r
                        }\r
@@ -807,7 +807,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                                continue;\r
                        }\r
 \r
-                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Can't select card");\r
                                rtr--;\r
                                continue;\r
@@ -881,7 +881,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
                                continue;\r
                        }\r
 \r
-                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Nested: Can't select card");\r
                                continue;\r
                        };\r
@@ -1000,7 +1000,7 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                // Iceman: use piwi's faster nonce collecting part in hardnested.\r
                if (!have_uid) { // need a full select cycle to get the uid first\r
                        iso14a_card_select_t card_info;\r
-                       if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
+                       if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {\r
                                if (OLD_MF_DBGLEVEL >= 1)       Dbprintf("ChkKeys: Can't select card");\r
                                --i; // try same key once again\r
                                continue;\r
@@ -1013,7 +1013,7 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
                        }\r
                        have_uid = true;\r
                } else { // no need for anticollision. We can directly select the card\r
-                       if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
+                       if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) {\r
                                if (OLD_MF_DBGLEVEL >= 1)       Dbprintf("ChkKeys: Can't select card (UID)");\r
                                --i; // try same key once again\r
                                continue;\r
@@ -1111,7 +1111,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 \r
        bool isOK = true;\r
 \r
-       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
                isOK = false;\r
                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
        }\r
@@ -1349,7 +1349,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 \r
                // get UID from chip\r
                if (workFlags & 0x01) {\r
-                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                                // Continue, if we set wrong UID or wrong UID checksum or some ATQA or SAK we will can't select card. But we need to write block 0 to make card work.\r
                                //break;\r
@@ -1573,7 +1573,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
        clear_trace();\r
 \r
-       int len = iso14443a_select_card(uid, NULL, &cuid, true, 0);\r
+       int len = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);\r
        if(!len) {\r
                if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
                OnError(1);\r
index b75215a0d41ef1b4f00a30e12a4ddf098dbbfc5e..db9ce46e4b65bea1544dfbe8a1a3b54e71e7329b 100644 (file)
@@ -442,7 +442,7 @@ int CmdHF14ACUIDs(const char *Cmd)
        // repeat n times
        for (int i = 0; i < n; i++) {
                // execute anticollision procedure
-               UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
+               UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0}};
                SendCommand(&c);
     
                UsbCommand resp;
@@ -581,6 +581,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
        bool power = false;
        bool active = false;
        bool active_select = false;
+       bool no_rats = false;
        uint16_t numbits = 0;
        bool bTimeout = false;
        uint32_t timeout = 0;
@@ -601,6 +602,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
                PrintAndLog("       -b    number of bits to send. Useful for send partial byte");
                PrintAndLog("       -t    timeout in ms");
                PrintAndLog("       -T    use Topaz protocol to send command");
+               PrintAndLog("       -3    ISO14443-3 select only (skip RATS)");
                return 0;
        }
 
@@ -645,6 +647,9 @@ int CmdHF14ACmdRaw(const char *cmd) {
                                case 'T':
                                        topazmode = true;
                                        break;
+                               case '3':
+                                       no_rats = true;
+                                       break;
                                default:
                                        PrintAndLog("Invalid option");
                                        return 0;
@@ -718,6 +723,10 @@ int CmdHF14ACmdRaw(const char *cmd) {
                c.arg[0] |= ISO14A_TOPAZMODE;
        }
 
+       if(no_rats) {
+               c.arg[0] |= ISO14A_NO_RATS;
+       }
+
        // Max buffer is USB_CMD_DATA_SIZE (512)
        c.arg[1] = (datalen & 0xFFFF) | ((uint32_t)numbits << 16);
        memcpy(c.d.asBytes,data,datalen);
index ca4544f37f6bc9f618f3671f6eaf3ebe191fc51f..3021631ac358a5485f02f8a2585703ed5f85f75d 100644 (file)
@@ -108,7 +108,7 @@ char *getUlev1CardSizeStr( uint8_t fsize ){
 }
 
 static void ul_switch_on_field(void) {
-       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
+       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0}};
        clearCommandBuffer();
        SendCommand(&c);
 }
index 8a840d4701a8ec852cf653c8c60349823accb492..629c8feb4a48c93b0d1431032d3261ebe6f8da60 100644 (file)
@@ -519,20 +519,20 @@ int mfCIdentify()
        UsbCommand resp;\r
        WaitForResponse(CMD_ACK,&resp);\r
 \r
-       iso14a_card_select_t card;\r
-       memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
-\r
-       uint64_t select_status = resp.arg[0];           // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
-\r
-       if(select_status != 0) {\r
-               uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
-               c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
-               c.arg[1] = 2;\r
-               c.arg[2] = 0;\r
-               memcpy(c.d.asBytes, rats, 2);\r
-               SendCommand(&c);\r
-               WaitForResponse(CMD_ACK,&resp);\r
-       }\r
+       // iso14a_card_select_t card;\r
+       // memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
+\r
+       // uint64_t select_status = resp.arg[0];                // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
+\r
+       // if(select_status != 0) {\r
+               // uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
+               // c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
+               // c.arg[1] = 2;\r
+               // c.arg[2] = 0;\r
+               // memcpy(c.d.asBytes, rats, 2);\r
+               // SendCommand(&c);\r
+               // WaitForResponse(CMD_ACK,&resp);\r
+       // }\r
 \r
        c.cmd = CMD_MIFARE_CIDENT;\r
        c.arg[0] = 0;\r
index e2386cd5926fb2c5869d189e88981e317246f806..bede67a97723ebe56d649839d5c378a706d7db90 100644 (file)
@@ -34,7 +34,8 @@ typedef enum ISO14A_COMMAND {
        ISO14A_APPEND_CRC =                     (1 << 5),
        ISO14A_SET_TIMEOUT =            (1 << 6),
        ISO14A_NO_SELECT =                      (1 << 7),
-       ISO14A_TOPAZMODE =                      (1 << 8)
+       ISO14A_TOPAZMODE =                      (1 << 8),
+       ISO14A_NO_RATS =                        (1 << 9)
 } iso14a_command_t;
 
 typedef struct {
Impressum, Datenschutz