]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/mifarecmd.c
Don't do iso14443-4 select for mifare emulations on processor cards (IDPrime, SmartMX...
[proxmark3-svn] / armsrc / mifarecmd.c
index 0e9c36725ec4ad24d2be46e2e51342c30b6a7534..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
@@ -1170,6 +1170,143 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 // Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
 //\r
 //-----------------------------------------------------------------------------\r
+\r
+static bool isBlockTrailer(int blockN) {\r
+       if (blockN >= 0 && blockN < 128) {\r
+               return ((blockN & 0x03) == 0x03);\r
+       }\r
+       if (blockN >= 128 && blockN <= 256) {\r
+               return ((blockN & 0x0F) == 0x0F);\r
+       }\r
+       return FALSE;\r
+}\r
+\r
+void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+       // var\r
+       byte_t isOK = 0;\r
+       uint32_t numBlocks = arg0;\r
+       // cmdParams:\r
+       // bit 0 - wipe gen1a\r
+       // bit 1 - fill card with default data\r
+       // bit 2 - gen1a = 0, gen1b = 1\r
+       uint8_t cmdParams = arg1;\r
+       bool needWipe = cmdParams & 0x01;\r
+       bool needFill = cmdParams & 0x02;\r
+       bool gen1b = cmdParams & 0x04;\r
+       \r
+       uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
+       uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+       \r
+       uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF};\r
+       uint8_t block1[16] = {0x00};\r
+       uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
+       uint8_t d_block[18] = {0x00};\r
+       \r
+       // card commands\r
+       uint8_t wupC1[]       = { 0x40 };\r
+       uint8_t wupC2[]       = { 0x43 };\r
+       uint8_t wipeC[]       = { 0x41 };\r
+       \r
+       // iso14443 setup\r
+       LED_A_ON();\r
+       LED_B_OFF();\r
+       LED_C_OFF();\r
+       iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+\r
+       // tracing\r
+       clear_trace();\r
+       set_tracing(true);\r
+               \r
+       while (true){\r
+               // wipe\r
+               if (needWipe){\r
+                       ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+                       if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
+                               break;\r
+                       };\r
+\r
+                       ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
+                       if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wipeC error");\r
+                               break;\r
+                       };\r
+\r
+                       if(mifare_classic_halt(NULL, 0)) {\r
+                               if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
+                       };\r
+               };\r
+       \r
+               // put default data\r
+               if (needFill){\r
+                       // select commands\r
+                       ReaderTransmitBitsPar(wupC1, 7, 0, NULL);\r
+\r
+                       // gen1b magic tag : do no issue wupC2 and don't expect 0x0a response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
+                       if (!gen1b) { \r
+\r
+                               if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
+                                       break;\r
+                               };\r
+\r
+                               ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
+                               if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
+                                       break;\r
+                               };\r
+                       }\r
+\r
+                       // send blocks command\r
+                       for (int blockNo = 0; blockNo < numBlocks; blockNo++) {\r
+                               if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("write block send command error");\r
+                                       break;\r
+                               };\r
+                               \r
+                               // check type of block and add crc\r
+                               if (!isBlockTrailer(blockNo)){\r
+                                       memcpy(d_block, block1, 16);\r
+                               } else {\r
+                                       memcpy(d_block, blockK, 16);\r
+                               }\r
+                               if (blockNo == 0) {\r
+                                       memcpy(d_block, block0, 16);\r
+                               }\r
+                               AppendCrc14443a(d_block, 16);\r
+\r
+                               // send write command\r
+                               ReaderTransmit(d_block, sizeof(d_block), NULL);\r
+                               if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+                                       if (MF_DBGLEVEL >= 1)   Dbprintf("write block send data error");\r
+                                       break;\r
+                               };\r
+                       }\r
+                       \r
+                       // halt\r
+                       // do no issue halt command for gen1b \r
+                       if (!gen1b) {\r
+                               if (mifare_classic_halt(NULL, 0)) {\r
+                                       if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
+                                               break;\r
+                               }\r
+                       }\r
+               }\r
+               break;\r
+       }       \r
+\r
+       // send USB response\r
+       LED_B_ON();\r
+       cmd_send(CMD_ACK,isOK,0,0,NULL,0);\r
+       LED_B_OFF();\r
+       \r
+       // reset fpga\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       LEDsoff();\r
+               \r
+       return;\r
+}\r
+\r
 void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
 \r
   // params\r
@@ -1212,15 +1349,16 @@ 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
-                               break;\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
                                };\r
 \r
                                if(mifare_classic_halt(NULL, cuid)) {\r
                                        if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
                                        // Continue, some magic tags misbehavies and send an answer to it.\r
-          // break;\r
+                                       // break;\r
                                };\r
                };\r
 \r
@@ -1239,7 +1377,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                                break;\r
                        };\r
 \r
-                       if(mifare_classic_halt(NULL, cuid)) {\r
+                       if(mifare_classic_halt(NULL, 0)) {\r
                                if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
                                // Continue, some magic tags misbehavies and send an answer to it.\r
                                // break;\r
@@ -1283,7 +1421,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                if (workFlags & 0x04) {\r
                        // do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)\r
                        if (!(workFlags & 0x40)) {\r
-                               if (mifare_classic_halt(NULL, cuid)) {\r
+                               if (mifare_classic_halt(NULL, 0)) {\r
                                        if (MF_DBGLEVEL > 2)    Dbprintf("Halt error");\r
                                        // Continue, some magic tags misbehavies and send an answer to it.\r
                                        // break;\r
@@ -1435,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
Impressum, Datenschutz