]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
integrated MIFARE ultralight features, contributed by 'midnitesnake'
authorroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Fri, 11 Oct 2013 08:43:23 +0000 (08:43 +0000)
committerroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Fri, 11 Oct 2013 08:43:23 +0000 (08:43 +0000)
armsrc/appmain.c
armsrc/apps.h
armsrc/iso14443a.c
armsrc/mifarecmd.c
armsrc/mifareutil.c
armsrc/mifareutil.h
client/cmdhfmf.c
client/cmdhfmf.h
client/proxmark3.c
include/usb_cmd.h

index b5a85deba690cef7d98e0a4629a16b4d163f218b..3f309520ef6bf991b8d5640c53d176abf51a8a14 100644 (file)
@@ -782,12 +782,24 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_MIFARE_READBL:
                        MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_READBL:
                        MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
+               case CMD_MIFAREU_READBL:
+                       MifareUReadBlock(c->arg[0],c->d.asBytes);
+                       break;
+               case CMD_MIFAREU_READCARD:
+                       MifareUReadCard(c->arg[0],c->d.asBytes);
+                        break;
                case CMD_MIFARE_READSC:
                        MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_WRITEBL:
                        MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_READSC:
                        MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_WRITEBL:
                        MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
+               case CMD_MIFAREU_WRITEBL_COMPAT:
+                       MifareUWriteBlock(c->arg[0], c->d.asBytes);
+                        break;
+               case CMD_MIFAREU_WRITEBL:
+                        MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
+                        break;
                case CMD_MIFARE_NESTED:
                        MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
                case CMD_MIFARE_NESTED:
                        MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
                        break;
index c0faaca2a0dada3811b7bf9c2cf60413812f9c1b..4e99b1aa58561c2f6c37d33b43a9e7545d1d2ce8 100644 (file)
@@ -158,8 +158,12 @@ void EPA_PACE_Collect_Nonce(UsbCommand * c);
 void ReaderMifare(bool first_try);
 int32_t dist_nt(uint32_t nt1, uint32_t nt2);
 void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
 void ReaderMifare(bool first_try);
 int32_t dist_nt(uint32_t nt1, uint32_t nt2);
 void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
+void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
+void MifareUReadCard(uint8_t arg0,uint8_t *datain);
 void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
+void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
+void MifareUWriteBlock_Special(uint8_t arg0,uint8_t *datain);
 void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
index b3316ef0b637b617c707c2eb9017eab0ec8807fa..63cc32aecf9761a29836139dcd9bc42603789fda 100644 (file)
@@ -1604,7 +1604,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, int maxLen, int
 
 void ReaderTransmitBitsPar(uint8_t* frame, int bits, uint32_t par, uint32_t *timing)
 {
 
 void ReaderTransmitBitsPar(uint8_t* frame, int bits, uint32_t par, uint32_t *timing)
 {
+
   CodeIso14443aBitsAsReaderPar(frame,bits,par);
   
   // Select the card
   CodeIso14443aBitsAsReaderPar(frame,bits,par);
   
   // Select the card
index 91ae90549b118de7da308c9357ec12cf3d3ce073..cbad7a905b890cda71c5df2f7afca34570121b02 100644 (file)
@@ -91,12 +91,66 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 //  iso14a_set_tracing(TRUE);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 //  iso14a_set_tracing(TRUE);\r
-\r
-}\r
-\r
-//-----------------------------------------------------------------------------\r
-// Select, Authenticaate, Read an MIFARE tag. \r
-// read sector (data = 4 x 16 bytes = 64 bytes)\r
+
+}
+
+void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
+{
+    // params
+       uint8_t blockNo = arg0;
+       
+       // variables
+       byte_t isOK = 0;
+       byte_t dataoutbuf[16];
+       uint8_t uid[10];
+       uint32_t cuid;
+    
+       // clear trace
+       iso14a_clear_trace();
+       iso14443a_setup();
+    
+       LED_A_ON();
+       LED_B_OFF();
+       LED_C_OFF();
+    
+       while (true) {
+               if(!iso14443a_select_card(uid, NULL, &cuid)) {
+            if (MF_DBGLEVEL >= 1)      Dbprintf("Can't select card");
+                       break;
+               };
+        
+               if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {
+            if (MF_DBGLEVEL >= 1)      Dbprintf("Read block error");
+                       break;
+               };
+        
+               if(mifare_ultra_halt(cuid)) {
+            if (MF_DBGLEVEL >= 1)      Dbprintf("Halt error");
+                       break;
+               };
+               
+               isOK = 1;
+               break;
+       }
+       
+       if (MF_DBGLEVEL >= 2)   DbpString("READ BLOCK FINISHED");
+    
+       // add trace trailer
+       memset(uid, 0x44, 4);
+       LogTrace(uid, 4, 0, 0, TRUE);
+       LED_B_ON();
+        cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
+       LED_B_OFF();
+    
+    
+    // Thats it...
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       LEDsoff();
+}
+
+//-----------------------------------------------------------------------------
+// Select, Authenticaate, Read an MIFARE tag. 
+// read sector (data = 4 x 16 bytes = 64 bytes)
 //-----------------------------------------------------------------------------\r
 void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
 {\r
 //-----------------------------------------------------------------------------\r
 void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
 {\r
@@ -188,12 +242,72 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 //  iso14a_set_tracing(TRUE);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 //  iso14a_set_tracing(TRUE);\r
-\r
-}\r
-\r
-//-----------------------------------------------------------------------------\r
-// Select, Authenticaate, Read an MIFARE tag. \r
-// read block\r
+
+}
+
+void MifareUReadCard(uint8_t arg0, uint8_t *datain)
+{
+  // params
+        uint8_t sectorNo = arg0;
+        
+        // variables
+        byte_t isOK = 0;
+        byte_t dataoutbuf[16 * 4];
+        uint8_t uid[10];
+        uint32_t cuid;
+
+        // clear trace
+        iso14a_clear_trace();
+//      iso14a_set_tracing(false);
+
+        iso14443a_setup();
+
+        LED_A_ON();
+        LED_B_OFF();
+        LED_C_OFF();
+
+        while (true) {
+                if(!iso14443a_select_card(uid, NULL, &cuid)) {
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
+                        break;
+                };
+               for(int sec=0;sec<16;sec++){
+                    if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {
+                    if (MF_DBGLEVEL >= 1)   Dbprintf("Read block %d error",sec);
+                        break;
+                    };
+                }
+                if(mifare_ultra_halt(cuid)) {
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
+                        break;
+                };
+
+                isOK = 1;
+                break;
+        }
+        
+        if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
+
+        // add trace trailer
+        memset(uid, 0x44, 4);
+        LogTrace(uid, 4, 0, 0, TRUE);
+        
+        LED_B_ON();
+  cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
+  //cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
+        LED_B_OFF();
+
+        // Thats it...
+        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+        LEDsoff();
+//  iso14a_set_tracing(TRUE);
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Select, Authenticaate, Read an MIFARE tag. 
+// read block
 //-----------------------------------------------------------------------------\r
 void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
 {\r
 //-----------------------------------------------------------------------------\r
 void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
 {\r
@@ -270,12 +384,137 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 //  iso14a_set_tracing(TRUE);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 //  iso14a_set_tracing(TRUE);\r
-\r
-}\r
-\r
-// Return 1 if the nonce is invalid else return 0\r
-int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {\r
-       return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \\r
+
+}
+
+void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
+{
+        // params
+        uint8_t blockNo = arg0;
+        byte_t blockdata[16];
+
+        memset(blockdata,'\0',16);
+        memcpy(blockdata, datain,16);
+        
+        // variables
+        byte_t isOK = 0;
+        uint8_t uid[10];
+        uint32_t cuid;
+
+        // clear trace
+        iso14a_clear_trace();
+       //  iso14a_set_tracing(false);
+
+        iso14443a_setup();
+
+        LED_A_ON();
+        LED_B_OFF();
+        LED_C_OFF();
+
+        while (true) {
+                if(!iso14443a_select_card(uid, NULL, &cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
+                        break;
+                };
+
+                if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");
+                        break;
+                };
+
+                if(mifare_ultra_halt(cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
+                        break;
+                };
+                
+                isOK = 1;
+                break;
+        }
+        
+        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");
+
+        // add trace trailer
+        memset(uid, 0x44, 4);
+        LogTrace(uid, 4, 0, 0, TRUE);
+
+        LED_B_ON();
+       cmd_send(CMD_ACK,isOK,0,0,0,0);
+//      UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+        LED_B_OFF();
+
+
+        // Thats it...
+        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+        LEDsoff();
+//  iso14a_set_tracing(TRUE);
+
+}
+
+void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
+{
+        // params
+        uint8_t blockNo = arg0;
+        byte_t blockdata[4];
+        
+       memcpy(blockdata, datain,4);
+
+        // variables
+        byte_t isOK = 0;
+        uint8_t uid[10];
+        uint32_t cuid;
+
+        // clear trace
+        iso14a_clear_trace();
+        //  iso14a_set_tracing(false);
+
+        iso14443a_setup();
+
+        LED_A_ON();
+        LED_B_OFF();
+        LED_C_OFF();
+
+        while (true) {
+                        if(!iso14443a_select_card(uid, NULL, &cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");
+                        break;
+                };
+
+                if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Write block error");
+                        break;
+                };
+
+                if(mifare_ultra_halt(cuid)) {
+                        if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");
+                        break;
+                };
+
+                isOK = 1;
+                break;
+        }
+
+        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");
+
+        // add trace trailer
+       memset(uid, 0x44, 4);
+        LogTrace(uid, 4, 0, 0, TRUE);
+
+       LED_B_ON();
+        cmd_send(CMD_ACK,isOK,0,0,0,0);
+//      UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+        LED_B_OFF();
+
+
+        // Thats it...
+        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+        LEDsoff();
+//  iso14a_set_tracing(TRUE);
+
+}
+
+// Return 1 if the nonce is invalid else return 0
+int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
+       return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
        (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \\r
        (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;\r
 }\r
        (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \\r
        (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;\r
 }\r
index 4f4e978c0a4a493e80848e077a652d2a65184c58..b847043bbd8a00237e54a77a4080ac383f9705fb 100644 (file)
@@ -79,12 +79,38 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
 // send commands\r
 int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing)\r
 {\r
 // send commands\r
 int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing)\r
 {\r
-       return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, NULL, timing);\r
-}\r
-\r
-int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing)\r
-{\r
-       uint8_t dcmd[4], ecmd[4];\r
+       return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, NULL, timing);
+}
+
+int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *timing)
+{
+        uint8_t dcmd[8];//, ecmd[4];
+        //uint32_t par=0;
+
+        dcmd[0] = cmd;
+        dcmd[1] = data[0];
+       dcmd[2] = data[1];
+       dcmd[3] = data[2];
+       dcmd[4] = data[3];
+       dcmd[5] = data[4];
+       AppendCrc14443a(dcmd, 6);
+       //Dbprintf("Data command: %02x", dcmd[0]);
+       //Dbprintf("Data R: %02x %02x %02x %02x %02x %02x %02x", dcmd[1],dcmd[2],dcmd[3],dcmd[4],dcmd[5],dcmd[6],dcmd[7]);
+
+        //memcpy(ecmd, dcmd, sizeof(dcmd));
+       ReaderTransmit(dcmd, sizeof(dcmd), NULL);
+       int len = ReaderReceive(answer);
+       if(!len)
+       {
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Authentication failed. Card timeout.");
+                return 2;
+        }
+       return len;
+}
+
+int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing)
+{
+       uint8_t dcmd[4], ecmd[4];
        uint32_t pos, par, res;\r
 \r
        dcmd[0] = cmd;\r
        uint32_t pos, par, res;\r
 \r
        dcmd[0] = cmd;\r
@@ -253,12 +279,43 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
        }\r
        \r
        memcpy(blockData, receivedAnswer, 16);\r
        }\r
        \r
        memcpy(blockData, receivedAnswer, 16);\r
-       return 0;\r
-}\r
-\r
-int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) \r
-{\r
-       // variables\r
+       return 0;
+}
+
+int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
+{
+       // variables
+       int len;
+       uint8_t bt[2];
+       
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();
+       
+       // command MIFARE_CLASSIC_READBLOCK
+       len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer,NULL);
+       if (len == 1) {
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
+               return 1;
+       }
+       if (len != 18) {
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Cmd Error: card timeout. len: %x", len);
+               return 2;
+       }
+    
+       memcpy(bt, receivedAnswer + 16, 2);
+       AppendCrc14443a(receivedAnswer, 16);
+       if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
+               if (MF_DBGLEVEL >= 1)   Dbprintf("Cmd CRC response error.");
+               return 3;
+       }
+       
+       memcpy(blockData, receivedAnswer, 14);
+       return 0;
+}
+
+
+int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) 
+{
+       // variables
        int len, i;     \r
        uint32_t pos;\r
        uint32_t par = 0;\r
        int len, i;     \r
        uint32_t pos;\r
        uint32_t par = 0;\r
@@ -300,12 +357,71 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
                return 2;\r
        }\r
        \r
                return 2;\r
        }\r
        \r
-       return 0;\r
-}\r
-\r
-int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) \r
-{\r
-       // variables\r
+       return 0;
+}
+
+int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) 
+{
+        // variables
+        int len;     
+        uint32_t par = 0;
+        
+        uint8_t d_block[18];
+        uint8_t* receivedAnswer = mifare_get_bigbufptr();
+        
+        // command MIFARE_CLASSIC_WRITEBLOCK
+        len = mifare_sendcmd_short(NULL, 1, 0xA0, blockNo, receivedAnswer,NULL);
+
+        if ((len != 1) || (receivedAnswer[0] != 0x0A)) {   //  0x0a - ACK
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);  
+                return 1;
+        }
+
+       memset(d_block,'\0',18);
+       memcpy(d_block, blockData, 16);
+        AppendCrc14443a(d_block, 16);
+
+       ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
+
+        // Receive the response
+        len = ReaderReceive(receivedAnswer);    
+
+       if ((len != 1) || (receivedAnswer[0] != 0x0A)) {   //  0x0a - ACK
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
+                return 2;
+        }        
+
+        return 0;
+} 
+
+int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
+{
+        // variables
+        int len;
+        //uint32_t par = 0;
+
+        uint8_t d_block[8];
+        uint8_t* receivedAnswer = mifare_get_bigbufptr();
+
+        // command MIFARE_CLASSIC_WRITEBLOCK
+       memset(d_block,'\0',8);
+       d_block[0]= blockNo;
+       memcpy(d_block+1,blockData,4);
+       AppendCrc14443a(d_block, 6);
+
+       //i know the data send here is correct
+        len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer,NULL);
+
+        if (receivedAnswer[0] != 0x0A) {   //  0x0a - ACK
+                if (MF_DBGLEVEL >= 1)   Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
+                return 1;
+        }
+        return 0;
+}
+
+int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) 
+{
+       // variables
        int len;        \r
        \r
        // Mifare HALT\r
        int len;        \r
        \r
        // Mifare HALT\r
@@ -317,12 +433,29 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
                return 1;\r
        }\r
 \r
                return 1;\r
        }\r
 \r
-       return 0;\r
-}\r
-\r
-// work with emulator memory\r
-void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {\r
-       uint8_t* emCARD = eml_get_bigbufptr_cardmem();\r
+       return 0;
+}
+
+int mifare_ultra_halt(uint32_t uid)
+{
+       // variables
+       int len;
+       
+       // Mifare HALT
+       uint8_t* receivedAnswer = mifare_get_bigbufptr();
+    
+       len = mifare_sendcmd_short(NULL, 1, 0x50, 0x00, receivedAnswer, NULL);
+       if (len != 0) {
+               if (MF_DBGLEVEL >= 1)   Dbprintf("halt error. response len: %x", len);
+               return 1;
+       }
+    
+       return 0;
+}
+
+// work with emulator memory
+void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
+       uint8_t* emCARD = eml_get_bigbufptr_cardmem();
        \r
        memcpy(emCARD + blockNum * 16, data, blocksCount * 16);\r
 }\r
        \r
        memcpy(emCARD + blockNum * 16, data, blocksCount * 16);\r
 }\r
index d170f3c69dee212d43663491def536af9dc95aa1..ad637ea02fd790492be2c26480bd3d982f9d469d 100644 (file)
@@ -52,21 +52,26 @@ extern int MF_DBGLEVEL;
 \r
 #define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();\r
 \r
 \r
 #define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();\r
 \r
-//functions\r
-uint8_t* mifare_get_bigbufptr(void);\r
-int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing);\r
-int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing);\r
-\r
-int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, \\r
+//functions
+uint8_t* mifare_get_bigbufptr(void);
+int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing);
+int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* amswer, uint8_t *timing);
+int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing);
+
+int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, \
                                                                                                uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested);\r
                                                                                                uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested);\r
-int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, \\r
-                                                                                                       uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested, uint32_t * ntptr, uint32_t *timing);\r
-int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); \r
-int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);\r
-int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); \r
-\r
-// crypto functions\r
-void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);\r
+int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, \
+                                                                                                       uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested, uint32_t * ntptr, uint32_t *timing);
+int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); 
+int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
+int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
+int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
+int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
+int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); 
+int mifare_ultra_halt(uint32_t uid);
+
+// crypto functions
+void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
 void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, int len, uint32_t *par);\r
 uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);\r
 \r
 void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, int len, uint32_t *par);\r
 uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);\r
 \r
@@ -82,7 +87,7 @@ void emlGetMem(uint8_t *data, int blockNum, int blocksCount);
 void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount);\r
 uint64_t emlGetKey(int sectorNum, int keyType);\r
 int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum);\r
 void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount);\r
 uint64_t emlGetKey(int sectorNum, int keyType);\r
 int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum);\r
-int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);\r
-int emlCheckValBl(int blockNum);\r
-\r
-#endif
\ No newline at end of file
+int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);
+int emlCheckValBl(int blockNum);
+
+#endif
index a0e671609acf3b5831588f7e75406063e40ddccb..74382886bafcd8d16076aaeed0cc3f6e3a0007f5 100644 (file)
@@ -137,12 +137,86 @@ int CmdHF14AMfWrBl(const char *Cmd)
                PrintAndLog("Command execute timeout");\r
        }\r
 \r
                PrintAndLog("Command execute timeout");\r
        }\r
 \r
-       return 0;\r
-}\r
-\r
-int CmdHF14AMfRdBl(const char *Cmd)\r
-{\r
-       uint8_t blockNo = 0;\r
+       return 0;
+}
+
+int CmdHF14AMfUWrBl(const char *Cmd)
+{
+        uint8_t blockNo = 0;
+        uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+       UsbCommand resp;
+        
+        if (strlen(Cmd)<3) {
+                PrintAndLog("Usage:  hf mf uwrbl    <block number> <block data (8 hex symbols)>");
+                PrintAndLog("        sample: hf mf uwrbl 0 01020304");
+                return 0;
+        }       
+
+        blockNo = param_get8(Cmd, 0);
+        if (param_gethex(Cmd, 1, bldata, 8)) {
+                PrintAndLog("Block data must include 8 HEX symbols");
+                return 1;
+        }
+
+       switch(blockNo)
+       {
+       case 0:
+               PrintAndLog("Access Denied");
+               break;
+       case 1:
+               PrintAndLog("Access Denied");
+               break;
+       case 2:
+               PrintAndLog("--specialblock no:%02x", blockNo);
+                PrintAndLog("--data: %s", sprint_hex(bldata, 4));
+                UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
+                memcpy(c.d.asBytes, bldata, 4);
+                SendCommand(&c);
+
+                if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+                        uint8_t isOK  = resp.arg[0] & 0xff;
+                        PrintAndLog("isOk:%02x", isOK);
+                } else {
+                        PrintAndLog("Command execute timeout");
+                }
+               break;
+       case 3:
+               PrintAndLog("--specialblock no:%02x", blockNo);
+                PrintAndLog("--data: %s", sprint_hex(bldata, 4));
+                UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
+                memcpy(d.d.asBytes,bldata, 4);
+                SendCommand(&d);
+
+                if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+                        uint8_t isOK  = resp.arg[0] & 0xff;
+                        PrintAndLog("isOk:%02x", isOK);
+                } else {
+                        PrintAndLog("Command execute timeout");
+                }
+               break;
+       default: 
+               PrintAndLog("--block no:%02x", blockNo);
+               PrintAndLog("--data: %s", sprint_hex(bldata, 4));               
+               //UsbCommand e = {CMD_MIFAREU_WRITEBL_COMPAT, {blockNo}};
+               //memcpy(e.d.asBytes,bldata, 16);
+               UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
+                memcpy(e.d.asBytes,bldata, 4);
+               SendCommand(&e);
+
+               if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+                       uint8_t isOK  = resp.arg[0] & 0xff;
+                       PrintAndLog("isOk:%02x", isOK);
+               } else {
+                       PrintAndLog("Command execute timeout");
+               }
+               break;
+       }
+        return 0;
+}
+
+int CmdHF14AMfRdBl(const char *Cmd)
+{
+       uint8_t blockNo = 0;
        uint8_t keyType = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
        \r
        uint8_t keyType = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
        \r
@@ -185,12 +259,135 @@ int CmdHF14AMfRdBl(const char *Cmd)
                PrintAndLog("Command execute timeout");\r
        }\r
 \r
                PrintAndLog("Command execute timeout");\r
        }\r
 \r
-  return 0;\r
-}\r
-\r
-int CmdHF14AMfRdSc(const char *Cmd)\r
-{\r
-       int i;\r
+  return 0;
+}
+
+int CmdHF14AMfURdBl(const char *Cmd)
+{
+        uint8_t blockNo = 0;
+
+        if (strlen(Cmd)<1) {
+                PrintAndLog("Usage:  hf mf urdbl    <block number>");
+                PrintAndLog("        sample: hf mf urdbl 0");
+                return 0;
+        }       
+        
+        blockNo = param_get8(Cmd, 0);
+        PrintAndLog("--block no:%02x", blockNo);
+        
+  UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
+  SendCommand(&c);
+
+        UsbCommand resp;
+        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+                uint8_t                isOK  = resp.arg[0] & 0xff;
+                uint8_t              * data  = resp.d.asBytes;
+
+                if (isOK)
+                        PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
+                else
+                        PrintAndLog("isOk:%02x", isOK);
+        } else {
+                PrintAndLog("Command execute timeout");
+        }
+
+  return 0;
+}
+
+int CmdHF14AMfURdCard(const char *Cmd)
+{
+        int i;
+        uint8_t sectorNo = 0;
+       uint8_t *lockbytes_t=NULL;
+       uint8_t lockbytes[2]={0,0};
+       bool bit[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+        
+        uint8_t isOK  = 0;
+        uint8_t * data  = NULL;
+
+        if (sectorNo > 15) {
+                PrintAndLog("Sector number must be less than 16");
+                return 1;
+        }
+        PrintAndLog("Attempting to Read Ultralight... ");
+        
+       UsbCommand c = {CMD_MIFAREU_READCARD, {sectorNo}};
+       SendCommand(&c);
+
+        UsbCommand resp;
+        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+                isOK  = resp.arg[0] & 0xff;
+                data  = resp.d.asBytes;
+
+                PrintAndLog("isOk:%02x", isOK);
+                if (isOK) 
+                        for (i = 0; i < 16; i++) {
+                               switch(i){
+                                 case 2:
+                                       //process lock bytes
+                                       lockbytes_t=data+(i*4);
+                                       lockbytes[0]=lockbytes_t[2];
+                                       lockbytes[1]=lockbytes_t[3];
+                                       for(int j=0; j<16; j++){
+                                               bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
+                                       }
+                                       //PrintAndLog("LB %02x %02x", lockbytes[0],lockbytes[1]);
+                                       //PrintAndLog("LB2b %02x %02x %02x %02x %02x %02x %02x %02x",bit[8],bit[9],bit[10],bit[11],bit[12],bit[13],bit[14],bit[15]);            
+                                       PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
+                                       break;
+                                 case 3: 
+                                       PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[4]);
+                                       break;
+                                 case 4:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[3]);
+                                       break;
+                                 case 5:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[2]);
+                                       break;
+                                 case 6:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[1]);
+                                       break;
+                                 case 7:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[0]);
+                                       break;
+                                 case 8:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[15]);
+                                       break;
+                                 case 9:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[14]);
+                                       break;
+                                 case 10:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[13]);
+                                       break;
+                                 case 11:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[12]);
+                                       break;
+                                 case 12:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[11]);
+                                       break;
+                                 case 13:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[10]);
+                                       break;
+                                 case 14:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[9]);
+                                       break;
+                                 case 15:
+                                        PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[8]);
+                                       break;
+                                 default:
+                                       PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
+                                       break;
+                               }
+                        }
+        } else {
+                PrintAndLog("Command1 execute timeout");
+        }
+  return 0;
+}
+
+int CmdHF14AMfRdSc(const char *Cmd)
+{
+       int i;
        uint8_t sectorNo = 0;\r
        uint8_t keyType = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
        uint8_t sectorNo = 0;\r
        uint8_t keyType = 0;\r
        uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
@@ -1667,12 +1864,15 @@ int CmdHF14AMfSniff(const char *Cmd){
 \r
 static command_t CommandTable[] =\r
 {\r
 \r
 static command_t CommandTable[] =\r
 {\r
-  {"help",             CmdHelp,                                                1, "This help"},\r
-  {"dbg",                      CmdHF14AMfDbg,                  0, "Set default debug mode"},\r
-  {"rdbl",             CmdHF14AMfRdBl,                 0, "Read MIFARE classic block"},\r
-  {"rdsc",             CmdHF14AMfRdSc,                 0, "Read MIFARE classic sector"},\r
-  {"dump",             CmdHF14AMfDump,                 0, "Dump MIFARE classic tag to binary file"},\r
-  {"restore",  CmdHF14AMfRestore,      0, "Restore MIFARE classic binary file to BLANK tag"},\r
+  {"help",             CmdHelp,                                                1, "This help"},
+  {"dbg",                      CmdHF14AMfDbg,                  0, "Set default debug mode"},
+  {"rdbl",             CmdHF14AMfRdBl,                 0, "Read MIFARE classic block"},
+  {"urdbl",              CmdHF14AMfURdBl,                 0, "Read MIFARE Ultralight block"},
+  {"urdcard",           CmdHF14AMfURdCard,               0,"Read MIFARE Ultralight Card"},
+  {"uwrbl",            CmdHF14AMfUWrBl,                0,"Write MIFARE Ultralight block"},
+  {"rdsc",             CmdHF14AMfRdSc,                 0, "Read MIFARE classic sector"},
+  {"dump",             CmdHF14AMfDump,                 0, "Dump MIFARE classic tag to binary file"},
+  {"restore",  CmdHF14AMfRestore,      0, "Restore MIFARE classic binary file to BLANK tag"},
   {"wrbl",             CmdHF14AMfWrBl,                 0, "Write MIFARE classic block"},\r
   {"chk",                      CmdHF14AMfChk,                  0, "Test block keys"},\r
   {"mifare",   CmdHF14AMifare,                 0, "Read parity error messages. param - <used card nonce>"},\r
   {"wrbl",             CmdHF14AMfWrBl,                 0, "Write MIFARE classic block"},\r
   {"chk",                      CmdHF14AMfChk,                  0, "Test block keys"},\r
   {"mifare",   CmdHF14AMifare,                 0, "Read parity error messages. param - <used card nonce>"},\r
index 16dcccfbccbeb6f499cfd31819f430a8d1a741fb..62e856ad6209cc3e98f462e404661db104ceddce 100644 (file)
 #include "mifarehost.h"\r
 \r
 int CmdHFMF(const char *Cmd);\r
 #include "mifarehost.h"\r
 \r
 int CmdHFMF(const char *Cmd);\r
-\r
-int CmdHF14AMfDbg(const char* cmd);\r
-int CmdHF14AMfRdBl(const char* cmd);\r
-int CmdHF14AMfRdSc(const char* cmd);\r
-int CmdHF14AMfDump(const char* cmd);\r
-int CmdHF14AMfRestore(const char* cmd);\r
-int CmdHF14AMfWrBl(const char* cmd);\r
-int CmdHF14AMfChk(const char* cmd);\r
-int CmdHF14AMifare(const char* cmd);\r
-int CmdHF14AMfNested(const char* cmd);\r
+
+int CmdHF14AMfDbg(const char* cmd);
+int CmdHF14AMfRdBl(const char* cmd);
+int CmdHF14AMfURdBl(const char* cmd);
+int CmdHF14AMfRdSc(const char* cmd);
+int CmdHF14SMfURdCard(const char* cmd);
+int CmdHF14AMfDump(const char* cmd);
+int CmdHF14AMfRestore(const char* cmd);
+int CmdHF14AMfWrBl(const char* cmd);
+int CmdHF14AMfUWrBl(const char* cmd);
+int CmdHF14AMfChk(const char* cmd);
+int CmdHF14AMifare(const char* cmd);
+int CmdHF14AMfNested(const char* cmd);
 int CmdHF14AMfSniff(const char* cmd);\r
 int CmdHF14AMf1kSim(const char* cmd);\r
 int CmdHF14AMfEClear(const char* cmd);\r
 int CmdHF14AMfSniff(const char* cmd);\r
 int CmdHF14AMf1kSim(const char* cmd);\r
 int CmdHF14AMfEClear(const char* cmd);\r
index 2fefc890f1b3bf9f3cbfde738ffb454851b1c779..102e03f72473ec0004028a522eb0c0ca4018e5ae 100644 (file)
@@ -168,6 +168,7 @@ static void *main_loop(void *targ) {
                        
                        if (cmd[0] != 0x00) {
                                if (strncmp(cmd, "quit", 4) == 0) {
                        
                        if (cmd[0] != 0x00) {
                                if (strncmp(cmd, "quit", 4) == 0) {
+                                       exit(0);
                                        break;
                                }
                                
                                        break;
                                }
                                
index 8726ec67513e2982f8cbb9b473b789394f00fef3..2673dcacb6f53e68943af70e45c4758ad9221029 100644 (file)
@@ -139,8 +139,12 @@ typedef struct {
 #define CMD_MIFARE_NESTED                                                 0x0612
 
 #define CMD_MIFARE_READBL                                                 0x0620
 #define CMD_MIFARE_NESTED                                                 0x0612
 
 #define CMD_MIFARE_READBL                                                 0x0620
+#define CMD_MIFAREU_READBL                                               0x0720
 #define CMD_MIFARE_READSC                                                 0x0621
 #define CMD_MIFARE_READSC                                                 0x0621
+#define CMD_MIFAREU_READCARD                                             0x0721
 #define CMD_MIFARE_WRITEBL                                                0x0622
 #define CMD_MIFARE_WRITEBL                                                0x0622
+#define CMD_MIFAREU_WRITEBL_COMPAT                                       0x0722
+#define CMD_MIFAREU_WRITEBL                                              0x0723
 #define CMD_MIFARE_CHKKEYS                                                0x0623
 
 #define CMD_MIFARE_SNIFFER                                                0x0630
 #define CMD_MIFARE_CHKKEYS                                                0x0623
 
 #define CMD_MIFARE_SNIFFER                                                0x0630
Impressum, Datenschutz