1 //-----------------------------------------------------------------------------
2 // (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
4 // 2018 AntiCat (rwd rewritten)
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
9 //-----------------------------------------------------------------------------
10 // LEGIC RF simulation code
11 //-----------------------------------------------------------------------------
13 #include "proxmark3.h"
19 #include "legic_prng.h"
23 static struct legic_frame
{
34 static crc_t legic_crc
;
35 static int legic_read_count
;
36 static uint32_t legic_prng_bc
;
37 static uint32_t legic_prng_iv
;
39 static int legic_phase_drift
;
40 static int legic_frame_drift
;
41 static int legic_reqresp_drift
;
46 static legic_card_select_t card
;/* metadata of currently selected card */
48 //-----------------------------------------------------------------------------
49 // Frame timing and pseudorandom number generator
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)
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.
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 //-----------------------------------------------------------------------------
64 static uint32_t last_frame_end
; /* ts of last bit of previews rx or tx frame */
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) */
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 */
79 #define LEGIC_READ 0x01 /* Read Command */
80 #define LEGIC_WRITE 0x00 /* Write Command */
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 */
86 #define INPUT_THRESHOLD 8 /* heuristically determined, lower values */
87 /* lead to detecting false ack during write */
89 #define FUZZ_EQUAL(value, target, fuzz) ((value) > ((target)-(fuzz)) && (value) < ((target)+(fuzz)))
91 //-----------------------------------------------------------------------------
92 // I/O interface abstraction (FPGA -> ARM)
93 //-----------------------------------------------------------------------------
95 static inline uint8_t rx_byte_from_fpga() {
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
;
106 //-----------------------------------------------------------------------------
107 // Demodulation (Reader)
108 //-----------------------------------------------------------------------------
110 // Returns a demedulated bit
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).
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))
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.
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
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.
129 static inline bool rx_bit_as_reader() {
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();
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();
146 int32_t power
= (MAX(ABS(ci
), ABS(cq
)) + (MIN(ABS(ci
), ABS(cq
)) >> 1));
148 // compare average (power / 8) to threshold
149 return ((power
>> 3) > INPUT_THRESHOLD
);
152 //-----------------------------------------------------------------------------
153 // Modulation (Reader)
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 //-----------------------------------------------------------------------------
161 static inline void tx_bit_as_reader(bool bit
) {
164 last_frame_end
+= RWD_TIME_PAUSE
;
165 while(GET_TICKS
< last_frame_end
) { };
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
) { };
173 //-----------------------------------------------------------------------------
174 // Frame Handling (Reader)
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
181 //-----------------------------------------------------------------------------
183 static void tx_frame_as_reader(uint32_t frame
, uint8_t len
) {
184 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX
);
186 // wait for next tx timeslot
187 last_frame_end
+= RWD_FRAME_WAIT
;
188 while(GET_TICKS
< last_frame_end
) { };
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);
197 // add pause to mark end of the frame
199 last_frame_end
+= RWD_TIME_PAUSE
;
200 while(GET_TICKS
< last_frame_end
) { };
204 static 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
);
209 // hold sampling until card is expected to respond
210 last_frame_end
+= TAG_FRAME_WAIT
;
211 while(GET_TICKS
< last_frame_end
) { };
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);
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
) { };
226 static 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
);
232 // hold sampling until card is expected to respond
233 last_frame_end
+= TAG_FRAME_WAIT
;
234 while(GET_TICKS
< last_frame_end
) { };
237 for(uint8_t i
= 0; i
< TAG_WRITE_TIMEOUT
; ++i
) {
239 ack
= rx_bit_as_reader();
240 legic_prng_forward(1);
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
) { };
246 // check if it was an ACK
255 //-----------------------------------------------------------------------------
257 //-----------------------------------------------------------------------------
259 int init_card(uint8_t cardtype
, legic_card_select_t
*p_card
) {
260 p_card
->tagtype
= cardtype
;
262 switch(p_card
->tagtype
) {
265 p_card
->addrsize
= 5;
266 p_card
->cardsize
= 22;
270 p_card
->addrsize
= 8;
271 p_card
->cardsize
= 256;
274 p_card
->cmdsize
= 11;
275 p_card
->addrsize
= 10;
276 p_card
->cardsize
= 1024;
280 p_card
->addrsize
= 0;
281 p_card
->cardsize
= 0;
287 static void init_reader(bool clear_mem
) {
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
);
296 // configure SSC with defaults
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
;
304 // init crc calculator
305 crc_init(&legic_crc
, 4, 0x19 >> 1, 0x05, 0);
311 // Setup reader to card connection
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
317 static uint32_t setup_phase_reader(uint8_t iv
) {
318 // init coordination timestamp
319 last_frame_end
= GET_TICKS
;
321 // Switch on carrier and let the card charge for 5ms.
322 last_frame_end
+= 7500;
323 while(GET_TICKS
< last_frame_end
) { };
326 tx_frame_as_reader(iv
, 7);
330 legic_prng_forward(2);
333 int32_t card_type
= rx_frame_as_reader(6);
334 legic_prng_forward(3);
336 // send obsfuscated acknowledgment frame
339 tx_frame_as_reader(0x19, 6); // MIM22 | READCMD = 0x18 | 0x01
343 tx_frame_as_reader(0x39, 6); // MIM256 | READCMD = 0x38 | 0x01
350 static 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
);
356 static int16_t read_byte(uint16_t index
, uint8_t cmd_sz
) {
357 uint16_t cmd
= (index
<< 1) | LEGIC_READ
;
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);
367 // split frame into data and crc
368 uint8_t byte
= BYTEx(frame
, 0);
369 uint8_t crc
= BYTEx(frame
, 1);
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
);
378 legic_prng_forward(1);
383 // Transmit write command, wait until (3.6ms) the tag sends back an unencrypted
384 // ACK ('1' bit) and forward the prng time based.
385 bool 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
391 // send write command
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);
399 return rx_ack_as_reader();
402 //-----------------------------------------------------------------------------
403 // Command Line Interface
405 // Only this functions are public / called from appmain.c
406 //-----------------------------------------------------------------------------
407 void LegicRfReader(int offset
, int bytes
) {
408 uint8_t *BigBuf
= BigBuf_get_addr();
409 memset(BigBuf
, 0, 1024);
411 // configure ARM and FPGA
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");
422 // if no argument is specified create full dump
424 bytes
= card
.cardsize
;
427 // do not read beyond card memory
428 if(bytes
+ offset
> card
.cardsize
) {
429 bytes
= card
.cardsize
- offset
;
432 for(uint16_t i
= 0; i
< bytes
; ++i
) {
433 int16_t byte
= read_byte(offset
+ i
, card
.cmdsize
);
435 Dbprintf("operation failed @ 0x%03.3x", bytes
);
442 Dbprintf("Card (MIM %i) read, use 'hf legic decode' or", card
.cardsize
);
443 Dbprintf("'data hexsamples %d' to view results", (bytes
+7) & ~7);
446 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
453 void LegicRfWriter(int bytes
, int offset
) {
454 uint8_t *BigBuf
= BigBuf_get_addr();
456 // configure ARM and FPGA
459 // uid is not writeable
460 if(offset
<= WRITE_LOWERLIMIT
) {
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");
472 // do not write beyond card memory
473 if(bytes
+ offset
> card
.cardsize
) {
474 bytes
= card
.cardsize
- offset
;
477 // write in reverse order, only then is DCF (decremental field) writable
478 while(bytes
-- > 0 && !BUTTON_PRESS()) {
479 if(!write_byte(bytes
+ offset
, BigBuf
[bytes
+ offset
], card
.addrsize
)) {
480 Dbprintf("operation failed @ 0x%03.3x", bytes
);
486 DbpString("Write successful");
489 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
496 //-----------------------------------------------------------------------------
498 //-----------------------------------------------------------------------------
500 static void setup_timer(void)
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.
505 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_TC1
);
506 timer
= AT91C_BASE_TC1
;
507 timer
->TC_CCR
= AT91C_TC_CLKDIS
;
508 timer
->TC_CMR
= AT91C_TC_CLKS_TIMER_DIV3_CLOCK
;
509 timer
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
512 * Set up Timer 2 to use for measuring time between frames in
513 * tag simulation mode. Runs 4x faster as Timer 1
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
;
522 /* Generate Keystream */
523 static uint32_t get_key_stream(int skip
, int count
)
525 uint32_t key
=0; int i
;
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
;
531 /* If skip == -1, forward prng time based */
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
);
538 legic_prng_forward(skip
);
541 /* Write Time Data into LOG */
542 uint8_t *BigBuf
= BigBuf_get_addr();
543 if(count
== 6) { i
= -1; } else { i
= legic_read_count
; }
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
;
551 /* Generate KeyStream */
552 for(i
=0; i
<count
; i
++) {
553 key
|= legic_prng_get_bit() << i
;
554 legic_prng_forward(1);
559 /* Send a frame in tag mode, the FPGA must have been set up by
562 static void frame_send_tag(uint16_t response
, int bits
, int crypt
)
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
;
569 /* Use time to crypt frame */
571 legic_prng_forward(2); /* TAG_TIME_WAIT -> shift by 2 */
573 for(i
=0; i
<bits
; i
++) {
574 key
|= legic_prng_get_bit() << i
;
575 legic_prng_forward(1);
577 //Dbprintf("key = 0x%x", key);
578 response
= response
^ key
;
581 /* Wait for the frame start */
582 while(timer
->TC_CV
< (TAG_FRAME_WAIT
- 30)) ;
585 for(i
=0; i
<bits
; i
++) {
586 int nextbit
= timer
->TC_CV
+ TAG_BIT_PERIOD
;
587 int bit
= response
& 1;
588 response
= response
>> 1;
590 AT91C_BASE_PIOA
->PIO_SODR
= GPIO_SSC_DOUT
;
592 AT91C_BASE_PIOA
->PIO_CODR
= GPIO_SSC_DOUT
;
594 while(timer
->TC_CV
< nextbit
) ;
596 AT91C_BASE_PIOA
->PIO_CODR
= GPIO_SSC_DOUT
;
599 static void frame_append_bit(struct legic_frame
* const f
, int bit
)
602 return; /* Overflow, won't happen */
604 f
->data
|= (bit
<<f
->bits
);
608 static void frame_clean(struct legic_frame
* const f
)
614 /* Handle (whether to respond) a frame in tag mode */
615 static void frame_handle_tag(struct legic_frame
const * const f
)
617 uint8_t *BigBuf
= BigBuf_get_addr();
619 /* First Part of Handshake (IV) */
621 if(f
->data
== SESSION_IV
) {
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;
629 legic_prng_iv
= f
->data
;
632 timer
->TC_CCR
= AT91C_TC_SWTRG
;
633 while(timer
->TC_CV
> 1);
634 while(timer
->TC_CV
< 280);
636 } else if((prng_timer
->TC_CV
% 50) > 40) {
637 legic_prng_init(f
->data
);
638 frame_send_tag(0x3d, 6, 1);
645 if(legic_state
== STATE_IV
) {
646 if((f
->bits
== 6) && (f
->data
== (0x19 ^ get_key_stream(1, 6)))) {
647 legic_state
= STATE_CON
;
650 timer
->TC_CCR
= AT91C_TC_SWTRG
;
651 while(timer
->TC_CV
> 1);
652 while(timer
->TC_CV
< 200);
655 legic_state
= STATE_DISCON
;
657 Dbprintf("0x19 - Frame: %03.3x", f
->data
);
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;
667 int data
= BigBuf
[addr
];
668 int hash
= calc_crc4(addr
, data
, 11) << 8;
669 BigBuf
[OFFSET_LOG
+legic_read_count
] = (uint8_t)addr
;
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
);
675 frame_send_tag(hash
| data
, 12, 1);
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);
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;
693 legic_state
= STATE_DISCON
;
695 Dbprintf("write - addr: %x, data: %x", addr
, data
);
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
);
702 Dbprintf("IV: %03.3x", legic_prng_iv
);
703 for(i
= 0; i
<legic_read_count
; i
++) {
704 Dbprintf("Read Nb: %u, Addr: %u", i
, BigBuf
[OFFSET_LOG
+i
]);
707 for(i
= -1; i
<legic_read_count
; i
++) {
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;
714 Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
715 BigBuf
[OFFSET_LOG
+128+i
],
716 BigBuf
[OFFSET_LOG
+384+i
],
720 legic_state
= STATE_DISCON
;
721 legic_read_count
= 0;
727 /* Read bit by bit untill full frame is received
728 * Call to process frame end answer
730 static void emit(int bit
)
733 if(current_frame
.bits
<= 4) {
734 frame_clean(¤t_frame
);
736 frame_handle_tag(¤t_frame
);
737 frame_clean(¤t_frame
);
740 } else if(bit
== 0) {
741 frame_append_bit(¤t_frame
, 0);
742 } else if(bit
== 1) {
743 frame_append_bit(¤t_frame
, 1);
747 void LegicRfSimulate(int phase
, int frame
, int reqresp
)
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.
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.
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
));
769 legic_phase_drift
= phase
;
770 legic_frame_drift
= frame
;
771 legic_reqresp_drift
= reqresp
;
773 FpgaDownloadAndGo(FPGA_BITSTREAM_HF
);
774 SetAdcMuxFor(GPIO_MUXSEL_HIPKD
);
776 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
| FPGA_HF_SIMULATOR_MODULATE_212K
);
778 /* Bitbang the receiver */
779 AT91C_BASE_PIOA
->PIO_ODR
= GPIO_SSC_DIN
;
780 AT91C_BASE_PIOA
->PIO_PER
= GPIO_SSC_DIN
;
783 crc_init(&legic_crc
, 4, 0x19 >> 1, 0x5, 0);
787 legic_state
= STATE_DISCON
;
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
;
795 if(level
!= old_level
) {
797 timer
->TC_CCR
= AT91C_TC_CLKEN
| AT91C_TC_SWTRG
;
798 if(FUZZ_EQUAL(time
, RWD_TIME_1
, RWD_TIME_FUZZ
)) {
803 } else if(FUZZ_EQUAL(time
, RWD_TIME_0
, RWD_TIME_FUZZ
)) {
817 if(time
>= (RWD_TIME_1
+RWD_TIME_FUZZ
) && active
) {
824 if(time
>= (20*RWD_TIME_1
) && (timer
->TC_SR
& AT91C_TC_CLKSTA
)) {
825 timer
->TC_CCR
= AT91C_TC_CLKDIS
;
831 DbpString("Stopped");