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