]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/mifarecmd.c
Attempt to use raw writing capabilities via scripting engine. Not functional yet
[proxmark3-svn] / armsrc / mifarecmd.c
index d2795b1a2c2ca2e5a810c4ea90629a1d51b254a9..a0e0b01f967c4f127fd796ca5ea80e813834dce5 100644 (file)
@@ -1,5 +1,5 @@
 //-----------------------------------------------------------------------------\r
-// Merlok - June 2011\r
+// Merlok - June 2011, 2012\r
 // Gerhard de Koning Gans - May 2008\r
 // Hagen Fritsch - June 2010\r
 //\r
@@ -35,7 +35,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        pcs = &mpcs;\r
 \r
        // clear trace\r
-       iso14a_clear_tracelen();\r
+       iso14a_clear_trace();\r
 //     iso14a_set_tracing(false);\r
 \r
        iso14443a_setup();\r
@@ -78,11 +78,12 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        memset(uid, 0x44, 4);\r
        LogTrace(uid, 4, 0, 0, TRUE);\r
 \r
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
-       memcpy(ack.d.asBytes, dataoutbuf, 16);\r
+//     UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+//     memcpy(ack.d.asBytes, dataoutbuf, 16);\r
        \r
        LED_B_ON();\r
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+  cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
        LED_B_OFF();\r
 \r
 \r
@@ -115,7 +116,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        pcs = &mpcs;\r
 \r
        // clear trace\r
-       iso14a_clear_tracelen();\r
+       iso14a_clear_trace();\r
 //     iso14a_set_tracing(false);\r
 \r
        iso14443a_setup();\r
@@ -170,17 +171,18 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        memset(uid, 0x44, 4);\r
        LogTrace(uid, 4, 0, 0, TRUE);\r
 \r
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
-       memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
+//     UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+//     memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
        \r
        LED_B_ON();\r
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
-\r
-       SpinDelay(100);\r
+  cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,32);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+//     SpinDelay(100);\r
        \r
-       memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
-       LED_B_OFF();    \r
+//     memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+  cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);\r
+       LED_B_OFF();\r
 \r
        // Thats it...\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
@@ -213,7 +215,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        pcs = &mpcs;\r
 \r
        // clear trace\r
-       iso14a_clear_tracelen();\r
+       iso14a_clear_trace();\r
 //  iso14a_set_tracing(false);\r
 \r
        iso14443a_setup();\r
@@ -256,11 +258,12 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        memset(uid, 0x44, 4);\r
        LogTrace(uid, 4, 0, 0, TRUE);\r
 \r
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+//     UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
        \r
        LED_B_ON();\r
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
-       LED_B_OFF();    \r
+  cmd_send(CMD_ACK,isOK,0,0,0,0);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();\r
 \r
 \r
        // Thats it...\r
@@ -298,10 +301,9 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
        uint8_t uid[8];\r
        uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;\r
        uint8_t par_array[4];\r
-       nestedVector nvector[NES_MAX_INFO + 1][10];\r
+       nestedVector nvector[NES_MAX_INFO + 1][11];\r
        int nvectorcount[NES_MAX_INFO + 1];\r
        int ncount = 0;\r
-       UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
        struct Crypto1State mpcs = {0, 0};\r
        struct Crypto1State *pcs;\r
        pcs = &mpcs;\r
@@ -311,7 +313,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
        for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11;  //  11 - empty block;\r
        \r
        // clear trace\r
-       iso14a_clear_tracelen();\r
+       iso14a_clear_trace();\r
   iso14a_set_tracing(false);\r
        \r
        iso14443a_setup();\r
@@ -417,8 +419,9 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
                }\r
                \r
                ncount = 0;\r
-               for (m = dmin - NS_TOLERANCE; m < dmax + NS_TOLERANCE; m++) {\r
-                       nttest = prng_successor(nt1, m);\r
+               nttest = prng_successor(nt1, dmin - NS_TOLERANCE);\r
+               for (m = dmin - NS_TOLERANCE + 1; m < dmax + NS_TOLERANCE; m++) {\r
+                       nttest = prng_successor(nttest, 1);\r
                        ks1 = nt2 ^ nttest;\r
 \r
                        if (valid_nonce(nttest, nt2, ks1, par_array) && (ncount < 11)){\r
@@ -467,6 +470,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
        memset(uid, 0x44, 4);\r
        LogTrace(uid, 4, 0, 0, TRUE);\r
 \r
+//  UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
+\r
        for (i = 0; i < NES_MAX_INFO; i++) {\r
                if (nvectorcount[i] > 10) continue;\r
                \r
@@ -474,34 +479,38 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
                        ncount = nvectorcount[i] - j;\r
                        if (ncount > 5) ncount = 5; \r
 \r
-                       ack.arg[0] = 0; // isEOF = 0\r
-                       ack.arg[1] = ncount;\r
-                       ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
-                       memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+//                     ack.arg[0] = 0; // isEOF = 0\r
+//                     ack.arg[1] = ncount;\r
+//                     ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
+//                     memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
                        \r
-                       memcpy(ack.d.asBytes, &cuid, 4);\r
+      byte_t buf[48];\r
+      memset(buf, 0x00, sizeof(buf));\r
+                       memcpy(buf, &cuid, 4);\r
                        for (m = 0; m < ncount; m++) {\r
-                               memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
-                               memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
+                               memcpy(buf + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
+                               memcpy(buf + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
                        }\r
        \r
                        LED_B_ON();\r
-                       SpinDelay(100);\r
-                       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
-                       LED_B_OFF();    \r
+//                     SpinDelay(100);\r
+      cmd_send(CMD_ACK,0,ncount,targetBlockNo + (targetKeyType * 0x100),buf,48);\r
+//                     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+                       LED_B_OFF();\r
                }\r
        }\r
 \r
        // finalize list\r
-       ack.arg[0] = 1; // isEOF = 1\r
-       ack.arg[1] = 0;\r
-       ack.arg[2] = 0;\r
-       memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+//     ack.arg[0] = 1; // isEOF = 1\r
+//     ack.arg[1] = 0;\r
+//     ack.arg[2] = 0;\r
+//     memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
        \r
        LED_B_ON();\r
-       SpinDelay(300);\r
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
-       LED_B_OFF();    \r
+//     SpinDelay(300);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+  cmd_send(CMD_ACK,1,0,0,0,0);\r
+       LED_B_OFF();\r
 \r
        if (MF_DBGLEVEL >= 4)   DbpString("NESTED FINISHED");\r
 \r
@@ -538,7 +547,7 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        MF_DBGLEVEL = MF_DBG_NONE;\r
        \r
        // clear trace\r
-       iso14a_clear_tracelen();\r
+       iso14a_clear_trace();\r
   iso14a_set_tracing(TRUE);\r
 \r
        iso14443a_setup();\r
@@ -574,11 +583,12 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        memset(uid, 0x44, 4);\r
        LogTrace(uid, 4, 0, 0, TRUE);\r
 \r
-       UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
-       if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
+//     UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+//     if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
        \r
        LED_B_ON();\r
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+    cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
        LED_B_OFF();\r
 \r
   // Thats it...\r
@@ -611,12 +621,14 @@ void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
 }\r
 \r
 void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
-       UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
+//     UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
 \r
-       emlGetMem(ack.d.asBytes, arg0, arg1); // data, block num, blocks count\r
+  byte_t buf[48];\r
+       emlGetMem(buf, arg0, arg1); // data, block num, blocks count\r
 \r
        LED_B_ON();\r
-       UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+  cmd_send(CMD_ACK,arg0,arg1,0,buf,48);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
        LED_B_OFF();\r
 }\r
 \r
@@ -640,7 +652,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        uint8_t uid[8];\r
 \r
        // clear trace\r
-       iso14a_clear_tracelen();\r
+       iso14a_clear_trace();\r
        iso14a_set_tracing(false);\r
        \r
        iso14443a_setup();\r
@@ -725,3 +737,245 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 // \r
 //-----------------------------------------------------------------------------\r
 \r
+\r
+//-----------------------------------------------------------------------------\r
+// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
+// \r
+//-----------------------------------------------------------------------------\r
+void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+  \r
+  // params\r
+       uint8_t needWipe = arg0;\r
+       // bit 0 - need get UID\r
+       // bit 1 - need wupC\r
+       // bit 2 - need HALT after sequence\r
+       // bit 3 - need init FPGA and field before sequence\r
+       // bit 4 - need reset FPGA and LED\r
+       uint8_t workFlags = arg1;\r
+       uint8_t blockNo = arg2;\r
+       \r
+       // card commands\r
+       uint8_t wupC1[]       = { 0x40 }; \r
+       uint8_t wupC2[]       = { 0x43 }; \r
+       uint8_t wipeC[]       = { 0x41 }; \r
+       \r
+       // variables\r
+       byte_t isOK = 0;\r
+       uint8_t uid[8];\r
+       uint8_t d_block[18];\r
+       uint32_t cuid;\r
+       \r
+       memset(uid, 0x00, 8);\r
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+       \r
+       if (workFlags & 0x08) {\r
+               // clear trace\r
+               iso14a_clear_trace();\r
+               iso14a_set_tracing(TRUE);\r
+\r
+               iso14443a_setup();\r
+\r
+               LED_A_ON();\r
+               LED_B_OFF();\r
+               LED_C_OFF();\r
+       \r
+               SpinDelay(300);\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               SpinDelay(100);\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+       }\r
+\r
+       while (true) {\r
+               // get UID from chip\r
+               if (workFlags & 0x01) {\r
+                       if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
+                               break;\r
+                       };\r
+\r
+                       if(mifare_classic_halt(NULL, cuid)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                               break;\r
+                       };\r
+               };\r
+       \r
+               // reset chip\r
+               if (needWipe){\r
+      ReaderTransmitBitsPar(wupC1,7,0);\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
+                               break;\r
+                       };\r
+\r
+                       ReaderTransmit(wipeC, sizeof(wipeC));\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wipeC error");\r
+                               break;\r
+                       };\r
+\r
+                       if(mifare_classic_halt(NULL, cuid)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                               break;\r
+                       };\r
+               };      \r
+\r
+               // write block\r
+               if (workFlags & 0x02) {\r
+      ReaderTransmitBitsPar(wupC1,7,0);\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
+                               break;\r
+                       };\r
+\r
+                       ReaderTransmit(wupC2, sizeof(wupC2));\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
+                               break;\r
+                       };\r
+               }\r
+\r
+               if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("write block send command error");\r
+                       break;\r
+               };\r
+       \r
+               memcpy(d_block, datain, 16);\r
+               AppendCrc14443a(d_block, 16);\r
+       \r
+               ReaderTransmit(d_block, sizeof(d_block));\r
+               if ((ReaderReceive(receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("write block send data error");\r
+                       break;\r
+               };      \r
+       \r
+               if (workFlags & 0x04) {\r
+                       if (mifare_classic_halt(NULL, cuid)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                               break;\r
+                       };\r
+               }\r
+               \r
+               isOK = 1;\r
+               break;\r
+       }\r
+       \r
+//     UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+//     if (isOK) memcpy(ack.d.asBytes, uid, 4);\r
+       \r
+       // add trace trailer\r
+       /**\r
+       *       Removed by Martin, the uid is overwritten with 0x44, \r
+       *       which can 't be intended. \r
+       *\r
+       *       memset(uid, 0x44, 4);\r
+       *       LogTrace(uid, 4, 0, 0, TRUE);\r
+       **/\r
+       \r
+\r
+       LED_B_ON();\r
+  cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();\r
+\r
+       if ((workFlags & 0x10) || (!isOK)) {\r
+               // Thats it...\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               LEDsoff();\r
+       }\r
+}\r
+\r
+void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+  \r
+  // params\r
+       // bit 1 - need wupC\r
+       // bit 2 - need HALT after sequence\r
+       // bit 3 - need init FPGA and field before sequence\r
+       // bit 4 - need reset FPGA and LED\r
+       uint8_t workFlags = arg0;\r
+       uint8_t blockNo = arg2;\r
+       \r
+       // card commands\r
+       uint8_t wupC1[]       = { 0x40 }; \r
+       uint8_t wupC2[]       = { 0x43 }; \r
+       \r
+       // variables\r
+       byte_t isOK = 0;\r
+       uint8_t data[18];\r
+       uint32_t cuid = 0;\r
+       \r
+       memset(data, 0x00, 18);\r
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
+       \r
+       if (workFlags & 0x08) {\r
+               // clear trace\r
+               iso14a_clear_trace();\r
+               iso14a_set_tracing(TRUE);\r
+\r
+               iso14443a_setup();\r
+\r
+               LED_A_ON();\r
+               LED_B_OFF();\r
+               LED_C_OFF();\r
+       \r
+               SpinDelay(300);\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               SpinDelay(100);\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+       }\r
+\r
+       while (true) {\r
+               if (workFlags & 0x02) {\r
+      ReaderTransmitBitsPar(wupC1,7,0);\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
+                               break;\r
+                       };\r
+\r
+                       ReaderTransmit(wupC2, sizeof(wupC2));\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
+                               break;\r
+                       };\r
+               }\r
+\r
+               // read block\r
+               if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer) != 18)) {\r
+                       if (MF_DBGLEVEL >= 1)   Dbprintf("read block send command error");\r
+                       break;\r
+               };\r
+               memcpy(data, receivedAnswer, 18);\r
+               \r
+               if (workFlags & 0x04) {\r
+                       if (mifare_classic_halt(NULL, cuid)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                               break;\r
+                       };\r
+               }\r
+               \r
+               isOK = 1;\r
+               break;\r
+       }\r
+       \r
+//     UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+//     if (isOK) memcpy(ack.d.asBytes, data, 18);\r
+       \r
+       // add trace trailer\r
+       /*\r
+       * Removed by Martin, this piece of overwrites the 'data' variable \r
+       * which is sent two lines down, and is obviously not correct. \r
+       * \r
+       * memset(data, 0x44, 4);\r
+       * LogTrace(data, 4, 0, 0, TRUE);\r
+       */\r
+       LED_B_ON();\r
+  cmd_send(CMD_ACK,isOK,0,0,data,18);\r
+//     UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+       LED_B_OFF();\r
+\r
+       if ((workFlags & 0x10) || (!isOK)) {\r
+               // Thats it...\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               LEDsoff();\r
+       }\r
+}\r
+\r
Impressum, Datenschutz