X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/d2d0af8ca61484f1460ea302e6bcc2e1cac71297..95e635947bc4628b713fa00d7a533a881bca7fc4:/armsrc/iclass.c diff --git a/armsrc/iclass.c b/armsrc/iclass.c index b14a0db5..91a802ca 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -36,7 +36,7 @@ // //----------------------------------------------------------------------------- -#include "proxmark3.h" +#include "../include/proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" @@ -45,9 +45,11 @@ // Needed for CRC in emulation mode; // same construction as in ISO 14443; // different initial value (CRC_ICLASS) -#include "iso14443crc.h" +#include "../common/iso14443crc.h" +#include "../common/iso15693tools.h" #include "iso15693tools.h" + static int timeout = 4096; @@ -226,7 +228,8 @@ static RAMFUNC int OutOfNDecoding(int bit) // Calculate the parity bit for the client... Uart.parityBits <<= 1; - Uart.parityBits ^= OddByteParity[(Uart.shiftReg & 0xff)]; + //Uart.parityBits ^= OddByteParity[(Uart.shiftReg & 0xff)]; + Uart.parityBits ^= oddparity(Uart.shiftReg & 0xff); Uart.bitCnt = 0; Uart.shiftReg = 0; @@ -249,7 +252,8 @@ static RAMFUNC int OutOfNDecoding(int bit) // Calculate the parity bit for the client... Uart.parityBits <<= 1; - Uart.parityBits ^= OddByteParity[(Uart.dropPosition & 0xff)]; + //Uart.parityBits ^= OddByteParity[(Uart.dropPosition & 0xff)]; + Uart.parityBits ^= oddparity((Uart.dropPosition & 0xff)); Uart.bitCnt = 0; Uart.shiftReg = 0; @@ -450,8 +454,7 @@ static RAMFUNC int ManchesterDecoding(int v) else { modulation = bit & Demod.syncBit; modulation |= ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit; - //modulation = ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit; - + Demod.samples += 4; if(Demod.posCount==0) { @@ -486,7 +489,8 @@ static RAMFUNC int ManchesterDecoding(int v) Demod.output[Demod.len] = 0x0f; Demod.len++; Demod.parityBits <<= 1; - Demod.parityBits ^= OddByteParity[0x0f]; + //Demod.parityBits ^= OddByteParity[0x0f]; + Demod.parityBits ^= oddparity(0x0f); Demod.state = DEMOD_UNSYNCD; // error = 0x0f; return TRUE; @@ -611,7 +615,8 @@ static RAMFUNC int ManchesterDecoding(int v) // FOR ISO15639 PARITY NOT SEND OTA, JUST CALCULATE IT FOR THE CLIENT Demod.parityBits <<= 1; - Demod.parityBits ^= OddByteParity[(Demod.shiftReg & 0xff)]; + //Demod.parityBits ^= OddByteParity[(Demod.shiftReg & 0xff)]; + Demod.parityBits ^= oddparity((Demod.shiftReg & 0xff)); Demod.bitCount = 0; Demod.shiftReg = 0; @@ -868,10 +873,7 @@ static int GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - /*if(OutOfNDecoding((b & 0xf0) >> 4)) { - *len = Uart.byteCnt; - return TRUE; - }*/ + if(OutOfNDecoding(b & 0x0f)) { *len = Uart.byteCnt; return TRUE; @@ -1393,7 +1395,6 @@ void ReaderTransmitIClass(uint8_t* frame, int len) int par = 0; // This is tied to other size changes - // uint8_t* frame_addr = ((uint8_t*)BigBuf) + 2024; CodeIClassCommand(frame,len); // Select the card @@ -1433,7 +1434,7 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, for(;;) { WDT_HIT(); - if(BUTTON_PRESS()) return FALSE; + if(BUTTON_PRESS()) return FALSE; if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!! @@ -1444,10 +1445,7 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; skip = !skip; if(skip) continue; - /*if(ManchesterDecoding((b>>4) & 0xf)) { - *samples = ((c - 1) << 3) + 4; - return TRUE; - }*/ + if(ManchesterDecoding(b & 0x0f)) { *samples = c << 3; return TRUE; @@ -1466,69 +1464,109 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer) return Demod.len; } +void setupIclassReader() +{ + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // Reset trace buffer + iso14a_set_tracing(TRUE); + iso14a_clear_trace(); + + // Setup SSC + FpgaSetupSsc(); + // Start from off (no field generated) + // Signal field is off with the appropriate LED + LED_D_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(200); + + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + + // Now give it time to spin up. + // Signal field is on with the appropriate LED + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + SpinDelay(200); + LED_A_ON(); + +} + // Reader iClass Anticollission void ReaderIClass(uint8_t arg0) { uint8_t act_all[] = { 0x0a }; uint8_t identify[] = { 0x0c }; uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t readcheck_cc[]= { 0x88, 0x02 }; - uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes - - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + uint8_t card_data[24]={0}; + uint8_t last_csn[8]={0}; - // Reset trace buffer - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); + uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes - // Setup SSC - FpgaSetupSsc(); - // Start from off (no field generated) - // Signal field is off with the appropriate LED - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); + int read_status= 0; + bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE; - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + setupIclassReader(); - // Now give it time to spin up. - // Signal field is on with the appropriate LED - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - SpinDelay(200); + size_t datasize = 0; + while(!BUTTON_PRESS()) + { + WDT_HIT(); - LED_A_ON(); + // Send act_all + ReaderTransmitIClass(act_all, 1); + // Card present? + if(ReaderReceiveIClass(resp)) { - for(;;) { - - if(traceLen > TRACE_SIZE) { - DbpString("Trace full"); - break; - } - - if (BUTTON_PRESS()) break; + ReaderTransmitIClass(identify, 1); - // Send act_all - ReaderTransmitIClass(act_all, 1); - // Card present? - if(ReaderReceiveIClass(resp)) { - ReaderTransmitIClass(identify, 1); - if(ReaderReceiveIClass(resp) == 10) { - // Select card - memcpy(&select[1],resp,8); - ReaderTransmitIClass(select, sizeof(select)); + if(ReaderReceiveIClass(resp) == 10) { + //Copy the Anti-collision CSN to our select-packet + memcpy(&select[1],resp,8); + //Dbprintf("Anti-collision CSN: %02x %02x %02x %02x %02x %02x %02x %02x",resp[0], resp[1], resp[2], + // resp[3], resp[4], resp[5], + // resp[6], resp[7]); + //Select the card + ReaderTransmitIClass(select, sizeof(select)); + + if(ReaderReceiveIClass(resp) == 10) { + //Save CSN in response data + memcpy(card_data,resp,8); + datasize += 8; + //Flag that we got to at least stage 1, read CSN + read_status = 1; + + // Card selected + //Dbprintf("Readcheck on Sector 2"); + ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); + if(ReaderReceiveIClass(resp) == 8) { + //Save CC (e-purse) in response data + memcpy(card_data+8,resp,8); + datasize += 8; + //Got both + read_status = 2; + } + + LED_B_ON(); + //Send back to client, but don't bother if we already sent this + if(memcmp(last_csn, card_data, 8) != 0) + cmd_send(CMD_ACK,read_status,0,0,card_data,datasize); + + //Save that we already sent this.... + if(read_status == 2) + memcpy(last_csn, card_data, 8); + + LED_B_OFF(); + + if(abort_after_read) break; + } + } + } - if(ReaderReceiveIClass(resp) == 10) { - Dbprintf(" Selected CSN: %02x %02x %02x %02x %02x %02x %02x %02x", - resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7]); - } - // Card selected, whats next... ;-) - } - } - WDT_HIT(); - } - - LED_A_OFF(); + if(traceLen > TRACE_SIZE) { + DbpString("Trace full"); + break; + } + } + LED_A_OFF(); } void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { @@ -1553,28 +1591,9 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { } memory; uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes - // Enable and clear the trace - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); - - - - // Setup SSC - FpgaSetupSsc(); - // Start from off (no field generated) - // Signal field is off with the appropriate LED - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - - // Now give it time to spin up. - // Signal field is on with the appropriate LED - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - SpinDelay(200); + setupIclassReader(); - LED_A_ON(); for(int i=0;i<1;i++) { @@ -1613,8 +1632,8 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { Dbprintf("Authenticate"); //for now replay captured auth (as cc not updated) memcpy(check+5,MAC,4); - Dbprintf(" AA: %02x %02x %02x %02x", - check[5], check[6], check[7],check[8]); + //Dbprintf(" AA: %02x %02x %02x %02x", + // check[5], check[6], check[7],check[8]); ReaderTransmitIClass(check, sizeof(check)); if(ReaderReceiveIClass(resp) == 4) { Dbprintf(" AR: %02x %02x %02x %02x", @@ -1675,89 +1694,6 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { LED_A_OFF(); } -//1. Create Method to Read sectors/blocks 0,1,2 and Send to client -void IClass_iso14443A_GetPublic(uint8_t arg0) { - uint8_t act_all[] = { 0x0a }; - uint8_t identify[] = { 0x0c }; - uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t readcheck_cc[]= { 0x88, 0x02 }; - - uint8_t card_data[24]={0}; - uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - - int read_success= 0; - - // Enable and clear the trace - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); - - // Setup SSC - FpgaSetupSsc(); - // Start from off (no field generated) - // Signal field is off with the appropriate LED - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); - - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - - // Now give it time to spin up. - // Signal field is on with the appropriate LED - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - SpinDelay(200); - - LED_A_ON(); - - // Send act_all - ReaderTransmitIClass(act_all, 1); - // Card present? - if(ReaderReceiveIClass(resp)) { - ReaderTransmitIClass(identify, 1); - if(ReaderReceiveIClass(resp) == 10) { - //Copy the Anti-collision CSN to our select-packet - memcpy(&select[1],resp,8); - Dbprintf("Anti-collision CSN: %02x %02x %02x %02x %02x %02x %02x %02x",resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7]); - //Select the card - ReaderTransmitIClass(select, sizeof(select)); - - if(ReaderReceiveIClass(resp) == 10) { - Dbprintf(" Selected CSN: %02x %02x %02x %02x %02x %02x %02x %02x", - resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7]); - //Save CSN in response data - memcpy(card_data,resp,8); - //Flag that we got to at least stage 1, read CSN - read_success = 1; - - // Card selected - Dbprintf("Readcheck on Sector 2"); - ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); - if(ReaderReceiveIClass(resp) == 8) { - Dbprintf(" CC: %02x %02x %02x %02x %02x %02x %02x %02x", - resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7]); - //Save CC (e-purse) in response data - memcpy(card_data+8,resp,8); - //Got both - read_success = 2; - } - } - } - } - WDT_HIT(); - - LED_A_OFF(); - LED_B_ON(); - //Send back to client - cmd_send(CMD_ACK,read_success,0,0,card_data,16); - LED_B_OFF(); -} - //2. Create Read method (cut-down from above) based off responses from 1. // Since we have the MAC could continue to use replay function. //3. Create Write method @@ -1776,7 +1712,7 @@ void IClass_iso14443A_write(uint8_t arg0, uint8_t blockNo, uint8_t *data, uint8_ uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes // Reset trace buffer - memset(trace, 0x44, RECV_CMD_OFFSET); + memset(trace, 0x44, RECV_CMD_OFFSET); traceLen = 0; // Setup SSC