X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/86087eba009ffe9440c3b24720ea5f3b8001e850..00271f774add30ff49118351be9a80af85252d60:/armsrc/legicrf.c diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 4e0bc240..9944ac46 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -72,7 +72,7 @@ static void setup_timer(void) { #define RWD_TIME_1 120 // READER_TIME_PAUSE 20us off, 80us on = 100us 80 * 1.5 == 120ticks #define RWD_TIME_0 60 // READER_TIME_PAUSE 20us off, 40us on = 60us 40 * 1.5 == 60ticks #define RWD_TIME_PAUSE 30 // 20us == 20 * 1.5 == 30ticks */ -#define TAG_BIT_PERIOD 143 // 100us == 100 * 1.5 == 150ticks +#define TAG_BIT_PERIOD 142 // 100us == 100 * 1.5 == 150ticks #define TAG_FRAME_WAIT 495 // 330us from READER frame end to TAG frame start. 330 * 1.5 == 495 #define RWD_TIME_FUZZ 20 // rather generous 13us, since the peak detector + hysteresis fuzz quite a bit @@ -140,14 +140,13 @@ static void frame_clean(struct legic_frame * const f) { /* Generate Keystream */ 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; // reset the prng timer. - ResetTimer(prng_timer); /* If skip == -1, forward prng time based */ if(skip == -1) { @@ -161,55 +160,41 @@ uint32_t get_key_stream(int skip, int count) { i = (count == 6) ? -1 : legic_read_count; - /* Write Time Data into LOG */ - // uint8_t *BigBuf = BigBuf_get_addr(); - // BigBuf[OFFSET_LOG+128+i] = legic_prng_count(); - // BigBuf[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 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; + // log + //uint8_t cmdbytes[] = {bits, BYTEx(data, 0), BYTEx(data, 1), BYTEx(send, 0), BYTEx(send, 1), legic_prng_count()}; + //LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GET_TICKS, NULL, TRUE); /* Generate KeyStream */ - for(i=0; iPIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - /* Use time to crypt frame */ - if(crypt) { - legic_prng_forward(2); /* TAG_FRAME_WAIT -> shift by 2 */ - response ^= legic_prng_get_bits(bits); - } + /* TAG_FRAME_WAIT -> shift by 2 */ + legic_prng_forward(2); + response ^= legic_prng_get_bits(bits); /* Wait for the frame start */ - WaitUS( TAG_FRAME_WAIT ); - - uint8_t bit = 0; - for(int i = 0; i < bits; i++) { - - bit = response & 1; - response >>= 1; + WaitTicks( TAG_FRAME_WAIT ); - if (bit) - HIGH(GPIO_SSC_DOUT); + for (; mask < BITMASK(bits); mask <<= 1) { + if (response & mask) + OPEN_COIL; else - LOW(GPIO_SSC_DOUT); - - WaitUS(100); + SHORT_COIL; + WaitTicks(TAG_BIT_PERIOD); } - LOW(GPIO_SSC_DOUT); + SHORT_COIL; } /* Send a frame in reader mode, the FPGA must have been set up by @@ -394,9 +379,10 @@ int legic_read_byte( uint16_t index, uint8_t cmd_sz) { uint8_t byte, crc, calcCrc = 0; uint32_t cmd = (index << 1) | LEGIC_READ; - - //WaitTicks(366); - WaitTicks(330); + + // 90ticks = 60us (should be 100us but crc calc takes time.) + //WaitTicks(330); // 330ticks prng(4) - works + WaitTicks(240); // 240ticks prng(3) - works frame_sendAsReader(cmd, cmd_sz); frame_receiveAsReader(¤t_frame, 12); @@ -411,7 +397,7 @@ int legic_read_byte( uint16_t index, uint8_t cmd_sz) { return -1; } - legic_prng_forward(4); + legic_prng_forward(3); return byte; } @@ -445,7 +431,7 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { uint32_t cmd_sz = addr_sz+1+8+4; //crc+data+cmd - legic_prng_forward(2); /* we wait anyways */ + legic_prng_forward(2); WaitTicks(330); @@ -458,7 +444,7 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { int t, old_level = 0, edges = 0; int next_bit_at = 0; - WaitUS(TAG_FRAME_WAIT); + WaitTicks(TAG_FRAME_WAIT); for( t = 0; t < 80; ++t) { edges = 0; @@ -486,8 +472,6 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { - len &= 0x3FF; - uint16_t i = 0; uint8_t isOK = 1; legic_card_select_t card; @@ -763,7 +747,7 @@ void LegicRfInfo(void){ } cmd_send(CMD_ACK, 1, 0, 0, buf, sizeof(legic_card_select_t)); - + OUT: switch_off_tag_rwd(); LEDsoff(); @@ -776,26 +760,26 @@ 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) { + /* First Part of Handshake (IV) */ + if(f->bits == 7) { + + LED_C_ON(); - LED_C_ON(); - // Reset prng timer ResetTimer(prng_timer); - - legic_prng_init(f->data); - frame_send_tag(0x3d, 6, 1); /* 0x3d^0x26 = 0x1B */ - legic_state = STATE_IV; - legic_read_count = 0; - legic_prng_bc = 0; - legic_prng_iv = f->data; - - + + legic_prng_init(f->data); + frame_send_tag(0x3d, 6); /* 0x3d^0x26 = 0x1B */ + legic_state = STATE_IV; + legic_read_count = 0; + legic_prng_bc = 0; + legic_prng_iv = f->data; + + ResetTimer(timer); WaitUS(280); - return; - } + return; + } /* 0x19==??? */ if(legic_state == STATE_IV) { @@ -829,7 +813,7 @@ static void frame_handle_tag(struct legic_frame const * const f) //Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c); legic_prng_forward(legic_reqresp_drift); - frame_send_tag(hash | data, 12, 1); + frame_send_tag(hash | data, 12); ResetTimer(timer); legic_prng_forward(2);