]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/legicrf.c
Legic: fixed write (#655)
[proxmark3-svn] / armsrc / legicrf.c
CommitLineData
bd20f8f4 1//-----------------------------------------------------------------------------
2// (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
da05bc6e
A
3// 2016 Iceman
4// 2018 AntiCat (rwd rewritten)
bd20f8f4 5//
6// This code is licensed to you under the terms of the GNU GPL, version 2 or,
7// at your option, any later version. See the LICENSE.txt file for the text of
8// the license.
9//-----------------------------------------------------------------------------
10// LEGIC RF simulation code
11//-----------------------------------------------------------------------------
a7247d85 12
e30c654b 13#include "proxmark3.h"
a7247d85 14#include "apps.h"
f7e3ed82 15#include "util.h"
9ab7a6c7 16#include "string.h"
a7247d85 17
f7e3ed82 18#include "legicrf.h"
8e220a91 19#include "legic_prng.h"
da05bc6e 20#include "legic.h"
8e220a91 21#include "crc.h"
22
a7247d85 23static struct legic_frame {
ccedd6ae 24 int bits;
a2b1414f 25 uint32_t data;
a7247d85 26} current_frame;
8e220a91 27
3612a8a8 28static enum {
29 STATE_DISCON,
30 STATE_IV,
31 STATE_CON,
32} legic_state;
33
34static crc_t legic_crc;
35static int legic_read_count;
36static uint32_t legic_prng_bc;
37static uint32_t legic_prng_iv;
38
39static int legic_phase_drift;
40static int legic_frame_drift;
41static int legic_reqresp_drift;
8e220a91 42
add16a62 43AT91PS_TC timer;
3612a8a8 44AT91PS_TC prng_timer;
add16a62 45
da05bc6e
A
46static legic_card_select_t card;/* metadata of currently selected card */
47
48//-----------------------------------------------------------------------------
49// Frame timing and pseudorandom number generator
50//
51// The Prng is forwarded every 100us (TAG_BIT_PERIOD), except when the reader is
52// transmitting. In that case the prng has to be forwarded every bit transmitted:
53// - 60us for a 0 (RWD_TIME_0)
54// - 100us for a 1 (RWD_TIME_1)
55//
56// The data dependent timing makes writing comprehensible code significantly
57// harder. The current aproach forwards the prng data based if there is data on
58// air and time based, using GET_TICKS, during computational and wait periodes.
59//
60// To not have the necessity to calculate/guess exection time dependend timeouts
61// tx_frame and rx_frame use a shared timestamp to coordinate tx and rx timeslots.
62//-----------------------------------------------------------------------------
63
64static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
65
66#define RWD_TIME_PAUSE 30 /* 20us */
67#define RWD_TIME_1 150 /* READER_TIME_PAUSE 20us off + 80us on = 100us */
68#define RWD_TIME_0 90 /* READER_TIME_PAUSE 20us off + 40us on = 60us */
69#define RWD_FRAME_WAIT 330 /* 220us from TAG frame end to READER frame start */
70#define TAG_FRAME_WAIT 495 /* 330us from READER frame end to TAG frame start */
71#define TAG_BIT_PERIOD 150 /* 100us */
72#define TAG_WRITE_TIMEOUT 60 /* 40 * 100us (write should take at most 3.6ms) */
73
74#define SIM_DIVISOR 586 /* prng_time/DIV count prng needs to be forwared */
75#define SIM_SHIFT 900 /* prng_time+SHIFT shift of delayed start */
76#define RWD_TIME_FUZZ 20 /* rather generous 13us, since the peak detector
77 /+ hysteresis fuzz quite a bit */
78
79#define LEGIC_READ 0x01 /* Read Command */
80#define LEGIC_WRITE 0x00 /* Write Command */
81
82#define SESSION_IV 0x55 /* An arbitrary chose session IV, all shoud work */
83#define OFFSET_LOG 1024 /* The largest Legic Prime card is 1k */
84#define WRITE_LOWERLIMIT 4 /* UID and MCC are not writable */
85
86#define INPUT_THRESHOLD 8 /* heuristically determined, lower values */
87 /* lead to detecting false ack during write */
88
89#define FUZZ_EQUAL(value, target, fuzz) ((value) > ((target)-(fuzz)) && (value) < ((target)+(fuzz)))
90
91//-----------------------------------------------------------------------------
92// I/O interface abstraction (FPGA -> ARM)
93//-----------------------------------------------------------------------------
94
95static inline uint8_t rx_byte_from_fpga() {
96 for(;;) {
97 WDT_HIT();
98
99 // wait for byte be become available in rx holding register
100 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
101 return AT91C_BASE_SSC->SSC_RHR;
102 }
103 }
104}
105
106//-----------------------------------------------------------------------------
107// Demodulation (Reader)
108//-----------------------------------------------------------------------------
109
110// Returns a demedulated bit
111//
112// The FPGA running xcorrelation samples the subcarrier at ~13.56 MHz. The mode
113// was initialy designed to receive BSPK/2-PSK. Hance, it reports an I/Q pair
114// every 4.7us (8 bits i and 8 bits q).
115//
116// The subcarrier amplitude can be calculated using Pythagoras sqrt(i^2 + q^2).
117// To reduce CPU time the amplitude is approximated by using linear functions:
118// am = MAX(ABS(i),ABS(q)) + 1/2*MIN(ABS(i),ABSq))
119//
120// Note: The SSC receiver is never synchronized the calculation my be performed
121// on a I/Q pair from two subsequent correlations, but does not matter.
122//
123// The bit time is 99.1us (21 I/Q pairs). The receiver skips the first 5 samples
124// and averages the next (most stable) 8 samples. The final 8 samples are dropped
125// also.
126//
127// The demedulated should be alligned to the bit periode by the caller. This is
128// done in rx_bit_as_reader and rx_ack_as_reader.
129static inline bool rx_bit_as_reader() {
130 int32_t cq = 0;
131 int32_t ci = 0;
132
133 // skip first 5 I/Q pairs
134 for(size_t i = 0; i<5; ++i) {
135 (int8_t)rx_byte_from_fpga();
136 (int8_t)rx_byte_from_fpga();
137 }
138
139 // sample next 8 I/Q pairs
140 for(size_t i = 0; i<8; ++i) {
141 cq += (int8_t)rx_byte_from_fpga();
142 ci += (int8_t)rx_byte_from_fpga();
143 }
144
145 // calculate power
146 int32_t power = (MAX(ABS(ci), ABS(cq)) + (MIN(ABS(ci), ABS(cq)) >> 1));
147
148 // compare average (power / 8) to threshold
149 return ((power >> 3) > INPUT_THRESHOLD);
150}
151
152//-----------------------------------------------------------------------------
153// Modulation (Reader)
154//
155// I've tried to modulate the Legic specific pause-puls using ssc and the default
156// ssc clock of 105.4 kHz (bit periode of 9.4us) - previous commit. However,
157// the timing was not precise enough. By increasing the ssc clock this could
158// be circumvented, but the adventage over bitbang would be little.
159//-----------------------------------------------------------------------------
160
161static inline void tx_bit_as_reader(bool bit) {
162 // insert pause
163 LOW(GPIO_SSC_DOUT);
164 last_frame_end += RWD_TIME_PAUSE;
165 while(GET_TICKS < last_frame_end) { };
166 HIGH(GPIO_SSC_DOUT);
167
168 // return to high, wait for bit periode to end
169 last_frame_end += (bit ? RWD_TIME_1 : RWD_TIME_0) - RWD_TIME_PAUSE;
170 while(GET_TICKS < last_frame_end) { };
171}
172
173//-----------------------------------------------------------------------------
174// Frame Handling (Reader)
175//
176// The LEGIC RF protocol from card to reader does not include explicit frame
177// start/stop information or length information. The reader must know beforehand
178// how many bits it wants to receive.
179// Notably: a card sending a stream of 0-bits is indistinguishable from no card
180// present.
181//-----------------------------------------------------------------------------
182
183static void tx_frame_as_reader(uint32_t frame, uint8_t len) {
184 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
185
186 // wait for next tx timeslot
187 last_frame_end += RWD_FRAME_WAIT;
188 while(GET_TICKS < last_frame_end) { };
189
190 // transmit frame, MSB first
191 for(uint8_t i = 0; i < len; ++i) {
192 bool bit = (frame >> i) & 0x01;
193 tx_bit_as_reader(bit ^ legic_prng_get_bit());
194 legic_prng_forward(1);
195 };
196
197 // add pause to mark end of the frame
198 LOW(GPIO_SSC_DOUT);
199 last_frame_end += RWD_TIME_PAUSE;
200 while(GET_TICKS < last_frame_end) { };
201 HIGH(GPIO_SSC_DOUT);
202}
203
204static uint32_t rx_frame_as_reader(uint8_t len) {
205 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
206 | FPGA_HF_READER_RX_XCORR_848_KHZ
207 | FPGA_HF_READER_RX_XCORR_QUARTER_FREQ);
208
209 // hold sampling until card is expected to respond
210 last_frame_end += TAG_FRAME_WAIT;
211 while(GET_TICKS < last_frame_end) { };
212
213 uint32_t frame = 0;
214 for(uint8_t i = 0; i < len; i++) {
215 frame |= (rx_bit_as_reader() ^ legic_prng_get_bit()) << i;
216 legic_prng_forward(1);
217
218 // rx_bit_as_reader runs only 95us, resync to TAG_BIT_PERIOD
219 last_frame_end += TAG_BIT_PERIOD;
220 while(GET_TICKS < last_frame_end) { };
221 }
222
223 return frame;
224}
225
226static bool rx_ack_as_reader() {
227 // change fpga into rx mode
228 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
229 | FPGA_HF_READER_RX_XCORR_848_KHZ
230 | FPGA_HF_READER_RX_XCORR_QUARTER_FREQ);
231
232 // hold sampling until card is expected to respond
233 last_frame_end += TAG_FRAME_WAIT;
234 while(GET_TICKS < last_frame_end) { };
235
236 uint32_t ack = 0;
237 for(uint8_t i = 0; i < TAG_WRITE_TIMEOUT; ++i) {
238 // sample bit
239 ack = rx_bit_as_reader();
240 legic_prng_forward(1);
241
242 // rx_bit_as_reader runs only 95us, resync to TAG_BIT_PERIOD
243 last_frame_end += TAG_BIT_PERIOD;
244 while(GET_TICKS < last_frame_end) { };
245
246 // check if it was an ACK
247 if(ack) {
248 break;
249 }
250 }
251
252 return ack;
253}
254
255//-----------------------------------------------------------------------------
256// Legic Reader
257//-----------------------------------------------------------------------------
258
259int init_card(uint8_t cardtype, legic_card_select_t *p_card) {
260 p_card->tagtype = cardtype;
261
262 switch(p_card->tagtype) {
263 case 0x0d:
264 p_card->cmdsize = 6;
265 p_card->addrsize = 5;
266 p_card->cardsize = 22;
267 break;
268 case 0x1d:
269 p_card->cmdsize = 9;
270 p_card->addrsize = 8;
271 p_card->cardsize = 256;
272 break;
273 case 0x3d:
274 p_card->cmdsize = 11;
275 p_card->addrsize = 10;
276 p_card->cardsize = 1024;
277 break;
278 default:
279 p_card->cmdsize = 0;
280 p_card->addrsize = 0;
281 p_card->cardsize = 0;
282 return 2;
283 }
284 return 0;
285}
286
287static void init_reader(bool clear_mem) {
288 // configure FPGA
289 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
290 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
291 | FPGA_HF_READER_RX_XCORR_848_KHZ
292 | FPGA_HF_READER_RX_XCORR_QUARTER_FREQ);
293 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
294 LED_D_ON();
295
296 // configure SSC with defaults
297 FpgaSetupSsc();
298
299 // re-claim GPIO_SSC_DOUT as GPIO and enable output
300 AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
301 AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
302 HIGH(GPIO_SSC_DOUT);
303
304 // init crc calculator
305 crc_init(&legic_crc, 4, 0x19 >> 1, 0x05, 0);
306
307 // start us timer
308 StartTicks();
309}
310
311// Setup reader to card connection
312//
313// The setup consists of a three way handshake:
314// - Transmit initialisation vector 7 bits
315// - Receive card type 6 bits
316// - Acknowledge frame 6 bits
317static uint32_t setup_phase_reader(uint8_t iv) {
318 // init coordination timestamp
319 last_frame_end = GET_TICKS;
320
321 // Switch on carrier and let the card charge for 5ms.
322 last_frame_end += 7500;
323 while(GET_TICKS < last_frame_end) { };
324
325 legic_prng_init(0);
326 tx_frame_as_reader(iv, 7);
327
328 // configure iv
329 legic_prng_init(iv);
330 legic_prng_forward(2);
331
332 // receive card type
333 int32_t card_type = rx_frame_as_reader(6);
334 legic_prng_forward(3);
335
336 // send obsfuscated acknowledgment frame
337 switch (card_type) {
338 case 0x0D:
339 tx_frame_as_reader(0x19, 6); // MIM22 | READCMD = 0x18 | 0x01
340 break;
341 case 0x1D:
342 case 0x3D:
343 tx_frame_as_reader(0x39, 6); // MIM256 | READCMD = 0x38 | 0x01
344 break;
345 }
346
347 return card_type;
348}
349
350static uint8_t calc_crc4(uint16_t cmd, uint8_t cmd_sz, uint8_t value) {
351 crc_clear(&legic_crc);
352 crc_update(&legic_crc, (value << cmd_sz) | cmd, 8 + cmd_sz);
353 return crc_finish(&legic_crc);
354}
355
356static int16_t read_byte(uint16_t index, uint8_t cmd_sz) {
357 uint16_t cmd = (index << 1) | LEGIC_READ;
358
359 // read one byte
360 LED_B_ON();
361 legic_prng_forward(2);
362 tx_frame_as_reader(cmd, cmd_sz);
363 legic_prng_forward(2);
364 uint32_t frame = rx_frame_as_reader(12);
365 LED_B_OFF();
366
367 // split frame into data and crc
368 uint8_t byte = BYTEx(frame, 0);
369 uint8_t crc = BYTEx(frame, 1);
370
371 // check received against calculated crc
372 uint8_t calc_crc = calc_crc4(cmd, cmd_sz, byte);
373 if(calc_crc != crc) {
374 Dbprintf("!!! crc mismatch: %x != %x !!!", calc_crc, crc);
375 return -1;
376 }
377
378 legic_prng_forward(1);
379
380 return byte;
381}
382
383// Transmit write command, wait until (3.6ms) the tag sends back an unencrypted
384// ACK ('1' bit) and forward the prng time based.
385bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) {
386 uint32_t cmd = index << 1 | LEGIC_WRITE; // prepare command
387 uint8_t crc = calc_crc4(cmd, addr_sz + 1, byte); // calculate crc
388 cmd |= byte << (addr_sz + 1); // append value
389 cmd |= (crc & 0xF) << (addr_sz + 1 + 8); // and crc
390
391 // send write command
392 LED_C_ON();
393 legic_prng_forward(2);
394 tx_frame_as_reader(cmd, addr_sz + 1 + 8 + 4); // sz = addr_sz + cmd + data + crc
395 legic_prng_forward(3);
396 LED_C_OFF();
397
398 // wait for ack
399 return rx_ack_as_reader();
400}
401
402//-----------------------------------------------------------------------------
403// Command Line Interface
404//
405// Only this functions are public / called from appmain.c
406//-----------------------------------------------------------------------------
407void LegicRfReader(int offset, int bytes) {
408 uint8_t *BigBuf = BigBuf_get_addr();
409 memset(BigBuf, 0, 1024);
410
411 // configure ARM and FPGA
412 init_reader(false);
413
414 // establish shared secret and detect card type
415 DbpString("Reading card ...");
416 uint8_t card_type = setup_phase_reader(SESSION_IV);
417 if(init_card(card_type, &card) != 0) {
418 Dbprintf("No or unknown card found, aborting");
419 goto OUT;
420 }
421
422 // if no argument is specified create full dump
423 if(bytes == -1) {
424 bytes = card.cardsize;
425 }
426
427 // do not read beyond card memory
428 if(bytes + offset > card.cardsize) {
429 bytes = card.cardsize - offset;
430 }
431
432 for(uint16_t i = 0; i < bytes; ++i) {
433 int16_t byte = read_byte(offset + i, card.cmdsize);
434 if(byte == -1) {
435 Dbprintf("operation failed @ 0x%03.3x", bytes);
436 goto OUT;
437 }
438 BigBuf[i] = byte;
439 }
440
441 // OK
442 Dbprintf("Card (MIM %i) read, use 'hf legic decode' or", card.cardsize);
443 Dbprintf("'data hexsamples %d' to view results", (bytes+7) & ~7);
444
445OUT:
446 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
447 LED_B_OFF();
448 LED_C_OFF();
449 LED_D_OFF();
450 StopTicks();
451}
452
453void LegicRfWriter(int bytes, int offset) {
454 uint8_t *BigBuf = BigBuf_get_addr();
455
456 // configure ARM and FPGA
457 init_reader(false);
458
459 // uid is not writeable
460 if(offset <= WRITE_LOWERLIMIT) {
461 goto OUT;
462 }
463
464 // establish shared secret and detect card type
465 Dbprintf("Writing 0x%02.2x - 0x%02.2x ...", offset, offset+bytes);
466 uint8_t card_type = setup_phase_reader(SESSION_IV);
467 if(init_card(card_type, &card) != 0) {
468 Dbprintf("No or unknown card found, aborting");
469 goto OUT;
470 }
471
472 // do not write beyond card memory
473 if(bytes + offset > card.cardsize) {
474 bytes = card.cardsize - offset;
475 }
476
477 // write in reverse order, only then is DCF (decremental field) writable
478 while(bytes-- > 0 && !BUTTON_PRESS()) {
f6842317 479 if(!write_byte(bytes + offset, BigBuf[bytes + offset], card.addrsize)) {
da05bc6e
A
480 Dbprintf("operation failed @ 0x%03.3x", bytes);
481 goto OUT;
482 }
483 }
484
485 // OK
486 DbpString("Write successful");
487
488OUT:
489 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
490 LED_B_OFF();
491 LED_C_OFF();
492 LED_D_OFF();
493 StopTicks();
494}
495
496//-----------------------------------------------------------------------------
497// Legic Simulator
498//-----------------------------------------------------------------------------
499
add16a62 500static void setup_timer(void)
501{
502 /* Set up Timer 1 to use for measuring time between pulses. Since we're bit-banging
503 * this it won't be terribly accurate but should be good enough.
504 */
505 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
506 timer = AT91C_BASE_TC1;
507 timer->TC_CCR = AT91C_TC_CLKDIS;
0aa4cfc2 508 timer->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK;
add16a62 509 timer->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
510
3612a8a8 511 /*
512 * Set up Timer 2 to use for measuring time between frames in
513 * tag simulation mode. Runs 4x faster as Timer 1
514 */
515 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC2);
516 prng_timer = AT91C_BASE_TC2;
517 prng_timer->TC_CCR = AT91C_TC_CLKDIS;
518 prng_timer->TC_CMR = AT91C_TC_CLKS_TIMER_DIV2_CLOCK;
519 prng_timer->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
520}
521
3612a8a8 522/* Generate Keystream */
523static uint32_t get_key_stream(int skip, int count)
524{
525 uint32_t key=0; int i;
526
527 /* Use int to enlarge timer tc to 32bit */
528 legic_prng_bc += prng_timer->TC_CV;
529 prng_timer->TC_CCR = AT91C_TC_SWTRG;
530
531 /* If skip == -1, forward prng time based */
532 if(skip == -1) {
533 i = (legic_prng_bc+SIM_SHIFT)/SIM_DIVISOR; /* Calculate Cycles based on timer */
534 i -= legic_prng_count(); /* substract cycles of finished frames */
535 i -= count; /* substract current frame length, rewidn to bedinning */
536 legic_prng_forward(i);
537 } else {
538 legic_prng_forward(skip);
539 }
540
541 /* Write Time Data into LOG */
117d9ec2 542 uint8_t *BigBuf = BigBuf_get_addr();
3612a8a8 543 if(count == 6) { i = -1; } else { i = legic_read_count; }
117d9ec2 544 BigBuf[OFFSET_LOG+128+i] = legic_prng_count();
545 BigBuf[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff;
546 BigBuf[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff;
547 BigBuf[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff;
548 BigBuf[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff;
549 BigBuf[OFFSET_LOG+384+i] = count;
3612a8a8 550
551 /* Generate KeyStream */
552 for(i=0; i<count; i++) {
553 key |= legic_prng_get_bit() << i;
554 legic_prng_forward(1);
555 }
556 return key;
557}
558
559/* Send a frame in tag mode, the FPGA must have been set up by
560 * LegicRfSimulate
561 */
562static void frame_send_tag(uint16_t response, int bits, int crypt)
563{
564 /* Bitbang the response */
565 AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
566 AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
567 AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
568
569 /* Use time to crypt frame */
570 if(crypt) {
571 legic_prng_forward(2); /* TAG_TIME_WAIT -> shift by 2 */
572 int i; int key = 0;
573 for(i=0; i<bits; i++) {
574 key |= legic_prng_get_bit() << i;
575 legic_prng_forward(1);
576 }
577 //Dbprintf("key = 0x%x", key);
578 response = response ^ key;
579 }
580
581 /* Wait for the frame start */
da05bc6e 582 while(timer->TC_CV < (TAG_FRAME_WAIT - 30)) ;
3612a8a8 583
584 int i;
585 for(i=0; i<bits; i++) {
da05bc6e 586 int nextbit = timer->TC_CV + TAG_BIT_PERIOD;
3612a8a8 587 int bit = response & 1;
588 response = response >> 1;
589 if(bit) {
590 AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT;
591 } else {
592 AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
593 }
594 while(timer->TC_CV < nextbit) ;
595 }
596 AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
597}
598
3612a8a8 599static void frame_append_bit(struct legic_frame * const f, int bit)
600{
601 if(f->bits >= 31) {
602 return; /* Overflow, won't happen */
603 }
604 f->data |= (bit<<f->bits);
605 f->bits++;
606}
607
ccedd6ae 608static void frame_clean(struct legic_frame * const f)
a7247d85 609{
ccedd6ae 610 f->data = 0;
611 f->bits = 0;
a7247d85 612}
613
3612a8a8 614/* Handle (whether to respond) a frame in tag mode */
615static void frame_handle_tag(struct legic_frame const * const f)
616{
117d9ec2 617 uint8_t *BigBuf = BigBuf_get_addr();
618
3612a8a8 619 /* First Part of Handshake (IV) */
620 if(f->bits == 7) {
621 if(f->data == SESSION_IV) {
622 LED_C_ON();
623 prng_timer->TC_CCR = AT91C_TC_SWTRG;
624 legic_prng_init(f->data);
625 frame_send_tag(0x3d, 6, 1); /* 0x3d^0x26 = 0x1b */
626 legic_state = STATE_IV;
627 legic_read_count = 0;
628 legic_prng_bc = 0;
629 legic_prng_iv = f->data;
630
631 /* TIMEOUT */
632 timer->TC_CCR = AT91C_TC_SWTRG;
633 while(timer->TC_CV > 1);
634 while(timer->TC_CV < 280);
635 return;
636 } else if((prng_timer->TC_CV % 50) > 40) {
637 legic_prng_init(f->data);
638 frame_send_tag(0x3d, 6, 1);
639 SpinDelay(20);
640 return;
641 }
642 }
643
644 /* 0x19==??? */
645 if(legic_state == STATE_IV) {
646 if((f->bits == 6) && (f->data == (0x19 ^ get_key_stream(1, 6)))) {
647 legic_state = STATE_CON;
648
649 /* TIMEOUT */
650 timer->TC_CCR = AT91C_TC_SWTRG;
651 while(timer->TC_CV > 1);
652 while(timer->TC_CV < 200);
653 return;
654 } else {
655 legic_state = STATE_DISCON;
656 LED_C_OFF();
657 Dbprintf("0x19 - Frame: %03.3x", f->data);
658 return;
659 }
660 }
661
662 /* Read */
663 if(f->bits == 11) {
664 if(legic_state == STATE_CON) {
665 int key = get_key_stream(-1, 11); //legic_phase_drift, 11);
666 int addr = f->data ^ key; addr = addr >> 1;
117d9ec2 667 int data = BigBuf[addr];
da05bc6e 668 int hash = calc_crc4(addr, data, 11) << 8;
117d9ec2 669 BigBuf[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
3612a8a8 670 legic_read_count++;
671
672 //Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c);
673 legic_prng_forward(legic_reqresp_drift);
674
675 frame_send_tag(hash | data, 12, 1);
676
677 /* SHORT TIMEOUT */
678 timer->TC_CCR = AT91C_TC_SWTRG;
679 while(timer->TC_CV > 1);
680 legic_prng_forward(legic_frame_drift);
681 while(timer->TC_CV < 180);
682 return;
683 }
684 }
685
686 /* Write */
687 if(f->bits == 23) {
688 int key = get_key_stream(-1, 23); //legic_frame_drift, 23);
689 int addr = f->data ^ key; addr = addr >> 1; addr = addr & 0x3ff;
690 int data = f->data ^ key; data = data >> 11; data = data & 0xff;
691
692 /* write command */
693 legic_state = STATE_DISCON;
694 LED_C_OFF();
695 Dbprintf("write - addr: %x, data: %x", addr, data);
696 return;
697 }
698
699 if(legic_state != STATE_DISCON) {
700 Dbprintf("Unexpected: sz:%u, Data:%03.3x, State:%u, Count:%u", f->bits, f->data, legic_state, legic_read_count);
701 int i;
702 Dbprintf("IV: %03.3x", legic_prng_iv);
703 for(i = 0; i<legic_read_count; i++) {
117d9ec2 704 Dbprintf("Read Nb: %u, Addr: %u", i, BigBuf[OFFSET_LOG+i]);
3612a8a8 705 }
706
707 for(i = -1; i<legic_read_count; i++) {
708 uint32_t t;
117d9ec2 709 t = BigBuf[OFFSET_LOG+256+i*4];
710 t |= BigBuf[OFFSET_LOG+256+i*4+1] << 8;
711 t |= BigBuf[OFFSET_LOG+256+i*4+2] <<16;
712 t |= BigBuf[OFFSET_LOG+256+i*4+3] <<24;
3612a8a8 713
714 Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
117d9ec2 715 BigBuf[OFFSET_LOG+128+i],
716 BigBuf[OFFSET_LOG+384+i],
3612a8a8 717 t);
718 }
719 }
720 legic_state = STATE_DISCON;
721 legic_read_count = 0;
722 SpinDelay(10);
723 LED_C_OFF();
724 return;
725}
726
727/* Read bit by bit untill full frame is received
728 * Call to process frame end answer
729 */
730static void emit(int bit)
731{
732 if(bit == -1) {
733 if(current_frame.bits <= 4) {
734 frame_clean(&current_frame);
735 } else {
736 frame_handle_tag(&current_frame);
737 frame_clean(&current_frame);
738 }
739 WDT_HIT();
740 } else if(bit == 0) {
741 frame_append_bit(&current_frame, 0);
742 } else if(bit == 1) {
743 frame_append_bit(&current_frame, 1);
744 }
745}
746
747void LegicRfSimulate(int phase, int frame, int reqresp)
748{
749 /* ADC path high-frequency peak detector, FPGA in high-frequency simulator mode,
750 * modulation mode set to 212kHz subcarrier. We are getting the incoming raw
751 * envelope waveform on DIN and should send our response on DOUT.
752 *
753 * The LEGIC RF protocol is pulse-pause-encoding from reader to card, so we'll
754 * measure the time between two rising edges on DIN, and no encoding on the
755 * subcarrier from card to reader, so we'll just shift out our verbatim data
756 * on DOUT, 1 bit is 100us. The time from reader to card frame is still unclear,
757 * seems to be 300us-ish.
758 */
759
760 if(phase < 0) {
761 int i;
762 for(i=0; i<=reqresp; i++) {
763 legic_prng_init(SESSION_IV);
764 Dbprintf("i=%u, key 0x%3.3x", i, get_key_stream(i, frame));
765 }
766 return;
767 }
768
769 legic_phase_drift = phase;
770 legic_frame_drift = frame;
771 legic_reqresp_drift = reqresp;
772
7cc204bf 773 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
3612a8a8 774 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
775 FpgaSetupSsc();
776 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K);
777
778 /* Bitbang the receiver */
779 AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_DIN;
780 AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DIN;
781
782 setup_timer();
783 crc_init(&legic_crc, 4, 0x19 >> 1, 0x5, 0);
784
785 int old_level = 0;
786 int active = 0;
787 legic_state = STATE_DISCON;
788
789 LED_B_ON();
790 DbpString("Starting Legic emulator, press button to end");
791 while(!BUTTON_PRESS()) {
792 int level = !!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN);
793 int time = timer->TC_CV;
794
795 if(level != old_level) {
796 if(level == 1) {
797 timer->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
798 if(FUZZ_EQUAL(time, RWD_TIME_1, RWD_TIME_FUZZ)) {
799 /* 1 bit */
800 emit(1);
801 active = 1;
802 LED_A_ON();
803 } else if(FUZZ_EQUAL(time, RWD_TIME_0, RWD_TIME_FUZZ)) {
804 /* 0 bit */
805 emit(0);
806 active = 1;
807 LED_A_ON();
808 } else if(active) {
809 /* invalid */
810 emit(-1);
811 active = 0;
812 LED_A_OFF();
813 }
814 }
815 }
816
817 if(time >= (RWD_TIME_1+RWD_TIME_FUZZ) && active) {
818 /* Frame end */
819 emit(-1);
820 active = 0;
821 LED_A_OFF();
822 }
823
824 if(time >= (20*RWD_TIME_1) && (timer->TC_SR & AT91C_TC_CLKSTA)) {
825 timer->TC_CCR = AT91C_TC_CLKDIS;
826 }
827
828 old_level = level;
829 WDT_HIT();
830 }
831 DbpString("Stopped");
832 LED_B_OFF();
833 LED_A_OFF();
834 LED_C_OFF();
dcc10e5e 835}
a2b1414f 836
Impressum, Datenschutz