]> cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/iso14443.c
Switch compiler to arm-eabi instead of arm-elf
[proxmark3-svn] / armsrc / iso14443.c
1 //-----------------------------------------------------------------------------
2 // Routines to support ISO 14443. This includes both the reader software and
3 // the `fake tag' modes. At the moment only the Type B modulation is
4 // supported.
5 // Jonathan Westhues, split Nov 2006
6 //-----------------------------------------------------------------------------
7 #include <proxmark3.h>
8 #include "apps.h"
9 #include "iso14443crc.h"
10
11
12 //static void GetSamplesFor14443(BOOL weTx, int n);
13
14 #define DEMOD_TRACE_SIZE 4096
15 #define READER_TAG_BUFFER_SIZE 2048
16 #define TAG_READER_BUFFER_SIZE 2048
17 #define DMA_BUFFER_SIZE 1024
18
19 //=============================================================================
20 // An ISO 14443 Type B tag. We listen for commands from the reader, using
21 // a UART kind of thing that's implemented in software. When we get a
22 // frame (i.e., a group of bytes between SOF and EOF), we check the CRC.
23 // If it's good, then we can do something appropriate with it, and send
24 // a response.
25 //=============================================================================
26
27 //-----------------------------------------------------------------------------
28 // Code up a string of octets at layer 2 (including CRC, we don't generate
29 // that here) so that they can be transmitted to the reader. Doesn't transmit
30 // them yet, just leaves them ready to send in ToSend[].
31 //-----------------------------------------------------------------------------
32 static void CodeIso14443bAsTag(const BYTE *cmd, int len)
33 {
34 int i;
35
36 ToSendReset();
37
38 // Transmit a burst of ones, as the initial thing that lets the
39 // reader get phase sync. This (TR1) must be > 80/fs, per spec,
40 // but tag that I've tried (a Paypass) exceeds that by a fair bit,
41 // so I will too.
42 for(i = 0; i < 20; i++) {
43 ToSendStuffBit(1);
44 ToSendStuffBit(1);
45 ToSendStuffBit(1);
46 ToSendStuffBit(1);
47 }
48
49 // Send SOF.
50 for(i = 0; i < 10; i++) {
51 ToSendStuffBit(0);
52 ToSendStuffBit(0);
53 ToSendStuffBit(0);
54 ToSendStuffBit(0);
55 }
56 for(i = 0; i < 2; i++) {
57 ToSendStuffBit(1);
58 ToSendStuffBit(1);
59 ToSendStuffBit(1);
60 ToSendStuffBit(1);
61 }
62
63 for(i = 0; i < len; i++) {
64 int j;
65 BYTE b = cmd[i];
66
67 // Start bit
68 ToSendStuffBit(0);
69 ToSendStuffBit(0);
70 ToSendStuffBit(0);
71 ToSendStuffBit(0);
72
73 // Data bits
74 for(j = 0; j < 8; j++) {
75 if(b & 1) {
76 ToSendStuffBit(1);
77 ToSendStuffBit(1);
78 ToSendStuffBit(1);
79 ToSendStuffBit(1);
80 } else {
81 ToSendStuffBit(0);
82 ToSendStuffBit(0);
83 ToSendStuffBit(0);
84 ToSendStuffBit(0);
85 }
86 b >>= 1;
87 }
88
89 // Stop bit
90 ToSendStuffBit(1);
91 ToSendStuffBit(1);
92 ToSendStuffBit(1);
93 ToSendStuffBit(1);
94 }
95
96 // Send SOF.
97 for(i = 0; i < 10; i++) {
98 ToSendStuffBit(0);
99 ToSendStuffBit(0);
100 ToSendStuffBit(0);
101 ToSendStuffBit(0);
102 }
103 for(i = 0; i < 10; i++) {
104 ToSendStuffBit(1);
105 ToSendStuffBit(1);
106 ToSendStuffBit(1);
107 ToSendStuffBit(1);
108 }
109
110 // Convert from last byte pos to length
111 ToSendMax++;
112
113 // Add a few more for slop
114 ToSendMax += 2;
115 }
116
117 //-----------------------------------------------------------------------------
118 // The software UART that receives commands from the reader, and its state
119 // variables.
120 //-----------------------------------------------------------------------------
121 static struct {
122 enum {
123 STATE_UNSYNCD,
124 STATE_GOT_FALLING_EDGE_OF_SOF,
125 STATE_AWAITING_START_BIT,
126 STATE_RECEIVING_DATA,
127 STATE_ERROR_WAIT
128 } state;
129 WORD shiftReg;
130 int bitCnt;
131 int byteCnt;
132 int byteCntMax;
133 int posCnt;
134 BYTE *output;
135 } Uart;
136
137 /* Receive & handle a bit coming from the reader.
138 *
139 * LED handling:
140 * LED A -> ON once we have received the SOF and are expecting the rest.
141 * LED A -> OFF once we have received EOF or are in error state or unsynced
142 *
143 * Returns: true if we received a EOF
144 * false if we are still waiting for some more
145 */
146 static BOOL Handle14443UartBit(int bit)
147 {
148 switch(Uart.state) {
149 case STATE_UNSYNCD:
150 LED_A_OFF();
151 if(!bit) {
152 // we went low, so this could be the beginning
153 // of an SOF
154 Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF;
155 Uart.posCnt = 0;
156 Uart.bitCnt = 0;
157 }
158 break;
159
160 case STATE_GOT_FALLING_EDGE_OF_SOF:
161 Uart.posCnt++;
162 if(Uart.posCnt == 2) {
163 if(bit) {
164 if(Uart.bitCnt >= 10) {
165 // we've seen enough consecutive
166 // zeros that it's a valid SOF
167 Uart.posCnt = 0;
168 Uart.byteCnt = 0;
169 Uart.state = STATE_AWAITING_START_BIT;
170 LED_A_ON(); // Indicate we got a valid SOF
171 } else {
172 // didn't stay down long enough
173 // before going high, error
174 Uart.state = STATE_ERROR_WAIT;
175 }
176 } else {
177 // do nothing, keep waiting
178 }
179 Uart.bitCnt++;
180 }
181 if(Uart.posCnt >= 4) Uart.posCnt = 0;
182 if(Uart.bitCnt > 14) {
183 // Give up if we see too many zeros without
184 // a one, too.
185 Uart.state = STATE_ERROR_WAIT;
186 }
187 break;
188
189 case STATE_AWAITING_START_BIT:
190 Uart.posCnt++;
191 if(bit) {
192 if(Uart.posCnt > 25) {
193 // stayed high for too long between
194 // characters, error
195 Uart.state = STATE_ERROR_WAIT;
196 }
197 } else {
198 // falling edge, this starts the data byte
199 Uart.posCnt = 0;
200 Uart.bitCnt = 0;
201 Uart.shiftReg = 0;
202 Uart.state = STATE_RECEIVING_DATA;
203 LED_A_ON(); // Indicate we're receiving
204 }
205 break;
206
207 case STATE_RECEIVING_DATA:
208 Uart.posCnt++;
209 if(Uart.posCnt == 2) {
210 // time to sample a bit
211 Uart.shiftReg >>= 1;
212 if(bit) {
213 Uart.shiftReg |= 0x200;
214 }
215 Uart.bitCnt++;
216 }
217 if(Uart.posCnt >= 4) {
218 Uart.posCnt = 0;
219 }
220 if(Uart.bitCnt == 10) {
221 if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001))
222 {
223 // this is a data byte, with correct
224 // start and stop bits
225 Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff;
226 Uart.byteCnt++;
227
228 if(Uart.byteCnt >= Uart.byteCntMax) {
229 // Buffer overflowed, give up
230 Uart.posCnt = 0;
231 Uart.state = STATE_ERROR_WAIT;
232 } else {
233 // so get the next byte now
234 Uart.posCnt = 0;
235 Uart.state = STATE_AWAITING_START_BIT;
236 }
237 } else if(Uart.shiftReg == 0x000) {
238 // this is an EOF byte
239 LED_A_OFF(); // Finished receiving
240 return TRUE;
241 } else {
242 // this is an error
243 Uart.posCnt = 0;
244 Uart.state = STATE_ERROR_WAIT;
245 }
246 }
247 break;
248
249 case STATE_ERROR_WAIT:
250 // We're all screwed up, so wait a little while
251 // for whatever went wrong to finish, and then
252 // start over.
253 Uart.posCnt++;
254 if(Uart.posCnt > 10) {
255 Uart.state = STATE_UNSYNCD;
256 }
257 break;
258
259 default:
260 Uart.state = STATE_UNSYNCD;
261 break;
262 }
263
264 if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error
265
266 return FALSE;
267 }
268
269 //-----------------------------------------------------------------------------
270 // Receive a command (from the reader to us, where we are the simulated tag),
271 // and store it in the given buffer, up to the given maximum length. Keeps
272 // spinning, waiting for a well-framed command, until either we get one
273 // (returns TRUE) or someone presses the pushbutton on the board (FALSE).
274 //
275 // Assume that we're called with the SSC (to the FPGA) and ADC path set
276 // correctly.
277 //-----------------------------------------------------------------------------
278 static BOOL GetIso14443CommandFromReader(BYTE *received, int *len, int maxLen)
279 {
280 BYTE mask;
281 int i, bit;
282
283 // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
284 // only, since we are receiving, not transmitting).
285 // Signal field is off with the appropriate LED
286 LED_D_OFF();
287 FpgaWriteConfWord(
288 FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
289
290
291 // Now run a `software UART' on the stream of incoming samples.
292 Uart.output = received;
293 Uart.byteCntMax = maxLen;
294 Uart.state = STATE_UNSYNCD;
295
296 for(;;) {
297 WDT_HIT();
298
299 if(BUTTON_PRESS()) return FALSE;
300
301 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
302 AT91C_BASE_SSC->SSC_THR = 0x00;
303 }
304 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
305 BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;
306
307 mask = 0x80;
308 for(i = 0; i < 8; i++, mask >>= 1) {
309 bit = (b & mask);
310 if(Handle14443UartBit(bit)) {
311 *len = Uart.byteCnt;
312 return TRUE;
313 }
314 }
315 }
316 }
317 }
318
319 //-----------------------------------------------------------------------------
320 // Main loop of simulated tag: receive commands from reader, decide what
321 // response to send, and send it.
322 //-----------------------------------------------------------------------------
323 void SimulateIso14443Tag(void)
324 {
325 static const BYTE cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
326 static const BYTE response1[] = {
327 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,
328 0x00, 0x21, 0x85, 0x5e, 0xd7
329 };
330
331 BYTE *resp;
332 int respLen;
333
334 BYTE *resp1 = (((BYTE *)BigBuf) + 800);
335 int resp1Len;
336
337 BYTE *receivedCmd = (BYTE *)BigBuf;
338 int len;
339
340 int i;
341
342 int cmdsRecvd = 0;
343
344 memset(receivedCmd, 0x44, 400);
345
346 CodeIso14443bAsTag(response1, sizeof(response1));
347 memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;
348
349 // We need to listen to the high-frequency, peak-detected path.
350 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
351 FpgaSetupSsc();
352
353 cmdsRecvd = 0;
354
355 for(;;) {
356 BYTE b1, b2;
357
358 if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) {
359 Dbprintf("button pressed, received %d commands", cmdsRecvd);
360 break;
361 }
362
363 // Good, look at the command now.
364
365 if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) {
366 resp = resp1; respLen = resp1Len;
367 } else {
368 Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
369 // And print whether the CRC fails, just for good measure
370 ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
371 if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
372 // Not so good, try again.
373 DbpString("+++CRC fail");
374 } else {
375 DbpString("CRC passes");
376 }
377 break;
378 }
379
380 memset(receivedCmd, 0x44, 32);
381
382 cmdsRecvd++;
383
384 if(cmdsRecvd > 0x30) {
385 DbpString("many commands later...");
386 break;
387 }
388
389 if(respLen <= 0) continue;
390
391 // Modulate BPSK
392 // Signal field is off with the appropriate LED
393 LED_D_OFF();
394 FpgaWriteConfWord(
395 FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
396 AT91C_BASE_SSC->SSC_THR = 0xff;
397 FpgaSetupSsc();
398
399 // Transmit the response.
400 i = 0;
401 for(;;) {
402 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
403 BYTE b = resp[i];
404
405 AT91C_BASE_SSC->SSC_THR = b;
406
407 i++;
408 if(i > respLen) {
409 break;
410 }
411 }
412 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
413 volatile BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;
414 (void)b;
415 }
416 }
417 }
418 }
419
420 //=============================================================================
421 // An ISO 14443 Type B reader. We take layer two commands, code them
422 // appropriately, and then send them to the tag. We then listen for the
423 // tag's response, which we leave in the buffer to be demodulated on the
424 // PC side.
425 //=============================================================================
426
427 static struct {
428 enum {
429 DEMOD_UNSYNCD,
430 DEMOD_PHASE_REF_TRAINING,
431 DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
432 DEMOD_GOT_FALLING_EDGE_OF_SOF,
433 DEMOD_AWAITING_START_BIT,
434 DEMOD_RECEIVING_DATA,
435 DEMOD_ERROR_WAIT
436 } state;
437 int bitCount;
438 int posCount;
439 int thisBit;
440 int metric;
441 int metricN;
442 WORD shiftReg;
443 BYTE *output;
444 int len;
445 int sumI;
446 int sumQ;
447 } Demod;
448
449 /*
450 * Handles reception of a bit from the tag
451 *
452 * LED handling:
453 * LED C -> ON once we have received the SOF and are expecting the rest.
454 * LED C -> OFF once we have received EOF or are unsynced
455 *
456 * Returns: true if we received a EOF
457 * false if we are still waiting for some more
458 *
459 */
460 static BOOL Handle14443SamplesDemod(int ci, int cq)
461 {
462 int v;
463
464 // The soft decision on the bit uses an estimate of just the
465 // quadrant of the reference angle, not the exact angle.
466 #define MAKE_SOFT_DECISION() { \
467 if(Demod.sumI > 0) { \
468 v = ci; \
469 } else { \
470 v = -ci; \
471 } \
472 if(Demod.sumQ > 0) { \
473 v += cq; \
474 } else { \
475 v -= cq; \
476 } \
477 }
478
479 switch(Demod.state) {
480 case DEMOD_UNSYNCD:
481 v = ci;
482 if(v < 0) v = -v;
483 if(cq > 0) {
484 v += cq;
485 } else {
486 v -= cq;
487 }
488 if(v > 40) {
489 Demod.posCount = 0;
490 Demod.state = DEMOD_PHASE_REF_TRAINING;
491 Demod.sumI = 0;
492 Demod.sumQ = 0;
493 }
494 break;
495
496 case DEMOD_PHASE_REF_TRAINING:
497 if(Demod.posCount < 8) {
498 Demod.sumI += ci;
499 Demod.sumQ += cq;
500 } else if(Demod.posCount > 100) {
501 // error, waited too long
502 Demod.state = DEMOD_UNSYNCD;
503 } else {
504 MAKE_SOFT_DECISION();
505 if(v < 0) {
506 Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
507 Demod.posCount = 0;
508 }
509 }
510 Demod.posCount++;
511 break;
512
513 case DEMOD_AWAITING_FALLING_EDGE_OF_SOF:
514 MAKE_SOFT_DECISION();
515 if(v < 0) {
516 Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
517 Demod.posCount = 0;
518 } else {
519 if(Demod.posCount > 100) {
520 Demod.state = DEMOD_UNSYNCD;
521 }
522 }
523 Demod.posCount++;
524 break;
525
526 case DEMOD_GOT_FALLING_EDGE_OF_SOF:
527 MAKE_SOFT_DECISION();
528 if(v > 0) {
529 if(Demod.posCount < 12) {
530 Demod.state = DEMOD_UNSYNCD;
531 } else {
532 LED_C_ON(); // Got SOF
533 Demod.state = DEMOD_AWAITING_START_BIT;
534 Demod.posCount = 0;
535 Demod.len = 0;
536 Demod.metricN = 0;
537 Demod.metric = 0;
538 }
539 } else {
540 if(Demod.posCount > 100) {
541 Demod.state = DEMOD_UNSYNCD;
542 }
543 }
544 Demod.posCount++;
545 break;
546
547 case DEMOD_AWAITING_START_BIT:
548 MAKE_SOFT_DECISION();
549 if(v > 0) {
550 if(Demod.posCount > 10) {
551 Demod.state = DEMOD_UNSYNCD;
552 }
553 } else {
554 Demod.bitCount = 0;
555 Demod.posCount = 1;
556 Demod.thisBit = v;
557 Demod.shiftReg = 0;
558 Demod.state = DEMOD_RECEIVING_DATA;
559 }
560 break;
561
562 case DEMOD_RECEIVING_DATA:
563 MAKE_SOFT_DECISION();
564 if(Demod.posCount == 0) {
565 Demod.thisBit = v;
566 Demod.posCount = 1;
567 } else {
568 Demod.thisBit += v;
569
570 if(Demod.thisBit > 0) {
571 Demod.metric += Demod.thisBit;
572 } else {
573 Demod.metric -= Demod.thisBit;
574 }
575 (Demod.metricN)++;
576
577 Demod.shiftReg >>= 1;
578 if(Demod.thisBit > 0) {
579 Demod.shiftReg |= 0x200;
580 }
581
582 Demod.bitCount++;
583 if(Demod.bitCount == 10) {
584 WORD s = Demod.shiftReg;
585 if((s & 0x200) && !(s & 0x001)) {
586 BYTE b = (s >> 1);
587 Demod.output[Demod.len] = b;
588 Demod.len++;
589 Demod.state = DEMOD_AWAITING_START_BIT;
590 } else if(s == 0x000) {
591 // This is EOF
592 LED_C_OFF();
593 return TRUE;
594 Demod.state = DEMOD_UNSYNCD;
595 } else {
596 Demod.state = DEMOD_UNSYNCD;
597 }
598 }
599 Demod.posCount = 0;
600 }
601 break;
602
603 default:
604 Demod.state = DEMOD_UNSYNCD;
605 break;
606 }
607
608 if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized...
609 return FALSE;
610 }
611
612 /*
613 * Demodulate the samples we received from the tag
614 * weTx: set to 'TRUE' if we behave like a reader
615 * set to 'FALSE' if we behave like a snooper
616 * quiet: set to 'TRUE' to disable debug output
617 */
618 static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet)
619 {
620 int max = 0;
621 BOOL gotFrame = FALSE;
622
623 //# define DMA_BUFFER_SIZE 8
624 SBYTE *dmaBuf;
625
626 int lastRxCounter;
627 SBYTE *upTo;
628
629 int ci, cq;
630
631 int samples = 0;
632
633 // Clear out the state of the "UART" that receives from the tag.
634 memset(BigBuf, 0x44, 400);
635 Demod.output = (BYTE *)BigBuf;
636 Demod.len = 0;
637 Demod.state = DEMOD_UNSYNCD;
638
639 // And the UART that receives from the reader
640 Uart.output = (((BYTE *)BigBuf) + 1024);
641 Uart.byteCntMax = 100;
642 Uart.state = STATE_UNSYNCD;
643
644 // Setup for the DMA.
645 dmaBuf = (SBYTE *)(BigBuf + 32);
646 upTo = dmaBuf;
647 lastRxCounter = DMA_BUFFER_SIZE;
648 FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE);
649
650 // Signal field is ON with the appropriate LED:
651 if (weTx) LED_D_ON(); else LED_D_OFF();
652 // And put the FPGA in the appropriate mode
653 FpgaWriteConfWord(
654 FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
655 (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
656
657 for(;;) {
658 int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
659 if(behindBy > max) max = behindBy;
660
661 while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1))
662 > 2)
663 {
664 ci = upTo[0];
665 cq = upTo[1];
666 upTo += 2;
667 if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
668 upTo -= DMA_BUFFER_SIZE;
669 AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD)upTo;
670 AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
671 }
672 lastRxCounter -= 2;
673 if(lastRxCounter <= 0) {
674 lastRxCounter += DMA_BUFFER_SIZE;
675 }
676
677 samples += 2;
678
679 Handle14443UartBit(1);
680 Handle14443UartBit(1);
681
682 if(Handle14443SamplesDemod(ci, cq)) {
683 gotFrame = 1;
684 }
685 }
686
687 if(samples > 2000) {
688 break;
689 }
690 }
691 AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
692 if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len);
693 }
694
695 //-----------------------------------------------------------------------------
696 // Read the tag's response. We just receive a stream of slightly-processed
697 // samples from the FPGA, which we will later do some signal processing on,
698 // to get the bits.
699 //-----------------------------------------------------------------------------
700 /*static void GetSamplesFor14443(BOOL weTx, int n)
701 {
702 BYTE *dest = (BYTE *)BigBuf;
703 int c;
704
705 FpgaWriteConfWord(
706 FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
707 (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
708
709 c = 0;
710 for(;;) {
711 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
712 AT91C_BASE_SSC->SSC_THR = 0x43;
713 }
714 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
715 SBYTE b;
716 b = (SBYTE)AT91C_BASE_SSC->SSC_RHR;
717
718 dest[c++] = (BYTE)b;
719
720 if(c >= n) {
721 break;
722 }
723 }
724 }
725 }*/
726
727 //-----------------------------------------------------------------------------
728 // Transmit the command (to the tag) that was placed in ToSend[].
729 //-----------------------------------------------------------------------------
730 static void TransmitFor14443(void)
731 {
732 int c;
733
734 FpgaSetupSsc();
735
736 while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
737 AT91C_BASE_SSC->SSC_THR = 0xff;
738 }
739
740 // Signal field is ON with the appropriate Red LED
741 LED_D_ON();
742 // Signal we are transmitting with the Green LED
743 LED_B_ON();
744 FpgaWriteConfWord(
745 FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
746
747 for(c = 0; c < 10;) {
748 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
749 AT91C_BASE_SSC->SSC_THR = 0xff;
750 c++;
751 }
752 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
753 volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
754 (void)r;
755 }
756 WDT_HIT();
757 }
758
759 c = 0;
760 for(;;) {
761 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
762 AT91C_BASE_SSC->SSC_THR = ToSend[c];
763 c++;
764 if(c >= ToSendMax) {
765 break;
766 }
767 }
768 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
769 volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
770 (void)r;
771 }
772 WDT_HIT();
773 }
774 LED_B_OFF(); // Finished sending
775 }
776
777 //-----------------------------------------------------------------------------
778 // Code a layer 2 command (string of octets, including CRC) into ToSend[],
779 // so that it is ready to transmit to the tag using TransmitFor14443().
780 //-----------------------------------------------------------------------------
781 void CodeIso14443bAsReader(const BYTE *cmd, int len)
782 {
783 int i, j;
784 BYTE b;
785
786 ToSendReset();
787
788 // Establish initial reference level
789 for(i = 0; i < 40; i++) {
790 ToSendStuffBit(1);
791 }
792 // Send SOF
793 for(i = 0; i < 10; i++) {
794 ToSendStuffBit(0);
795 }
796
797 for(i = 0; i < len; i++) {
798 // Stop bits/EGT
799 ToSendStuffBit(1);
800 ToSendStuffBit(1);
801 // Start bit
802 ToSendStuffBit(0);
803 // Data bits
804 b = cmd[i];
805 for(j = 0; j < 8; j++) {
806 if(b & 1) {
807 ToSendStuffBit(1);
808 } else {
809 ToSendStuffBit(0);
810 }
811 b >>= 1;
812 }
813 }
814 // Send EOF
815 ToSendStuffBit(1);
816 for(i = 0; i < 10; i++) {
817 ToSendStuffBit(0);
818 }
819 for(i = 0; i < 8; i++) {
820 ToSendStuffBit(1);
821 }
822
823 // And then a little more, to make sure that the last character makes
824 // it out before we switch to rx mode.
825 for(i = 0; i < 24; i++) {
826 ToSendStuffBit(1);
827 }
828
829 // Convert from last character reference to length
830 ToSendMax++;
831 }
832
833 //-----------------------------------------------------------------------------
834 // Read an ISO 14443 tag. We send it some set of commands, and record the
835 // responses.
836 // The command name is misleading, it actually decodes the reponse in HEX
837 // into the output buffer (read the result using hexsamples, not hisamples)
838 //-----------------------------------------------------------------------------
839 void AcquireRawAdcSamplesIso14443(DWORD parameter)
840 {
841 BYTE cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
842
843 // Make sure that we start from off, since the tags are stateful;
844 // confusing things will happen if we don't reset them between reads.
845 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
846 LED_D_OFF();
847 SpinDelay(200);
848
849 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
850 FpgaSetupSsc();
851
852 // Now give it time to spin up.
853 // Signal field is on with the appropriate LED
854 LED_D_ON();
855 FpgaWriteConfWord(
856 FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
857 SpinDelay(200);
858
859 CodeIso14443bAsReader(cmd1, sizeof(cmd1));
860 TransmitFor14443();
861 // LED_A_ON();
862 GetSamplesFor14443Demod(TRUE, 2000, FALSE);
863 // LED_A_OFF();
864 }
865
866 //-----------------------------------------------------------------------------
867 // Read a SRI512 ISO 14443 tag.
868 //
869 // SRI512 tags are just simple memory tags, here we're looking at making a dump
870 // of the contents of the memory. No anticollision algorithm is done, we assume
871 // we have a single tag in the field.
872 //
873 // I tried to be systematic and check every answer of the tag, every CRC, etc...
874 //-----------------------------------------------------------------------------
875 void ReadSRI512Iso14443(DWORD parameter)
876 {
877 ReadSTMemoryIso14443(parameter,0x0F);
878 }
879 void ReadSRIX4KIso14443(DWORD parameter)
880 {
881 ReadSTMemoryIso14443(parameter,0x7F);
882 }
883
884 void ReadSTMemoryIso14443(DWORD parameter,DWORD dwLast)
885 {
886 BYTE i = 0x00;
887
888 // Make sure that we start from off, since the tags are stateful;
889 // confusing things will happen if we don't reset them between reads.
890 LED_D_OFF();
891 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
892 SpinDelay(200);
893
894 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
895 FpgaSetupSsc();
896
897 // Now give it time to spin up.
898 // Signal field is on with the appropriate LED
899 LED_D_ON();
900 FpgaWriteConfWord(
901 FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
902 SpinDelay(200);
903
904 // First command: wake up the tag using the INITIATE command
905 BYTE cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
906 CodeIso14443bAsReader(cmd1, sizeof(cmd1));
907 TransmitFor14443();
908 // LED_A_ON();
909 GetSamplesFor14443Demod(TRUE, 2000,TRUE);
910 // LED_A_OFF();
911
912 if (Demod.len == 0) {
913 DbpString("No response from tag");
914 return;
915 } else {
916 Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %x %x %x",
917 Demod.output[0], Demod.output[1],Demod.output[2]);
918 }
919 // There is a response, SELECT the uid
920 DbpString("Now SELECT tag:");
921 cmd1[0] = 0x0E; // 0x0E is SELECT
922 cmd1[1] = Demod.output[0];
923 ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
924 CodeIso14443bAsReader(cmd1, sizeof(cmd1));
925 TransmitFor14443();
926 // LED_A_ON();
927 GetSamplesFor14443Demod(TRUE, 2000,TRUE);
928 // LED_A_OFF();
929 if (Demod.len != 3) {
930 Dbprintf("Expected 3 bytes from tag, got %d", Demod.len);
931 return;
932 }
933 // Check the CRC of the answer:
934 ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);
935 if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {
936 DbpString("CRC Error reading select response.");
937 return;
938 }
939 // Check response from the tag: should be the same UID as the command we just sent:
940 if (cmd1[1] != Demod.output[0]) {
941 Dbprintf("Bad response to SELECT from Tag, aborting: %x %x", cmd1[1], Demod.output[0]);
942 return;
943 }
944 // Tag is now selected,
945 // First get the tag's UID:
946 cmd1[0] = 0x0B;
947 ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
948 CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one
949 TransmitFor14443();
950 // LED_A_ON();
951 GetSamplesFor14443Demod(TRUE, 2000,TRUE);
952 // LED_A_OFF();
953 if (Demod.len != 10) {
954 Dbprintf("Expected 10 bytes from tag, got %d", Demod.len);
955 return;
956 }
957 // The check the CRC of the answer (use cmd1 as temporary variable):
958 ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
959 if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
960 Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
961 (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]);
962 // Do not return;, let's go on... (we should retry, maybe ?)
963 }
964 Dbprintf("Tag UID (64 bits): %08x %08x",
965 (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
966 (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
967
968 // Now loop to read all 16 blocks, address from 0 to 15
969 DbpString("Tag memory dump, block 0 to 15");
970 cmd1[0] = 0x08;
971 i = 0x00;
972 dwLast++;
973 for (;;) {
974 if (i == dwLast) {
975 DbpString("System area block (0xff):");
976 i = 0xff;
977 }
978 cmd1[1] = i;
979 ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
980 CodeIso14443bAsReader(cmd1, sizeof(cmd1));
981 TransmitFor14443();
982 // LED_A_ON();
983 GetSamplesFor14443Demod(TRUE, 2000,TRUE);
984 // LED_A_OFF();
985 if (Demod.len != 6) { // Check if we got an answer from the tag
986 DbpString("Expected 6 bytes from tag, got less...");
987 return;
988 }
989 // The check the CRC of the answer (use cmd1 as temporary variable):
990 ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
991 if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
992 Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
993 (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]);
994 // Do not return;, let's go on... (we should retry, maybe ?)
995 }
996 // Now print out the memory location:
997 Dbprintf("Address=%x, Contents=%x, CRC=%x", i,
998 (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
999 (Demod.output[4]<<8)+Demod.output[5]);
1000 if (i == 0xff) {
1001 break;
1002 }
1003 i++;
1004 }
1005 }
1006
1007
1008 //=============================================================================
1009 // Finally, the `sniffer' combines elements from both the reader and
1010 // simulated tag, to show both sides of the conversation.
1011 //=============================================================================
1012
1013 //-----------------------------------------------------------------------------
1014 // Record the sequence of commands sent by the reader to the tag, with
1015 // triggering so that we start recording at the point that the tag is moved
1016 // near the reader.
1017 //-----------------------------------------------------------------------------
1018 /*
1019 * Memory usage for this function, (within BigBuf)
1020 * 0-4095 : Demodulated samples receive (4096 bytes) - DEMOD_TRACE_SIZE
1021 * 4096-6143 : Last Received command, 2048 bytes (reader->tag) - READER_TAG_BUFFER_SIZE
1022 * 6144-8191 : Last Received command, 2048 bytes(tag->reader) - TAG_READER_BUFFER_SIZE
1023 * 8192-9215 : DMA Buffer, 1024 bytes (samples) - DMA_BUFFER_SIZE
1024 */
1025 void SnoopIso14443(void)
1026 {
1027 // We won't start recording the frames that we acquire until we trigger;
1028 // a good trigger condition to get started is probably when we see a
1029 // response from the tag.
1030 BOOL triggered = FALSE;
1031
1032 // The command (reader -> tag) that we're working on receiving.
1033 BYTE *receivedCmd = (BYTE *)(BigBuf) + DEMOD_TRACE_SIZE;
1034 // The response (tag -> reader) that we're working on receiving.
1035 BYTE *receivedResponse = (BYTE *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE;
1036
1037 // As we receive stuff, we copy it from receivedCmd or receivedResponse
1038 // into trace, along with its length and other annotations.
1039 BYTE *trace = (BYTE *)BigBuf;
1040 int traceLen = 0;
1041
1042 // The DMA buffer, used to stream samples from the FPGA.
1043 SBYTE *dmaBuf = (SBYTE *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE;
1044 int lastRxCounter;
1045 SBYTE *upTo;
1046 int ci, cq;
1047 int maxBehindBy = 0;
1048
1049 // Count of samples received so far, so that we can include timing
1050 // information in the trace buffer.
1051 int samples = 0;
1052
1053 // Initialize the trace buffer
1054 memset(trace, 0x44, DEMOD_TRACE_SIZE);
1055
1056 // Set up the demodulator for tag -> reader responses.
1057 Demod.output = receivedResponse;
1058 Demod.len = 0;
1059 Demod.state = DEMOD_UNSYNCD;
1060
1061 // And the reader -> tag commands
1062 memset(&Uart, 0, sizeof(Uart));
1063 Uart.output = receivedCmd;
1064 Uart.byteCntMax = 100;
1065 Uart.state = STATE_UNSYNCD;
1066
1067 // Print some debug information about the buffer sizes
1068 Dbprintf("Snooping buffers initialized:");
1069 Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE);
1070 Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
1071 Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
1072 Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE);
1073
1074 // Use a counter for blinking the LED
1075 long ledCount=0;
1076 long ledFlashAt=200000;
1077
1078 // And put the FPGA in the appropriate mode
1079 // Signal field is off with the appropriate LED
1080 LED_D_OFF();
1081 FpgaWriteConfWord(
1082 FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
1083 FPGA_HF_READER_RX_XCORR_SNOOP);
1084 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1085
1086 // Setup for the DMA.
1087 FpgaSetupSsc();
1088 upTo = dmaBuf;
1089 lastRxCounter = DMA_BUFFER_SIZE;
1090 FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE);
1091 // And now we loop, receiving samples.
1092 for(;;) {
1093 // Blink the LED while Snooping
1094 ledCount++;
1095 if (ledCount == ledFlashAt) {
1096 LED_D_ON();
1097 }
1098 if (ledCount >= 2*ledFlashAt) {
1099 LED_D_OFF();
1100 ledCount=0;
1101 }
1102
1103 int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
1104 (DMA_BUFFER_SIZE-1);
1105 if(behindBy > maxBehindBy) {
1106 maxBehindBy = behindBy;
1107 if(behindBy > (DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not?
1108 Dbprintf("blew circular buffer! behindBy=%x", behindBy);
1109 goto done;
1110 }
1111 }
1112 if(behindBy < 2) continue;
1113
1114 ci = upTo[0];
1115 cq = upTo[1];
1116 upTo += 2;
1117 lastRxCounter -= 2;
1118 if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
1119 upTo -= DMA_BUFFER_SIZE;
1120 lastRxCounter += DMA_BUFFER_SIZE;
1121 AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD) upTo;
1122 AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
1123 }
1124
1125 samples += 2;
1126
1127 #define HANDLE_BIT_IF_BODY \
1128 if(triggered) { \
1129 ledFlashAt=30000; \
1130 trace[traceLen++] = ((samples >> 0) & 0xff); \
1131 trace[traceLen++] = ((samples >> 8) & 0xff); \
1132 trace[traceLen++] = ((samples >> 16) & 0xff); \
1133 trace[traceLen++] = ((samples >> 24) & 0xff); \
1134 trace[traceLen++] = 0; \
1135 trace[traceLen++] = 0; \
1136 trace[traceLen++] = 0; \
1137 trace[traceLen++] = 0; \
1138 trace[traceLen++] = Uart.byteCnt; \
1139 memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \
1140 traceLen += Uart.byteCnt; \
1141 if(traceLen > 1000) break; \
1142 } \
1143 /* And ready to receive another command. */ \
1144 memset(&Uart, 0, sizeof(Uart)); \
1145 Uart.output = receivedCmd; \
1146 Uart.byteCntMax = 100; \
1147 Uart.state = STATE_UNSYNCD; \
1148 /* And also reset the demod code, which might have been */ \
1149 /* false-triggered by the commands from the reader. */ \
1150 memset(&Demod, 0, sizeof(Demod)); \
1151 Demod.output = receivedResponse; \
1152 Demod.state = DEMOD_UNSYNCD; \
1153
1154 if(Handle14443UartBit(ci & 1)) {
1155 HANDLE_BIT_IF_BODY
1156 }
1157 if(Handle14443UartBit(cq & 1)) {
1158 HANDLE_BIT_IF_BODY
1159 }
1160
1161 if(Handle14443SamplesDemod(ci, cq)) {
1162 // timestamp, as a count of samples
1163 trace[traceLen++] = ((samples >> 0) & 0xff);
1164 trace[traceLen++] = ((samples >> 8) & 0xff);
1165 trace[traceLen++] = ((samples >> 16) & 0xff);
1166 trace[traceLen++] = 0x80 | ((samples >> 24) & 0xff);
1167 // correlation metric (~signal strength estimate)
1168 if(Demod.metricN != 0) {
1169 Demod.metric /= Demod.metricN;
1170 }
1171 trace[traceLen++] = ((Demod.metric >> 0) & 0xff);
1172 trace[traceLen++] = ((Demod.metric >> 8) & 0xff);
1173 trace[traceLen++] = ((Demod.metric >> 16) & 0xff);
1174 trace[traceLen++] = ((Demod.metric >> 24) & 0xff);
1175 // length
1176 trace[traceLen++] = Demod.len;
1177 memcpy(trace+traceLen, receivedResponse, Demod.len);
1178 traceLen += Demod.len;
1179 if(traceLen > DEMOD_TRACE_SIZE) {
1180 DbpString("Reached trace limit");
1181 goto done;
1182 }
1183
1184 triggered = TRUE;
1185
1186 // And ready to receive another response.
1187 memset(&Demod, 0, sizeof(Demod));
1188 Demod.output = receivedResponse;
1189 Demod.state = DEMOD_UNSYNCD;
1190 }
1191 WDT_HIT();
1192
1193 if(BUTTON_PRESS()) {
1194 DbpString("cancelled");
1195 goto done;
1196 }
1197 }
1198
1199 done:
1200 LED_D_OFF();
1201 AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
1202 DbpString("Snoop statistics:");
1203 Dbprintf(" Max behind by: %i", maxBehindBy);
1204 Dbprintf(" Uart State: %x", Uart.state);
1205 Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
1206 Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);
1207 Dbprintf(" Trace length: %i", traceLen);
1208 }
Impressum, Datenschutz