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 static int timeout 
= 4096; 
  62 // iCLASS has a slightly different timing compared to ISO15693. According to the picopass data sheet the tag response is expected 330us after 
  63 // 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. 
  64 // 330us = 140 ssp_clk cycles @ 423,75kHz when simulating. 
  65 // 56,64us = 24 ssp_clk_cycles 
  66 #define DELAY_ICLASS_VCD_TO_VICC_SIM 140 
  67 #define TAG_SOF_UNMODULATED          24 
  69 //----------------------------------------------------------------------------- 
  70 // The software UART that receives commands from the reader, and its state 
  72 //----------------------------------------------------------------------------- 
  76                 STATE_START_OF_COMMUNICATION
, 
  96 static RAMFUNC 
int OutOfNDecoding(int bit
) { 
 100         if (!Uart
.bitBuffer
) { 
 101                 Uart
.bitBuffer 
= bit 
^ 0xFF0; 
 104                 Uart
.bitBuffer 
<<= 4; 
 105                 Uart
.bitBuffer 
^= bit
; 
 108         /*if (Uart.swapper) { 
 109                 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; 
 112                 if (Uart.byteCnt > 15) { return true; } 
 118         if (Uart
.state 
!= STATE_UNSYNCD
) { 
 121                 if ((Uart
.bitBuffer 
& Uart
.syncBit
) ^ Uart
.syncBit
) { 
 126                 if (((Uart
.bitBuffer 
<< 1) & Uart
.syncBit
) ^ Uart
.syncBit
) { 
 131                 if (bit 
!= bitright
) { 
 136                 // So, now we only have to deal with *bit*, lets see... 
 137                 if (Uart
.posCnt 
== 1) { 
 138                         // measurement first half bitperiod 
 140                                 // Drop in first half means that we are either seeing 
 143                                 if (Uart
.nOutOfCnt 
== 1) { 
 144                                         // End of Communication 
 145                                         Uart
.state 
= STATE_UNSYNCD
; 
 147                                         if (Uart
.byteCnt 
== 0) { 
 148                                                 // Its not straightforward to show single EOFs 
 149                                                 // So just leave it and do not return true 
 150                                                 Uart
.output
[0] = 0xf0; 
 155                                 } else if (Uart
.state 
!= STATE_START_OF_COMMUNICATION
) { 
 156                                         // When not part of SOF or EOF, it is an error 
 157                                         Uart
.state 
= STATE_UNSYNCD
; 
 163                         // measurement second half bitperiod 
 164                         // Count the bitslot we are in... (ISO 15693) 
 168                                 if (Uart
.dropPosition
) { 
 169                                         if (Uart
.state 
== STATE_START_OF_COMMUNICATION
) { 
 174                                         // It is an error if we already have seen a drop in current frame 
 175                                         Uart
.state 
= STATE_UNSYNCD
; 
 178                                         Uart
.dropPosition 
= Uart
.nOutOfCnt
; 
 185                         if (Uart
.nOutOfCnt 
== Uart
.OutOfCnt 
&& Uart
.OutOfCnt 
== 4) { 
 188                                 if (Uart
.state 
== STATE_START_OF_COMMUNICATION
) { 
 189                                         if (Uart
.dropPosition 
== 4) { 
 190                                                 Uart
.state 
= STATE_RECEIVING
; 
 192                                         } else if (Uart
.dropPosition 
== 3) { 
 193                                                 Uart
.state 
= STATE_RECEIVING
; 
 195                                                 //Uart.output[Uart.byteCnt] = 0xdd; 
 198                                                 Uart
.state 
= STATE_UNSYNCD
; 
 201                                         Uart
.dropPosition 
= 0; 
 205                                         if (!Uart
.dropPosition
) { 
 206                                                 Uart
.state 
= STATE_UNSYNCD
; 
 214                                                 //if (Uart.dropPosition == 1) { Uart.dropPosition = 2; } 
 215                                                 //else if (Uart.dropPosition == 2) { Uart.dropPosition = 1; } 
 217                                                 Uart
.shiftReg 
^= ((Uart
.dropPosition 
& 0x03) << 6); 
 219                                                 Uart
.dropPosition 
= 0; 
 221                                                 if (Uart
.bitCnt 
== 8) { 
 222                                                         Uart
.output
[Uart
.byteCnt
] = (Uart
.shiftReg 
& 0xff); 
 229                         } else if (Uart
.nOutOfCnt 
== Uart
.OutOfCnt
) { 
 232                                 if (!Uart
.dropPosition
) { 
 233                                         Uart
.state 
= STATE_UNSYNCD
; 
 238                                         Uart
.output
[Uart
.byteCnt
] = (Uart
.dropPosition 
& 0xff); 
 243                                         Uart
.dropPosition 
= 0; 
 248                                 Uart.output[Uart.byteCnt] = 0xAA; 
 250                                 Uart.output[Uart.byteCnt] = error & 0xFF; 
 252                                 Uart.output[Uart.byteCnt] = 0xAA; 
 254                                 Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF; 
 256                                 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; 
 258                                 Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF; 
 260                                 Uart.output[Uart.byteCnt] = 0xAA; 
 267                 bit 
= Uart
.bitBuffer 
& 0xf0; 
 269                 bit 
^= 0x0F; // drops become 1s ;-) 
 271                         // should have been high or at least (4 * 128) / fc 
 272                         // according to ISO this should be at least (9 * 128 + 20) / fc 
 273                         if (Uart
.highCnt 
== 8) { 
 274                                 // we went low, so this could be start of communication 
 275                                 // it turns out to be safer to choose a less significant 
 276                                 // syncbit... so we check whether the neighbour also represents the drop 
 277                                 Uart
.posCnt 
= 1;   // apparently we are busy with our first half bit period 
 278                                 Uart
.syncBit 
= bit 
& 8; 
 280                                 if (!Uart
.syncBit
)  { Uart
.syncBit 
= bit 
& 4; Uart
.samples 
= 2; } 
 281                                 else if (bit 
& 4)   { Uart
.syncBit 
= bit 
& 4; Uart
.samples 
= 2; bit 
<<= 2; } 
 282                                 if (!Uart
.syncBit
)  { Uart
.syncBit 
= bit 
& 2; Uart
.samples 
= 1; } 
 283                                 else if (bit 
& 2)   { Uart
.syncBit 
= bit 
& 2; Uart
.samples 
= 1; bit 
<<= 1; } 
 284                                 if (!Uart
.syncBit
)  { Uart
.syncBit 
= bit 
& 1; Uart
.samples 
= 0; 
 285                                         if (Uart
.syncBit 
&& (Uart
.bitBuffer 
& 8)) { 
 288                                                 // the first half bit period is expected in next sample 
 292                                 } else if (bit 
& 1) { Uart
.syncBit 
= bit 
& 1; Uart
.samples 
= 0; } 
 295                                 Uart
.state 
= STATE_START_OF_COMMUNICATION
; 
 299                                 Uart
.OutOfCnt 
= 4; // Start at 1/4, could switch to 1/256 
 300                                 Uart
.dropPosition 
= 0; 
 306                 } else if (Uart
.highCnt 
< 8) { 
 315 //============================================================================= 
 317 //============================================================================= 
 322                 DEMOD_START_OF_COMMUNICATION
, 
 323                 DEMOD_START_OF_COMMUNICATION2
, 
 324                 DEMOD_START_OF_COMMUNICATION3
, 
 328                 DEMOD_END_OF_COMMUNICATION
, 
 329                 DEMOD_END_OF_COMMUNICATION2
, 
 352 static RAMFUNC 
int ManchesterDecoding(int v
) { 
 358         Demod
.buffer 
= Demod
.buffer2
; 
 359         Demod
.buffer2 
= Demod
.buffer3
; 
 362         if (Demod
.buff 
< 3) { 
 367         if (Demod
.state
==DEMOD_UNSYNCD
) { 
 368                 Demod
.output
[Demod
.len
] = 0xfa; 
 371                 Demod
.posCount 
= 1;     // This is the first half bit period, so after syncing handle the second part 
 374                         Demod
.syncBit 
= 0x08; 
 381                         Demod
.syncBit 
= 0x04; 
 388                         Demod
.syncBit 
= 0x02; 
 391                 if (bit 
& 0x01 && Demod
.syncBit
) { 
 392                         Demod
.syncBit 
= 0x01; 
 397                         Demod
.state 
= DEMOD_START_OF_COMMUNICATION
; 
 398                         Demod
.sub 
= SUB_FIRST_HALF
; 
 402                         if (Demod
.posCount
) { 
 403                                 switch (Demod
.syncBit
) { 
 404                                         case 0x08: Demod
.samples 
= 3; break; 
 405                                         case 0x04: Demod
.samples 
= 2; break; 
 406                                         case 0x02: Demod
.samples 
= 1; break; 
 407                                         case 0x01: Demod
.samples 
= 0; break; 
 409                                 // SOF must be long burst... otherwise stay unsynced!!! 
 410                                 if (!(Demod
.buffer 
& Demod
.syncBit
) || !(Demod
.buffer2 
& Demod
.syncBit
)) { 
 411                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 414                                 // SOF must be long burst... otherwise stay unsynced!!! 
 415                                 if (!(Demod
.buffer2 
& Demod
.syncBit
) || !(Demod
.buffer3 
& Demod
.syncBit
)) { 
 416                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 425                 // state is DEMOD is in SYNC from here on. 
 426                 modulation 
= bit 
& Demod
.syncBit
; 
 427                 modulation 
|= ((bit 
<< 1) ^ ((Demod
.buffer 
& 0x08) >> 3)) & Demod
.syncBit
; 
 431                 if (Demod
.posCount 
== 0) { 
 434                                 Demod
.sub 
= SUB_FIRST_HALF
; 
 436                                 Demod
.sub 
= SUB_NONE
; 
 441                                 if (Demod
.sub 
== SUB_FIRST_HALF
) { 
 442                                         Demod
.sub 
= SUB_BOTH
; 
 444                                         Demod
.sub 
= SUB_SECOND_HALF
; 
 446                         } else if (Demod
.sub 
== SUB_NONE
) { 
 447                                 if (Demod
.state 
== DEMOD_SOF_COMPLETE
) { 
 448                                         Demod
.output
[Demod
.len
] = 0x0f; 
 450                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 453                                         Demod
.state 
= DEMOD_ERROR_WAIT
; 
 458                         switch(Demod
.state
) { 
 459                                 case DEMOD_START_OF_COMMUNICATION
: 
 460                                         if (Demod
.sub 
== SUB_BOTH
) { 
 461                                                 Demod
.state 
= DEMOD_START_OF_COMMUNICATION2
; 
 463                                                 Demod
.sub 
= SUB_NONE
; 
 465                                                 Demod
.output
[Demod
.len
] = 0xab; 
 466                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 470                                 case DEMOD_START_OF_COMMUNICATION2
: 
 471                                         if (Demod
.sub 
== SUB_SECOND_HALF
) { 
 472                                                 Demod
.state 
= DEMOD_START_OF_COMMUNICATION3
; 
 474                                                 Demod
.output
[Demod
.len
] = 0xab; 
 475                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 479                                 case DEMOD_START_OF_COMMUNICATION3
: 
 480                                         if (Demod
.sub 
== SUB_SECOND_HALF
) { 
 481                                                 Demod
.state 
= DEMOD_SOF_COMPLETE
; 
 483                                                 Demod
.output
[Demod
.len
] = 0xab; 
 484                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 488                                 case DEMOD_SOF_COMPLETE
: 
 489                                 case DEMOD_MANCHESTER_D
: 
 490                                 case DEMOD_MANCHESTER_E
: 
 491                                         // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443) 
 492                                         //                          00001111 = 1 (0 in 14443) 
 493                                         if (Demod
.sub 
== SUB_SECOND_HALF
) { // SUB_FIRST_HALF 
 495                                                 Demod
.shiftReg 
= (Demod
.shiftReg 
>> 1) ^ 0x100; 
 496                                                 Demod
.state 
= DEMOD_MANCHESTER_D
; 
 497                                         } else if (Demod
.sub 
== SUB_FIRST_HALF
) { // SUB_SECOND_HALF 
 499                                                 Demod
.shiftReg 
>>= 1; 
 500                                                 Demod
.state 
= DEMOD_MANCHESTER_E
; 
 501                                         } else if (Demod
.sub 
== SUB_BOTH
) { 
 502                                                 Demod
.state 
= DEMOD_MANCHESTER_F
; 
 504                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 509                                 case DEMOD_MANCHESTER_F
: 
 510                                         // Tag response does not need to be a complete byte! 
 511                                         if (Demod
.len 
> 0 || Demod
.bitCount 
> 0) { 
 512                                                 if (Demod
.bitCount 
> 1) {  // was > 0, do not interpret last closing bit, is part of EOF 
 513                                                         Demod
.shiftReg 
>>= (9 - Demod
.bitCount
);    // right align data 
 514                                                         Demod
.output
[Demod
.len
] = Demod
.shiftReg 
& 0xff; 
 518                                                 Demod
.state 
= DEMOD_UNSYNCD
; 
 521                                                 Demod
.output
[Demod
.len
] = 0xad; 
 522                                                 Demod
.state 
= DEMOD_ERROR_WAIT
; 
 527                                 case DEMOD_ERROR_WAIT
: 
 528                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 532                                         Demod
.output
[Demod
.len
] = 0xdd; 
 533                                         Demod
.state 
= DEMOD_UNSYNCD
; 
 537                         if (Demod
.bitCount 
>= 8) { 
 538                                 Demod
.shiftReg 
>>= 1; 
 539                                 Demod
.output
[Demod
.len
] = (Demod
.shiftReg 
& 0xff); 
 546                                 Demod
.output
[Demod
.len
] = 0xBB; 
 548                                 Demod
.output
[Demod
.len
] = error 
& 0xFF; 
 550                                 Demod
.output
[Demod
.len
] = 0xBB; 
 552                                 Demod
.output
[Demod
.len
] = bit 
& 0xFF; 
 554                                 Demod
.output
[Demod
.len
] = Demod
.buffer 
& 0xFF; 
 557                                 Demod
.output
[Demod
.len
] = Demod
.buffer2 
& 0xFF; 
 559                                 Demod
.output
[Demod
.len
] = Demod
.syncBit 
& 0xFF; 
 561                                 Demod
.output
[Demod
.len
] = 0xBB; 
 568         } // end (state != UNSYNCED) 
 573 //============================================================================= 
 574 // Finally, a `sniffer' for iClass communication 
 575 // Both sides of communication! 
 576 //============================================================================= 
 578 //----------------------------------------------------------------------------- 
 579 // Record the sequence of commands sent by the reader to the tag, with 
 580 // triggering so that we start recording at the point that the tag is moved 
 582 //----------------------------------------------------------------------------- 
 583 void RAMFUNC 
SnoopIClass(void) { 
 585         // We won't start recording the frames that we acquire until we trigger; 
 586         // a good trigger condition to get started is probably when we see a 
 587         // response from the tag. 
 588         //int triggered = false; // false to wait first for card 
 590         // The command (reader -> tag) that we're receiving. 
 591         // The length of a received command will in most cases be no more than 18 bytes. 
 592         // So 32 should be enough! 
 593         #define ICLASS_BUFFER_SIZE 32 
 594         uint8_t readerToTagCmd
[ICLASS_BUFFER_SIZE
]; 
 595         // The response (tag -> reader) that we're receiving. 
 596         uint8_t tagToReaderResponse
[ICLASS_BUFFER_SIZE
]; 
 598         FpgaDownloadAndGo(FPGA_BITSTREAM_HF
); 
 600         // free all BigBuf memory 
 602         // The DMA buffer, used to stream samples from the FPGA 
 603         uint8_t *dmaBuf 
= BigBuf_malloc(DMA_BUFFER_SIZE
); 
 607         iso14a_set_trigger(false); 
 614         // Count of samples received so far, so that we can include timing 
 615         // information in the trace buffer. 
 619         // Set up the demodulator for tag -> reader responses. 
 620         Demod
.output 
= tagToReaderResponse
; 
 622         Demod
.state 
= DEMOD_UNSYNCD
; 
 624         // Setup for the DMA. 
 625         FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A
); 
 627         lastRxCounter 
= DMA_BUFFER_SIZE
; 
 628         FpgaSetupSscDma((uint8_t *)dmaBuf
, DMA_BUFFER_SIZE
); 
 630         // And the reader -> tag commands 
 631         memset(&Uart
, 0, sizeof(Uart
)); 
 632         Uart
.output 
= readerToTagCmd
; 
 633         Uart
.byteCntMax 
= 32; // was 100 (greg)//////////////////////////////////////////////////////////////////////// 
 634         Uart
.state 
= STATE_UNSYNCD
; 
 636         // And put the FPGA in the appropriate mode 
 637         // Signal field is off with the appropriate LED 
 639         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A 
| FPGA_HF_ISO14443A_SNIFFER
); 
 640         SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); 
 642         uint32_t time_0 
= GetCountSspClk(); 
 643         uint32_t time_start 
= 0; 
 644         uint32_t time_stop  
= 0; 
 651         // And now we loop, receiving samples. 
 655                 int behindBy 
= (lastRxCounter 
- AT91C_BASE_PDC_SSC
->PDC_RCR
) & (DMA_BUFFER_SIZE
-1); 
 656                 if (behindBy 
> maxBehindBy
) { 
 657                         maxBehindBy 
= behindBy
; 
 658                         if (behindBy 
> (9 * DMA_BUFFER_SIZE 
/ 10)) { 
 659                                 Dbprintf("blew circular buffer! behindBy=0x%x", behindBy
); 
 663                 if (behindBy 
< 1) continue; 
 669                 if (upTo 
- dmaBuf 
> DMA_BUFFER_SIZE
) { 
 670                         upTo 
-= DMA_BUFFER_SIZE
; 
 671                         lastRxCounter 
+= DMA_BUFFER_SIZE
; 
 672                         AT91C_BASE_PDC_SSC
->PDC_RNPR 
= (uint32_t) upTo
; 
 673                         AT91C_BASE_PDC_SSC
->PDC_RNCR 
= DMA_BUFFER_SIZE
; 
 680                         decbyte 
^= (1 << (3 - div
)); 
 683                 // FOR READER SIDE COMMUMICATION... 
 686                 decbyter 
^= (smpl 
& 0x30); 
 690                 if ((div 
+ 1) % 2 == 0) { 
 692                         if (OutOfNDecoding((smpl 
& 0xF0) >> 4)) { 
 693                                 rsamples 
= samples 
- Uart
.samples
; 
 694                                 time_stop 
= (GetCountSspClk()-time_0
) << 4; 
 697                                 //if (!LogTrace(Uart.output, Uart.byteCnt, rsamples, Uart.parityBits,true)) break; 
 698                                 //if (!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, true)) break; 
 699                                 uint8_t parity
[MAX_PARITY_SIZE
]; 
 700                                 GetParity(Uart
.output
, Uart
.byteCnt
, parity
); 
 701                                 LogTrace(Uart
.output
, Uart
.byteCnt
, time_start
, time_stop
, parity
, true); 
 703                                 /* And ready to receive another command. */ 
 704                                 Uart
.state 
= STATE_UNSYNCD
; 
 705                                 /* And also reset the demod code, which might have been */ 
 706                                 /* false-triggered by the commands from the reader. */ 
 707                                 Demod
.state 
= DEMOD_UNSYNCD
; 
 711                                 time_start 
= (GetCountSspClk()-time_0
) << 4; 
 718                         if (ManchesterDecoding(smpl 
& 0x0F)) { 
 719                                 time_stop 
= (GetCountSspClk()-time_0
) << 4; 
 721                                 rsamples 
= samples 
- Demod
.samples
; 
 724                                 uint8_t parity
[MAX_PARITY_SIZE
]; 
 725                                 GetParity(Demod
.output
, Demod
.len
, parity
); 
 726                                 LogTrace(Demod
.output
, Demod
.len
, time_start
, time_stop
, parity
, false); 
 728                                 // And ready to receive another response. 
 729                                 memset(&Demod
, 0, sizeof(Demod
)); 
 730                                 Demod
.output 
= tagToReaderResponse
; 
 731                                 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 
- TAG_SOF_UNMODULATED 
- DELAY_ARM_TO_READER_SIM
; 
1234                         TransmitTo15693Reader(modulated_response
, modulated_response_size
, &response_time
, 0, false); 
1235                         LogTrace(trace_data
, trace_data_size
, response_time 
+ DELAY_ARM_TO_READER_SIM
, response_time 
+ (modulated_response_size 
<< 6) + DELAY_ARM_TO_READER_SIM
, 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 //----------------------------------------------------------------------------- 
1331 // Transmit the command (to the tag) that was placed in ToSend[]. 
1332 //----------------------------------------------------------------------------- 
1333 static void TransmitIClassCommand(const uint8_t *cmd
, int len
, int *samples
, int *wait
) { 
1335         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A 
| FPGA_HF_ISO14443A_READER_MOD
); 
1336         AT91C_BASE_SSC
->SSC_THR 
= 0x00; 
1337         FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A
); 
1340                 if (*wait 
< 10) *wait 
= 10; 
1342                 for (c 
= 0; c 
< *wait
;) { 
1343                         if (AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_TXRDY
)) { 
1344                                 AT91C_BASE_SSC
->SSC_THR 
= 0x00;     // For exact timing! 
1347                         if (AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_RXRDY
)) { 
1348                                 volatile uint32_t r 
= AT91C_BASE_SSC
->SSC_RHR
; 
1356         bool firstpart 
= true; 
1359                 if (AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_TXRDY
)) { 
1361                         // DOUBLE THE SAMPLES! 
1363                                 sendbyte 
= (cmd
[c
] & 0xf0) | (cmd
[c
] >> 4); 
1365                                 sendbyte 
= (cmd
[c
] & 0x0f) | (cmd
[c
] << 4); 
1368                         if (sendbyte 
== 0xff) { 
1371                         AT91C_BASE_SSC
->SSC_THR 
= sendbyte
; 
1372                         firstpart 
= !firstpart
; 
1378                 if (AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_RXRDY
)) { 
1379                         volatile uint32_t r 
= AT91C_BASE_SSC
->SSC_RHR
; 
1384         if (samples 
&& wait
) *samples 
= (c 
+ *wait
) << 3; 
1388 //----------------------------------------------------------------------------- 
1389 // Prepare iClass reader command to send to FPGA 
1390 //----------------------------------------------------------------------------- 
1391 void CodeIClassCommand(const uint8_t *cmd
, int len
) { 
1396         // Start of Communication: 1 out of 4 
1397         ToSend
[++ToSendMax
] = 0xf0; 
1398         ToSend
[++ToSendMax
] = 0x00; 
1399         ToSend
[++ToSendMax
] = 0x0f; 
1400         ToSend
[++ToSendMax
] = 0x00; 
1402         // Modulate the bytes 
1403         for (i 
= 0; i 
< len
; i
++) { 
1405                 for (j 
= 0; j 
< 4; j
++) { 
1406                         for (k 
= 0; k 
< 4; k
++) { 
1408                                         ToSend
[++ToSendMax
] = 0x0f; 
1410                                         ToSend
[++ToSendMax
] = 0x00; 
1417         // End of Communication 
1418         ToSend
[++ToSendMax
] = 0x00; 
1419         ToSend
[++ToSendMax
] = 0x00; 
1420         ToSend
[++ToSendMax
] = 0xf0; 
1421         ToSend
[++ToSendMax
] = 0x00; 
1423         // Convert from last character reference to length 
1427 static void ReaderTransmitIClass(uint8_t *frame
, int len
) { 
1431         // This is tied to other size changes 
1432         CodeIClassCommand(frame
, len
); 
1435         TransmitIClassCommand(ToSend
, ToSendMax
, &samples
, &wait
); 
1439         // Store reader command in buffer 
1440         uint8_t par
[MAX_PARITY_SIZE
]; 
1441         GetParity(frame
, len
, par
); 
1442         LogTrace(frame
, len
, rsamples
, rsamples
, par
, true); 
1445 //----------------------------------------------------------------------------- 
1446 // Wait a certain time for tag response 
1447 //  If a response is captured return true 
1448 //  If it takes too long return false 
1449 //----------------------------------------------------------------------------- 
1450 static int GetIClassAnswer(uint8_t *receivedResponse
, int maxLen
, int *samples
, int *elapsed
) { 
1452         // buffer needs to be 512 bytes 
1455         // Set FPGA mode to "reader listen mode", no modulation (listen 
1456         // only, since we are receiving, not transmitting). 
1457         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A 
| FPGA_HF_ISO14443A_READER_LISTEN
); 
1459         // Now get the answer from the card 
1460         Demod
.output 
= receivedResponse
; 
1462         Demod
.state 
= DEMOD_UNSYNCD
; 
1465         if (elapsed
) *elapsed 
= 0; 
1473                 if (BUTTON_PRESS()) return false; 
1475                 if (AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_TXRDY
)) { 
1476                         AT91C_BASE_SSC
->SSC_THR 
= 0x00;  // To make use of exact timing of next command from reader!! 
1477                         if (elapsed
) (*elapsed
)++; 
1479                 if (AT91C_BASE_SSC
->SSC_SR 
& (AT91C_SSC_RXRDY
)) { 
1485                         b 
= (uint8_t)AT91C_BASE_SSC
->SSC_RHR
; 
1489                         if (ManchesterDecoding(b 
& 0x0f)) { 
1497 static int ReaderReceiveIClass(uint8_t *receivedAnswer
) { 
1499         if (!GetIClassAnswer(receivedAnswer
, 160, &samples
, 0)) { 
1502         rsamples 
+= samples
; 
1503         uint8_t parity
[MAX_PARITY_SIZE
]; 
1504         GetParity(receivedAnswer
, Demod
.len
, parity
); 
1505         LogTrace(receivedAnswer
, Demod
.len
, rsamples
, rsamples
, parity
, false); 
1506         if (samples 
== 0) return false; 
1510 static void setupIclassReader() { 
1511         FpgaDownloadAndGo(FPGA_BITSTREAM_HF
); 
1512         // Reset trace buffer 
1517         FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A
); 
1518         // Start from off (no field generated) 
1519         // Signal field is off with the appropriate LED 
1521         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1524         SetAdcMuxFor(GPIO_MUXSEL_HIPKD
); 
1526         // Now give it time to spin up. 
1527         // Signal field is on with the appropriate LED 
1528         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A 
| FPGA_HF_ISO14443A_READER_MOD
); 
1534 static bool sendCmdGetResponseWithRetries(uint8_t* command
, size_t cmdsize
, uint8_t* resp
, uint8_t expected_size
, uint8_t retries
) { 
1535         while (retries
-- > 0) { 
1536                 ReaderTransmitIClass(command
, cmdsize
); 
1537                 if (expected_size 
== ReaderReceiveIClass(resp
)) { 
1541         return false;//Error 
1545  * @brief Talks to an iclass tag, sends the commands to get CSN and CC. 
1546  * @param card_data where the CSN and CC are stored for return 
1549  *         2 = Got CSN and CC 
1551 static uint8_t handshakeIclassTag_ext(uint8_t *card_data
, bool use_credit_key
) { 
1552         static uint8_t act_all
[]     = { 0x0a }; 
1553         //static uint8_t identify[]    = { 0x0c }; 
1554         static uint8_t identify
[]    = { 0x0c, 0x00, 0x73, 0x33 }; 
1555         static uint8_t select
[]      = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
1556         static uint8_t readcheck_cc
[]= { 0x88, 0x02 }; 
1558                 readcheck_cc
[0] = 0x18; 
1560                 readcheck_cc
[0] = 0x88; 
1562         uint8_t resp
[ICLASS_BUFFER_SIZE
]; 
1564         uint8_t read_status 
= 0; 
1567         ReaderTransmitIClass(act_all
, 1); 
1569         if (!ReaderReceiveIClass(resp
)) return read_status
;//Fail 
1572         ReaderTransmitIClass(identify
, 1); 
1573         //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC 
1574         uint8_t len 
= ReaderReceiveIClass(resp
); 
1575         if (len 
!= 10) return read_status
;//Fail 
1577         //Copy the Anti-collision CSN to our select-packet 
1578         memcpy(&select
[1], resp
, 8); 
1580         ReaderTransmitIClass(select
, sizeof(select
)); 
1581         //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC 
1582         len 
= ReaderReceiveIClass(resp
); 
1583         if (len 
!= 10) return read_status
;//Fail 
1585         //Success - level 1, we got CSN 
1586         //Save CSN in response data 
1587         memcpy(card_data
, resp
, 8); 
1589         //Flag that we got to at least stage 1, read CSN 
1592         // Card selected, now read e-purse (cc) (only 8 bytes no CRC) 
1593         ReaderTransmitIClass(readcheck_cc
, sizeof(readcheck_cc
)); 
1594         if (ReaderReceiveIClass(resp
) == 8) { 
1595                 //Save CC (e-purse) in response data 
1596                 memcpy(card_data
+8, resp
, 8); 
1603 static uint8_t handshakeIclassTag(uint8_t *card_data
) { 
1604         return handshakeIclassTag_ext(card_data
, false); 
1608 // Reader iClass Anticollission 
1609 void ReaderIClass(uint8_t arg0
) { 
1611         uint8_t card_data
[6 * 8] = {0}; 
1612         memset(card_data
, 0xFF, sizeof(card_data
)); 
1613         uint8_t last_csn
[8] = {0,0,0,0,0,0,0,0}; 
1614         uint8_t resp
[ICLASS_BUFFER_SIZE
]; 
1615         memset(resp
, 0xFF, sizeof(resp
)); 
1616         //Read conf block CRC(0x01) => 0xfa 0x22 
1617         uint8_t readConf
[] = { ICLASS_CMD_READ_OR_IDENTIFY
, 0x01, 0xfa, 0x22}; 
1618         //Read App Issuer Area block CRC(0x05) => 0xde  0x64 
1619         uint8_t readAA
[] = { ICLASS_CMD_READ_OR_IDENTIFY
, 0x05, 0xde, 0x64}; 
1622         uint8_t result_status 
= 0; 
1623         // flag to read until one tag is found successfully 
1624         bool abort_after_read 
= arg0 
& FLAG_ICLASS_READER_ONLY_ONCE
; 
1625         // flag to only try 5 times to find one tag then return 
1626         bool try_once 
= arg0 
& FLAG_ICLASS_READER_ONE_TRY
; 
1627         // if neither abort_after_read nor try_once then continue reading until button pressed. 
1629         bool use_credit_key 
= arg0 
& FLAG_ICLASS_READER_CEDITKEY
; 
1630         // test flags for what blocks to be sure to read 
1631         uint8_t flagReadConfig 
= arg0 
& FLAG_ICLASS_READER_CONF
; 
1632         uint8_t flagReadCC 
= arg0 
& FLAG_ICLASS_READER_CC
; 
1633         uint8_t flagReadAA 
= arg0 
& FLAG_ICLASS_READER_AA
; 
1636         setupIclassReader(); 
1638         uint16_t tryCnt 
= 0; 
1639         bool userCancelled 
= BUTTON_PRESS() || usb_poll_validate_length(); 
1640         while (!userCancelled
) { 
1641                 // if only looking for one card try 2 times if we missed it the first time 
1642                 if (try_once 
&& tryCnt 
> 2) { 
1646                 if (!get_tracing()) { 
1647                         DbpString("Trace full"); 
1652                 read_status 
= handshakeIclassTag_ext(card_data
, use_credit_key
); 
1654                 if (read_status 
== 0) continue; 
1655                 if (read_status 
== 1) result_status 
= FLAG_ICLASS_READER_CSN
; 
1656                 if (read_status 
== 2) result_status 
= FLAG_ICLASS_READER_CSN 
| FLAG_ICLASS_READER_CC
; 
1658                 // handshakeIclass returns CSN|CC, but the actual block 
1659                 // layout is CSN|CONFIG|CC, so here we reorder the data, 
1660                 // moving CC forward 8 bytes 
1661                 memcpy(card_data
+16, card_data
+8, 8); 
1662                 //Read block 1, config 
1663                 if (flagReadConfig
) { 
1664                         if (sendCmdGetResponseWithRetries(readConf
, sizeof(readConf
), resp
, 10, 10)) { 
1665                                 result_status 
|= FLAG_ICLASS_READER_CONF
; 
1666                                 memcpy(card_data
+8, resp
, 8); 
1668                                 Dbprintf("Failed to dump config block"); 
1674                         if (sendCmdGetResponseWithRetries(readAA
, sizeof(readAA
), resp
, 10, 10)) { 
1675                                 result_status 
|= FLAG_ICLASS_READER_AA
; 
1676                                 memcpy(card_data 
+ (8*5), resp
, 8); 
1678                                 //Dbprintf("Failed to dump AA block"); 
1683                 // 1 : Configuration 
1685                 // 3 : kd / debit / aa2 (write-only) 
1686                 // 4 : kc / credit / aa1 (write-only) 
1687                 // 5 : AIA, Application issuer area 
1688                 //Then we can 'ship' back the 6 * 8 bytes of data, 
1689                 // with 0xFF:s in block 3 and 4. 
1692                 //Send back to client, but don't bother if we already sent this - 
1693                 //  only useful if looping in arm (not try_once && not abort_after_read) 
1694                 if (memcmp(last_csn
, card_data
, 8) != 0) { 
1695                         // If caller requires that we get Conf, CC, AA, continue until we got it 
1696                         if ( (result_status 
^ FLAG_ICLASS_READER_CSN 
^ flagReadConfig 
^ flagReadCC 
^ flagReadAA
) == 0) { 
1697                                 cmd_send(CMD_ACK
, result_status
, 0, 0, card_data
, sizeof(card_data
)); 
1698                                 if (abort_after_read
) { 
1699                                         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1704                                 //Save that we already sent this.... 
1705                                 memcpy(last_csn
, card_data
, 8); 
1710                 userCancelled 
= BUTTON_PRESS() || usb_poll_validate_length(); 
1712         if (userCancelled
) { 
1713                 cmd_send(CMD_ACK
, 0xFF, 0, 0, card_data
, 0); 
1715                 cmd_send(CMD_ACK
, 0, 0, 0, card_data
, 0); 
1720 void ReaderIClass_Replay(uint8_t arg0
, uint8_t *MAC
) { 
1722         uint8_t card_data
[USB_CMD_DATA_SIZE
]={0}; 
1723         uint16_t block_crc_LUT
[255] = {0}; 
1725         //Generate a lookup table for block crc 
1726         for (int block 
= 0; block 
< 255; block
++){ 
1728                 block_crc_LUT
[block
] = iclass_crc16(&bl 
,1); 
1730         //Dbprintf("Lookup table: %02x %02x %02x" ,block_crc_LUT[0],block_crc_LUT[1],block_crc_LUT[2]); 
1732         uint8_t check
[]       = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
1733         uint8_t read
[]        = { 0x0c, 0x00, 0x00, 0x00 }; 
1736         uint8_t cardsize 
= 0; 
1739         static struct memory_t 
{ 
1747         uint8_t resp
[ICLASS_BUFFER_SIZE
]; 
1749         setupIclassReader(); 
1752         while (!BUTTON_PRESS()) { 
1756                 if (!get_tracing()) { 
1757                         DbpString("Trace full"); 
1761                 uint8_t read_status 
= handshakeIclassTag(card_data
); 
1762                 if (read_status 
< 2) continue; 
1764                 //for now replay captured auth (as cc not updated) 
1765                 memcpy(check
+5, MAC
, 4); 
1767                 if (!sendCmdGetResponseWithRetries(check
, sizeof(check
), resp
, 4, 5)) { 
1768                         Dbprintf("Error: Authentication Fail!"); 
1772                 //first get configuration block (block 1) 
1773                 crc 
= block_crc_LUT
[1]; 
1776                 read
[3] = crc 
& 0xff; 
1778                 if (!sendCmdGetResponseWithRetries(read
, sizeof(read
),resp
, 10, 10)) { 
1779                         Dbprintf("Dump config (block 1) failed"); 
1784                 memory
.k16 
= (mem 
& 0x80); 
1785                 memory
.book 
= (mem 
& 0x20); 
1786                 memory
.k2 
= (mem 
& 0x8); 
1787                 memory
.lockauth 
= (mem 
& 0x2); 
1788                 memory
.keyaccess 
= (mem 
& 0x1); 
1790                 cardsize 
= memory
.k16 
? 255 : 32; 
1792                 //Set card_data to all zeroes, we'll fill it with data 
1793                 memset(card_data
, 0x0, USB_CMD_DATA_SIZE
); 
1794                 uint8_t failedRead 
= 0; 
1795                 uint32_t stored_data_length 
= 0; 
1796                 //then loop around remaining blocks 
1797                 for (int block 
= 0; block 
< cardsize
; block
++) { 
1799                         crc 
= block_crc_LUT
[block
]; 
1801                         read
[3] = crc 
& 0xff; 
1803                         if (sendCmdGetResponseWithRetries(read
, sizeof(read
), resp
, 10, 10)) { 
1804                                 Dbprintf("     %02x: %02x %02x %02x %02x %02x %02x %02x %02x", 
1805                                                 block
, resp
[0], resp
[1], resp
[2], 
1806                                                 resp
[3], resp
[4], resp
[5], 
1809                                 //Fill up the buffer 
1810                                 memcpy(card_data
+stored_data_length
, resp
, 8); 
1811                                 stored_data_length 
+= 8; 
1812                                 if (stored_data_length 
+8 > USB_CMD_DATA_SIZE
) { 
1813                                         //Time to send this off and start afresh 
1815                                                          stored_data_length
,//data length 
1816                                                          failedRead
,//Failed blocks? 
1818                                                          card_data
, stored_data_length
); 
1820                                         stored_data_length 
= 0; 
1826                                 stored_data_length 
+= 8;//Otherwise, data becomes misaligned 
1827                                 Dbprintf("Failed to dump block %d", block
); 
1831                 //Send off any remaining data 
1832                 if (stored_data_length 
> 0) { 
1834                                          stored_data_length
,//data length 
1835                                          failedRead
,//Failed blocks? 
1838                                          stored_data_length
); 
1840                 //If we got here, let's break 
1843         //Signal end of transmission 
1851         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1855 void iClass_Authentication(uint8_t *MAC
) { 
1856         uint8_t check
[] = { ICLASS_CMD_CHECK_KD
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
1857         uint8_t resp
[ICLASS_BUFFER_SIZE
]; 
1858         memcpy(check
+5, MAC
, 4); 
1860         isOK 
= sendCmdGetResponseWithRetries(check
, sizeof(check
), resp
, 4, 6); 
1861         cmd_send(CMD_ACK
,isOK
, 0, 0, 0, 0); 
1864 static bool iClass_ReadBlock(uint8_t blockNo
, uint8_t *readdata
) { 
1865         uint8_t readcmd
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, blockNo
, 0x00, 0x00}; //0x88, 0x00 // can i use 0C? 
1867         uint16_t rdCrc 
= iclass_crc16(&bl
, 1); 
1868         readcmd
[2] = rdCrc 
>> 8; 
1869         readcmd
[3] = rdCrc 
& 0xff; 
1870         uint8_t resp
[] = {0,0,0,0,0,0,0,0,0,0}; 
1873         //readcmd[1] = blockNo; 
1874         isOK 
= sendCmdGetResponseWithRetries(readcmd
, sizeof(readcmd
), resp
, 10, 10); 
1875         memcpy(readdata
, resp
, sizeof(resp
)); 
1880 void iClass_ReadBlk(uint8_t blockno
) { 
1881         uint8_t readblockdata
[] = {0,0,0,0,0,0,0,0,0,0}; 
1883         isOK 
= iClass_ReadBlock(blockno
, readblockdata
); 
1884         cmd_send(CMD_ACK
, isOK
, 0, 0, readblockdata
, 8); 
1885         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1888 void iClass_Dump(uint8_t blockno
, uint8_t numblks
) { 
1889         uint8_t readblockdata
[] = {0,0,0,0,0,0,0,0,0,0}; 
1894         uint8_t *dataout 
= BigBuf_malloc(255*8); 
1895         if (dataout 
== NULL
) { 
1896                 Dbprintf("out of memory"); 
1897                 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1899                 cmd_send(CMD_ACK
, 0, 1, 0, 0, 0); 
1903         memset(dataout
, 0xFF, 255*8); 
1905         for ( ; blkCnt 
< numblks
; blkCnt
++) { 
1906                 isOK 
= iClass_ReadBlock(blockno
+blkCnt
, readblockdata
); 
1907                 if (!isOK 
|| (readblockdata
[0] == 0xBB || readblockdata
[7] == 0xBB || readblockdata
[2] == 0xBB)) { //try again 
1908                         isOK 
= iClass_ReadBlock(blockno
+blkCnt
, readblockdata
); 
1910                                 Dbprintf("Block %02X failed to read", blkCnt
+blockno
); 
1914                 memcpy(dataout 
+ (blkCnt
*8), readblockdata
, 8); 
1916         //return pointer to dump memory in arg3 
1917         cmd_send(CMD_ACK
, isOK
, blkCnt
, BigBuf_max_traceLen(), 0, 0); 
1918         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1923 static bool iClass_WriteBlock_ext(uint8_t blockNo
, uint8_t *data
) { 
1924         uint8_t write
[] = { ICLASS_CMD_UPDATE
, blockNo
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
1925         //uint8_t readblockdata[10]; 
1926         //write[1] = blockNo; 
1927         memcpy(write
+2, data
, 12); // data + mac 
1928         char *wrCmd 
= (char *)(write
+1); 
1929         uint16_t wrCrc 
= iclass_crc16(wrCmd
, 13); 
1930         write
[14] = wrCrc 
>> 8; 
1931         write
[15] = wrCrc 
& 0xff; 
1932         uint8_t resp
[] = {0,0,0,0,0,0,0,0,0,0}; 
1935         isOK 
= sendCmdGetResponseWithRetries(write
, sizeof(write
), resp
, sizeof(resp
), 10); 
1936         if (isOK
) { //if reader responded correctly 
1937                 //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]); 
1938                 if (memcmp(write
+2, resp
, 8)) {  //if response is not equal to write values 
1939                         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) 
1941                                 isOK 
= sendCmdGetResponseWithRetries(write
, sizeof(write
), resp
, sizeof(resp
), 10); 
1948 void iClass_WriteBlock(uint8_t blockNo
, uint8_t *data
) { 
1949         bool isOK 
= iClass_WriteBlock_ext(blockNo
, data
); 
1951                 Dbprintf("Write block [%02x] successful", blockNo
); 
1953                 Dbprintf("Write block [%02x] failed", blockNo
); 
1955         cmd_send(CMD_ACK
, isOK
, 0, 0, 0, 0); 
1956         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
1959 void iClass_Clone(uint8_t startblock
, uint8_t endblock
, uint8_t *data
) { 
1962         int total_block 
= (endblock 
- startblock
) + 1; 
1963         for (i 
= 0; i 
< total_block
; i
++) { 
1965                 if (iClass_WriteBlock_ext(i
+startblock
, data 
+ (i
*12))){ 
1966                         Dbprintf("Write block [%02x] successful", i 
+ startblock
); 
1969                         if (iClass_WriteBlock_ext(i
+startblock
, data 
+ (i
*12))){ 
1970                                 Dbprintf("Write block [%02x] successful", i 
+ startblock
); 
1973                                 Dbprintf("Write block [%02x] failed", i 
+ startblock
); 
1977         if (written 
== total_block
) 
1978                 Dbprintf("Clone complete"); 
1980                 Dbprintf("Clone incomplete"); 
1982         cmd_send(CMD_ACK
, 1, 0, 0, 0, 0); 
1983         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);