]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iclass.c
CHG: 'lf em4x' - the em4x50 demod didn't calc ASKDemod_ext with a refenence bool.
[proxmark3-svn] / armsrc / iclass.c
index 7a68ea6bcbb478302cd05a10c2e874293dd6e2c3..f5e821cb3a8a3dabc83c9f4454b5c12a2760c7bc 100644 (file)
 //
 //-----------------------------------------------------------------------------
 
 //
 //-----------------------------------------------------------------------------
 
-#include "proxmark3.h"
 #include "apps.h"
 #include "apps.h"
-#include "util.h"
-#include "string.h"
-#include "common.h"
 #include "cmd.h"
 // Needed for CRC in emulation mode;
 // same construction as in ISO 14443;
 #include "cmd.h"
 // Needed for CRC in emulation mode;
 // same construction as in ISO 14443;
@@ -52,7 +48,6 @@
 
 static int timeout = 4096;
 
 
 static int timeout = 4096;
 
-
 static int SendIClassAnswer(uint8_t *resp, int respLen, int delay);
 
 //-----------------------------------------------------------------------------
 static int SendIClassAnswer(uint8_t *resp, int respLen, int delay);
 
 //-----------------------------------------------------------------------------
@@ -63,7 +58,7 @@ static struct {
     enum {
         STATE_UNSYNCD,
         STATE_START_OF_COMMUNICATION,
     enum {
         STATE_UNSYNCD,
         STATE_START_OF_COMMUNICATION,
-       STATE_RECEIVING
+               STATE_RECEIVING
     }       state;
     uint16_t    shiftReg;
     int     bitCnt;
     }       state;
     uint16_t    shiftReg;
     int     bitCnt;
@@ -425,6 +420,7 @@ static RAMFUNC int ManchesterDecoding(int v)
                                if(!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) {
                                        Demod.state = DEMOD_UNSYNCD;
                                        error = 0x88;
                                if(!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) {
                                        Demod.state = DEMOD_UNSYNCD;
                                        error = 0x88;
+                                       return FALSE;
                                }
                                
                                // TODO: use this error value to print?  Ask Holiman.
                                }
                                
                                // TODO: use this error value to print?  Ask Holiman.
@@ -653,8 +649,9 @@ void RAMFUNC SnoopIClass(void)
     // The DMA buffer, used to stream samples from the FPGA
     uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
  
     // The DMA buffer, used to stream samples from the FPGA
     uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
  
-       set_tracing(TRUE);
        clear_trace();
        clear_trace();
+       set_tracing(TRUE);
+       
     iso14a_set_trigger(FALSE);
 
     int lastRxCounter;
     iso14a_set_trigger(FALSE);
 
     int lastRxCounter;
@@ -676,7 +673,11 @@ void RAMFUNC SnoopIClass(void)
     FpgaSetupSsc();
     upTo = dmaBuf;
     lastRxCounter = DMA_BUFFER_SIZE;
     FpgaSetupSsc();
     upTo = dmaBuf;
     lastRxCounter = DMA_BUFFER_SIZE;
-    FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+       // Setup and start DMA.
+       if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){
+               if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); 
+               return;
+       }
 
     // And the reader -> tag commands
     memset(&Uart, 0, sizeof(Uart));
 
     // And the reader -> tag commands
     memset(&Uart, 0, sizeof(Uart));
@@ -806,7 +807,7 @@ void RAMFUNC SnoopIClass(void)
        Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
 
 done:
        Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
 
 done:
-    AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+    FpgaDisableSscDma();
     Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
        Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
        LEDsoff();
     Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
        Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
        LEDsoff();
@@ -918,7 +919,7 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
         * The mode FPGA_HF_SIMULATOR_MODULATE_424K_8BIT which we use to simulate tag,
         * works like this.
         * - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us).
         * The mode FPGA_HF_SIMULATOR_MODULATE_424K_8BIT which we use to simulate tag,
         * works like this.
         * - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us).
-        * - A 0-bit inptu to the FPGA becomes an unmodulated time of 18.88us
+        * - A 0-bit input to the FPGA becomes an unmodulated time of 18.88us
         *
         * In this mode the SOF can be written as 00011101 = 0x1D
         * The EOF can be written as 10111000 = 0xb8
         *
         * In this mode the SOF can be written as 00011101 = 0x1D
         * The EOF can be written as 10111000 = 0xb8
@@ -985,8 +986,9 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
        // Enable and clear the trace
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
        // Enable and clear the trace
-       set_tracing(TRUE);
        clear_trace();
        clear_trace();
+       set_tracing(TRUE);
+
        //Use the emulator memory for SIM
        uint8_t *emulator = BigBuf_get_EM_addr();
 
        //Use the emulator memory for SIM
        uint8_t *emulator = BigBuf_get_EM_addr();
 
@@ -1288,13 +1290,14 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf)
                else {
                        //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44
                        // Never seen this command before
                else {
                        //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44
                        // Never seen this command before
-                       Dbprintf("Unknown command received from reader (len=%d): %x %x %x %x %x %x %x %x %x",
+                       Dbprintf("Unhandled command received from reader (len=%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]);
                        // Do not respond
                        len,
                        receivedCmd[0], receivedCmd[1], receivedCmd[2],
                        receivedCmd[3], receivedCmd[4], receivedCmd[5],
                        receivedCmd[6], receivedCmd[7], receivedCmd[8]);
                        // Do not respond
-                       modulated_response = resp_sof; modulated_response_size = 0; //order = 0;
+                       modulated_response = resp_sof;
+                       modulated_response_size = 0; //order = 0;
                        trace_data = NULL;
                        trace_data_size = 0;
                }
                        trace_data = NULL;
                        trace_data_size = 0;
                }
@@ -1323,10 +1326,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf)
                                GetParity(trace_data, trace_data_size, parity);
                                LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, FALSE);
                        }
                                GetParity(trace_data, trace_data_size, parity);
                                LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, FALSE);
                        }
-                       if(!tracing) {
+                       if(!tracing)
                                DbpString("Trace full");
                                DbpString("Trace full");
-                               //break;
-                       }
 
                }
        }
 
                }
        }
@@ -1383,63 +1384,62 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
 //-----------------------------------------------------------------------------
 static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait)
 {
 //-----------------------------------------------------------------------------
 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();
-
-   if (wait)
-   {
-     if(*wait < 10) *wait = 10;
-     
-  for(c = 0; c < *wait;) {
-    if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-      AT91C_BASE_SSC->SSC_THR = 0x00;          // For exact timing!
-      c++;
-    }
-    if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-      volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-      (void)r;
-    }
-    WDT_HIT();
-  }
+       int c;
+       volatile uint32_t r;
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
+       AT91C_BASE_SSC->SSC_THR = 0x00;
+       FpgaSetupSsc();
 
 
-   }
+       if (wait) {
+               if(*wait < 10) *wait = 10;
 
 
+               for(c = 0; c < *wait;) {
+                       if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                               AT91C_BASE_SSC->SSC_THR = 0x00;         // For exact timing!
+                               c++;
+                       }
+                       if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                               r = AT91C_BASE_SSC->SSC_RHR;
+                               (void)r;
+                       }
+                       WDT_HIT();
+               }
+       }
 
 
-  uint8_t sendbyte;
-  bool firstpart = TRUE;
-  c = 0;
-  for(;;) {
-    if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
 
 
-      // DOUBLE THE SAMPLES!
-      if(firstpart) {
-       sendbyte = (cmd[c] & 0xf0) | (cmd[c] >> 4); 
-      }
-      else {
-       sendbyte = (cmd[c] & 0x0f) | (cmd[c] << 4);
-        c++;
-      }
-      if(sendbyte == 0xff) {
-       sendbyte = 0xfe;
-      }
-      AT91C_BASE_SSC->SSC_THR = sendbyte;
-      firstpart = !firstpart;
+       uint8_t sendbyte;
+       bool firstpart = TRUE;
+       c = 0;
+       for(;;) {
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
 
 
-      if(c >= len) {
-        break;
-      }
-    }
-    if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-      volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-      (void)r;
-    }
-    WDT_HIT();
-  }
-  if (samples) *samples = (c + *wait) << 3;
-}
+                       // DOUBLE THE SAMPLES!
+                       if(firstpart) {
+                               sendbyte = (cmd[c] & 0xf0) | (cmd[c] >> 4); 
+                       }
+                       else {
+                               sendbyte = (cmd[c] & 0x0f) | (cmd[c] << 4);
+                               c++;
+                       }
+
+                       if(sendbyte == 0xff)
+                               sendbyte = 0xfe;
+
+                       AT91C_BASE_SSC->SSC_THR = sendbyte;
+                       firstpart = !firstpart;
 
 
+                       if(c >= len) break;
+
+               }
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                       r = AT91C_BASE_SSC->SSC_RHR;
+                       (void)r;
+               }
+               
+               WDT_HIT();
+       }
+       if (samples && wait) *samples = (c + *wait) << 3;
+}
 
 //-----------------------------------------------------------------------------
 // Prepare iClass reader command to send to FPGA
 
 //-----------------------------------------------------------------------------
 // Prepare iClass reader command to send to FPGA
@@ -1463,7 +1463,7 @@ void CodeIClassCommand(const uint8_t * cmd, int len)
     for(j = 0; j < 4; j++) {
       for(k = 0; k < 4; k++) {
                        if(k == (b & 3)) {
     for(j = 0; j < 4; j++) {
       for(k = 0; k < 4; k++) {
                        if(k == (b & 3)) {
-                               ToSend[++ToSendMax] = 0x0f;
+                               ToSend[++ToSendMax] = 0xf0;
                        }
                        else {
                                ToSend[++ToSendMax] = 0x00;
                        }
                        else {
                                ToSend[++ToSendMax] = 0x00;
@@ -1539,9 +1539,15 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
                        if (elapsed) (*elapsed)++;
                }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
                        if (elapsed) (*elapsed)++;
                }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       if(c < timeout) { c++; } else { return FALSE; }
+                       if(c < timeout)
+                               c++;
+                       else 
+                               return FALSE;
+                       
                        b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
                        b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+                       
                        skip = !skip;
                        skip = !skip;
+                       
                        if(skip) continue;
                
                        if(ManchesterDecoding(b & 0x0f)) {
                        if(skip) continue;
                
                        if(ManchesterDecoding(b & 0x0f)) {
@@ -1570,9 +1576,9 @@ void setupIclassReader()
 {
     FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
     // Reset trace buffer
 {
     FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
     // Reset trace buffer
-       set_tracing(TRUE);
        clear_trace();
        clear_trace();
-
+       set_tracing(TRUE);
+       
     // Setup SSC
     FpgaSetupSsc();
     // Start from off (no field generated)
     // Setup SSC
     FpgaSetupSsc();
     // Start from off (no field generated)
@@ -1693,7 +1699,9 @@ void ReaderIClass(uint8_t arg0) {
     while(!BUTTON_PRESS())
     {
                if (try_once && tryCnt > 5) break; 
     while(!BUTTON_PRESS())
     {
                if (try_once && tryCnt > 5) break; 
+               
                tryCnt++;
                tryCnt++;
+               
                if(!tracing) {
                        DbpString("Trace full");
                        break;
                if(!tracing) {
                        DbpString("Trace full");
                        break;
@@ -1974,18 +1982,26 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
 }
 
 bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) {
 }
 
 bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) {
-       uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        //uint8_t readblockdata[10];
        //write[1] = blockNo;
        memcpy(write+2, data, 12); // data + mac
        //uint8_t readblockdata[10];
        //write[1] = blockNo;
        memcpy(write+2, data, 12); // data + mac
+       char *wrCmd = (char *)(write+1); 
+       uint16_t wrCrc = iclass_crc16(wrCmd, 13);
+       write[14] = wrCrc >> 8;
+       write[15] = wrCrc & 0xff;
        uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0};
        uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0};
-       bool isOK;
+       bool isOK = false;
+
        isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
        isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
-       if (isOK) {
+       if (isOK) { //if reader responded correctly
                //Dbprintf("WriteResp: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]);
                //Dbprintf("WriteResp: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]);
-               if (memcmp(write+2,resp,8)) {
+               if (memcmp(write+2,resp,8)) {  //if response is not equal to write values
+                       if (blockNo != 3 && blockNo != 4) { //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data)
                        //error try again
                        isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
                        //error try again
                        isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
+                       } 
+                       
                }
        }
        return isOK;
                }
        }
        return isOK;
Impressum, Datenschutz