X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/f83cc12613d18f6a5a3a5e6c01f7b83cae2ee92f..9a573554e0c86736cbded236edb363cd566ffa47:/armsrc/iclass.c?ds=sidebyside diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 5a4c15d0..d5cd366d 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -48,17 +48,6 @@ static int timeout = 4096; -// CARD TO READER -// Sequence D: 11110000 modulation with subcarrier during first half -// Sequence E: 00001111 modulation with subcarrier during second half -// Sequence F: 00000000 no modulation with subcarrier -// READER TO CARD -// Sequence X: 00001100 drop after half a period -// Sequence Y: 00000000 no drop -// Sequence Z: 11000000 drop at start -#define SEC_X 0x0c -#define SEC_Y 0x00 -#define SEC_Z 0xc0 static int SendIClassAnswer(uint8_t *resp, int respLen, int delay); @@ -680,6 +669,8 @@ void RAMFUNC SnoopIClass(void) // The response (tag -> reader) that we're receiving. uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // reset traceLen to 0 iso14a_set_tracing(TRUE); iso14a_clear_trace(); @@ -697,8 +688,6 @@ void RAMFUNC SnoopIClass(void) int samples = 0; rsamples = 0; - memset(trace, 0x44, RECV_CMD_OFFSET); - // Set up the demodulator for tag -> reader responses. Demod.output = tagToReaderResponse; Demod.len = 0; @@ -722,6 +711,9 @@ void RAMFUNC SnoopIClass(void) FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + uint32_t time_0 = GetCountSspClk(); + + int div = 0; //int div2 = 0; int decbyte = 0; @@ -773,8 +765,14 @@ void RAMFUNC SnoopIClass(void) rsamples = samples - Uart.samples; LED_C_ON(); - if(!LogTrace(readerToTagCmd,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break; + //if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break; //if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break; + if(tracing) + { + LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, Uart.parityBits,TRUE); + LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, TRUE); + } + /* And ready to receive another command. */ Uart.state = STATE_UNSYNCD; @@ -793,8 +791,11 @@ void RAMFUNC SnoopIClass(void) rsamples = samples - Demod.samples; LED_B_ON(); - if(!LogTrace(tagToReaderResponse,Demod.len, rsamples, Demod.parityBits,FALSE)) break; - //if (!LogTrace(NULL, 0, Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, 0, FALSE)) break; + if(tracing) + { + LogTrace(Demod.output,Demod.len, (GetCountSspClk()-time_0) << 4 , Demod.parityBits,FALSE); + LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, FALSE); + } // And ready to receive another response. @@ -883,6 +884,8 @@ static int GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) //----------------------------------------------------------------------------- static void CodeIClassTagAnswer(const uint8_t *cmd, int len) { + //So far a dummy implementation, not used + //int lastProxToAirDuration =0; int i; ToSendReset(); @@ -891,7 +894,7 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; - ToSend[++ToSendMax] = 0xff; + ToSend[++ToSendMax] = 0xff;//Proxtoair duration starts here ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0x00; @@ -919,11 +922,13 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0xff; - ToSend[++ToSendMax] = 0xff; + ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; + //lastProxToAirDuration = 8*ToSendMax - 3*8 - 3*8;//Not counting zeroes in the beginning or end + // Convert from last byte pos to length ToSendMax++; } @@ -931,8 +936,10 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) // Only SOF static void CodeIClassTagSOF() { - ToSendReset(); + //So far a dummy implementation, not used + //int lastProxToAirDuration =0; + ToSendReset(); // Send SOF ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; @@ -942,11 +949,14 @@ static void CodeIClassTagSOF() ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0xff; + +// lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning + // 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 @@ -963,42 +973,49 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain { uint32_t simType = arg0; uint32_t numberOfCSNS = arg1; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Enable and clear the trace iso14a_set_tracing(TRUE); 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 } } - }else{ + 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..."); } /** @@ -1006,8 +1023,10 @@ 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 uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t response3[] = { 0,0,0,0,0,0,0,0,0,0}; @@ -1080,22 +1099,45 @@ 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(); // To control where we are in the protocol int cmdsRecvd = 0; + uint32_t time_0 = GetCountSspClk(); + uint32_t t2r_time =0; + 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) { + 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 ) { @@ -1103,13 +1145,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. @@ -1134,11 +1174,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) { @@ -1160,9 +1204,9 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) respsize = 0; } - if(cmdsRecvd > 999) { - DbpString("1000 commands later..."); - break; + if(cmdsRecvd > 100) { + //DbpString("100 commands later..."); + //break; } else { cmdsRecvd++; @@ -1170,88 +1214,68 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if(respLen > 0) { SendIClassAnswer(resp, respLen, 21); - - 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]); - + t2r_time = GetCountSspClk(); } if (tracing) { - //LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE); - if(!LogTrace(receivedCmd,len, rsamples, Uart.parityBits,TRUE)) - { - DbpString("Trace full"); - break; - } + 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)) - if(!LogTrace(respdata,respsize, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE)) - { - DbpString("Trace full"); - break; - } + LogTrace(respdata,respsize, (t2r_time-time_0) << 4,SwapBits(GetParity(respdata,respsize),respsize),FALSE); + LogTrace(NULL,0, (t2r_time-time_0) << 4,0,FALSE); + + } + if(!tracing) { + DbpString("Trace full"); + //break; + } + } memset(receivedCmd, 0x44, RECV_CMD_SIZE); } - Dbprintf("%x", cmdsRecvd); + //Dbprintf("%x", cmdsRecvd); LED_A_OFF(); LED_B_OFF(); if(buttonPressed) { DbpString("Button pressed"); } - return buttonPressed; } 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; @@ -1265,7 +1289,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(); @@ -1341,12 +1364,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; } @@ -1450,6 +1473,8 @@ void ReaderIClass(uint8_t arg0) { uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // Reset trace buffer memset(trace, 0x44, RECV_CMD_OFFSET); traceLen = 0;