X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/22f4dca88cc008287b1ef01bb4da0d46cbcf76d1..9b8fb1da6696a29c6b792b1c4def2ea694fafde6:/armsrc/legicrf.c diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index e8a2e1aa..5b0cccf0 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -89,11 +89,9 @@ static void setup_timer(void) { #define FUZZ_EQUAL(value, target, fuzz) ((value) > ((target)-(fuzz)) && (value) < ((target)+(fuzz))) #ifndef SHORT_COIL -//#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x) # define SHORT_COIL LOW(GPIO_SSC_DOUT); #endif #ifndef OPEN_COIL -//#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x) # define OPEN_COIL HIGH(GPIO_SSC_DOUT); #endif @@ -104,12 +102,13 @@ uint32_t sendFrameStop = 0; // one == 80us / 120ticks // zero == 40us / 60ticks #ifndef COIL_PULSE -# define COIL_PULSE(x) { \ +# define COIL_PULSE(x) \ + do { \ SHORT_COIL; \ - WaitTicks(RWD_TIME_PAUSE); \ + WaitTicks( (RWD_TIME_PAUSE) ); \ OPEN_COIL; \ WaitTicks((x)); \ - } + } while (0) #endif // ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces. @@ -117,7 +116,7 @@ uint32_t sendFrameStop = 0; #define LEGIC_CARD_MEMSIZE 1024 static uint8_t* cardmem; -static void frame_append_bit(struct legic_frame * const f, int bit) { +static void frame_append_bit(struct legic_frame * const f, uint8_t bit) { // Overflow, won't happen if (f->bits >= 31) return; @@ -226,7 +225,7 @@ void frame_sendAsReader(uint32_t data, uint8_t bits){ uint32_t starttime = GET_TICKS, send = 0; uint16_t mask = 1; - uint8_t prng1 = legic_prng_count() ; + uint8_t prngstart = legic_prng_count() ; // xor lsfr onto data. send = data ^ legic_prng_get_bits(bits); @@ -244,10 +243,12 @@ void frame_sendAsReader(uint32_t data, uint8_t bits){ sendFrameStop = GET_TICKS; uint8_t cmdbytes[] = { + bits, BYTEx(data, 0), BYTEx(data, 1), - bits, - prng1, + 0x00, + 0x00, + prngstart, legic_prng_count() }; LogTrace(cmdbytes, sizeof(cmdbytes), starttime, sendFrameStop, NULL, TRUE); @@ -282,31 +283,40 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { uint8_t i = bits, edges = 0; uint16_t lsfr = 0; uint32_t the_bit = 1, next_bit_at = 0, data; + int old_level = 0, level = 0; - + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_DIN; AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DIN; - // calibrate the prng. + // calibrate the prng. + // legic_prng_forward(2); // precompute the cipher - uint8_t prng_before = legic_prng_count() ; - - lsfr = legic_prng_get_bits(bits); + uint8_t prngstart = legic_prng_count() ; - data = lsfr; + data = lsfr = legic_prng_get_bits(bits); //FIXED time between sending frame and now listening frame. 330us - //WaitTicks( GET_TICKS - sendFrameStop - TAG_FRAME_WAIT); - WaitTicks( 490 ); - + // 387 = 0x19 0001 1001 + // 480 = 0x19 + // 500 = 0x1C 0001 1100 uint32_t starttime = GET_TICKS; - + //uint16_t mywait = TAG_FRAME_WAIT - (starttime - sendFrameStop); + uint16_t mywait = 495 - (starttime - sendFrameStop); + if ( bits == 6) + WaitTicks( 495 - 9 ); + else { + //Dbprintf("WAIT %d", mywait ); + WaitTicks( mywait ); + } + next_bit_at = GET_TICKS + TAG_BIT_PERIOD; - + while ( i-- ){ edges = 0; + uint8_t adjust = 0; while ( GET_TICKS < next_bit_at) { level = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN); @@ -315,11 +325,18 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { ++edges; old_level = level; - } + + if(edges > 20 && adjust == 0) { + next_bit_at -= 15; + adjust = 1; + } + } + next_bit_at += TAG_BIT_PERIOD; // We expect 42 edges == ONE - if(edges > 30 && edges < 64) + //if (edges > 20 && edges < 64) + if ( edges > 20 ) data ^= the_bit; the_bit <<= 1; @@ -328,22 +345,17 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { // output f->data = data; f->bits = bits; - - // log - sendFrameStop = GET_TICKS; - uint8_t cmdbytes[] = { + uint8_t cmdbytes[] = { + bits, BYTEx(data,0), BYTEx(data,1), - bits, - BYTEx(lsfr,0), - BYTEx(lsfr,1), BYTEx(data, 0) ^ BYTEx(lsfr,0), BYTEx(data, 1) ^ BYTEx(lsfr,1), - prng_before, + prngstart, legic_prng_count() }; - LogTrace(cmdbytes, sizeof(cmdbytes), starttime, sendFrameStop, NULL, FALSE); + LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GET_TICKS, NULL, FALSE); } // Setup pm3 as a Legic Reader @@ -351,7 +363,7 @@ static uint32_t setup_phase_reader(uint8_t iv) { // Switch on carrier and let the tag charge for 1ms HIGH(GPIO_SSC_DOUT); - WaitUS(300); + WaitUS(1000); ResetTicks(); @@ -367,8 +379,8 @@ static uint32_t setup_phase_reader(uint8_t iv) { frame_receiveAsReader(¤t_frame, 6); // fixed delay before sending ack. - WaitTicks(387); // 244us - legic_prng_forward(3); //240us / 100 == 2.4 iterations + WaitTicks(366); // 244us + legic_prng_forward(1); //240us / 100 == 2.4 iterations // Send obsfuscated acknowledgment frame. // 0x19 = 0x18 MIM22, 0x01 LSB READCMD @@ -432,8 +444,8 @@ int legic_read_byte(int byte_index, int cmd_sz) { // 460 | 690 // 258 | 387 // 244 | 366 - WaitTicks(332); - legic_prng_forward(2); // 460 / 100 = 4.6 iterations + WaitTicks(387); + legic_prng_forward(4); // 460 / 100 = 4.6 iterations uint8_t byte = 0, crc = 0, calcCrc = 0; uint32_t cmd = (byte_index << 1) | LEGIC_READ; @@ -449,9 +461,6 @@ int legic_read_byte(int byte_index, int cmd_sz) { Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc); return -1; } - - -// legic_prng_forward(2); // 460 / 100 = 4.6 iterations return byte; } @@ -528,18 +537,13 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { int LegicRfReader(int offset, int bytes, int iv) { uint16_t byte_index = 0; - uint8_t cmd_sz = 0; - int card_sz = 0; - uint8_t isOK = 1; - - if ( MF_DBGLEVEL >= 2) - Dbprintf("setting up legic card, IV = 0x%02x", iv); - + uint8_t cmd_sz = 0, isOK = 1; + int card_sz = 0; + LegicCommonInit(); uint32_t tag_type = setup_phase_reader(iv); - - //we lose to mutch time with dprintf + switch_off_tag_rwd(); switch(tag_type) { @@ -578,16 +582,16 @@ int LegicRfReader(int offset, int bytes, int iv) { int r = legic_read_byte(byte_index + offset, cmd_sz); if (r == -1 || BUTTON_PRESS()) { - if ( MF_DBGLEVEL >= 2) DbpString("operation aborted"); + if ( MF_DBGLEVEL >= 3) DbpString("operation aborted"); isOK = 0; goto OUT; } cardmem[++byte_index] = r; - //byte_index++; WDT_HIT(); } OUT: + WDT_HIT(); switch_off_tag_rwd(); LEDsoff(); uint8_t len = (bytes & 0x3FF);