]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iclass.c
Legic TagSim: increased reader timeout (#771)
[proxmark3-svn] / armsrc / iclass.c
CommitLineData
cee5a30d 1//-----------------------------------------------------------------------------
2// Gerhard de Koning Gans - May 2008
3// Hagen Fritsch - June 2010
4// Gerhard de Koning Gans - May 2011
1e262141 5// Gerhard de Koning Gans - June 2012 - Added iClass card and reader emulation
cee5a30d 6//
7// This code is licensed to you under the terms of the GNU GPL, version 2 or,
8// at your option, any later version. See the LICENSE.txt file for the text of
9// the license.
10//-----------------------------------------------------------------------------
11// Routines to support iClass.
12//-----------------------------------------------------------------------------
13// Based on ISO14443a implementation. Still in experimental phase.
14// Contribution made during a security research at Radboud University Nijmegen
15//
16// Please feel free to contribute and extend iClass support!!
17//-----------------------------------------------------------------------------
18//
cee5a30d 19// FIX:
20// ====
21// We still have sometimes a demodulation error when snooping iClass communication.
22// The resulting trace of a read-block-03 command may look something like this:
23//
24// + 22279: : 0c 03 e8 01
25//
26// ...with an incorrect answer...
27//
28// + 85: 0: TAG ff! ff! ff! ff! ff! ff! ff! ff! bb 33 bb 00 01! 0e! 04! bb !crc
29//
30// We still left the error signalling bytes in the traces like 0xbb
31//
32// A correct trace should look like this:
33//
34// + 21112: : 0c 03 e8 01
35// + 85: 0: TAG ff ff ff ff ff ff ff ff ea f5
36//
37//-----------------------------------------------------------------------------
38
39#include "proxmark3.h"
40#include "apps.h"
41#include "util.h"
42#include "string.h"
7e67e42f 43#include "common.h"
fecd8202 44#include "cmd.h"
6e49717b 45#include "iso14443a.h"
1e262141 46// Needed for CRC in emulation mode;
47// same construction as in ISO 14443;
48// different initial value (CRC_ICLASS)
49#include "iso14443crc.h"
c3963755 50#include "iso15693tools.h"
b67f7ec3 51#include "protocols.h"
10a8875c 52#include "optimized_cipher.h"
979c7655 53#include "usb_cdc.h" // for usb_poll_validate_length
10a8875c 54
1e262141 55static int timeout = 4096;
cee5a30d 56
cee5a30d 57
1e262141 58static int SendIClassAnswer(uint8_t *resp, int respLen, int delay);
cee5a30d 59
60//-----------------------------------------------------------------------------
61// The software UART that receives commands from the reader, and its state
62// variables.
63//-----------------------------------------------------------------------------
64static struct {
65 enum {
66 STATE_UNSYNCD,
67 STATE_START_OF_COMMUNICATION,
68 STATE_RECEIVING
69 } state;
70 uint16_t shiftReg;
71 int bitCnt;
72 int byteCnt;
73 int byteCntMax;
74 int posCnt;
75 int nOutOfCnt;
76 int OutOfCnt;
77 int syncBit;
1e262141 78 int samples;
cee5a30d 79 int highCnt;
80 int swapper;
81 int counter;
82 int bitBuffer;
83 int dropPosition;
6a1f2d82 84 uint8_t *output;
cee5a30d 85} Uart;
86
1e262141 87static RAMFUNC int OutOfNDecoding(int bit)
cee5a30d 88{
9f693930 89 //int error = 0;
cee5a30d 90 int bitright;
91
92 if(!Uart.bitBuffer) {
93 Uart.bitBuffer = bit ^ 0xFF0;
44964fd1 94 return false;
cee5a30d 95 }
96 else {
97 Uart.bitBuffer <<= 4;
98 Uart.bitBuffer ^= bit;
99 }
100
101 /*if(Uart.swapper) {
102 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF;
103 Uart.byteCnt++;
104 Uart.swapper = 0;
44964fd1 105 if(Uart.byteCnt > 15) { return true; }
cee5a30d 106 }
107 else {
108 Uart.swapper = 1;
109 }*/
110
111 if(Uart.state != STATE_UNSYNCD) {
112 Uart.posCnt++;
113
114 if((Uart.bitBuffer & Uart.syncBit) ^ Uart.syncBit) {
115 bit = 0x00;
116 }
117 else {
118 bit = 0x01;
119 }
120 if(((Uart.bitBuffer << 1) & Uart.syncBit) ^ Uart.syncBit) {
121 bitright = 0x00;
122 }
123 else {
124 bitright = 0x01;
125 }
126 if(bit != bitright) { bit = bitright; }
127
128
129 // So, now we only have to deal with *bit*, lets see...
130 if(Uart.posCnt == 1) {
131 // measurement first half bitperiod
132 if(!bit) {
133 // Drop in first half means that we are either seeing
134 // an SOF or an EOF.
135
136 if(Uart.nOutOfCnt == 1) {
137 // End of Communication
138 Uart.state = STATE_UNSYNCD;
139 Uart.highCnt = 0;
140 if(Uart.byteCnt == 0) {
141 // Its not straightforward to show single EOFs
44964fd1 142 // So just leave it and do not return true
6a1f2d82 143 Uart.output[0] = 0xf0;
cee5a30d 144 Uart.byteCnt++;
cee5a30d 145 }
146 else {
44964fd1 147 return true;
cee5a30d 148 }
149 }
150 else if(Uart.state != STATE_START_OF_COMMUNICATION) {
151 // When not part of SOF or EOF, it is an error
152 Uart.state = STATE_UNSYNCD;
153 Uart.highCnt = 0;
9f693930 154 //error = 4;
cee5a30d 155 }
156 }
157 }
158 else {
159 // measurement second half bitperiod
160 // Count the bitslot we are in... (ISO 15693)
161 Uart.nOutOfCnt++;
162
163 if(!bit) {
164 if(Uart.dropPosition) {
165 if(Uart.state == STATE_START_OF_COMMUNICATION) {
9f693930 166 //error = 1;
cee5a30d 167 }
168 else {
9f693930 169 //error = 7;
cee5a30d 170 }
171 // It is an error if we already have seen a drop in current frame
172 Uart.state = STATE_UNSYNCD;
173 Uart.highCnt = 0;
174 }
175 else {
176 Uart.dropPosition = Uart.nOutOfCnt;
177 }
178 }
179
180 Uart.posCnt = 0;
181
182
183 if(Uart.nOutOfCnt == Uart.OutOfCnt && Uart.OutOfCnt == 4) {
184 Uart.nOutOfCnt = 0;
185
186 if(Uart.state == STATE_START_OF_COMMUNICATION) {
187 if(Uart.dropPosition == 4) {
188 Uart.state = STATE_RECEIVING;
189 Uart.OutOfCnt = 256;
190 }
191 else if(Uart.dropPosition == 3) {
192 Uart.state = STATE_RECEIVING;
193 Uart.OutOfCnt = 4;
194 //Uart.output[Uart.byteCnt] = 0xdd;
195 //Uart.byteCnt++;
196 }
197 else {
198 Uart.state = STATE_UNSYNCD;
199 Uart.highCnt = 0;
200 }
201 Uart.dropPosition = 0;
202 }
203 else {
204 // RECEIVING DATA
205 // 1 out of 4
206 if(!Uart.dropPosition) {
207 Uart.state = STATE_UNSYNCD;
208 Uart.highCnt = 0;
9f693930 209 //error = 9;
cee5a30d 210 }
211 else {
212 Uart.shiftReg >>= 2;
213
214 // Swap bit order
215 Uart.dropPosition--;
216 //if(Uart.dropPosition == 1) { Uart.dropPosition = 2; }
217 //else if(Uart.dropPosition == 2) { Uart.dropPosition = 1; }
218
219 Uart.shiftReg ^= ((Uart.dropPosition & 0x03) << 6);
220 Uart.bitCnt += 2;
221 Uart.dropPosition = 0;
222
223 if(Uart.bitCnt == 8) {
224 Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff);
225 Uart.byteCnt++;
cee5a30d 226 Uart.bitCnt = 0;
227 Uart.shiftReg = 0;
228 }
229 }
230 }
231 }
232 else if(Uart.nOutOfCnt == Uart.OutOfCnt) {
233 // RECEIVING DATA
234 // 1 out of 256
235 if(!Uart.dropPosition) {
236 Uart.state = STATE_UNSYNCD;
237 Uart.highCnt = 0;
9f693930 238 //error = 3;
cee5a30d 239 }
240 else {
241 Uart.dropPosition--;
242 Uart.output[Uart.byteCnt] = (Uart.dropPosition & 0xff);
243 Uart.byteCnt++;
cee5a30d 244 Uart.bitCnt = 0;
245 Uart.shiftReg = 0;
246 Uart.nOutOfCnt = 0;
247 Uart.dropPosition = 0;
248 }
249 }
250
251 /*if(error) {
252 Uart.output[Uart.byteCnt] = 0xAA;
253 Uart.byteCnt++;
254 Uart.output[Uart.byteCnt] = error & 0xFF;
255 Uart.byteCnt++;
256 Uart.output[Uart.byteCnt] = 0xAA;
257 Uart.byteCnt++;
258 Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF;
259 Uart.byteCnt++;
260 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF;
261 Uart.byteCnt++;
262 Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF;
263 Uart.byteCnt++;
264 Uart.output[Uart.byteCnt] = 0xAA;
265 Uart.byteCnt++;
44964fd1 266 return true;
cee5a30d 267 }*/
268 }
269
270 }
271 else {
272 bit = Uart.bitBuffer & 0xf0;
273 bit >>= 4;
274 bit ^= 0x0F; // drops become 1s ;-)
275 if(bit) {
276 // should have been high or at least (4 * 128) / fc
277 // according to ISO this should be at least (9 * 128 + 20) / fc
278 if(Uart.highCnt == 8) {
279 // we went low, so this could be start of communication
280 // it turns out to be safer to choose a less significant
281 // syncbit... so we check whether the neighbour also represents the drop
282 Uart.posCnt = 1; // apparently we are busy with our first half bit period
283 Uart.syncBit = bit & 8;
284 Uart.samples = 3;
285 if(!Uart.syncBit) { Uart.syncBit = bit & 4; Uart.samples = 2; }
286 else if(bit & 4) { Uart.syncBit = bit & 4; Uart.samples = 2; bit <<= 2; }
287 if(!Uart.syncBit) { Uart.syncBit = bit & 2; Uart.samples = 1; }
288 else if(bit & 2) { Uart.syncBit = bit & 2; Uart.samples = 1; bit <<= 1; }
289 if(!Uart.syncBit) { Uart.syncBit = bit & 1; Uart.samples = 0;
290 if(Uart.syncBit && (Uart.bitBuffer & 8)) {
291 Uart.syncBit = 8;
292
293 // the first half bit period is expected in next sample
294 Uart.posCnt = 0;
295 Uart.samples = 3;
296 }
297 }
298 else if(bit & 1) { Uart.syncBit = bit & 1; Uart.samples = 0; }
299
300 Uart.syncBit <<= 4;
301 Uart.state = STATE_START_OF_COMMUNICATION;
302 Uart.bitCnt = 0;
303 Uart.byteCnt = 0;
cee5a30d 304 Uart.nOutOfCnt = 0;
305 Uart.OutOfCnt = 4; // Start at 1/4, could switch to 1/256
306 Uart.dropPosition = 0;
307 Uart.shiftReg = 0;
9f693930 308 //error = 0;
cee5a30d 309 }
310 else {
311 Uart.highCnt = 0;
312 }
313 }
314 else {
315 if(Uart.highCnt < 8) {
316 Uart.highCnt++;
317 }
318 }
319 }
320
44964fd1 321 return false;
cee5a30d 322}
323
324//=============================================================================
1e262141 325// Manchester
cee5a30d 326//=============================================================================
327
328static struct {
329 enum {
330 DEMOD_UNSYNCD,
331 DEMOD_START_OF_COMMUNICATION,
332 DEMOD_START_OF_COMMUNICATION2,
333 DEMOD_START_OF_COMMUNICATION3,
334 DEMOD_SOF_COMPLETE,
335 DEMOD_MANCHESTER_D,
336 DEMOD_MANCHESTER_E,
337 DEMOD_END_OF_COMMUNICATION,
338 DEMOD_END_OF_COMMUNICATION2,
339 DEMOD_MANCHESTER_F,
340 DEMOD_ERROR_WAIT
341 } state;
342 int bitCount;
343 int posCount;
344 int syncBit;
cee5a30d 345 uint16_t shiftReg;
346 int buffer;
347 int buffer2;
348 int buffer3;
349 int buff;
350 int samples;
351 int len;
352 enum {
353 SUB_NONE,
354 SUB_FIRST_HALF,
355 SUB_SECOND_HALF,
356 SUB_BOTH
357 } sub;
6a1f2d82 358 uint8_t *output;
cee5a30d 359} Demod;
360
361static RAMFUNC int ManchesterDecoding(int v)
362{
363 int bit;
364 int modulation;
365 int error = 0;
366
367 bit = Demod.buffer;
368 Demod.buffer = Demod.buffer2;
369 Demod.buffer2 = Demod.buffer3;
370 Demod.buffer3 = v;
371
372 if(Demod.buff < 3) {
373 Demod.buff++;
44964fd1 374 return false;
cee5a30d 375 }
376
377 if(Demod.state==DEMOD_UNSYNCD) {
378 Demod.output[Demod.len] = 0xfa;
379 Demod.syncBit = 0;
380 //Demod.samples = 0;
381 Demod.posCount = 1; // This is the first half bit period, so after syncing handle the second part
cee5a30d 382
383 if(bit & 0x08) {
384 Demod.syncBit = 0x08;
385 }
386
387 if(bit & 0x04) {
388 if(Demod.syncBit) {
389 bit <<= 4;
390 }
391 Demod.syncBit = 0x04;
392 }
393
394 if(bit & 0x02) {
395 if(Demod.syncBit) {
396 bit <<= 2;
397 }
398 Demod.syncBit = 0x02;
399 }
400
401 if(bit & 0x01 && Demod.syncBit) {
402 Demod.syncBit = 0x01;
403 }
404
405 if(Demod.syncBit) {
406 Demod.len = 0;
407 Demod.state = DEMOD_START_OF_COMMUNICATION;
408 Demod.sub = SUB_FIRST_HALF;
409 Demod.bitCount = 0;
410 Demod.shiftReg = 0;
cee5a30d 411 Demod.samples = 0;
412 if(Demod.posCount) {
413 //if(trigger) LED_A_OFF(); // Not useful in this case...
414 switch(Demod.syncBit) {
415 case 0x08: Demod.samples = 3; break;
416 case 0x04: Demod.samples = 2; break;
417 case 0x02: Demod.samples = 1; break;
418 case 0x01: Demod.samples = 0; break;
419 }
420 // SOF must be long burst... otherwise stay unsynced!!!
421 if(!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit)) {
422 Demod.state = DEMOD_UNSYNCD;
423 }
424 }
425 else {
426 // SOF must be long burst... otherwise stay unsynced!!!
427 if(!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) {
428 Demod.state = DEMOD_UNSYNCD;
429 error = 0x88;
430 }
431
432 }
433 error = 0;
434
435 }
436 }
437 else {
438 modulation = bit & Demod.syncBit;
439 modulation |= ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit;
cee5a30d 440
441 Demod.samples += 4;
442
443 if(Demod.posCount==0) {
444 Demod.posCount = 1;
445 if(modulation) {
446 Demod.sub = SUB_FIRST_HALF;
447 }
448 else {
449 Demod.sub = SUB_NONE;
450 }
451 }
452 else {
453 Demod.posCount = 0;
454 /*(modulation && (Demod.sub == SUB_FIRST_HALF)) {
455 if(Demod.state!=DEMOD_ERROR_WAIT) {
456 Demod.state = DEMOD_ERROR_WAIT;
457 Demod.output[Demod.len] = 0xaa;
458 error = 0x01;
459 }
460 }*/
461 //else if(modulation) {
462 if(modulation) {
463 if(Demod.sub == SUB_FIRST_HALF) {
464 Demod.sub = SUB_BOTH;
465 }
466 else {
467 Demod.sub = SUB_SECOND_HALF;
468 }
469 }
470 else if(Demod.sub == SUB_NONE) {
471 if(Demod.state == DEMOD_SOF_COMPLETE) {
472 Demod.output[Demod.len] = 0x0f;
473 Demod.len++;
cee5a30d 474 Demod.state = DEMOD_UNSYNCD;
475// error = 0x0f;
44964fd1 476 return true;
cee5a30d 477 }
478 else {
479 Demod.state = DEMOD_ERROR_WAIT;
480 error = 0x33;
481 }
482 /*if(Demod.state!=DEMOD_ERROR_WAIT) {
483 Demod.state = DEMOD_ERROR_WAIT;
484 Demod.output[Demod.len] = 0xaa;
485 error = 0x01;
486 }*/
487 }
488
489 switch(Demod.state) {
490 case DEMOD_START_OF_COMMUNICATION:
491 if(Demod.sub == SUB_BOTH) {
492 //Demod.state = DEMOD_MANCHESTER_D;
493 Demod.state = DEMOD_START_OF_COMMUNICATION2;
494 Demod.posCount = 1;
495 Demod.sub = SUB_NONE;
496 }
497 else {
498 Demod.output[Demod.len] = 0xab;
499 Demod.state = DEMOD_ERROR_WAIT;
500 error = 0xd2;
501 }
502 break;
503 case DEMOD_START_OF_COMMUNICATION2:
504 if(Demod.sub == SUB_SECOND_HALF) {
505 Demod.state = DEMOD_START_OF_COMMUNICATION3;
506 }
507 else {
508 Demod.output[Demod.len] = 0xab;
509 Demod.state = DEMOD_ERROR_WAIT;
510 error = 0xd3;
511 }
512 break;
513 case DEMOD_START_OF_COMMUNICATION3:
514 if(Demod.sub == SUB_SECOND_HALF) {
515// Demod.state = DEMOD_MANCHESTER_D;
516 Demod.state = DEMOD_SOF_COMPLETE;
517 //Demod.output[Demod.len] = Demod.syncBit & 0xFF;
518 //Demod.len++;
519 }
520 else {
521 Demod.output[Demod.len] = 0xab;
522 Demod.state = DEMOD_ERROR_WAIT;
523 error = 0xd4;
524 }
525 break;
526 case DEMOD_SOF_COMPLETE:
527 case DEMOD_MANCHESTER_D:
528 case DEMOD_MANCHESTER_E:
529 // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443)
530 // 00001111 = 1 (0 in 14443)
531 if(Demod.sub == SUB_SECOND_HALF) { // SUB_FIRST_HALF
532 Demod.bitCount++;
533 Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100;
534 Demod.state = DEMOD_MANCHESTER_D;
535 }
536 else if(Demod.sub == SUB_FIRST_HALF) { // SUB_SECOND_HALF
537 Demod.bitCount++;
538 Demod.shiftReg >>= 1;
539 Demod.state = DEMOD_MANCHESTER_E;
540 }
541 else if(Demod.sub == SUB_BOTH) {
542 Demod.state = DEMOD_MANCHESTER_F;
543 }
544 else {
545 Demod.state = DEMOD_ERROR_WAIT;
546 error = 0x55;
547 }
548 break;
549
550 case DEMOD_MANCHESTER_F:
551 // Tag response does not need to be a complete byte!
552 if(Demod.len > 0 || Demod.bitCount > 0) {
553 if(Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF
6a1f2d82 554 Demod.shiftReg >>= (9 - Demod.bitCount); // right align data
cee5a30d 555 Demod.output[Demod.len] = Demod.shiftReg & 0xff;
556 Demod.len++;
cee5a30d 557 }
558
559 Demod.state = DEMOD_UNSYNCD;
44964fd1 560 return true;
cee5a30d 561 }
562 else {
563 Demod.output[Demod.len] = 0xad;
564 Demod.state = DEMOD_ERROR_WAIT;
565 error = 0x03;
566 }
567 break;
568
569 case DEMOD_ERROR_WAIT:
570 Demod.state = DEMOD_UNSYNCD;
571 break;
572
573 default:
574 Demod.output[Demod.len] = 0xdd;
575 Demod.state = DEMOD_UNSYNCD;
576 break;
577 }
578
579 /*if(Demod.bitCount>=9) {
580 Demod.output[Demod.len] = Demod.shiftReg & 0xff;
581 Demod.len++;
582
583 Demod.parityBits <<= 1;
584 Demod.parityBits ^= ((Demod.shiftReg >> 8) & 0x01);
585
586 Demod.bitCount = 0;
587 Demod.shiftReg = 0;
588 }*/
589 if(Demod.bitCount>=8) {
590 Demod.shiftReg >>= 1;
591 Demod.output[Demod.len] = (Demod.shiftReg & 0xff);
592 Demod.len++;
cee5a30d 593 Demod.bitCount = 0;
594 Demod.shiftReg = 0;
595 }
596
597 if(error) {
598 Demod.output[Demod.len] = 0xBB;
599 Demod.len++;
600 Demod.output[Demod.len] = error & 0xFF;
601 Demod.len++;
602 Demod.output[Demod.len] = 0xBB;
603 Demod.len++;
604 Demod.output[Demod.len] = bit & 0xFF;
605 Demod.len++;
606 Demod.output[Demod.len] = Demod.buffer & 0xFF;
607 Demod.len++;
608 // Look harder ;-)
609 Demod.output[Demod.len] = Demod.buffer2 & 0xFF;
610 Demod.len++;
611 Demod.output[Demod.len] = Demod.syncBit & 0xFF;
612 Demod.len++;
613 Demod.output[Demod.len] = 0xBB;
614 Demod.len++;
44964fd1 615 return true;
cee5a30d 616 }
617
618 }
619
620 } // end (state != UNSYNCED)
621
44964fd1 622 return false;
cee5a30d 623}
624
625//=============================================================================
1e262141 626// Finally, a `sniffer' for iClass communication
cee5a30d 627// Both sides of communication!
628//=============================================================================
629
630//-----------------------------------------------------------------------------
631// Record the sequence of commands sent by the reader to the tag, with
632// triggering so that we start recording at the point that the tag is moved
633// near the reader.
634//-----------------------------------------------------------------------------
635void RAMFUNC SnoopIClass(void)
636{
17cba269 637
cee5a30d 638
639 // We won't start recording the frames that we acquire until we trigger;
640 // a good trigger condition to get started is probably when we see a
641 // response from the tag.
44964fd1 642 //int triggered = false; // false to wait first for card
cee5a30d 643
644 // The command (reader -> tag) that we're receiving.
645 // The length of a received command will in most cases be no more than 18 bytes.
646 // So 32 should be enough!
f71f4deb 647 #define ICLASS_BUFFER_SIZE 32
648 uint8_t readerToTagCmd[ICLASS_BUFFER_SIZE];
cee5a30d 649 // The response (tag -> reader) that we're receiving.
f71f4deb 650 uint8_t tagToReaderResponse[ICLASS_BUFFER_SIZE];
6a1f2d82 651
7cc204bf 652 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
653
f71f4deb 654 // free all BigBuf memory
655 BigBuf_free();
656 // The DMA buffer, used to stream samples from the FPGA
657 uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
658
44964fd1 659 set_tracing(true);
3000dc4e 660 clear_trace();
44964fd1 661 iso14a_set_trigger(false);
cee5a30d 662
f71f4deb 663 int lastRxCounter;
117d9ec2 664 uint8_t *upTo;
cee5a30d 665 int smpl;
666 int maxBehindBy = 0;
667
668 // Count of samples received so far, so that we can include timing
669 // information in the trace buffer.
670 int samples = 0;
671 rsamples = 0;
672
cee5a30d 673 // Set up the demodulator for tag -> reader responses.
17cba269 674 Demod.output = tagToReaderResponse;
cee5a30d 675 Demod.len = 0;
676 Demod.state = DEMOD_UNSYNCD;
677
678 // Setup for the DMA.
6a5d4e17 679 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
cee5a30d 680 upTo = dmaBuf;
681 lastRxCounter = DMA_BUFFER_SIZE;
682 FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
683
684 // And the reader -> tag commands
685 memset(&Uart, 0, sizeof(Uart));
17cba269 686 Uart.output = readerToTagCmd;
cee5a30d 687 Uart.byteCntMax = 32; // was 100 (greg)////////////////////////////////////////////////////////////////////////
688 Uart.state = STATE_UNSYNCD;
689
690 // And put the FPGA in the appropriate mode
691 // Signal field is off with the appropriate LED
692 LED_D_OFF();
693 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
694 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
695
81012e67 696 uint32_t time_0 = GetCountSspClk();
55eaed8f
MHS
697 uint32_t time_start = 0;
698 uint32_t time_stop = 0;
81012e67 699
cee5a30d 700 int div = 0;
701 //int div2 = 0;
702 int decbyte = 0;
703 int decbyter = 0;
704
705 // And now we loop, receiving samples.
706 for(;;) {
707 LED_A_ON();
708 WDT_HIT();
709 int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
710 (DMA_BUFFER_SIZE-1);
711 if(behindBy > maxBehindBy) {
712 maxBehindBy = behindBy;
f71f4deb 713 if(behindBy > (9 * DMA_BUFFER_SIZE / 10)) {
cee5a30d 714 Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
715 goto done;
716 }
717 }
718 if(behindBy < 1) continue;
719
720 LED_A_OFF();
721 smpl = upTo[0];
722 upTo++;
723 lastRxCounter -= 1;
724 if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
725 upTo -= DMA_BUFFER_SIZE;
726 lastRxCounter += DMA_BUFFER_SIZE;
727 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
728 AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
729 }
730
731 //samples += 4;
732 samples += 1;
cee5a30d 733
cee5a30d 734 if(smpl & 0xF) {
735 decbyte ^= (1 << (3 - div));
736 }
cee5a30d 737
738 // FOR READER SIDE COMMUMICATION...
17cba269 739
cee5a30d 740 decbyter <<= 2;
741 decbyter ^= (smpl & 0x30);
742
743 div++;
744
745 if((div + 1) % 2 == 0) {
746 smpl = decbyter;
1e262141 747 if(OutOfNDecoding((smpl & 0xF0) >> 4)) {
cee5a30d 748 rsamples = samples - Uart.samples;
55eaed8f 749 time_stop = (GetCountSspClk()-time_0) << 4;
cee5a30d 750 LED_C_ON();
17cba269 751
44964fd1 752 //if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,true)) break;
753 //if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, true)) break;
d9de20fa 754 uint8_t parity[MAX_PARITY_SIZE];
755 GetParity(Uart.output, Uart.byteCnt, parity);
756 LogTrace(Uart.output,Uart.byteCnt, time_start, time_stop, parity, true);
17cba269
MHS
757
758 /* And ready to receive another command. */
cee5a30d 759 Uart.state = STATE_UNSYNCD;
760 /* And also reset the demod code, which might have been */
761 /* false-triggered by the commands from the reader. */
762 Demod.state = DEMOD_UNSYNCD;
763 LED_B_OFF();
764 Uart.byteCnt = 0;
55eaed8f
MHS
765 }else{
766 time_start = (GetCountSspClk()-time_0) << 4;
cee5a30d 767 }
768 decbyter = 0;
769 }
770
771 if(div > 3) {
772 smpl = decbyte;
773 if(ManchesterDecoding(smpl & 0x0F)) {
55eaed8f
MHS
774 time_stop = (GetCountSspClk()-time_0) << 4;
775
776 rsamples = samples - Demod.samples;
cee5a30d 777 LED_B_ON();
778
d9de20fa 779 uint8_t parity[MAX_PARITY_SIZE];
780 GetParity(Demod.output, Demod.len, parity);
781 LogTrace(Demod.output, Demod.len, time_start, time_stop, parity, false);
17cba269 782
cee5a30d 783 // And ready to receive another response.
784 memset(&Demod, 0, sizeof(Demod));
17cba269 785 Demod.output = tagToReaderResponse;
cee5a30d 786 Demod.state = DEMOD_UNSYNCD;
787 LED_C_OFF();
55eaed8f
MHS
788 }else{
789 time_start = (GetCountSspClk()-time_0) << 4;
cee5a30d 790 }
791
792 div = 0;
793 decbyte = 0x00;
794 }
795 //}
796
797 if(BUTTON_PRESS()) {
798 DbpString("cancelled_a");
799 goto done;
800 }
801 }
802
803 DbpString("COMMAND FINISHED");
804
805 Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
3000dc4e 806 Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
cee5a30d 807
808done:
809 AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
810 Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
3000dc4e 811 Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
cee5a30d 812 LED_A_OFF();
813 LED_B_OFF();
1e262141 814 LED_C_OFF();
815 LED_D_OFF();
816}
817
912a3e94 818void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) {
819 int i;
820 for(i = 0; i < 8; i++) {
821 rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i+1)%8] << 5);
1e262141 822 }
823}
824
825//-----------------------------------------------------------------------------
826// Wait for commands from reader
827// Stop when button is pressed
44964fd1 828// Or return true when command is captured
1e262141 829//-----------------------------------------------------------------------------
830static int GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
831{
912a3e94 832 // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
1e262141 833 // only, since we are receiving, not transmitting).
834 // Signal field is off with the appropriate LED
835 LED_D_OFF();
836 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
837
838 // Now run a `software UART' on the stream of incoming samples.
839 Uart.output = received;
840 Uart.byteCntMax = maxLen;
841 Uart.state = STATE_UNSYNCD;
842
843 for(;;) {
844 WDT_HIT();
845
44964fd1 846 if(BUTTON_PRESS()) return false;
1e262141 847
848 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
849 AT91C_BASE_SSC->SSC_THR = 0x00;
850 }
851 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
852 uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
3fe4ff4f 853
1e262141 854 if(OutOfNDecoding(b & 0x0f)) {
855 *len = Uart.byteCnt;
44964fd1 856 return true;
1e262141 857 }
858 }
859 }
860}
861
645c960f
MHS
862static uint8_t encode4Bits(const uint8_t b)
863{
864 uint8_t c = b & 0xF;
865 // OTA, the least significant bits first
866 // The columns are
867 // 1 - Bit value to send
868 // 2 - Reversed (big-endian)
869 // 3 - Encoded
870 // 4 - Hex values
871
872 switch(c){
873 // 1 2 3 4
874 case 15: return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55
875 case 14: return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95
876 case 13: return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65
877 case 12: return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5
878 case 11: return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59
879 case 10: return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99
880 case 9: return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69
881 case 8: return 0xa9; // 1000 -> 0001 -> 10101001 -> 0xa9
882 case 7: return 0x56; // 0111 -> 1110 -> 01010110 -> 0x56
883 case 6: return 0x96; // 0110 -> 0110 -> 10010110 -> 0x96
884 case 5: return 0x66; // 0101 -> 1010 -> 01100110 -> 0x66
885 case 4: return 0xa6; // 0100 -> 0010 -> 10100110 -> 0xa6
886 case 3: return 0x5a; // 0011 -> 1100 -> 01011010 -> 0x5a
887 case 2: return 0x9a; // 0010 -> 0100 -> 10011010 -> 0x9a
888 case 1: return 0x6a; // 0001 -> 1000 -> 01101010 -> 0x6a
889 default: return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa
890
891 }
892}
1e262141 893
894//-----------------------------------------------------------------------------
895// Prepare tag messages
896//-----------------------------------------------------------------------------
897static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
898{
645c960f
MHS
899
900 /*
901 * SOF comprises 3 parts;
902 * * An unmodulated time of 56.64 us
903 * * 24 pulses of 423.75 KHz (fc/32)
904 * * A logic 1, which starts with an unmodulated time of 18.88us
905 * followed by 8 pulses of 423.75kHz (fc/32)
906 *
907 *
908 * EOF comprises 3 parts:
909 * - A logic 0 (which starts with 8 pulses of fc/32 followed by an unmodulated
910 * time of 18.88us.
911 * - 24 pulses of fc/32
912 * - An unmodulated time of 56.64 us
913 *
914 *
915 * A logic 0 starts with 8 pulses of fc/32
916 * followed by an unmodulated time of 256/fc (~18,88us).
917 *
918 * A logic 0 starts with unmodulated time of 256/fc (~18,88us) followed by
919 * 8 pulses of fc/32 (also 18.88us)
920 *
921 * The mode FPGA_HF_SIMULATOR_MODULATE_424K_8BIT which we use to simulate tag,
922 * works like this.
923 * - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us).
924 * - A 0-bit inptu to the FPGA becomes an unmodulated time of 18.88us
925 *
6b038d19 926 * In this mode the SOF can be written as 00011101 = 0x1D
645c960f
MHS
927 * The EOF can be written as 10111000 = 0xb8
928 * A logic 1 is 01
929 * A logic 0 is 10
930 *
931 * */
932
1e262141 933 int i;
934
935 ToSendReset();
936
937 // Send SOF
645c960f 938 ToSend[++ToSendMax] = 0x1D;
1e262141 939
940 for(i = 0; i < len; i++) {
1e262141 941 uint8_t b = cmd[i];
645c960f
MHS
942 ToSend[++ToSendMax] = encode4Bits(b & 0xF); //Least significant half
943 ToSend[++ToSendMax] = encode4Bits((b >>4) & 0xF);//Most significant half
1e262141 944 }
945
946 // Send EOF
645c960f 947 ToSend[++ToSendMax] = 0xB8;
81012e67 948 //lastProxToAirDuration = 8*ToSendMax - 3*8 - 3*8;//Not counting zeroes in the beginning or end
1e262141 949 // Convert from last byte pos to length
950 ToSendMax++;
951}
952
953// Only SOF
954static void CodeIClassTagSOF()
955{
81012e67
MHS
956 //So far a dummy implementation, not used
957 //int lastProxToAirDuration =0;
1e262141 958
81012e67 959 ToSendReset();
1e262141 960 // Send SOF
645c960f 961 ToSend[++ToSendMax] = 0x1D;
81012e67
MHS
962// lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning
963
1e262141 964 // Convert from last byte pos to length
965 ToSendMax++;
966}
b67f7ec3
MHS
967#define MODE_SIM_CSN 0
968#define MODE_EXIT_AFTER_MAC 1
969#define MODE_FULLSIM 2
55eaed8f 970
b67f7ec3 971int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf);
ff7bb4ef
MHS
972/**
973 * @brief SimulateIClass simulates an iClass card.
974 * @param arg0 type of simulation
975 * - 0 uses the first 8 bytes in usb data as CSN
976 * - 2 "dismantling iclass"-attack. This mode iterates through all CSN's specified
977 * in the usb data. This mode collects MAC from the reader, in order to do an offline
978 * attack on the keys. For more info, see "dismantling iclass" and proxclone.com.
979 * - Other : Uses the default CSN (031fec8af7ff12e0)
980 * @param arg1 - number of CSN's contained in datain (applicable for mode 2 only)
981 * @param arg2
982 * @param datain
983 */
984void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
1e262141 985{
ff7bb4ef
MHS
986 uint32_t simType = arg0;
987 uint32_t numberOfCSNS = arg1;
7cc204bf 988 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1e262141 989
ff7bb4ef 990 // Enable and clear the trace
44964fd1 991 set_tracing(true);
3000dc4e 992 clear_trace();
b67f7ec3
MHS
993 //Use the emulator memory for SIM
994 uint8_t *emulator = BigBuf_get_EM_addr();
81cd0474 995
ff7bb4ef
MHS
996 if(simType == 0) {
997 // Use the CSN from commandline
b67f7ec3
MHS
998 memcpy(emulator, datain, 8);
999 doIClassSimulation(MODE_SIM_CSN,NULL);
ff7bb4ef
MHS
1000 }else if(simType == 1)
1001 {
b67f7ec3
MHS
1002 //Default CSN
1003 uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
1004 // Use the CSN from commandline
1005 memcpy(emulator, csn_crc, 8);
1006 doIClassSimulation(MODE_SIM_CSN,NULL);
ff7bb4ef
MHS
1007 }
1008 else if(simType == 2)
1009 {
9f6e9d15 1010
7b941c8d 1011 uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 };
eabba3df 1012 Dbprintf("Going into attack mode, %d CSNS sent", numberOfCSNS);
ff7bb4ef
MHS
1013 // In this mode, a number of csns are within datain. We'll simulate each one, one at a time
1014 // in order to collect MAC's from the reader. This can later be used in an offlne-attack
1015 // in order to obtain the keys, as in the "dismantling iclass"-paper.
9f6e9d15
MHS
1016 int i = 0;
1017 for( ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++)
ff7bb4ef
MHS
1018 {
1019 // The usb data is 512 bytes, fitting 65 8-byte CSNs in there.
1020
b67f7ec3
MHS
1021 memcpy(emulator, datain+(i*8), 8);
1022 if(doIClassSimulation(MODE_EXIT_AFTER_MAC,mac_responses+i*8))
f83cc126 1023 {
645c960f 1024 cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
f83cc126
MHS
1025 return; // Button pressed
1026 }
ff7bb4ef 1027 }
9f6e9d15
MHS
1028 cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
1029
b67f7ec3
MHS
1030 }else if(simType == 3){
1031 //This is 'full sim' mode, where we use the emulator storage for data.
1032 doIClassSimulation(MODE_FULLSIM, NULL);
81012e67
MHS
1033 }
1034 else{
ff7bb4ef
MHS
1035 // We may want a mode here where we hardcode the csns to use (from proxclone).
1036 // That will speed things up a little, but not required just yet.
1037 Dbprintf("The mode is not implemented, reserved for future use");
1038 }
9f6e9d15 1039 Dbprintf("Done...");
ff7bb4ef
MHS
1040
1041}
c8387e85
MHS
1042void AppendCrc(uint8_t* data, int len)
1043{
1044 ComputeCrc14443(CRC_ICLASS,data,len,data+len,data+len+1);
1045}
b67f7ec3 1046
ff7bb4ef
MHS
1047/**
1048 * @brief Does the actual simulation
1049 * @param csn - csn to use
1050 * @param breakAfterMacReceived if true, returns after reader MAC has been received.
1051 */
b67f7ec3 1052int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf)
ff7bb4ef 1053{
b67f7ec3
MHS
1054 // free eventually allocated BigBuf memory
1055 BigBuf_free_keep_EM();
55eaed8f 1056
61fe9073
MHS
1057 State cipher_state;
1058// State cipher_state_reserve;
b67f7ec3
MHS
1059 uint8_t *csn = BigBuf_get_EM_addr();
1060 uint8_t *emulator = csn;
1061 uint8_t sof_data[] = { 0x0F} ;
1e262141 1062 // CSN followed by two CRC bytes
b67f7ec3
MHS
1063 uint8_t anticoll_data[10] = { 0 };
1064 uint8_t csn_data[10] = { 0 };
1065 memcpy(csn_data,csn,sizeof(csn_data));
f83cc126 1066 Dbprintf("Simulating CSN %02x%02x%02x%02x%02x%02x%02x%02x",csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]);
1e262141 1067
1e262141 1068 // Construct anticollision-CSN
b67f7ec3 1069 rotateCSN(csn_data,anticoll_data);
1e262141 1070
1071 // Compute CRC on both CSNs
b67f7ec3
MHS
1072 ComputeCrc14443(CRC_ICLASS, anticoll_data, 8, &anticoll_data[8], &anticoll_data[9]);
1073 ComputeCrc14443(CRC_ICLASS, csn_data, 8, &csn_data[8], &csn_data[9]);
1074
61fe9073 1075 uint8_t diversified_key[8] = { 0 };
b67f7ec3
MHS
1076 // e-Purse
1077 uint8_t card_challenge_data[8] = { 0x00 };
1078 if(simulationMode == MODE_FULLSIM)
1079 {
e5cd4ee4
MHS
1080 //The diversified key should be stored on block 3
1081 //Get the diversified key from emulator memory
1082 memcpy(diversified_key, emulator+(8*3),8);
1083
b67f7ec3
MHS
1084 //Card challenge, a.k.a e-purse is on block 2
1085 memcpy(card_challenge_data,emulator + (8 * 2) , 8);
61fe9073 1086 //Precalculate the cipher state, feeding it the CC
e5cd4ee4
MHS
1087 cipher_state = opt_doTagMAC_1(card_challenge_data,diversified_key);
1088
b67f7ec3 1089 }
1e262141 1090
ff7bb4ef 1091 int exitLoop = 0;
1e262141 1092 // Reader 0a
1093 // Tag 0f
1094 // Reader 0c
1095 // Tag anticoll. CSN
1096 // Reader 81 anticoll. CSN
1097 // Tag CSN
1098
55eaed8f 1099 uint8_t *modulated_response;
b19caaef 1100 int modulated_response_size = 0;
55eaed8f
MHS
1101 uint8_t* trace_data = NULL;
1102 int trace_data_size = 0;
1e262141 1103
b67f7ec3 1104
645c960f 1105 // Respond SOF -- takes 1 bytes
b67f7ec3
MHS
1106 uint8_t *resp_sof = BigBuf_malloc(2);
1107 int resp_sof_Len;
1e262141 1108
1109 // Anticollision CSN (rotated CSN)
645c960f 1110 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
b67f7ec3
MHS
1111 uint8_t *resp_anticoll = BigBuf_malloc(28);
1112 int resp_anticoll_len;
1e262141 1113
1114 // CSN
645c960f 1115 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
b67f7ec3
MHS
1116 uint8_t *resp_csn = BigBuf_malloc(30);
1117 int resp_csn_len;
1e262141 1118
1119 // e-Purse
b3cc5f29 1120 // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
b67f7ec3
MHS
1121 uint8_t *resp_cc = BigBuf_malloc(20);
1122 int resp_cc_len;
1e262141 1123
f71f4deb 1124 uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
1e262141 1125 int len;
1126
1e262141 1127 // Prepare card messages
1128 ToSendMax = 0;
1129
1130 // First card answer: SOF
1131 CodeIClassTagSOF();
b67f7ec3 1132 memcpy(resp_sof, ToSend, ToSendMax); resp_sof_Len = ToSendMax;
1e262141 1133
1134 // Anticollision CSN
b67f7ec3
MHS
1135 CodeIClassTagAnswer(anticoll_data, sizeof(anticoll_data));
1136 memcpy(resp_anticoll, ToSend, ToSendMax); resp_anticoll_len = ToSendMax;
1e262141 1137
1138 // CSN
b67f7ec3
MHS
1139 CodeIClassTagAnswer(csn_data, sizeof(csn_data));
1140 memcpy(resp_csn, ToSend, ToSendMax); resp_csn_len = ToSendMax;
1e262141 1141
1142 // e-Purse
b67f7ec3
MHS
1143 CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data));
1144 memcpy(resp_cc, ToSend, ToSendMax); resp_cc_len = ToSendMax;
1e262141 1145
b19caaef 1146 //This is used for responding to READ-block commands or other data which is dynamically generated
c8387e85
MHS
1147 //First the 'trace'-data, not encoded for FPGA
1148 uint8_t *data_generic_trace = BigBuf_malloc(8 + 2);//8 bytes data + 2byte CRC is max tag answer
1149 //Then storage for the modulated data
1150 //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes)
1151 uint8_t *data_response = BigBuf_malloc( (8+2) * 2 + 2);
e3dc1e4c
MHS
1152
1153 // Start from off (no field generated)
fa541aca
MHS
1154 //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1155 //SpinDelay(200);
1156 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
1157 SpinDelay(100);
1158 StartCountSspClk();
1e262141 1159 // We need to listen to the high-frequency, peak-detected path.
1160 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
6a5d4e17 1161 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
1e262141 1162
1163 // To control where we are in the protocol
1e262141 1164 int cmdsRecvd = 0;
81012e67
MHS
1165 uint32_t time_0 = GetCountSspClk();
1166 uint32_t t2r_time =0;
1167 uint32_t r2t_time =0;
912a3e94 1168
1e262141 1169 LED_A_ON();
f83cc126 1170 bool buttonPressed = false;
e5cd4ee4 1171 uint8_t response_delay = 1;
ff7bb4ef 1172 while(!exitLoop) {
e5cd4ee4 1173 response_delay = 1;
1e262141 1174 LED_B_OFF();
e3dc1e4c
MHS
1175 //Signal tracer
1176 // Can be used to get a trigger for an oscilloscope..
1177 LED_C_OFF();
3fe4ff4f 1178
1e262141 1179 if(!GetIClassCommandFromReader(receivedCmd, &len, 100)) {
f83cc126 1180 buttonPressed = true;
1e262141 1181 break;
81cd0474 1182 }
81012e67 1183 r2t_time = GetCountSspClk();
e3dc1e4c
MHS
1184 //Signal tracer
1185 LED_C_ON();
1e262141 1186
81cd0474 1187 // Okay, look at the command now.
b67f7ec3 1188 if(receivedCmd[0] == ICLASS_CMD_ACTALL ) {
1e262141 1189 // Reader in anticollission phase
b67f7ec3
MHS
1190 modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1;
1191 trace_data = sof_data;
1192 trace_data_size = sizeof(sof_data);
1193 } else if(receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 1) {
1e262141 1194 // Reader asks for anticollission CSN
b67f7ec3
MHS
1195 modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2;
1196 trace_data = anticoll_data;
1197 trace_data_size = sizeof(anticoll_data);
1e262141 1198 //DbpString("Reader requests anticollission CSN:");
b67f7ec3 1199 } else if(receivedCmd[0] == ICLASS_CMD_SELECT) {
1e262141 1200 // Reader selects anticollission CSN.
1201 // Tag sends the corresponding real CSN
b67f7ec3
MHS
1202 modulated_response = resp_csn; modulated_response_size = resp_csn_len; //order = 3;
1203 trace_data = csn_data;
1204 trace_data_size = sizeof(csn_data);
1e262141 1205 //DbpString("Reader selects anticollission CSN:");
b67f7ec3 1206 } else if(receivedCmd[0] == ICLASS_CMD_READCHECK_KD) {
1e262141 1207 // Read e-purse (88 02)
b67f7ec3
MHS
1208 modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4;
1209 trace_data = card_challenge_data;
1210 trace_data_size = sizeof(card_challenge_data);
1e262141 1211 LED_B_ON();
b67f7ec3 1212 } else if(receivedCmd[0] == ICLASS_CMD_CHECK) {
1e262141 1213 // Reader random and reader MAC!!!
b67f7ec3 1214 if(simulationMode == MODE_FULLSIM)
61fe9073
MHS
1215 {
1216 //NR, from reader, is in receivedCmd +1
1217 opt_doTagMAC_2(cipher_state,receivedCmd+1,data_generic_trace,diversified_key);
1218
b19caaef 1219 trace_data = data_generic_trace;
b67f7ec3
MHS
1220 trace_data_size = 4;
1221 CodeIClassTagAnswer(trace_data , trace_data_size);
1222 memcpy(data_response, ToSend, ToSendMax);
1223 modulated_response = data_response;
1224 modulated_response_size = ToSendMax;
e5cd4ee4 1225 response_delay = 0;//We need to hurry here...
10a8875c 1226 //exitLoop = true;
b67f7ec3
MHS
1227 }else
1228 { //Not fullsim, we don't respond
1229 // We do not know what to answer, so lets keep quiet
1230 modulated_response = resp_sof; modulated_response_size = 0;
1231 trace_data = NULL;
1232 trace_data_size = 0;
1233 if (simulationMode == MODE_EXIT_AFTER_MAC){
1234 // dbprintf:ing ...
1235 Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x"
1236 ,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]);
1237 Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len,
1238 receivedCmd[0], receivedCmd[1], receivedCmd[2],
1239 receivedCmd[3], receivedCmd[4], receivedCmd[5],
1240 receivedCmd[6], receivedCmd[7], receivedCmd[8]);
1241 if (reader_mac_buf != NULL)
1242 {
1243 memcpy(reader_mac_buf,receivedCmd+1,8);
1244 }
1245 exitLoop = true;
9f6e9d15 1246 }
ff7bb4ef 1247 }
b67f7ec3
MHS
1248
1249 } else if(receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
1e262141 1250 // Reader ends the session
b67f7ec3 1251 modulated_response = resp_sof; modulated_response_size = 0; //order = 0;
55eaed8f
MHS
1252 trace_data = NULL;
1253 trace_data_size = 0;
b67f7ec3
MHS
1254 } else if(simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){
1255 //Read block
1256 uint16_t blk = receivedCmd[1];
c8387e85
MHS
1257 //Take the data...
1258 memcpy(data_generic_trace, emulator+(blk << 3),8);
1259 //Add crc
1260 AppendCrc(data_generic_trace, 8);
1261 trace_data = data_generic_trace;
1262 trace_data_size = 10;
1263 CodeIClassTagAnswer(trace_data , trace_data_size);
1264 memcpy(data_response, ToSend, ToSendMax);
1265 modulated_response = data_response;
1266 modulated_response_size = ToSendMax;
1267 }else if(receivedCmd[0] == ICLASS_CMD_UPDATE && simulationMode == MODE_FULLSIM)
1268 {//Probably the reader wants to update the nonce. Let's just ignore that for now.
1269 // OBS! If this is implemented, don't forget to regenerate the cipher_state
1270 //We're expected to respond with the data+crc, exactly what's already in the receivedcmd
1271 //receivedcmd is now UPDATE 1b | ADDRESS 1b| DATA 8b| Signature 4b or CRC 2b|
1272
1273 //Take the data...
1274 memcpy(data_generic_trace, receivedCmd+2,8);
1275 //Add crc
1276 AppendCrc(data_generic_trace, 8);
1277 trace_data = data_generic_trace;
1278 trace_data_size = 10;
b67f7ec3
MHS
1279 CodeIClassTagAnswer(trace_data , trace_data_size);
1280 memcpy(data_response, ToSend, ToSendMax);
1281 modulated_response = data_response;
1282 modulated_response_size = ToSendMax;
1283 }
b19caaef
MHS
1284 else if(receivedCmd[0] == ICLASS_CMD_PAGESEL)
1285 {//Pagesel
1286 //Pagesel enables to select a page in the selected chip memory and return its configuration block
1287 //Chips with a single page will not answer to this command
1288 // It appears we're fine ignoring this.
1289 //Otherwise, we should answer 8bytes (block) + 2bytes CRC
1290 }
b67f7ec3 1291 else {
17cba269 1292 //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44
1e262141 1293 // Never seen this command before
1294 Dbprintf("Unknown command received from reader (len=%d): %x %x %x %x %x %x %x %x %x",
1295 len,
1296 receivedCmd[0], receivedCmd[1], receivedCmd[2],
1297 receivedCmd[3], receivedCmd[4], receivedCmd[5],
1298 receivedCmd[6], receivedCmd[7], receivedCmd[8]);
1299 // Do not respond
b67f7ec3 1300 modulated_response = resp_sof; modulated_response_size = 0; //order = 0;
55eaed8f
MHS
1301 trace_data = NULL;
1302 trace_data_size = 0;
1e262141 1303 }
1304
81012e67
MHS
1305 if(cmdsRecvd > 100) {
1306 //DbpString("100 commands later...");
9f6e9d15 1307 //break;
1e262141 1308 }
1309 else {
1310 cmdsRecvd++;
1311 }
55eaed8f 1312 /**
6b038d19 1313 A legit tag has about 380us delay between reader EOT and tag SOF.
55eaed8f
MHS
1314 **/
1315 if(modulated_response_size > 0) {
e5cd4ee4 1316 SendIClassAnswer(modulated_response, modulated_response_size, response_delay);
81012e67 1317 t2r_time = GetCountSspClk();
81cd0474 1318 }
f83cc126 1319
d9de20fa 1320 uint8_t parity[MAX_PARITY_SIZE];
1321 GetParity(receivedCmd, len, parity);
1322 LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, true);
81012e67 1323
d9de20fa 1324 if (trace_data != NULL) {
1325 GetParity(trace_data, trace_data_size, parity);
1326 LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, false);
1327 }
1328 if(!get_tracing()) {
1329 DbpString("Trace full");
1330 //break;
81cd0474 1331 }
81cd0474 1332 }
1e262141 1333
9f6e9d15 1334 //Dbprintf("%x", cmdsRecvd);
1e262141 1335 LED_A_OFF();
1336 LED_B_OFF();
7b941c8d
MHS
1337 LED_C_OFF();
1338
f83cc126
MHS
1339 if(buttonPressed)
1340 {
1341 DbpString("Button pressed");
1342 }
f83cc126 1343 return buttonPressed;
1e262141 1344}
1345
1346static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
1347{
e3dc1e4c 1348 int i = 0, d=0;//, u = 0, d = 0;
1e262141 1349 uint8_t b = 0;
e3dc1e4c 1350
645c960f
MHS
1351 //FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
1352 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K_8BIT);
e3dc1e4c 1353
1e262141 1354 AT91C_BASE_SSC->SSC_THR = 0x00;
6a5d4e17 1355 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
e3dc1e4c
MHS
1356 while(!BUTTON_PRESS()) {
1357 if((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)){
1358 b = AT91C_BASE_SSC->SSC_RHR; (void) b;
1e262141 1359 }
e3dc1e4c
MHS
1360 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)){
1361 b = 0x00;
1e262141 1362 if(d < delay) {
1e262141 1363 d++;
1364 }
e3dc1e4c
MHS
1365 else {
1366 if( i < respLen){
1367 b = resp[i];
1368 //Hack
1369 //b = 0xAC;
1370 }
1371 i++;
1e262141 1372 }
1373 AT91C_BASE_SSC->SSC_THR = b;
1e262141 1374 }
e3dc1e4c 1375
645c960f
MHS
1376// if (i > respLen +4) break;
1377 if (i > respLen +1) break;
1e262141 1378 }
1379
1380 return 0;
1381}
1382
1383/// THE READER CODE
1384
1385//-----------------------------------------------------------------------------
1386// Transmit the command (to the tag) that was placed in ToSend[].
1387//-----------------------------------------------------------------------------
1388static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait)
1389{
1390 int c;
1e262141 1391 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
1392 AT91C_BASE_SSC->SSC_THR = 0x00;
6a5d4e17 1393 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
1e262141 1394
1395 if (wait)
2ed270a8
MHS
1396 {
1397 if(*wait < 10) *wait = 10;
1398
1399 for(c = 0; c < *wait;) {
1400 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
1401 AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
1402 c++;
1403 }
1404 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
1405 volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
1406 (void)r;
1407 }
1408 WDT_HIT();
1409 }
1410
1411 }
1e262141 1412
1e262141 1413
1414 uint8_t sendbyte;
44964fd1 1415 bool firstpart = true;
1e262141 1416 c = 0;
1417 for(;;) {
1418 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
1419
1420 // DOUBLE THE SAMPLES!
1421 if(firstpart) {
1422 sendbyte = (cmd[c] & 0xf0) | (cmd[c] >> 4);
1423 }
1424 else {
1425 sendbyte = (cmd[c] & 0x0f) | (cmd[c] << 4);
1426 c++;
1427 }
1428 if(sendbyte == 0xff) {
1429 sendbyte = 0xfe;
1430 }
1431 AT91C_BASE_SSC->SSC_THR = sendbyte;
1432 firstpart = !firstpart;
1433
1434 if(c >= len) {
1435 break;
1436 }
1437 }
1438 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
1439 volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
1440 (void)r;
1441 }
1442 WDT_HIT();
1443 }
e7707cdb 1444 if (samples && wait) *samples = (c + *wait) << 3;
1e262141 1445}
1446
1447
1448//-----------------------------------------------------------------------------
1449// Prepare iClass reader command to send to FPGA
1450//-----------------------------------------------------------------------------
1451void CodeIClassCommand(const uint8_t * cmd, int len)
1452{
1453 int i, j, k;
1454 uint8_t b;
1455
1456 ToSendReset();
1457
1458 // Start of Communication: 1 out of 4
1459 ToSend[++ToSendMax] = 0xf0;
1460 ToSend[++ToSendMax] = 0x00;
1461 ToSend[++ToSendMax] = 0x0f;
1462 ToSend[++ToSendMax] = 0x00;
1463
1464 // Modulate the bytes
1465 for (i = 0; i < len; i++) {
1466 b = cmd[i];
1467 for(j = 0; j < 4; j++) {
1468 for(k = 0; k < 4; k++) {
e3dc1e4c 1469 if(k == (b & 3)) {
671ff89f 1470 ToSend[++ToSendMax] = 0xf0;
e3dc1e4c
MHS
1471 }
1472 else {
1473 ToSend[++ToSendMax] = 0x00;
1474 }
1e262141 1475 }
1476 b >>= 2;
1477 }
1478 }
1479
1480 // End of Communication
1481 ToSend[++ToSendMax] = 0x00;
1482 ToSend[++ToSendMax] = 0x00;
1483 ToSend[++ToSendMax] = 0xf0;
1484 ToSend[++ToSendMax] = 0x00;
1485
1486 // Convert from last character reference to length
1487 ToSendMax++;
1488}
1489
1490void ReaderTransmitIClass(uint8_t* frame, int len)
1491{
6a1f2d82 1492 int wait = 0;
1493 int samples = 0;
1494
1495 // This is tied to other size changes
6a1f2d82 1496 CodeIClassCommand(frame,len);
1497
1498 // Select the card
1499 TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
1500 if(trigger)
1501 LED_A_ON();
1502
1503 // Store reader command in buffer
d9de20fa 1504 uint8_t par[MAX_PARITY_SIZE];
1505 GetParity(frame, len, par);
1506 LogTrace(frame, len, rsamples, rsamples, par, true);
1e262141 1507}
1508
1509//-----------------------------------------------------------------------------
1510// Wait a certain time for tag response
44964fd1 1511// If a response is captured return true
1512// If it takes too long return false
1e262141 1513//-----------------------------------------------------------------------------
1514static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed) //uint8_t *buffer
1515{
1516 // buffer needs to be 512 bytes
1517 int c;
1518
1519 // Set FPGA mode to "reader listen mode", no modulation (listen
1520 // only, since we are receiving, not transmitting).
1521 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
1522
1523 // Now get the answer from the card
1524 Demod.output = receivedResponse;
1525 Demod.len = 0;
1526 Demod.state = DEMOD_UNSYNCD;
1527
1528 uint8_t b;
1529 if (elapsed) *elapsed = 0;
1530
44964fd1 1531 bool skip = false;
1e262141 1532
1533 c = 0;
1534 for(;;) {
1535 WDT_HIT();
1536
44964fd1 1537 if(BUTTON_PRESS()) return false;
1e262141 1538
1539 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
1540 AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!!
1541 if (elapsed) (*elapsed)++;
1542 }
1543 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
44964fd1 1544 if(c < timeout) { c++; } else { return false; }
1e262141 1545 b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
1546 skip = !skip;
1547 if(skip) continue;
3fe4ff4f 1548
1e262141 1549 if(ManchesterDecoding(b & 0x0f)) {
1550 *samples = c << 3;
44964fd1 1551 return true;
1e262141 1552 }
1553 }
1554 }
1555}
1556
1557int ReaderReceiveIClass(uint8_t* receivedAnswer)
1558{
1559 int samples = 0;
44964fd1 1560 if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return false;
7bc95e2e 1561 rsamples += samples;
d9de20fa 1562 uint8_t parity[MAX_PARITY_SIZE];
1563 GetParity(receivedAnswer, Demod.len, parity);
1564 LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,false);
44964fd1 1565 if(samples == 0) return false;
1e262141 1566 return Demod.len;
1567}
1568
aa41c605
MHS
1569void setupIclassReader()
1570{
1571 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1572 // Reset trace buffer
44964fd1 1573 set_tracing(true);
671ff89f 1574 clear_trace();
aa41c605
MHS
1575
1576 // Setup SSC
6a5d4e17 1577 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
aa41c605
MHS
1578 // Start from off (no field generated)
1579 // Signal field is off with the appropriate LED
1580 LED_D_OFF();
1581 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1582 SpinDelay(200);
1583
1584 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
1585
1586 // Now give it time to spin up.
1587 // Signal field is on with the appropriate LED
1588 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
1589 SpinDelay(200);
1590 LED_A_ON();
1591
1592}
1593
aa53efc3 1594bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* resp, uint8_t expected_size, uint8_t retries)
c8dd9b09
MHS
1595{
1596 while(retries-- > 0)
1597 {
1598 ReaderTransmitIClass(command, cmdsize);
1599 if(expected_size == ReaderReceiveIClass(resp)){
aa53efc3 1600 return true;
c8dd9b09
MHS
1601 }
1602 }
aa53efc3 1603 return false;//Error
c8dd9b09
MHS
1604}
1605
1606/**
1607 * @brief Talks to an iclass tag, sends the commands to get CSN and CC.
1608 * @param card_data where the CSN and CC are stored for return
1609 * @return 0 = fail
1610 * 1 = Got CSN
1611 * 2 = Got CSN and CC
1612 */
aa53efc3 1613uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key)
c8dd9b09
MHS
1614{
1615 static uint8_t act_all[] = { 0x0a };
aa53efc3 1616 //static uint8_t identify[] = { 0x0c };
1617 static uint8_t identify[] = { 0x0c, 0x00, 0x73, 0x33 };
c8dd9b09 1618 static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
aa53efc3 1619 static uint8_t readcheck_cc[]= { 0x88, 0x02 };
1620 if (use_credit_key)
1621 readcheck_cc[0] = 0x18;
1622 else
1623 readcheck_cc[0] = 0x88;
caaf9618 1624
f71f4deb 1625 uint8_t resp[ICLASS_BUFFER_SIZE];
c8dd9b09
MHS
1626
1627 uint8_t read_status = 0;
1628
1629 // Send act_all
1630 ReaderTransmitIClass(act_all, 1);
1631 // Card present?
1632 if(!ReaderReceiveIClass(resp)) return read_status;//Fail
1633 //Send Identify
1634 ReaderTransmitIClass(identify, 1);
1635 //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
1636 uint8_t len = ReaderReceiveIClass(resp);
1637 if(len != 10) return read_status;//Fail
1638
1639 //Copy the Anti-collision CSN to our select-packet
1640 memcpy(&select[1],resp,8);
1641 //Select the card
1642 ReaderTransmitIClass(select, sizeof(select));
1643 //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC
1644 len = ReaderReceiveIClass(resp);
1645 if(len != 10) return read_status;//Fail
1646
1647 //Success - level 1, we got CSN
1648 //Save CSN in response data
1649 memcpy(card_data,resp,8);
1650
1651 //Flag that we got to at least stage 1, read CSN
1652 read_status = 1;
1653
34e2af02 1654 // Card selected, now read e-purse (cc) (only 8 bytes no CRC)
c8dd9b09
MHS
1655 ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
1656 if(ReaderReceiveIClass(resp) == 8) {
1657 //Save CC (e-purse) in response data
1658 memcpy(card_data+8,resp,8);
caaf9618 1659 read_status++;
c8dd9b09
MHS
1660 }
1661
1662 return read_status;
1663}
671ff89f 1664uint8_t handshakeIclassTag(uint8_t *card_data) {
aa53efc3 1665 return handshakeIclassTag_ext(card_data, false);
1666}
c8dd9b09 1667
caaf9618 1668
1e262141 1669// Reader iClass Anticollission
1670void ReaderIClass(uint8_t arg0) {
1e262141 1671
83602aff
MHS
1672 uint8_t card_data[6 * 8]={0};
1673 memset(card_data, 0xFF, sizeof(card_data));
979c7655 1674 uint8_t last_csn[8]={0,0,0,0,0,0,0,0};
34e2af02 1675 uint8_t resp[ICLASS_BUFFER_SIZE];
1676 memset(resp, 0xFF, sizeof(resp));
caaf9618
MHS
1677 //Read conf block CRC(0x01) => 0xfa 0x22
1678 uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22};
34e2af02 1679 //Read App Issuer Area block CRC(0x05) => 0xde 0x64
caaf9618
MHS
1680 uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64};
1681
6ce0e538 1682 int read_status= 0;
caaf9618 1683 uint8_t result_status = 0;
34e2af02 1684 // flag to read until one tag is found successfully
6ce0e538 1685 bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
34e2af02 1686 // flag to only try 5 times to find one tag then return
6ce0e538 1687 bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY;
34e2af02 1688 // if neither abort_after_read nor try_once then continue reading until button pressed.
1689
1690 bool use_credit_key = arg0 & FLAG_ICLASS_READER_CEDITKEY;
1691 // test flags for what blocks to be sure to read
1692 uint8_t flagReadConfig = arg0 & FLAG_ICLASS_READER_CONF;
1693 uint8_t flagReadCC = arg0 & FLAG_ICLASS_READER_CC;
1694 uint8_t flagReadAA = arg0 & FLAG_ICLASS_READER_AA;
1695
1696 set_tracing(true);
6ce0e538 1697 setupIclassReader();
1e262141 1698
6ce0e538 1699 uint16_t tryCnt=0;
979c7655 1700 bool userCancelled = BUTTON_PRESS() || usb_poll_validate_length();
1701 while(!userCancelled)
6ce0e538 1702 {
979c7655 1703 // if only looking for one card try 2 times if we missed it the first time
1704 if (try_once && tryCnt > 2) break;
6ce0e538 1705 tryCnt++;
d9de20fa 1706 if(!get_tracing()) {
c8dd9b09
MHS
1707 DbpString("Trace full");
1708 break;
1709 }
1710 WDT_HIT();
4ab4336a 1711
aa53efc3 1712 read_status = handshakeIclassTag_ext(card_data, use_credit_key);
2e9d4b3f 1713
c8dd9b09 1714 if(read_status == 0) continue;
caaf9618
MHS
1715 if(read_status == 1) result_status = FLAG_ICLASS_READER_CSN;
1716 if(read_status == 2) result_status = FLAG_ICLASS_READER_CSN|FLAG_ICLASS_READER_CC;
1717
1718 // handshakeIclass returns CSN|CC, but the actual block
1719 // layout is CSN|CONFIG|CC, so here we reorder the data,
1720 // moving CC forward 8 bytes
1721 memcpy(card_data+16,card_data+8, 8);
1722 //Read block 1, config
34e2af02 1723 if(flagReadConfig) {
1724 if(sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, 10, 10))
caaf9618
MHS
1725 {
1726 result_status |= FLAG_ICLASS_READER_CONF;
34e2af02 1727 memcpy(card_data+8, resp, 8);
aa53efc3 1728 } else {
1729 Dbprintf("Failed to dump config block");
caaf9618
MHS
1730 }
1731 }
c8dd9b09 1732
caaf9618 1733 //Read block 5, AA
34e2af02 1734 if(flagReadAA) {
1735 if(sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, 10, 10))
caaf9618 1736 {
caaf9618 1737 result_status |= FLAG_ICLASS_READER_AA;
34e2af02 1738 memcpy(card_data+(8*5), resp, 8);
aa53efc3 1739 } else {
1740 //Dbprintf("Failed to dump AA block");
caaf9618
MHS
1741 }
1742 }
1743
1744 // 0 : CSN
b67f7ec3 1745 // 1 : Configuration
caaf9618
MHS
1746 // 2 : e-purse
1747 // (3,4 write-only, kc and kd)
b67f7ec3
MHS
1748 // 5 Application issuer area
1749 //
34e2af02 1750 //Then we can 'ship' back the 8 * 6 bytes of data,
b67f7ec3
MHS
1751 // with 0xFF:s in block 3 and 4.
1752
c8dd9b09 1753 LED_B_ON();
979c7655 1754 //Send back to client, but don't bother if we already sent this -
1755 // only useful if looping in arm (not try_once && not abort_after_read)
c8dd9b09
MHS
1756 if(memcmp(last_csn, card_data, 8) != 0)
1757 {
34e2af02 1758 // If caller requires that we get Conf, CC, AA, continue until we got it
1759 if( (result_status ^ FLAG_ICLASS_READER_CSN ^ flagReadConfig ^ flagReadCC ^ flagReadAA) == 0) {
caaf9618 1760 cmd_send(CMD_ACK,result_status,0,0,card_data,sizeof(card_data));
c8dd9b09
MHS
1761 if(abort_after_read) {
1762 LED_A_OFF();
979c7655 1763 LED_B_OFF();
c8dd9b09
MHS
1764 return;
1765 }
1766 //Save that we already sent this....
1767 memcpy(last_csn, card_data, 8);
1768 }
caaf9618 1769
c8dd9b09
MHS
1770 }
1771 LED_B_OFF();
979c7655 1772 userCancelled = BUTTON_PRESS() || usb_poll_validate_length();
1773 }
1774 if (userCancelled) {
1775 cmd_send(CMD_ACK,0xFF,0,0,card_data, 0);
1776 } else {
1777 cmd_send(CMD_ACK,0,0,0,card_data, 0);
6ce0e538 1778 }
3ac22ee1 1779 LED_A_OFF();
cee5a30d 1780}
1781
c3963755 1782void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
c8dd9b09 1783
cb29e00a 1784 uint8_t card_data[USB_CMD_DATA_SIZE]={0};
39d3ce5d
MHS
1785 uint16_t block_crc_LUT[255] = {0};
1786
1787 {//Generate a lookup table for block crc
1788 for(int block = 0; block < 255; block++){
1789 char bl = block;
1790 block_crc_LUT[block] = iclass_crc16(&bl ,1);
1791 }
1792 }
1793 //Dbprintf("Lookup table: %02x %02x %02x" ,block_crc_LUT[0],block_crc_LUT[1],block_crc_LUT[2]);
c8dd9b09 1794
c3963755 1795 uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1796 uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 };
1797
fecd8202 1798 uint16_t crc = 0;
c3963755 1799 uint8_t cardsize=0;
c3963755 1800 uint8_t mem=0;
1801
1802 static struct memory_t{
1803 int k16;
1804 int book;
1805 int k2;
1806 int lockauth;
1807 int keyaccess;
1808 } memory;
1809
f71f4deb 1810 uint8_t resp[ICLASS_BUFFER_SIZE];
6a1f2d82 1811
9b82de75 1812 setupIclassReader();
44964fd1 1813 set_tracing(true);
c3963755 1814
c8dd9b09 1815 while(!BUTTON_PRESS()) {
c3963755 1816
39d3ce5d
MHS
1817 WDT_HIT();
1818
d9de20fa 1819 if(!get_tracing()) {
c3963755 1820 DbpString("Trace full");
1821 break;
1822 }
1823
c8dd9b09
MHS
1824 uint8_t read_status = handshakeIclassTag(card_data);
1825 if(read_status < 2) continue;
1826
1827 //for now replay captured auth (as cc not updated)
1828 memcpy(check+5,MAC,4);
1829
aa53efc3 1830 if(!sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5))
c8dd9b09
MHS
1831 {
1832 Dbprintf("Error: Authentication Fail!");
1833 continue;
1834 }
1835
39d3ce5d
MHS
1836 //first get configuration block (block 1)
1837 crc = block_crc_LUT[1];
c8dd9b09 1838 read[1]=1;
c8dd9b09
MHS
1839 read[2] = crc >> 8;
1840 read[3] = crc & 0xff;
1841
aa53efc3 1842 if(!sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10))
c8dd9b09 1843 {
39d3ce5d 1844 Dbprintf("Dump config (block 1) failed");
c8dd9b09
MHS
1845 continue;
1846 }
1847
1848 mem=resp[5];
1849 memory.k16= (mem & 0x80);
1850 memory.book= (mem & 0x20);
1851 memory.k2= (mem & 0x8);
1852 memory.lockauth= (mem & 0x2);
1853 memory.keyaccess= (mem & 0x1);
1854
1855 cardsize = memory.k16 ? 255 : 32;
1856 WDT_HIT();
cb29e00a
MHS
1857 //Set card_data to all zeroes, we'll fill it with data
1858 memset(card_data,0x0,USB_CMD_DATA_SIZE);
1859 uint8_t failedRead =0;
428d6221 1860 uint32_t stored_data_length =0;
c8dd9b09 1861 //then loop around remaining blocks
39d3ce5d 1862 for(int block=0; block < cardsize; block++){
c8dd9b09
MHS
1863
1864 read[1]= block;
39d3ce5d 1865 crc = block_crc_LUT[block];
c8dd9b09
MHS
1866 read[2] = crc >> 8;
1867 read[3] = crc & 0xff;
1868
aa53efc3 1869 if(sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10))
c8dd9b09
MHS
1870 {
1871 Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
1872 block, resp[0], resp[1], resp[2],
1873 resp[3], resp[4], resp[5],
1874 resp[6], resp[7]);
1875
cb29e00a
MHS
1876 //Fill up the buffer
1877 memcpy(card_data+stored_data_length,resp,8);
1878 stored_data_length += 8;
cb29e00a
MHS
1879 if(stored_data_length +8 > USB_CMD_DATA_SIZE)
1880 {//Time to send this off and start afresh
1881 cmd_send(CMD_ACK,
1882 stored_data_length,//data length
1883 failedRead,//Failed blocks?
1884 0,//Not used ATM
1885 card_data, stored_data_length);
1886 //reset
1887 stored_data_length = 0;
1888 failedRead = 0;
1889 }
1890
c8dd9b09 1891 }else{
cb29e00a
MHS
1892 failedRead = 1;
1893 stored_data_length +=8;//Otherwise, data becomes misaligned
c8dd9b09 1894 Dbprintf("Failed to dump block %d", block);
c3963755 1895 }
1896 }
428d6221 1897
cb29e00a
MHS
1898 //Send off any remaining data
1899 if(stored_data_length > 0)
1900 {
1901 cmd_send(CMD_ACK,
1902 stored_data_length,//data length
1903 failedRead,//Failed blocks?
1904 0,//Not used ATM
1905 card_data, stored_data_length);
1906 }
c8dd9b09
MHS
1907 //If we got here, let's break
1908 break;
c3963755 1909 }
cb29e00a
MHS
1910 //Signal end of transmission
1911 cmd_send(CMD_ACK,
1912 0,//data length
1913 0,//Failed blocks?
1914 0,//Not used ATM
1915 card_data, 0);
1916
c3963755 1917 LED_A_OFF();
1918}
1919
3ac22ee1 1920void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType) {
1921 uint8_t readcheck[] = { keyType, blockNo };
1922 uint8_t resp[] = {0,0,0,0,0,0,0,0};
1923 size_t isOK = 0;
1924 isOK = sendCmdGetResponseWithRetries(readcheck, sizeof(readcheck), resp, sizeof(resp), 6);
1925 cmd_send(CMD_ACK,isOK,0,0,0,0);
1926}
1927
aa53efc3 1928void iClass_Authentication(uint8_t *MAC) {
3ac22ee1 1929 uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
aa53efc3 1930 uint8_t resp[ICLASS_BUFFER_SIZE];
1931 memcpy(check+5,MAC,4);
1932 bool isOK;
3ac22ee1 1933 isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6);
aa53efc3 1934 cmd_send(CMD_ACK,isOK,0,0,0,0);
aa53efc3 1935}
3ac22ee1 1936bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata) {
1937 uint8_t readcmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00}; //0x88, 0x00 // can i use 0C?
1938 char bl = blockNo;
1939 uint16_t rdCrc = iclass_crc16(&bl, 1);
1940 readcmd[2] = rdCrc >> 8;
1941 readcmd[3] = rdCrc & 0xff;
1942 uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0};
1943 bool isOK = false;
912a3e94 1944
3ac22ee1 1945 //readcmd[1] = blockNo;
1946 isOK = sendCmdGetResponseWithRetries(readcmd, sizeof(readcmd), resp, 10, 10);
1947 memcpy(readdata, resp, sizeof(resp));
fecd8202 1948
aa53efc3 1949 return isOK;
1950}
fecd8202 1951
3ac22ee1 1952void iClass_ReadBlk(uint8_t blockno) {
1953 uint8_t readblockdata[] = {0,0,0,0,0,0,0,0,0,0};
aa53efc3 1954 bool isOK = false;
3ac22ee1 1955 isOK = iClass_ReadBlock(blockno, readblockdata);
1956 cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
aa53efc3 1957}
fecd8202 1958
3ac22ee1 1959void iClass_Dump(uint8_t blockno, uint8_t numblks) {
1960 uint8_t readblockdata[] = {0,0,0,0,0,0,0,0,0,0};
aa53efc3 1961 bool isOK = false;
1962 uint8_t blkCnt = 0;
fecd8202 1963
aa53efc3 1964 BigBuf_free();
1965 uint8_t *dataout = BigBuf_malloc(255*8);
aa53efc3 1966 if (dataout == NULL){
1967 Dbprintf("out of memory");
1968 OnError(1);
1969 return;
1970 }
3ac22ee1 1971 memset(dataout,0xFF,255*8);
fecd8202 1972
aa53efc3 1973 for (;blkCnt < numblks; blkCnt++) {
3ac22ee1 1974 isOK = iClass_ReadBlock(blockno+blkCnt, readblockdata);
1975 if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0xBB || readblockdata[2] == 0xBB)) { //try again
1976 isOK = iClass_ReadBlock(blockno+blkCnt, readblockdata);
aa53efc3 1977 if (!isOK) {
1978 Dbprintf("Block %02X failed to read", blkCnt+blockno);
1979 break;
1980 }
fecd8202 1981 }
aa53efc3 1982 memcpy(dataout+(blkCnt*8),readblockdata,8);
aa53efc3 1983 }
1984 //return pointer to dump memory in arg3
1985 cmd_send(CMD_ACK,isOK,blkCnt,BigBuf_max_traceLen(),0,0);
1986 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1987 LEDsoff();
1988 BigBuf_free();
1989}
1990
3ac22ee1 1991bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) {
671ff89f 1992 uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3ac22ee1 1993 //uint8_t readblockdata[10];
1994 //write[1] = blockNo;
aa53efc3 1995 memcpy(write+2, data, 12); // data + mac
671ff89f 1996 char *wrCmd = (char *)(write+1);
1997 uint16_t wrCrc = iclass_crc16(wrCmd, 13);
1998 write[14] = wrCrc >> 8;
1999 write[15] = wrCrc & 0xff;
3ac22ee1 2000 uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0};
671ff89f 2001 bool isOK = false;
2002
3ac22ee1 2003 isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
671ff89f 2004 if (isOK) { //if reader responded correctly
3ac22ee1 2005 //Dbprintf("WriteResp: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]);
671ff89f 2006 if (memcmp(write+2,resp,8)) { //if response is not equal to write values
2007 if (blockNo != 3 && blockNo != 4) { //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data)
2008 //error try again
2009 isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
2010 }
2011
fecd8202 2012 }
fecd8202 2013 }
aa53efc3 2014 return isOK;
2015}
2016
3ac22ee1 2017void iClass_WriteBlock(uint8_t blockNo, uint8_t *data) {
2018 bool isOK = iClass_WriteBlock_ext(blockNo, data);
aa53efc3 2019 if (isOK){
2020 Dbprintf("Write block [%02x] successful",blockNo);
2021 } else {
2022 Dbprintf("Write block [%02x] failed",blockNo);
2023 }
2024 cmd_send(CMD_ACK,isOK,0,0,0,0);
2025}
2026
3ac22ee1 2027void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
aa53efc3 2028 int i;
2029 int written = 0;
2030 int total_block = (endblock - startblock) + 1;
2031 for (i = 0; i < total_block;i++){
2032 // block number
3ac22ee1 2033 if (iClass_WriteBlock_ext(i+startblock, data+(i*12))){
aa53efc3 2034 Dbprintf("Write block [%02x] successful",i + startblock);
2035 written++;
2036 } else {
3ac22ee1 2037 if (iClass_WriteBlock_ext(i+startblock, data+(i*12))){
aa53efc3 2038 Dbprintf("Write block [%02x] successful",i + startblock);
2039 written++;
2040 } else {
2041 Dbprintf("Write block [%02x] failed",i + startblock);
2042 }
2043 }
2044 }
2045 if (written == total_block)
2046 Dbprintf("Clone complete");
2047 else
2048 Dbprintf("Clone incomplete");
2049
2050 cmd_send(CMD_ACK,1,0,0,0,0);
2051 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2052 LEDsoff();
2053}
Impressum, Datenschutz