X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/3612a8a8e2b3118e0bcb4ea0ef9a6c59d3635696..b82c2f85e457f361b119d21a31f3263ac3489cc8:/armsrc/legicrf.c diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index f2eb680b..5ad1fdf1 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -81,37 +81,39 @@ static void setup_timer(void) /* Generate Keystream */ static uint32_t get_key_stream(int skip, int count) { - uint32_t key=0; int i; - - /* Use int to enlarge timer tc to 32bit */ - legic_prng_bc += prng_timer->TC_CV; - prng_timer->TC_CCR = AT91C_TC_SWTRG; - - /* If skip == -1, forward prng time based */ - if(skip == -1) { - i = (legic_prng_bc+SIM_SHIFT)/SIM_DIVISOR; /* Calculate Cycles based on timer */ - i -= legic_prng_count(); /* substract cycles of finished frames */ - i -= count; /* substract current frame length, rewidn to bedinning */ - legic_prng_forward(i); - } else { - legic_prng_forward(skip); - } + uint32_t key=0; int i; + + /* Use int to enlarge timer tc to 32bit */ + legic_prng_bc += prng_timer->TC_CV; + prng_timer->TC_CCR = AT91C_TC_SWTRG; + + /* If skip == -1, forward prng time based */ + if(skip == -1) { + i = (legic_prng_bc+SIM_SHIFT)/SIM_DIVISOR; /* Calculate Cycles based on timer */ + i -= legic_prng_count(); /* substract cycles of finished frames */ + i -= count; /* substract current frame length, rewidn to bedinning */ + legic_prng_forward(i); + } else { + legic_prng_forward(skip); + } - /* Write Time Data into LOG */ - if(count == 6) { i = -1; } else { i = legic_read_count; } - ((uint8_t*)BigBuf)[OFFSET_LOG+128+i] = legic_prng_count(); - ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff; - ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff; - ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff; - ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff; - ((uint8_t*)BigBuf)[OFFSET_LOG+384+i] = count; - - /* Generate KeyStream */ - for(i=0; i> 0) & 0xff; + BigBuf[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff; + BigBuf[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff; + BigBuf[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff; + BigBuf[OFFSET_LOG+384+i] = count; + + /* Generate KeyStream */ + for(i=0; iTC_CV + TAG_TIME_BIT; int bit = response & 1; response = response >> 1; - if(bit) { + if(bit) AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT; - } else { + else AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT; - } + while(timer->TC_CV < nextbit) ; } AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT; @@ -170,11 +172,11 @@ static void frame_send_rwd(uint32_t data, int bits) int bit = data & 1; data = data >> 1; - if(bit ^ legic_prng_get_bit()) { + if(bit ^ legic_prng_get_bit()) bit_end = starttime + RWD_TIME_1; - } else { + else bit_end = starttime + RWD_TIME_0; - } + /* RWD_TIME_PAUSE time off, then some time on, so that the complete bit time is * RWD_TIME_x, where x is the bit to be transmitted */ @@ -183,16 +185,15 @@ static void frame_send_rwd(uint32_t data, int bits) AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT; legic_prng_forward(1); /* bit duration is longest. use this time to forward the lfsr */ - while(timer->TC_CV < bit_end) ; + while(timer->TC_CV < bit_end); } - { - /* One final pause to mark the end of the frame */ - int pause_end = timer->TC_CV + RWD_TIME_PAUSE; - AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT; - while(timer->TC_CV < pause_end) ; - AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT; - } + /* One final pause to mark the end of the frame */ + int pause_end = timer->TC_CV + RWD_TIME_PAUSE; + AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT; + while(timer->TC_CV < pause_end) ; + AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT; + /* Reset the timer, to measure time until the start of the tag frame */ timer->TC_CCR = AT91C_TC_SWTRG; @@ -238,8 +239,7 @@ static void frame_receive_rwd(struct legic_frame * const f, int bits, int crypt) * since we cannot compute it on the fly while reading */ legic_prng_forward(2); - if(crypt) - { + if(crypt) { for(i=0; ibits >= 31) { + if (f->bits >= 31) return; /* Overflow, won't happen */ - } - f->data |= (bit<bits); + + f->data |= (bit << f->bits); f->bits++; } @@ -310,6 +310,7 @@ static uint32_t perform_setup_phase_rwd(int iv) } static void LegicCommonInit(void) { + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaSetupSsc(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); @@ -353,9 +354,11 @@ int legic_read_byte(int byte_index, int cmd_sz) { frame_receive_rwd(¤t_frame, 12, 1); byte = current_frame.data & 0xff; + if( LegicCRC(byte_index, byte, cmd_sz) != (current_frame.data >> 8) ) { Dbprintf("!!! crc mismatch: expected %x but got %x !!!", - LegicCRC(byte_index, current_frame.data & 0xff, cmd_sz), current_frame.data >> 8); + LegicCRC(byte_index, current_frame.data & 0xff, cmd_sz), + current_frame.data >> 8); return -1; } @@ -371,9 +374,8 @@ int legic_read_byte(int byte_index, int cmd_sz) { */ int legic_write_byte(int byte, int addr, int addr_sz) { //do not write UID, CRC, DCF - if(addr <= 0x06) { + if(addr <= 0x06) return 0; - } //== send write command ============================== crc_clear(&legic_crc); @@ -425,6 +427,7 @@ int LegicRfReader(int offset, int bytes) { LegicCommonInit(); + uint8_t *BigBuf = BigBuf_get_addr(); memset(BigBuf, 0, 1024); DbpString("setting up legic card"); @@ -445,12 +448,11 @@ int LegicRfReader(int offset, int bytes) { Dbprintf("Unknown card format: %x",tag_type); return -1; } - if(bytes == -1) { + if(bytes == -1) bytes = card_sz; - } - if(bytes+offset >= card_sz) { + + if(bytes+offset >= card_sz) bytes = card_sz-offset; - } perform_setup_phase_rwd(SESSION_IV); @@ -464,7 +466,7 @@ int LegicRfReader(int offset, int bytes) { LED_C_OFF(); return -1; } - ((uint8_t*)BigBuf)[byte_index] = r; + BigBuf[byte_index] = r; WDT_HIT(); byte_index++; if(byte_index & 0x10) LED_C_ON(); else LED_C_OFF(); @@ -479,7 +481,8 @@ int LegicRfReader(int offset, int bytes) { void LegicRfWriter(int bytes, int offset) { int byte_index=0, addr_sz=0; - + uint8_t *BigBuf = BigBuf_get_addr(); + LegicCommonInit(); DbpString("setting up legic card"); @@ -511,7 +514,7 @@ void LegicRfWriter(int bytes, int offset) { perform_setup_phase_rwd(SESSION_IV); legic_prng_forward(2); while(byte_index < bytes) { - int r = legic_write_byte(((uint8_t*)BigBuf)[byte_index+offset], byte_index+offset, addr_sz); + int r = legic_write_byte(BigBuf[byte_index+offset], byte_index+offset, addr_sz); if((r != 0) || BUTTON_PRESS()) { Dbprintf("operation aborted @ 0x%03.3x", byte_index); switch_off_tag_rwd(); @@ -533,6 +536,8 @@ int timestamp; /* Handle (whether to respond) a frame in tag mode */ static void frame_handle_tag(struct legic_frame const * const f) { + uint8_t *BigBuf = BigBuf_get_addr(); + /* First Part of Handshake (IV) */ if(f->bits == 7) { if(f->data == SESSION_IV) { @@ -581,9 +586,9 @@ static void frame_handle_tag(struct legic_frame const * const f) if(legic_state == STATE_CON) { int key = get_key_stream(-1, 11); //legic_phase_drift, 11); int addr = f->data ^ key; addr = addr >> 1; - int data = ((uint8_t*)BigBuf)[addr]; + int data = BigBuf[addr]; int hash = LegicCRC(addr, data, 11) << 8; - ((uint8_t*)BigBuf)[OFFSET_LOG+legic_read_count] = (uint8_t)addr; + BigBuf[OFFSET_LOG+legic_read_count] = (uint8_t)addr; legic_read_count++; //Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c); @@ -618,19 +623,19 @@ static void frame_handle_tag(struct legic_frame const * const f) int i; Dbprintf("IV: %03.3x", legic_prng_iv); for(i = 0; iPIO_PDSR & GPIO_SSC_DIN); int time = timer->TC_CV;