1 //----------------------------------------------------------------------------- 
   2 // Gerhard de Koning Gans - May 2008 
   3 // Hagen Fritsch - June 2010 
   4 // Gerhard de Koning Gans - May 2011 
   5 // Gerhard de Koning Gans - June 2012 - Added iClass card and reader emulation 
   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 
  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 
  16 // Please feel free to contribute and extend iClass support!! 
  17 //----------------------------------------------------------------------------- 
  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: 
  24 //  +  22279:    :     0c  03  e8  01 
  26 //    ...with an incorrect answer... 
  28 //  +     85:   0: TAG ff! ff! ff! ff! ff! ff! ff! ff! bb  33  bb  00  01! 0e! 04! bb     !crc 
  30 // We still left the error signalling bytes in the traces like 0xbb 
  32 // A correct trace should look like this: 
  34 // +  21112:    :     0c  03  e8  01 
  35 // +     85:   0: TAG ff  ff  ff  ff  ff  ff  ff  ff  ea  f5 
  37 //----------------------------------------------------------------------------- 
  41 #include "proxmark3.h" 
  48 #include "iso14443a.h" 
  50 // Needed for CRC in emulation mode; 
  51 // same construction as in ISO 14443; 
  52 // different initial value (CRC_ICLASS) 
  53 #include "iso14443crc.h" 
  54 #include "iso15693tools.h" 
  55 #include "protocols.h" 
  56 #include "optimized_cipher.h" 
  57 #include "usb_cdc.h" // for usb_poll_validate_length 
  58 #include "fpgaloader.h" 
  60 // iCLASS has a slightly different timing compared to ISO15693. According to the picopass data sheet the tag response is expected 330us after 
  61 // the reader command. This is measured from end of reader EOF to first modulation of the tag's SOF which starts with a 56,64us unmodulated period. 
  62 // 330us = 140 ssp_clk cycles @ 423,75kHz when simulating. 
  63 // 56,64us = 24 ssp_clk_cycles 
  64 #define DELAY_ICLASS_VCD_TO_VICC_SIM     (140 - 24) 
  65 // times in ssp_clk_cycles @ 3,3625MHz when acting as reader 
  66 #define DELAY_ICLASS_VICC_TO_VCD_READER  DELAY_ISO15693_VICC_TO_VCD_READER 
  67 // times in samples @ 212kHz when acting as reader 
  68 #define ICLASS_READER_TIMEOUT_ACTALL     330 // 1558us, nominal 330us + 7slots*160us = 1450us 
  69 #define ICLASS_READER_TIMEOUT_UPDATE    3390 // 16000us, nominal 4-15ms 
  70 #define ICLASS_READER_TIMEOUT_OTHERS      80 // 380us, nominal 330us 
  73 //----------------------------------------------------------------------------- 
  74 // The software UART that receives commands from the reader, and its state 
  76 //----------------------------------------------------------------------------- 
  80                 STATE_START_OF_COMMUNICATION
, 
 100 static RAMFUNC 
int OutOfNDecoding(int bit
) { 
 104         if (!Uart
.bitBuffer
) { 
 105                 Uart
.bitBuffer 
= bit 
^ 0xFF0; 
 108                 Uart
.bitBuffer 
<<= 4; 
 109                 Uart
.bitBuffer 
^= bit
; 
 112         /*if (Uart.swapper) { 
 113                 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; 
 116                 if (Uart.byteCnt > 15) { return true; } 
 122         if (Uart
.state 
!= STATE_UNSYNCD
) { 
 125                 if ((Uart
.bitBuffer 
& Uart
.syncBit
) ^ Uart
.syncBit
) { 
 130                 if (((Uart
.bitBuffer 
<< 1) & Uart
.syncBit
) ^ Uart
.syncBit
) { 
 135                 if (bit 
!= bitright
) { 
 140                 // So, now we only have to deal with *bit*, lets see... 
 141                 if (Uart
.posCnt 
== 1) { 
 142                         // measurement first half bitperiod 
 144                                 // Drop in first half means that we are either seeing 
 147                                 if (Uart
.nOutOfCnt 
== 1) { 
 148                                         // End of Communication 
 149                                         Uart
.state 
= STATE_UNSYNCD
; 
 151                                         if (Uart
.byteCnt 
== 0) { 
 152                                                 // Its not straightforward to show single EOFs 
 153                                                 // So just leave it and do not return true 
 154                                                 Uart
.output
[0] = 0xf0; 
 159                                 } else if (Uart
.state 
!= STATE_START_OF_COMMUNICATION
) { 
 160                                         // When not part of SOF or EOF, it is an error 
 161                                         Uart
.state 
= STATE_UNSYNCD
; 
 167                         // measurement second half bitperiod 
 168                         // Count the bitslot we are in... (ISO 15693) 
 172                                 if (Uart
.dropPosition
) { 
 173                                         if (Uart
.state 
== STATE_START_OF_COMMUNICATION
) { 
 178                                         // It is an error if we already have seen a drop in current frame 
 179                                         Uart
.state 
= STATE_UNSYNCD
; 
 182                                         Uart
.dropPosition 
= Uart
.nOutOfCnt
; 
 189                         if (Uart
.nOutOfCnt 
== Uart
.OutOfCnt 
&& Uart
.OutOfCnt 
== 4) { 
 192                                 if (Uart
.state 
== STATE_START_OF_COMMUNICATION
) { 
 193                                         if (Uart
.dropPosition 
== 4) { 
 194                                                 Uart
.state 
= STATE_RECEIVING
; 
 196                                         } else if (Uart
.dropPosition 
== 3) { 
 197                                                 Uart
.state 
= STATE_RECEIVING
; 
 199                                                 //Uart.output[Uart.byteCnt] = 0xdd; 
 202                                                 Uart
.state 
= STATE_UNSYNCD
; 
 205                                         Uart
.dropPosition 
= 0; 
 209                                         if (!Uart
.dropPosition
) { 
 210                                                 Uart
.state 
= STATE_UNSYNCD
; 
 218                                                 //if (Uart.dropPosition == 1) { Uart.dropPosition = 2; } 
 219                                                 //else if (Uart.dropPosition == 2) { Uart.dropPosition = 1; } 
 221                                                 Uart
.shiftReg 
^= ((Uart
.dropPosition 
& 0x03) << 6); 
 223                                                 Uart
.dropPosition 
= 0; 
 225                                                 if (Uart
.bitCnt 
== 8) { 
 226                                                         Uart
.output
[Uart
.byteCnt
] = (Uart
.shiftReg 
& 0xff); 
 233                         } else if (Uart
.nOutOfCnt 
== Uart
.OutOfCnt
) { 
 236                                 if (!Uart
.dropPosition
) { 
 237                                         Uart
.state 
= STATE_UNSYNCD
; 
 242                                         Uart
.output
[Uart
.byteCnt
] = (Uart
.dropPosition 
& 0xff); 
 247                                         Uart
.dropPosition 
= 0; 
 252                                 Uart.output[Uart.byteCnt] = 0xAA; 
 254                                 Uart.output[Uart.byteCnt] = error & 0xFF; 
 256                                 Uart.output[Uart.byteCnt] = 0xAA; 
 258                                 Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF; 
 260                                 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; 
 262                                 Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF; 
 264                                 Uart.output[Uart.byteCnt] = 0xAA; 
 271                 bit 
= Uart
.bitBuffer 
& 0xf0; 
 273                 bit 
^= 0x0F; // drops become 1s ;-) 
 275                         // should have been high or at least (4 * 128) / fc 
 276                         // according to ISO this should be at least (9 * 128 + 20) / fc 
 277                         if (Uart
.highCnt 
== 8) { 
 278                                 // we went low, so this could be start of communication 
 279                                 // it turns out to be safer to choose a less significant 
 280                                 // syncbit... so we check whether the neighbour also represents the drop 
 281                                 Uart
.posCnt 
= 1;   // apparently we are busy with our first half bit period 
 282                                 Uart
.syncBit 
= bit 
& 8; 
 284                                 if (!Uart
.syncBit
)  { Uart
.syncBit 
= bit 
& 4; Uart
.samples 
= 2; } 
 285                                 else if (bit 
& 4)   { Uart
.syncBit 
= bit 
& 4; Uart
.samples 
= 2; bit 
<<= 2; } 
 286                                 if (!Uart
.syncBit
)  { Uart
.syncBit 
= bit 
& 2; Uart
.samples 
= 1; } 
 287                                 else if (bit 
& 2)   { Uart
.syncBit 
= bit 
& 2; Uart
.samples 
= 1; bit 
<<= 1; } 
 288                                 if (!Uart
.syncBit
)  { Uart
.syncBit 
= bit 
& 1; Uart
.samples 
= 0; 
 289                                         if (Uart
.syncBit 
&& (Uart
.bitBuffer 
& 8)) { 
 292                                                 // the first half bit period is expected in next sample 
 296                                 } else if (bit 
& 1) { Uart
.syncBit 
= bit 
& 1; Uart
.samples 
= 0; } 
 299                                 Uart
.state 
= STATE_START_OF_COMMUNICATION
; 
 303                                 Uart
.OutOfCnt 
= 4; // Start at 1/4, could switch to 1/256 
 304                                 Uart
.dropPosition 
= 0; 
 310                 } else if (Uart
.highCnt 
< 8) { 
 319 //============================================================================= 
 321 //============================================================================= 
 326                 DEMOD_START_OF_COMMUNICATION
, 
 327                 DEMOD_START_OF_COMMUNICATION2
, 
 328                 DEMOD_START_OF_COMMUNICATION3
, 
 332                 DEMOD_END_OF_COMMUNICATION
, 
 333                 DEMOD_END_OF_COMMUNICATION2
, 
 356 static RAMFUNC 
int ManchesterDecoding(int v
) { 
 362         Demod
.buffer 
= Demod
.buffer2
; 
 363         Demod
.buffer2 
= Demod
.buffer3
; 
 366         if (Demod
.buff 
< 3) { 
 371         if (Demod
.state
==DEMOD_UNSYNCD
) { 
 372                 Demod
.output
[Demod
.len
] = 0xfa; 
 375                 Demod
.posCount 
= 1;     // This is the first half bit period, so after syncing handle the second part 
 378                         Demod
.syncBit 
= 0x08; 
 385                         Demod
.syncBit 
= 0x04; 
 392                         Demod
.syncBit 
= 0x02; 
 395                 if (bit 
& 0x01 && Demod
.syncBit
) { 
 396                         Demod
.syncBit 
= 0x01; 
 401                         Demod
.state 
= DEMOD_START_OF_COMMUNICATION
; 
 402                         Demod
.sub 
= SUB_FIRST_HALF
; 
 406                         if (Demod
.posCount
) { 
 407                                 switch (Demod
.syncBit
) { 
 408                                         case 0x08: Demod
.samples 
= 3; break; 
 409                                         case 0x04: Demod
.samples 
= 2; break; 
 410                                         case 0x02: Demod
.samples 
= 1; break; 
 411                                         case 0x01: Demod
.samples 
= 0; break; 
 413                                 // SOF must be long burst... otherwise stay unsynced!!! 
 414                                 if (!(Demod
.buffer 
& Demod
.syncBit
) || !(Demod
.buffer2 
& Demod
.syncBit
)) { 
 415                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 418                                 // SOF must be long burst... otherwise stay unsynced!!! 
 419                                 if (!(Demod
.buffer2 
& Demod
.syncBit
) || !(Demod
.buffer3 
& Demod
.syncBit
)) { 
 420                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 429                 // state is DEMOD is in SYNC from here on. 
 430                 modulation 
= bit 
& Demod
.syncBit
; 
 431                 modulation 
|= ((bit 
<< 1) ^ ((Demod
.buffer 
& 0x08) >> 3)) & Demod
.syncBit
; 
 435                 if (Demod
.posCount 
== 0) { 
 438                                 Demod
.sub 
= SUB_FIRST_HALF
; 
 440                                 Demod
.sub 
= SUB_NONE
; 
 445                                 if (Demod
.sub 
== SUB_FIRST_HALF
) { 
 446                                         Demod
.sub 
= SUB_BOTH
; 
 448                                         Demod
.sub 
= SUB_SECOND_HALF
; 
 450                         } else if (Demod
.sub 
== SUB_NONE
) { 
 451                                 if (Demod
.state 
== DEMOD_SOF_COMPLETE
) { 
 452                                         Demod
.output
[Demod
.len
] = 0x0f; 
 454                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 457                                         Demod
.state 
= DEMOD_ERROR_WAIT
; 
 462                         switch(Demod
.state
) { 
 463                                 case DEMOD_START_OF_COMMUNICATION
: 
 464                                         if (Demod
.sub 
== SUB_BOTH
) { 
 465                                                 Demod
.state 
= DEMOD_START_OF_COMMUNICATION2
; 
 467                                                 Demod
.sub 
= SUB_NONE
; 
 469                                                 Demod
.output
[Demod
.len
] = 0xab; 
 470                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 474                                 case DEMOD_START_OF_COMMUNICATION2
: 
 475                                         if (Demod
.sub 
== SUB_SECOND_HALF
) { 
 476                                                 Demod
.state 
= DEMOD_START_OF_COMMUNICATION3
; 
 478                                                 Demod
.output
[Demod
.len
] = 0xab; 
 479                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 483                                 case DEMOD_START_OF_COMMUNICATION3
: 
 484                                         if (Demod
.sub 
== SUB_SECOND_HALF
) { 
 485                                                 Demod
.state 
= DEMOD_SOF_COMPLETE
; 
 487                                                 Demod
.output
[Demod
.len
] = 0xab; 
 488                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 492                                 case DEMOD_SOF_COMPLETE
: 
 493                                 case DEMOD_MANCHESTER_D
: 
 494                                 case DEMOD_MANCHESTER_E
: 
 495                                         // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443) 
 496                                         //                          00001111 = 1 (0 in 14443) 
 497                                         if (Demod
.sub 
== SUB_SECOND_HALF
) { // SUB_FIRST_HALF 
 499                                                 Demod
.shiftReg 
= (Demod
.shiftReg 
>> 1) ^ 0x100; 
 500                                                 Demod
.state 
= DEMOD_MANCHESTER_D
; 
 501                                         } else if (Demod
.sub 
== SUB_FIRST_HALF
) { // SUB_SECOND_HALF 
 503                                                 Demod
.shiftReg 
>>= 1; 
 504                                                 Demod
.state 
= DEMOD_MANCHESTER_E
; 
 505                                         } else if (Demod
.sub 
== SUB_BOTH
) { 
 506                                                 Demod
.state 
= DEMOD_MANCHESTER_F
; 
 508                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 513                                 case DEMOD_MANCHESTER_F
: 
 514                                         // Tag response does not need to be a complete byte! 
 515                                         if (Demod
.len 
> 0 || Demod
.bitCount 
> 0) { 
 516                                                 if (Demod
.bitCount 
> 1) {  // was > 0, do not interpret last closing bit, is part of EOF 
 517                                                         Demod
.shiftReg 
>>= (9 - Demod
.bitCount
);    // right align data 
 518                                                         Demod
.output
[Demod
.len
] = Demod
.shiftReg 
& 0xff; 
 522                                                 Demod
.state 
= DEMOD_UNSYNCD
; 
 525                                                 Demod
.output
[Demod
.len
] = 0xad; 
 526                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 531                                 case DEMOD_ERROR_WAIT
: 
 532                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 536                                         Demod
.output
[Demod
.len
] = 0xdd; 
 537                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 541                         if (Demod
.bitCount 
>= 8) { 
 542                                 Demod
.shiftReg 
>>= 1; 
 543                                 Demod
.output
[Demod
.len
] = (Demod
.shiftReg 
& 0xff); 
 550                                 Demod
.output
[Demod
.len
] = 0xBB; 
 552                                 Demod
.output
[Demod
.len
] = error 
& 0xFF; 
 554                                 Demod
.output
[Demod
.len
] = 0xBB; 
 556                                 Demod
.output
[Demod
.len
] = bit 
& 0xFF; 
 558                                 Demod
.output
[Demod
.len
] = Demod
.buffer 
& 0xFF; 
 561                                 Demod
.output
[Demod
.len
] = Demod
.buffer2 
& 0xFF; 
 563                                 Demod
.output
[Demod
.len
] = Demod
.syncBit 
& 0xFF; 
 565                                 Demod
.output
[Demod
.len
] = 0xBB; 
 572         } // end (state != UNSYNCED) 
 577 //============================================================================= 
 578 // Finally, a `sniffer' for iClass communication 
 579 // Both sides of communication! 
 580 //============================================================================= 
 582 //----------------------------------------------------------------------------- 
 583 // Record the sequence of commands sent by the reader to the tag, with 
 584 // triggering so that we start recording at the point that the tag is moved 
 586 //----------------------------------------------------------------------------- 
 587 void RAMFUNC 
SnoopIClass(void) { 
 589         // We won't start recording the frames that we acquire until we trigger; 
 590         // a good trigger condition to get started is probably when we see a 
 591         // response from the tag. 
 592         //int triggered = false; // false to wait first for card 
 594         // The command (reader -> tag) that we're receiving. 
 595         // The length of a received command will in most cases be no more than 18 bytes. 
 596         // So 32 should be enough! 
 597         #define ICLASS_BUFFER_SIZE 32 
 598         uint8_t readerToTagCmd
[ICLASS_BUFFER_SIZE
]; 
 599         // The response (tag -> reader) that we're receiving. 
 600         uint8_t tagToReaderResponse
[ICLASS_BUFFER_SIZE
]; 
 602         FpgaDownloadAndGo(FPGA_BITSTREAM_HF
); 
 604         // free all BigBuf memory 
 606         // The DMA buffer, used to stream samples from the FPGA 
 607         uint8_t *dmaBuf 
= BigBuf_malloc(DMA_BUFFER_SIZE
); 
 611         iso14a_set_trigger(false); 
 618         // Count of samples received so far, so that we can include timing 
 619         // information in the trace buffer. 
 623         // Set up the demodulator for tag -> reader responses. 
 624         Demod
.output 
= tagToReaderResponse
; 
 626         Demod
.state 
= DEMOD_UNSYNCD
; 
 628         // Setup for the DMA. 
 629         FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A
); 
 631         lastRxCounter 
= DMA_BUFFER_SIZE
; 
 632         FpgaSetupSscDma((uint8_t *)dmaBuf
, DMA_BUFFER_SIZE
); 
 634         // And the reader -> tag commands 
 635         memset(&Uart
, 0, sizeof(Uart
)); 
 636         Uart
.output 
= readerToTagCmd
; 
 637         Uart
.byteCntMax 
= 32; // was 100 (greg)//////////////////////////////////////////////////////////////////////// 
 638         Uart
.state 
= STATE_UNSYNCD
; 
 640         // And put the FPGA in the appropriate mode 
 641         // Signal field is off with the appropriate LED 
 643         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A 
| FPGA_HF_ISO14443A_SNIFFER
); 
 644         SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); 
 646         uint32_t time_0 
= GetCountSspClk(); 
 647         uint32_t time_start 
= 0; 
 648         uint32_t time_stop  
= 0; 
 655         // And now we loop, receiving samples. 
 659                 int behindBy 
= (lastRxCounter 
- AT91C_BASE_PDC_SSC
->PDC_RCR
) & (DMA_BUFFER_SIZE
-1); 
 660                 if (behindBy 
> maxBehindBy
) { 
 661                         maxBehindBy 
= behindBy
; 
 662                         if (behindBy 
> (9 * DMA_BUFFER_SIZE 
/ 10)) { 
 663                                 Dbprintf("blew circular buffer! behindBy=0x%x", behindBy
); 
 667                 if (behindBy 
< 1) continue; 
 673                 if (upTo 
- dmaBuf 
> DMA_BUFFER_SIZE
) { 
 674                         upTo 
-= DMA_BUFFER_SIZE
; 
 675                         lastRxCounter 
+= DMA_BUFFER_SIZE
; 
 676                         AT91C_BASE_PDC_SSC
->PDC_RNPR 
= (uint32_t) upTo
; 
 677                         AT91C_BASE_PDC_SSC
->PDC_RNCR 
= DMA_BUFFER_SIZE
; 
 684                         decbyte 
^= (1 << (3 - div
)); 
 687                 // FOR READER SIDE COMMUMICATION... 
 690                 decbyter 
^= (smpl 
& 0x30); 
 694                 if ((div 
+ 1) % 2 == 0) { 
 696                         if (OutOfNDecoding((smpl 
& 0xF0) >> 4)) { 
 697                                 rsamples 
= samples 
- Uart
.samples
; 
 698                                 time_stop 
= (GetCountSspClk()-time_0
) << 4; 
 700                                 //if (!LogTrace(Uart.output, Uart.byteCnt, rsamples, Uart.parityBits,true)) break; 
 701                                 //if (!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, true)) break; 
 702                                 uint8_t parity
[MAX_PARITY_SIZE
]; 
 703                                 GetParity(Uart
.output
, Uart
.byteCnt
, parity
); 
 704                                 LogTrace_ISO15693(Uart
.output
, Uart
.byteCnt
, time_start
*32, time_stop
*32, parity
, true); 
 706                                 /* And ready to receive another command. */ 
 707                                 Uart
.state 
= STATE_UNSYNCD
; 
 708                                 /* And also reset the demod code, which might have been */ 
 709                                 /* false-triggered by the commands from the reader. */ 
 710                                 Demod
.state 
= DEMOD_UNSYNCD
; 
 713                                 time_start 
= (GetCountSspClk()-time_0
) << 4; 
 720                         if (ManchesterDecoding(smpl 
& 0x0F)) { 
 721                                 time_stop 
= (GetCountSspClk()-time_0
) << 4; 
 723                                 rsamples 
= samples 
- Demod
.samples
; 
 725                                 uint8_t parity
[MAX_PARITY_SIZE
]; 
 726                                 GetParity(Demod
.output
, Demod
.len
, parity
); 
 727                                 LogTrace_ISO15693(Demod
.output
, Demod
.len
, time_start
*32, time_stop
*32, parity
, false); 
 729                                 // And ready to receive another response. 
 730                                 memset(&Demod
, 0, sizeof(Demod
)); 
 731                                 Demod
.output 
= tagToReaderResponse
; 
 732                                 Demod
.state 
= DEMOD_UNSYNCD
; 
 734                                 time_start 
= (GetCountSspClk()-time_0
) << 4; 
 741                 if (BUTTON_PRESS()) { 
 742                         DbpString("cancelled_a"); 
 747         DbpString("COMMAND FINISHED"); 
 749         Dbprintf("%x %x %x", maxBehindBy
, Uart
.state
, Uart
.byteCnt
); 
 750         Dbprintf("%x %x %x", Uart
.byteCntMax
, BigBuf_get_traceLen(), (int)Uart
.output
[0]); 
 753         AT91C_BASE_PDC_SSC
->PDC_PTCR 
= AT91C_PDC_RXTDIS
; 
 754         Dbprintf("%x %x %x", maxBehindBy
, Uart
.state
, Uart
.byteCnt
); 
 755         Dbprintf("%x %x %x", Uart
.byteCntMax
, BigBuf_get_traceLen(), (int)Uart
.output
[0]); 
 759 void rotateCSN(uint8_t* originalCSN
, uint8_t* rotatedCSN
) { 
 761         for (i 
= 0; i 
< 8; i
++) { 
 762                 rotatedCSN
[i
] = (originalCSN
[i
] >> 3) | (originalCSN
[(i
+1)%8
] << 5); 
 767 static void CodeIClassTagSOF() { 
 769         ToSend
[++ToSendMax
] = 0x1D; 
 773 static void AppendCrc(uint8_t *data
, int len
) { 
 774         ComputeCrc14443(CRC_ICLASS
, data
, len
, data
+len
, data
+len
+1); 
 779  * @brief Does the actual simulation 
 781 int doIClassSimulation(int simulationMode
, uint8_t *reader_mac_buf
) { 
 783         // free eventually allocated BigBuf memory 
 784         BigBuf_free_keep_EM(); 
 786         uint16_t page_size 
= 32 * 8; 
 787         uint8_t current_page 
= 0; 
 789         // maintain cipher states for both credit and debit key for each page 
 790         State cipher_state_KC
[8]; 
 791         State cipher_state_KD
[8]; 
 792         State 
*cipher_state 
= &cipher_state_KD
[0]; 
 794         uint8_t *emulator 
= BigBuf_get_EM_addr(); 
 795         uint8_t *csn 
= emulator
; 
 797         // CSN followed by two CRC bytes 
 798         uint8_t anticoll_data
[10]; 
 799         uint8_t csn_data
[10]; 
 800         memcpy(csn_data
, csn
, sizeof(csn_data
)); 
 801         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]); 
 803         // Construct anticollision-CSN 
 804         rotateCSN(csn_data
, anticoll_data
); 
 806         // Compute CRC on both CSNs 
 807         AppendCrc(anticoll_data
, 8); 
 808         AppendCrc(csn_data
, 8); 
 810         uint8_t diversified_key_d
[8] = { 0x00 }; 
 811         uint8_t diversified_key_c
[8] = { 0x00 }; 
 812         uint8_t *diversified_key 
= diversified_key_d
; 
 814         // configuration block 
 815         uint8_t conf_block
[10] = {0x12, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xFF, 0x3C, 0x00, 0x00}; 
 818         uint8_t card_challenge_data
[8] = { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
 820         if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { 
 821                 // initialize from page 0 
 822                 memcpy(conf_block
, emulator 
+ 8 * 1, 8); 
 823                 memcpy(card_challenge_data
, emulator 
+ 8 * 2, 8); // e-purse 
 824                 memcpy(diversified_key_d
, emulator 
+ 8 * 3, 8);   // Kd 
 825                 memcpy(diversified_key_c
, emulator 
+ 8 * 4, 8);   // Kc 
 828         AppendCrc(conf_block
, 8); 
 830         // save card challenge for sim2,4 attack 
 831         if (reader_mac_buf 
!= NULL
) { 
 832                 memcpy(reader_mac_buf
, card_challenge_data
, 8); 
 835         if (conf_block
[5] & 0x80) { 
 840         // When the page is in personalization mode this bit is equal to 1. 
 841         // Once the application issuer has personalized and coded its dedicated areas, this bit must be set to 0: 
 842         // the page is then "in application mode". 
 843         bool personalization_mode 
= conf_block
[7] & 0x80; 
 845         // chip memory may be divided in 8 pages 
 846         uint8_t max_page 
= conf_block
[4] & 0x10 ? 0 : 7; 
 848         // Precalculate the cipher states, feeding it the CC 
 849         cipher_state_KD
[0] = opt_doTagMAC_1(card_challenge_data
, diversified_key_d
); 
 850         cipher_state_KC
[0] = opt_doTagMAC_1(card_challenge_data
, diversified_key_c
); 
 851         if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { 
 852                 for (int i 
= 1; i 
< max_page
; i
++) { 
 853                         uint8_t *epurse 
= emulator 
+ i
*page_size 
+ 8*2; 
 854                         uint8_t *Kd 
= emulator 
+ i
*page_size 
+ 8*3; 
 855                         uint8_t *Kc 
= emulator 
+ i
*page_size 
+ 8*4; 
 856                         cipher_state_KD
[i
] = opt_doTagMAC_1(epurse
, Kd
); 
 857                         cipher_state_KC
[i
] = opt_doTagMAC_1(epurse
, Kc
); 
 866         // Reader 81 anticoll. CSN 
 869         uint8_t *modulated_response
; 
 870         int modulated_response_size 
= 0; 
 871         uint8_t *trace_data 
= NULL
; 
 872         int trace_data_size 
= 0; 
 874         // Respond SOF -- takes 1 bytes 
 875         uint8_t *resp_sof 
= BigBuf_malloc(1); 
 878         // Anticollision CSN (rotated CSN) 
 879         // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) 
 880         uint8_t *resp_anticoll 
= BigBuf_malloc(22); 
 881         int resp_anticoll_len
; 
 884         // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) 
 885         uint8_t *resp_csn 
= BigBuf_malloc(22); 
 888         // configuration (block 1) picopass 2ks 
 889         uint8_t *resp_conf 
= BigBuf_malloc(22); 
 893         // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit) 
 894         uint8_t *resp_cc 
= BigBuf_malloc(18); 
 897         // Kd, Kc (blocks 3 and 4). Cannot be read. Always respond with 0xff bytes only 
 898         uint8_t *resp_ff 
= BigBuf_malloc(22); 
 900         uint8_t ff_data
[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00}; 
 901         AppendCrc(ff_data
, 8); 
 903         // Application Issuer Area (block 5) 
 904         uint8_t *resp_aia 
= BigBuf_malloc(22); 
 906         uint8_t aia_data
[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00}; 
 907         AppendCrc(aia_data
, 8); 
 909         uint8_t *receivedCmd 
= BigBuf_malloc(MAX_FRAME_SIZE
); 
 912         // Prepare card messages 
 914         // First card answer: SOF only 
 916         memcpy(resp_sof
, ToSend
, ToSendMax
); 
 917         resp_sof_Len 
= ToSendMax
; 
 920         CodeIso15693AsTag(anticoll_data
, sizeof(anticoll_data
)); 
 921         memcpy(resp_anticoll
, ToSend
, ToSendMax
); 
 922         resp_anticoll_len 
= ToSendMax
; 
 925         CodeIso15693AsTag(csn_data
, sizeof(csn_data
)); 
 926         memcpy(resp_csn
, ToSend
, ToSendMax
); 
 927         resp_csn_len 
= ToSendMax
; 
 929         // Configuration (block 1) 
 930         CodeIso15693AsTag(conf_block
, sizeof(conf_block
)); 
 931         memcpy(resp_conf
, ToSend
, ToSendMax
); 
 932         resp_conf_len 
= ToSendMax
; 
 935         CodeIso15693AsTag(card_challenge_data
, sizeof(card_challenge_data
)); 
 936         memcpy(resp_cc
, ToSend
, ToSendMax
); 
 937         resp_cc_len 
= ToSendMax
; 
 939         // Kd, Kc (blocks 3 and 4) 
 940         CodeIso15693AsTag(ff_data
, sizeof(ff_data
)); 
 941         memcpy(resp_ff
, ToSend
, ToSendMax
); 
 942         resp_ff_len 
= ToSendMax
; 
 944         // Application Issuer Area (block 5) 
 945         CodeIso15693AsTag(aia_data
, sizeof(aia_data
)); 
 946         memcpy(resp_aia
, ToSend
, ToSendMax
); 
 947         resp_aia_len 
= ToSendMax
; 
 949         //This is used for responding to READ-block commands or other data which is dynamically generated 
 950         uint8_t *data_generic_trace 
= BigBuf_malloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer 
 951         uint8_t *data_response 
= BigBuf_malloc( (32 + 2) * 2 + 2); 
 953         bool buttonPressed 
= false; 
 954         enum { IDLE
, ACTIVATED
, SELECTED
, HALTED 
} chip_state 
= IDLE
; 
 959                 uint32_t reader_eof_time 
= 0; 
 960                 len 
= GetIso15693CommandFromReader(receivedCmd
, MAX_FRAME_SIZE
, &reader_eof_time
); 
 962                         buttonPressed 
= true; 
 966                 // Now look at the reader command and provide appropriate responses 
 967                 // default is no response: 
 968                 modulated_response 
= NULL
; 
 969                 modulated_response_size 
= 0; 
 973                 if (receivedCmd
[0] == ICLASS_CMD_ACTALL 
&& len 
== 1) { 
 974                         // Reader in anticollision phase 
 975                         if (chip_state 
!= HALTED
) { 
 976                                 modulated_response 
= resp_sof
; 
 977                                 modulated_response_size 
= resp_sof_Len
; 
 978                                 chip_state 
= ACTIVATED
; 
 981                 } else if (receivedCmd
[0] == ICLASS_CMD_READ_OR_IDENTIFY 
&& len 
== 1) { // identify 
 982                         // Reader asks for anticollision CSN 
 983                         if (chip_state 
== SELECTED 
|| chip_state 
== ACTIVATED
) { 
 984                                 modulated_response 
= resp_anticoll
; 
 985                                 modulated_response_size 
= resp_anticoll_len
; 
 986                                 trace_data 
= anticoll_data
; 
 987                                 trace_data_size 
= sizeof(anticoll_data
); 
 990                 } else if (receivedCmd
[0] == ICLASS_CMD_SELECT 
&& len 
== 9) { 
 991                         // Reader selects anticollision CSN. 
 992                         // Tag sends the corresponding real CSN 
 993                         if (chip_state 
== ACTIVATED 
|| chip_state 
== SELECTED
) { 
 994                                 if (!memcmp(receivedCmd
+1, anticoll_data
, 8)) { 
 995                                         modulated_response 
= resp_csn
; 
 996                                         modulated_response_size 
= resp_csn_len
; 
 997                                         trace_data 
= csn_data
; 
 998                                         trace_data_size 
= sizeof(csn_data
); 
 999                                         chip_state 
= SELECTED
; 
1003                         } else if (chip_state 
== HALTED
) { 
1004                                 // RESELECT with CSN 
1005                                 if (!memcmp(receivedCmd
+1, csn_data
, 8)) { 
1006                                         modulated_response 
= resp_csn
; 
1007                                         modulated_response_size 
= resp_csn_len
; 
1008                                         trace_data 
= csn_data
; 
1009                                         trace_data_size 
= sizeof(csn_data
); 
1010                                         chip_state 
= SELECTED
; 
1014                 } else if (receivedCmd
[0] == ICLASS_CMD_READ_OR_IDENTIFY 
&& len 
== 4) { // read block 
1015                         uint16_t blockNo 
= receivedCmd
[1]; 
1016                         if (chip_state 
== SELECTED
) { 
1017                                 if (simulationMode 
== ICLASS_SIM_MODE_EXIT_AFTER_MAC
) { 
1018                                         // provide defaults for blocks 0 ... 5 
1020                                                 case 0: // csn (block 00) 
1021                                                         modulated_response 
= resp_csn
; 
1022                                                         modulated_response_size 
= resp_csn_len
; 
1023                                                         trace_data 
= csn_data
; 
1024                                                         trace_data_size 
= sizeof(csn_data
); 
1026                                                 case 1: // configuration (block 01) 
1027                                                         modulated_response 
= resp_conf
; 
1028                                                         modulated_response_size 
= resp_conf_len
; 
1029                                                         trace_data 
= conf_block
; 
1030                                                         trace_data_size 
= sizeof(conf_block
); 
1032                                                 case 2: // e-purse (block 02) 
1033                                                         modulated_response 
= resp_cc
; 
1034                                                         modulated_response_size 
= resp_cc_len
; 
1035                                                         trace_data 
= card_challenge_data
; 
1036                                                         trace_data_size 
= sizeof(card_challenge_data
); 
1037                                                         // set epurse of sim2,4 attack 
1038                                                         if (reader_mac_buf 
!= NULL
) { 
1039                                                                 memcpy(reader_mac_buf
, card_challenge_data
, 8); 
1043                                                 case 4: // Kd, Kc, always respond with 0xff bytes 
1044                                                         modulated_response 
= resp_ff
; 
1045                                                         modulated_response_size 
= resp_ff_len
; 
1046                                                         trace_data 
= ff_data
; 
1047                                                         trace_data_size 
= sizeof(ff_data
); 
1049                                                 case 5: // Application Issuer Area (block 05) 
1050                                                         modulated_response 
= resp_aia
; 
1051                                                         modulated_response_size 
= resp_aia_len
; 
1052                                                         trace_data 
= aia_data
; 
1053                                                         trace_data_size 
= sizeof(aia_data
); 
1055                                                 // default: don't respond 
1057                                 } else if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { 
1058                                         if (blockNo 
== 3 || blockNo 
== 4) { // Kd, Kc, always respond with 0xff bytes 
1059                                                 modulated_response 
= resp_ff
; 
1060                                                 modulated_response_size 
= resp_ff_len
; 
1061                                                 trace_data 
= ff_data
; 
1062                                                 trace_data_size 
= sizeof(ff_data
); 
1063                                         } else { // use data from emulator memory 
1064                                                 memcpy(data_generic_trace
, emulator 
+ current_page
*page_size 
+ 8*blockNo
, 8); 
1065                                                 AppendCrc(data_generic_trace
, 8); 
1066                                                 trace_data 
= data_generic_trace
; 
1067                                                 trace_data_size 
= 10; 
1068                                                 CodeIso15693AsTag(trace_data
, trace_data_size
); 
1069                                                 memcpy(data_response
, ToSend
, ToSendMax
); 
1070                                                 modulated_response 
= data_response
; 
1071                                                 modulated_response_size 
= ToSendMax
; 
1076                 } else if ((receivedCmd
[0] == ICLASS_CMD_READCHECK_KD
 
1077                                         || receivedCmd
[0] == ICLASS_CMD_READCHECK_KC
) && receivedCmd
[1] == 0x02 && len 
== 2) { 
1078                         // Read e-purse (88 02 || 18 02) 
1079                         if (chip_state 
== SELECTED
) { 
1080                                 if(receivedCmd
[0] == ICLASS_CMD_READCHECK_KD
){ 
1081                                         cipher_state 
= &cipher_state_KD
[current_page
]; 
1082                                         diversified_key 
= diversified_key_d
; 
1084                                         cipher_state 
= &cipher_state_KC
[current_page
]; 
1085                                         diversified_key 
= diversified_key_c
; 
1087                                 modulated_response 
= resp_cc
; 
1088                                 modulated_response_size 
= resp_cc_len
; 
1089                                 trace_data 
= card_challenge_data
; 
1090                                 trace_data_size 
= sizeof(card_challenge_data
); 
1093                 } else if ((receivedCmd
[0] == ICLASS_CMD_CHECK_KC
 
1094                                         || receivedCmd
[0] == ICLASS_CMD_CHECK_KD
) && len 
== 9) { 
1095                         // Reader random and reader MAC!!! 
1096                         if (chip_state 
== SELECTED
) { 
1097                                 if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { 
1098                                         //NR, from reader, is in receivedCmd+1 
1099                                         opt_doTagMAC_2(*cipher_state
, receivedCmd
+1, data_generic_trace
, diversified_key
); 
1100                                         trace_data 
= data_generic_trace
; 
1101                                         trace_data_size 
= 4; 
1102                                         CodeIso15693AsTag(trace_data
, trace_data_size
); 
1103                                         memcpy(data_response
, ToSend
, ToSendMax
); 
1104                                         modulated_response 
= data_response
; 
1105                                         modulated_response_size 
= ToSendMax
; 
1107                                 } else { // Not fullsim, we don't respond 
1108                                         // We do not know what to answer, so lets keep quiet 
1109                                         if (simulationMode 
== ICLASS_SIM_MODE_EXIT_AFTER_MAC
) { 
1110                                                 if (reader_mac_buf 
!= NULL
) { 
1111                                                         // save NR and MAC for sim 2,4 
1112                                                         memcpy(reader_mac_buf 
+ 8, receivedCmd 
+ 1, 8); 
1119                 } else if (receivedCmd
[0] == ICLASS_CMD_HALT 
&& len 
== 1) { 
1120                         if (chip_state 
== SELECTED
) { 
1121                                 // Reader ends the session 
1122                                 modulated_response 
= resp_sof
; 
1123                                 modulated_response_size 
= resp_sof_Len
; 
1124                                 chip_state 
= HALTED
; 
1127                 } else if (simulationMode 
== ICLASS_SIM_MODE_FULL 
&& receivedCmd
[0] == ICLASS_CMD_READ4 
&& len 
== 4) {  // 0x06 
1129                         if (chip_state 
== SELECTED
) { 
1130                                 uint8_t blockNo 
= receivedCmd
[1]; 
1131                                 memcpy(data_generic_trace
, emulator 
+ current_page
*page_size 
+ blockNo
*8, 8 * 4); 
1132                                 AppendCrc(data_generic_trace
, 8 * 4); 
1133                                 trace_data 
= data_generic_trace
; 
1134                                 trace_data_size 
= 8 * 4 + 2; 
1135                                 CodeIso15693AsTag(trace_data
, trace_data_size
); 
1136                                 memcpy(data_response
, ToSend
, ToSendMax
); 
1137                                 modulated_response 
= data_response
; 
1138                                 modulated_response_size 
= ToSendMax
; 
1141                 } else if (receivedCmd
[0] == ICLASS_CMD_UPDATE 
&& (len 
== 12 || len 
== 14)) { 
1142                         // We're expected to respond with the data+crc, exactly what's already in the receivedCmd 
1143                         // receivedCmd is now UPDATE 1b | ADDRESS 1b | DATA 8b | Signature 4b or CRC 2b 
1144                         if (chip_state 
== SELECTED
) { 
1145                                 uint8_t blockNo 
= receivedCmd
[1]; 
1146                                 if (blockNo 
== 2) { // update e-purse 
1147                                         memcpy(card_challenge_data
, receivedCmd
+2, 8); 
1148                                         CodeIso15693AsTag(card_challenge_data
, sizeof(card_challenge_data
)); 
1149                                         memcpy(resp_cc
, ToSend
, ToSendMax
); 
1150                                         resp_cc_len 
= ToSendMax
; 
1151                                         cipher_state_KD
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_key_d
); 
1152                                         cipher_state_KC
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_key_c
); 
1153                                         if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { 
1154                                                 memcpy(emulator 
+ current_page
*page_size 
+ 8*2, card_challenge_data
, 8); 
1156                                 } else if (blockNo 
== 3) { // update Kd 
1157                                         for (int i 
= 0; i 
< 8; i
++) { 
1158                                                 if (personalization_mode
) { 
1159                                                         diversified_key_d
[i
] = receivedCmd
[2 + i
]; 
1161                                                         diversified_key_d
[i
] ^= receivedCmd
[2 + i
]; 
1164                                         cipher_state_KD
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_key_d
); 
1165                                         if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { 
1166                                                 memcpy(emulator 
+ current_page
*page_size 
+ 8*3, diversified_key_d
, 8); 
1168                                 } else if (blockNo 
== 4) { // update Kc 
1169                                         for (int i 
= 0; i 
< 8; i
++) { 
1170                                                 if (personalization_mode
) { 
1171                                                         diversified_key_c
[i
] = receivedCmd
[2 + i
]; 
1173                                                         diversified_key_c
[i
] ^= receivedCmd
[2 + i
]; 
1176                                         cipher_state_KC
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_key_c
); 
1177                                         if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { 
1178                                                 memcpy(emulator 
+ current_page
*page_size 
+ 8*4, diversified_key_c
, 8); 
1180                                 } else if (simulationMode 
== ICLASS_SIM_MODE_FULL
) { // update any other data block 
1181                                                 memcpy(emulator 
+ current_page
*page_size 
+ 8*blockNo
, receivedCmd
+2, 8); 
1183                                 memcpy(data_generic_trace
, receivedCmd 
+ 2, 8); 
1184                                 AppendCrc(data_generic_trace
, 8); 
1185                                 trace_data 
= data_generic_trace
; 
1186                                 trace_data_size 
= 10; 
1187                                 CodeIso15693AsTag(trace_data
, trace_data_size
); 
1188                                 memcpy(data_response
, ToSend
, ToSendMax
); 
1189                                 modulated_response 
= data_response
; 
1190                                 modulated_response_size 
= ToSendMax
; 
1193                 } else if (receivedCmd
[0] == ICLASS_CMD_PAGESEL 
&& len 
== 4) { 
1195                         // Chips with a single page will not answer to this command 
1196                         // Otherwise, we should answer 8bytes (conf block 1) + 2bytes CRC 
1197                         if (chip_state 
== SELECTED
) { 
1198                                 if (simulationMode 
== ICLASS_SIM_MODE_FULL 
&& max_page 
> 0) { 
1199                                         current_page 
= receivedCmd
[1]; 
1200                                         memcpy(data_generic_trace
, emulator 
+ current_page
*page_size 
+ 8*1, 8); 
1201                                         memcpy(diversified_key_d
, emulator 
+ current_page
*page_size 
+ 8*3, 8); 
1202                                         memcpy(diversified_key_c
, emulator 
+ current_page
*page_size 
+ 8*4, 8); 
1203                                         cipher_state 
= &cipher_state_KD
[current_page
]; 
1204                                         personalization_mode 
= data_generic_trace
[7] & 0x80; 
1205                                         AppendCrc(data_generic_trace
, 8); 
1206                                         trace_data 
= data_generic_trace
; 
1207                                         trace_data_size 
= 10; 
1208                                         CodeIso15693AsTag(trace_data
, trace_data_size
); 
1209                                         memcpy(data_response
, ToSend
, ToSendMax
); 
1210                                         modulated_response 
= data_response
; 
1211                                         modulated_response_size 
= ToSendMax
; 
1215                 } else if (receivedCmd
[0] == 0x26 && len 
== 5) { 
1216                         // standard ISO15693 INVENTORY command. Ignore. 
1219                         // don't know how to handle this command 
1220                         char debug_message
[250]; // should be enough 
1221                         sprintf(debug_message
, "Unhandled command (len = %d) received from reader:", len
); 
1222                         for (int i 
= 0; i 
< len 
&& strlen(debug_message
) < sizeof(debug_message
) - 3 - 1; i
++) { 
1223                                 sprintf(debug_message 
+ strlen(debug_message
), " %02x", receivedCmd
[i
]); 
1225                         Dbprintf("%s", debug_message
); 
1230                 A legit tag has about 273,4us delay between reader EOT and tag SOF. 
1232                 if (modulated_response_size 
> 0) { 
1233                         uint32_t response_time 
= reader_eof_time 
+ DELAY_ICLASS_VCD_TO_VICC_SIM
; 
1234                         TransmitTo15693Reader(modulated_response
, modulated_response_size
, &response_time
, 0, false); 
1235                         LogTrace_ISO15693(trace_data
, trace_data_size
, response_time
*32, response_time
*32 + modulated_response_size
/2, NULL
, false); 
1242                 DbpString("Button pressed"); 
1244         return buttonPressed
; 
1248  * @brief SimulateIClass simulates an iClass card. 
1249  * @param arg0 type of simulation 
1250  *          - 0 uses the first 8 bytes in usb data as CSN 
1251  *          - 2 "dismantling iclass"-attack. This mode iterates through all CSN's specified 
1252  *          in the usb data. This mode collects MAC from the reader, in order to do an offline 
1253  *          attack on the keys. For more info, see "dismantling iclass" and proxclone.com. 
1254  *          - Other : Uses the default CSN (031fec8af7ff12e0) 
1255  * @param arg1 - number of CSN's contained in datain (applicable for mode 2 only) 
1259 void SimulateIClass(uint32_t arg0
, uint32_t arg1
, uint32_t arg2
, uint8_t *datain
) { 
1263         uint32_t simType 
= arg0
; 
1264         uint32_t numberOfCSNS 
= arg1
; 
1266         // setup hardware for simulation: 
1267         FpgaDownloadAndGo(FPGA_BITSTREAM_HF
); 
1268         SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); 
1269         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR 
| FPGA_HF_SIMULATOR_NO_MODULATION
); 
1271         FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR
); 
1274         // Enable and clear the trace 
1277         //Use the emulator memory for SIM 
1278         uint8_t *emulator 
= BigBuf_get_EM_addr(); 
1280         if (simType 
== ICLASS_SIM_MODE_CSN
) { 
1281                 // Use the CSN from commandline 
1282                 memcpy(emulator
, datain
, 8); 
1283                 doIClassSimulation(ICLASS_SIM_MODE_CSN
, NULL
); 
1284         } else if (simType 
== ICLASS_SIM_MODE_CSN_DEFAULT
) { 
1286                 uint8_t csn_crc
[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 }; 
1287                 // Use the CSN from commandline 
1288                 memcpy(emulator
, csn_crc
, 8); 
1289                 doIClassSimulation(ICLASS_SIM_MODE_CSN
, NULL
); 
1290         } else if (simType 
== ICLASS_SIM_MODE_READER_ATTACK
) { 
1291                 uint8_t mac_responses
[USB_CMD_DATA_SIZE
] = { 0 }; 
1292                 Dbprintf("Going into attack mode, %d CSNS sent", numberOfCSNS
); 
1293                 // In this mode, a number of csns are within datain. We'll simulate each one, one at a time 
1294                 // in order to collect MAC's from the reader. This can later be used in an offline-attack 
1295                 // in order to obtain the keys, as in the "dismantling iclass"-paper. 
1297                 for (i 
= 0; i 
< numberOfCSNS 
&& i
*16+16 <= USB_CMD_DATA_SIZE
; i
++) { 
1298                         // The usb data is 512 bytes, fitting 32 responses (8 byte CC + 4 Byte NR + 4 Byte MAC = 16 Byte response). 
1299                         memcpy(emulator
, datain
+(i
*8), 8); 
1300                         if (doIClassSimulation(ICLASS_SIM_MODE_EXIT_AFTER_MAC
, mac_responses
+i
*16)) { 
1304                         Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x", 
1305                                         datain
[i
*8+0], datain
[i
*8+1], datain
[i
*8+2], datain
[i
*8+3], 
1306                                         datain
[i
*8+4], datain
[i
*8+5], datain
[i
*8+6], datain
[i
*8+7]); 
1307                         Dbprintf("NR,MAC: %02x %02x %02x %02x %02x %02x %02x %02x", 
1308                                         mac_responses
[i
*16+ 8], mac_responses
[i
*16+ 9], mac_responses
[i
*16+10], mac_responses
[i
*16+11], 
1309                                         mac_responses
[i
*16+12], mac_responses
[i
*16+13], mac_responses
[i
*16+14], mac_responses
[i
*16+15]); 
1310                         SpinDelay(100); // give the reader some time to prepare for next CSN 
1312                 cmd_send(CMD_ACK
, CMD_SIMULATE_TAG_ICLASS
, i
, 0, mac_responses
, i
*16); 
1313         } else if (simType 
== ICLASS_SIM_MODE_FULL
) { 
1314                 //This is 'full sim' mode, where we use the emulator storage for data. 
1315                 doIClassSimulation(ICLASS_SIM_MODE_FULL
, NULL
); 
1317                 // We may want a mode here where we hardcode the csns to use (from proxclone). 
1318                 // That will speed things up a little, but not required just yet. 
1319                 Dbprintf("The mode is not implemented, reserved for future use"); 
1322         Dbprintf("Done..."); 
1330 static void ReaderTransmitIClass(uint8_t *frame
, int len
, uint32_t *start_time
) { 
1332         CodeIso15693AsReader(frame
, len
); 
1334         TransmitTo15693Tag(ToSend
, ToSendMax
, start_time
); 
1336         uint32_t end_time 
= *start_time 
+ 32*(8*ToSendMax
-4); // substract the 4 padding bits after EOF 
1337         LogTrace_ISO15693(frame
, len
, *start_time
*4, end_time
*4, NULL
, true); 
1341 static bool sendCmdGetResponseWithRetries(uint8_t* command
, size_t cmdsize
, uint8_t* resp
, size_t max_resp_size
, 
1342                                                                                   uint8_t expected_size
, uint8_t retries
, uint32_t start_time
, uint32_t timeout
, uint32_t *eof_time
) { 
1343         while (retries
-- > 0) { 
1344                 ReaderTransmitIClass(command
, cmdsize
, &start_time
); 
1345                 if (expected_size 
== GetIso15693AnswerFromTag(resp
, max_resp_size
, timeout
, eof_time
)) { 
1349         return false;//Error 
1353  * @brief Selects an iclass tag 
1354  * @param card_data where the CSN is stored for return 
1355  * @return false = fail 
1358 static bool selectIclassTag(uint8_t *card_data
, uint32_t *eof_time
) { 
1359         uint8_t act_all
[]      = { 0x0a }; 
1360         uint8_t identify
[]     = { 0x0c }; 
1361         uint8_t select
[]       = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
1363         uint8_t resp
[ICLASS_BUFFER_SIZE
]; 
1365         uint32_t start_time 
= GetCountSspClk(); 
1368         ReaderTransmitIClass(act_all
, 1, &start_time
); 
1370         if (GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_ACTALL
, eof_time
) < 0) return false;//Fail 
1373         start_time 
= *eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1374         ReaderTransmitIClass(identify
, 1, &start_time
); 
1375         //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC 
1376         uint8_t len 
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
); 
1377         if (len 
!= 10) return false;//Fail 
1379         //Copy the Anti-collision CSN to our select-packet 
1380         memcpy(&select
[1], resp
, 8); 
1382         start_time 
= *eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1383         ReaderTransmitIClass(select
, sizeof(select
), &start_time
); 
1384         //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC 
1385         len 
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
); 
1386         if (len 
!= 10) return false;//Fail 
1388         //Success - we got CSN 
1389         //Save CSN in response data 
1390         memcpy(card_data
, resp
, 8); 
1396 // Select an iClass tag and read all blocks which are always readable without authentication 
1397 void ReaderIClass(uint8_t flags
) { 
1401         uint8_t card_data
[6 * 8] = {0}; 
1402         memset(card_data
, 0xFF, sizeof(card_data
)); 
1403         uint8_t resp
[ICLASS_BUFFER_SIZE
]; 
1404         //Read conf block CRC(0x01) => 0xfa 0x22 
1405         uint8_t readConf
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, 0x01, 0xfa, 0x22}; 
1406         //Read e-purse block CRC(0x02) => 0x61 0x10 
1407         uint8_t readEpurse
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, 0x02, 0x61, 0x10}; 
1408         //Read App Issuer Area block CRC(0x05) => 0xde  0x64 
1409         uint8_t readAA
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, 0x05, 0xde, 0x64}; 
1411         uint8_t result_status 
= 0; 
1413         if (flags 
& FLAG_ICLASS_READER_INIT
) { 
1414                 Iso15693InitReader(); 
1417         if (flags 
& FLAG_ICLASS_READER_CLEARTRACE
) { 
1423         uint32_t start_time 
= 0; 
1424         uint32_t eof_time 
= 0; 
1426         if (selectIclassTag(resp
, &eof_time
)) { 
1427                 result_status 
= FLAG_ICLASS_READER_CSN
; 
1428                 memcpy(card_data
, resp
, 8); 
1431         start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1433         //Read block 1, config 
1434         if (flags 
& FLAG_ICLASS_READER_CONF
) { 
1435                 if (sendCmdGetResponseWithRetries(readConf
, sizeof(readConf
), resp
, sizeof(resp
), 10, 10, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
)) { 
1436                         result_status 
|= FLAG_ICLASS_READER_CONF
; 
1437                         memcpy(card_data
+8, resp
, 8); 
1439                         Dbprintf("Failed to read config block"); 
1441                 start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1444         //Read block 2, e-purse 
1445         if (flags 
& FLAG_ICLASS_READER_CC
) { 
1446                 if (sendCmdGetResponseWithRetries(readEpurse
, sizeof(readEpurse
), resp
, sizeof(resp
), 10, 10, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
)) { 
1447                         result_status 
|= FLAG_ICLASS_READER_CC
; 
1448                         memcpy(card_data 
+ (8*2), resp
, 8); 
1450                         Dbprintf("Failed to read e-purse"); 
1452                 start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1456         if (flags 
& FLAG_ICLASS_READER_AA
) { 
1457                 if (sendCmdGetResponseWithRetries(readAA
, sizeof(readAA
), resp
, sizeof(resp
), 10, 10, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
)) { 
1458                         result_status 
|= FLAG_ICLASS_READER_AA
; 
1459                         memcpy(card_data 
+ (8*5), resp
, 8); 
1461                         Dbprintf("Failed to read AA block"); 
1465         cmd_send(CMD_ACK
, result_status
, 0, 0, card_data
, sizeof(card_data
)); 
1471 void ReaderIClass_Replay(uint8_t arg0
, uint8_t *MAC
) { 
1475         bool use_credit_key 
= false; 
1476         uint8_t card_data
[USB_CMD_DATA_SIZE
]={0}; 
1477         uint16_t block_crc_LUT
[255] = {0}; 
1479         //Generate a lookup table for block crc 
1480         for (int block 
= 0; block 
< 255; block
++){ 
1482                 block_crc_LUT
[block
] = iclass_crc16(&bl 
,1); 
1484         //Dbprintf("Lookup table: %02x %02x %02x" ,block_crc_LUT[0],block_crc_LUT[1],block_crc_LUT[2]); 
1486         uint8_t readcheck_cc
[] = { ICLASS_CMD_READCHECK_KD
, 0x02 }; 
1488                 readcheck_cc
[0] = ICLASS_CMD_READCHECK_KC
; 
1489         uint8_t check
[]       = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
1490         uint8_t read
[]        = { 0x0c, 0x00, 0x00, 0x00 }; 
1493         uint8_t cardsize 
= 0; 
1496         static struct memory_t 
{ 
1504         uint8_t resp
[ICLASS_BUFFER_SIZE
]; 
1508         Iso15693InitReader(); 
1511         uint32_t start_time 
= 0; 
1512         uint32_t eof_time 
= 0; 
1514         while (!BUTTON_PRESS()) { 
1518                 if (!get_tracing()) { 
1519                         DbpString("Trace full"); 
1523                 if (!selectIclassTag(card_data
, &eof_time
)) continue; 
1525                 start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1526                 if (!sendCmdGetResponseWithRetries(readcheck_cc
, sizeof(readcheck_cc
), resp
, sizeof(resp
), 8, 3, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
)) continue; 
1528                 // replay captured auth (cc must not have been updated) 
1529                 memcpy(check
+5, MAC
, 4); 
1531                 start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1532                 if (!sendCmdGetResponseWithRetries(check
, sizeof(check
), resp
, sizeof(resp
), 4, 5, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
)) { 
1533                         Dbprintf("Error: Authentication Fail!"); 
1537                 //first get configuration block (block 1) 
1538                 crc 
= block_crc_LUT
[1]; 
1541                 read
[3] = crc 
& 0xff; 
1543                 start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1544                 if (!sendCmdGetResponseWithRetries(read
, sizeof(read
), resp
, sizeof(resp
), 10, 10, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
)) { 
1545                         start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1546                         Dbprintf("Dump config (block 1) failed"); 
1551                 memory
.k16 
= (mem 
& 0x80); 
1552                 memory
.book 
= (mem 
& 0x20); 
1553                 memory
.k2 
= (mem 
& 0x8); 
1554                 memory
.lockauth 
= (mem 
& 0x2); 
1555                 memory
.keyaccess 
= (mem 
& 0x1); 
1557                 cardsize 
= memory
.k16 
? 255 : 32; 
1559                 //Set card_data to all zeroes, we'll fill it with data 
1560                 memset(card_data
, 0x0, USB_CMD_DATA_SIZE
); 
1561                 uint8_t failedRead 
= 0; 
1562                 uint32_t stored_data_length 
= 0; 
1563                 //then loop around remaining blocks 
1564                 for (int block 
= 0; block 
< cardsize
; block
++) { 
1566                         crc 
= block_crc_LUT
[block
]; 
1568                         read
[3] = crc 
& 0xff; 
1570                         start_time 
= eof_time 
+ DELAY_ICLASS_VICC_TO_VCD_READER
; 
1571                         if (sendCmdGetResponseWithRetries(read
, sizeof(read
), resp
, sizeof(resp
), 10, 10, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
)) { 
1572                                 Dbprintf("     %02x: %02x %02x %02x %02x %02x %02x %02x %02x", 
1573                                                 block
, resp
[0], resp
[1], resp
[2], 
1574                                                 resp
[3], resp
[4], resp
[5], 
1577                                 //Fill up the buffer 
1578                                 memcpy(card_data
+stored_data_length
, resp
, 8); 
1579                                 stored_data_length 
+= 8; 
1580                                 if (stored_data_length 
+8 > USB_CMD_DATA_SIZE
) { 
1581                                         //Time to send this off and start afresh 
1583                                                          stored_data_length
,//data length 
1584                                                          failedRead
,//Failed blocks? 
1586                                                          card_data
, stored_data_length
); 
1588                                         stored_data_length 
= 0; 
1594                                 stored_data_length 
+= 8;//Otherwise, data becomes misaligned 
1595                                 Dbprintf("Failed to dump block %d", block
); 
1599                 //Send off any remaining data 
1600                 if (stored_data_length 
> 0) { 
1602                                          stored_data_length
,//data length 
1603                                          failedRead
,//Failed blocks? 
1606                                          stored_data_length
); 
1608                 //If we got here, let's break 
1611         //Signal end of transmission 
1619         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1625 void iClass_Check(uint8_t *MAC
) { 
1626         uint8_t check
[9] = {ICLASS_CMD_CHECK_KD
, 0x00}; 
1628         memcpy(check
+5, MAC
, 4); 
1630         bool isOK 
= sendCmdGetResponseWithRetries(check
, sizeof(check
), resp
, sizeof(resp
), 4, 6, 0, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
); 
1631         cmd_send(CMD_ACK
, isOK
, 0, 0, resp
, sizeof(resp
)); 
1635 void iClass_Readcheck(uint8_t block
, bool use_credit_key
) { 
1636         uint8_t readcheck
[2] = {ICLASS_CMD_READCHECK_KD
, block
}; 
1637         if (use_credit_key
) { 
1638                 readcheck
[0] = ICLASS_CMD_READCHECK_KC
; 
1642         bool isOK 
= sendCmdGetResponseWithRetries(readcheck
, sizeof(readcheck
), resp
, sizeof(resp
), 8, 6, 0, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
); 
1643         cmd_send(CMD_ACK
, isOK
, 0, 0, resp
, sizeof(resp
)); 
1647 static bool iClass_ReadBlock(uint8_t blockNo
, uint8_t *readdata
) { 
1648         uint8_t readcmd
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, blockNo
, 0x00, 0x00}; //0x88, 0x00 // can i use 0C? 
1650         uint16_t rdCrc 
= iclass_crc16(&bl
, 1); 
1651         readcmd
[2] = rdCrc 
>> 8; 
1652         readcmd
[3] = rdCrc 
& 0xff; 
1656         bool isOK 
= sendCmdGetResponseWithRetries(readcmd
, sizeof(readcmd
), resp
, sizeof(resp
), 10, 10, 0, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
); 
1657         memcpy(readdata
, resp
, sizeof(resp
)); 
1663 void iClass_ReadBlk(uint8_t blockno
) { 
1667         uint8_t readblockdata
[] = {0,0,0,0,0,0,0,0,0,0}; 
1668         bool isOK 
= iClass_ReadBlock(blockno
, readblockdata
); 
1669         cmd_send(CMD_ACK
, isOK
, 0, 0, readblockdata
, 8); 
1670         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1677 void iClass_Dump(uint8_t startblock
, uint8_t numblks
) { 
1681         uint8_t readblockdata
[USB_CMD_DATA_SIZE
+2] = {0}; 
1683         uint16_t blkCnt 
= 0; 
1685         if (numblks 
> USB_CMD_DATA_SIZE 
/ 8) { 
1686                 numblks 
= USB_CMD_DATA_SIZE 
/ 8; 
1689         for (blkCnt 
= 0; blkCnt 
< numblks
; blkCnt
++) { 
1690                 isOK 
= iClass_ReadBlock(startblock
+blkCnt
, readblockdata
+8*blkCnt
); 
1692                         Dbprintf("Block %02X failed to read", startblock
+blkCnt
); 
1697         cmd_send(CMD_ACK
, isOK
, blkCnt
, 0, readblockdata
, blkCnt
*8); 
1703 static bool iClass_WriteBlock_ext(uint8_t blockNo
, uint8_t *data
) { 
1705         uint8_t write
[16] = {ICLASS_CMD_UPDATE
, blockNo
}; 
1706         memcpy(write
+2, data
, 12); // data + mac 
1707         AppendCrc(write
+1, 13); 
1710         uint32_t eof_time 
= 0; 
1712         isOK 
= sendCmdGetResponseWithRetries(write
, sizeof(write
), resp
, sizeof(resp
), 10, 10, 0, ICLASS_READER_TIMEOUT_UPDATE
, &eof_time
); 
1713         if (isOK 
&& blockNo 
!= 3 && blockNo 
!= 4 && memcmp(write
+2, resp
, 8)) { // check response 
1721 void iClass_WriteBlock(uint8_t blockNo
, uint8_t *data
) { 
1725         bool isOK 
= iClass_WriteBlock_ext(blockNo
, data
); 
1727                 Dbprintf("Write block [%02x] successful", blockNo
); 
1729                 Dbprintf("Write block [%02x] failed", blockNo
); 
1731         cmd_send(CMD_ACK
, isOK
, 0, 0, 0, 0); 
1733         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1740 void iClass_Clone(uint8_t startblock
, uint8_t endblock
, uint8_t *data
) { 
1743         int total_block 
= (endblock 
- startblock
) + 1; 
1744         for (i 
= 0; i 
< total_block
; i
++) { 
1746                 if (iClass_WriteBlock_ext(i
+startblock
, data 
+ (i
*12))){ 
1747                         Dbprintf("Write block [%02x] successful", i 
+ startblock
); 
1750                         if (iClass_WriteBlock_ext(i
+startblock
, data 
+ (i
*12))){ 
1751                                 Dbprintf("Write block [%02x] successful", i 
+ startblock
); 
1754                                 Dbprintf("Write block [%02x] failed", i 
+ startblock
); 
1758         if (written 
== total_block
) 
1759                 Dbprintf("Clone complete"); 
1761                 Dbprintf("Clone incomplete"); 
1763         cmd_send(CMD_ACK
, 1, 0, 0, 0, 0); 
1764         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);