]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iclass.c
More work on iclass simulation attack
[proxmark3-svn] / armsrc / iclass.c
index 7474598b6168a7fd78203c3c3c2265e8ea7f4ba9..be27aa3ad6d11ed9f13fd8c2b7f4c7e22a3624bc 100644 (file)
@@ -954,7 +954,7 @@ static void CodeIClassTagSOF()
        // Convert from last byte pos to length
        ToSendMax++;
 }
-
+int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf);
 /**
  * @brief SimulateIClass simulates an iClass card.
  * @param arg0 type of simulation
@@ -977,37 +977,42 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
        iso14a_clear_trace();
 
        uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
-
        if(simType == 0) {
                // Use the CSN from commandline
                memcpy(csn_crc, datain, 8);
-               doIClassSimulation(csn_crc,0);
+               doIClassSimulation(csn_crc,0,NULL);
        }else if(simType == 1)
        {
-               doIClassSimulation(csn_crc,0);
+               doIClassSimulation(csn_crc,0,NULL);
        }
        else if(simType == 2)
        {
+
+               uint8_t mac_responses[64] = { 0 };
                Dbprintf("Going into attack mode");
                // In this mode, a number of csns are within datain. We'll simulate each one, one at a time
                // in order to collect MAC's from the reader. This can later be used in an offlne-attack
                // in order to obtain the keys, as in the "dismantling iclass"-paper.
-               for(int i = 0 ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++)
+               int i = 0;
+               for( ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++)
                {
                        // The usb data is 512 bytes, fitting 65 8-byte CSNs in there.
 
                        memcpy(csn_crc, datain+(i*8), 8);
-                       if(doIClassSimulation(csn_crc,1))
+                       if(doIClassSimulation(csn_crc,1,mac_responses))
                        {
                                return; // Button pressed
                        }
                }
+               cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
+
        }
        else{
                // We may want a mode here where we hardcode the csns to use (from proxclone).
                // That will speed things up a little, but not required just yet.
                Dbprintf("The mode is not implemented, reserved for future use");
        }
+       Dbprintf("Done...");
 
 }
 /**
@@ -1015,7 +1020,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
  * @param csn - csn to use
  * @param breakAfterMacReceived if true, returns after reader MAC has been received.
  */
-int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
+int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf)
 {
 
        // CSN followed by two CRC bytes
@@ -1090,6 +1095,13 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
        CodeIClassTagAnswer(response4, sizeof(response4));
        memcpy(resp4, ToSend, ToSendMax); resp4Len = ToSendMax;
 
+
+       // Start from off (no field generated)
+       //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       //SpinDelay(200);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
+       SpinDelay(100);
+       StartCountSspClk();
        // We need to listen to the high-frequency, peak-detected path.
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaSetupSsc();
@@ -1101,17 +1113,27 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
        uint32_t r2t_time =0;
 
        LED_A_ON();
-       bool displayDebug = true;
        bool buttonPressed = false;
+
+       /** Hack  for testing
+       memcpy(reader_mac_buf,csn,8);
+       exitLoop = true;
+       end hack **/
+
        while(!exitLoop) {
-               displayDebug = true;
 
                LED_B_OFF();
+               //Signal tracer
+               // Can be used to get a trigger for an oscilloscope..
+               LED_C_OFF();
+
                if(!GetIClassCommandFromReader(receivedCmd, &len, 100)) {
                        buttonPressed = true;
                        break;
                }
                r2t_time = GetCountSspClk();
+               //Signal tracer
+               LED_C_ON();
 
                // Okay, look at the command now.
                if(receivedCmd[0] == 0x0a ) {
@@ -1119,13 +1141,11 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
                        resp = resp1; respLen = resp1Len; //order = 1;
                        respdata = &sof;
                        respsize = sizeof(sof);
-                       displayDebug = false;
                } else if(receivedCmd[0] == 0x0c) {
                        // Reader asks for anticollission CSN
                        resp = resp2; respLen = resp2Len; //order = 2;
                        respdata = response2;
                        respsize = sizeof(response2);
-                       //displayDebug = false;
                        //DbpString("Reader requests anticollission CSN:");
                } else if(receivedCmd[0] == 0x81) {
                        // Reader selects anticollission CSN.
@@ -1150,11 +1170,15 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
                        if (breakAfterMacReceived){
                                // TODO, actually return this to the caller instead of just
                                // dbprintf:ing ...
-                               Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x");
+                               Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x",csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]);
                                Dbprintf("RDR:  (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len,
                                                 receivedCmd[0], receivedCmd[1], receivedCmd[2],
                                                receivedCmd[3], receivedCmd[4], receivedCmd[5],
                                                receivedCmd[6], receivedCmd[7], receivedCmd[8]);
+                               if (reader_mac_buf != NULL)
+                               {
+                                       memcpy(reader_mac_buf,receivedCmd+1,8);
+                               }
                                exitLoop = true;
                        }
                } else if(receivedCmd[0] == 0x00 && len == 1) {
@@ -1178,7 +1202,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
 
                if(cmdsRecvd >  100) {
                        //DbpString("100 commands later...");
-                       break;
+                       //break;
                }
                else {
                        cmdsRecvd++;
@@ -1187,29 +1211,13 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
                if(respLen > 0) {
                        SendIClassAnswer(resp, respLen, 21);
                        t2r_time = GetCountSspClk();
-
-//                     }
-                       if(displayDebug) Dbprintf("R2T:(len=%d): %x %x %x %x %x %x %x %x %x\nT2R: (total/data =%d/%d): %x %x %x %x %x %x %x %x %x",
-                       len,
-                       receivedCmd[0], receivedCmd[1], receivedCmd[2],
-                       receivedCmd[3], receivedCmd[4], receivedCmd[5],
-                       receivedCmd[6], receivedCmd[7], receivedCmd[8],
-                       respLen,respsize,
-                       resp[0], resp[1], resp[2],
-                       resp[3], resp[4], resp[5],
-                       resp[6], resp[7], resp[8]);
-
                }
 
                if (tracing) {
-                       //LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE);
-
                        LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, Uart.parityBits,TRUE);
                        LogTrace(NULL,0, (r2t_time-time_0) << 4, 0,TRUE);
 
                        if (respdata != NULL) {
-                               //LogTrace(respdata,respsize, rsamples, SwapBits(GetParity(respdata,respsize),respsize), FALSE);
-                               //if(!LogTrace(resp,respLen, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE))
                                LogTrace(respdata,respsize, (t2r_time-time_0) << 4,SwapBits(GetParity(respdata,respsize),respsize),FALSE);
                                LogTrace(NULL,0, (t2r_time-time_0) << 4,0,FALSE);
 
@@ -1224,7 +1232,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
                memset(receivedCmd, 0x44, RECV_CMD_SIZE);
        }
 
-       Dbprintf("%x", cmdsRecvd);
+       //Dbprintf("%x", cmdsRecvd);
        LED_A_OFF();
        LED_B_OFF();
        if(buttonPressed)
@@ -1236,41 +1244,34 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived)
 
 static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
 {
-       int i = 0, u = 0, d = 0;
+       int i = 0, d=0;//, u = 0, d = 0;
        uint8_t b = 0;
-       // return 0;
-       // Modulate Manchester
-       // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD424);
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
+
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
+
        AT91C_BASE_SSC->SSC_THR = 0x00;
        FpgaSetupSsc();
-       
-       // send cycle
-       for(;;) {
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-                       (void)b;
+       while(!BUTTON_PRESS()) {
+               if((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)){
+                       b = AT91C_BASE_SSC->SSC_RHR; (void) b;
                }
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)){
+                       b = 0x00;
                        if(d < delay) {
-                               b = 0x00;
                                d++;
                        }
-                       else if(i >= respLen) {
-                               b = 0x00;
-                               u++;
-                       } else {
-                               b = resp[i];
-                               u++;
-                               if(u > 1) { i++; u = 0; }
+                       else {
+                               if( i < respLen){
+                                       b = resp[i];
+                                       //Hack
+                                       //b = 0xAC;
+                               }
+                               i++;
                        }
                        AT91C_BASE_SSC->SSC_THR = b;
-
-                       if(u > 4) break;
-               }
-               if(BUTTON_PRESS()) {
-                       break;
                }
+
+               if (i > respLen +4) break;
        }
 
        return 0;
@@ -1284,7 +1285,6 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
 static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait)
 {
   int c;
-
   FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
   AT91C_BASE_SSC->SSC_THR = 0x00;
   FpgaSetupSsc();
@@ -1360,12 +1360,12 @@ void CodeIClassCommand(const uint8_t * cmd, int len)
     b = cmd[i];
     for(j = 0; j < 4; j++) {
       for(k = 0; k < 4; k++) {
-       if(k == (b & 3)) {
-           ToSend[++ToSendMax] = 0x0f;
-       }
-       else {
-           ToSend[++ToSendMax] = 0x00;
-       }
+                       if(k == (b & 3)) {
+                               ToSend[++ToSendMax] = 0x0f;
+                       }
+                       else {
+                               ToSend[++ToSendMax] = 0x00;
+                       }
       }
       b >>= 2;
     }
Impressum, Datenschutz