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
8 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
9 // at your option, any later version. See the LICENSE.txt file for the text of
11 //-----------------------------------------------------------------------------
12 // Routines to support iClass.
13 //-----------------------------------------------------------------------------
14 // Contribution made during a security research at Radboud University Nijmegen
16 // Please feel free to contribute and extend iClass support!!
17 //-----------------------------------------------------------------------------
20 #include "proxmark3_arm.h"
22 // Needed for CRC in emulation mode;
23 // same construction as in ISO 14443;
24 // different initial value (CRC_ICLASS)
26 #include "optimized_cipher.h"
30 #include "fpgaloader.h"
34 #include "protocols.h"
38 static uint8_t get_pagemap(const picopass_hdr_t
*hdr
) {
39 return (hdr
->conf
.fuses
& (FUSE_CRYPT0
| FUSE_CRYPT1
)) >> 3;
42 // The length of a received command will in most cases be no more than 18 bytes.
43 // we expect max 34 (32+2) bytes as tag answer (response to READ4)
44 #ifndef ICLASS_BUFFER_SIZE
45 #define ICLASS_BUFFER_SIZE 34 + 2
48 #ifndef ICLASS_16KS_SIZE
49 #define ICLASS_16KS_SIZE 0x100 * 8
52 // iCLASS has a slightly different timing compared to ISO15693. According to the picopass data sheet the tag response is expected 330us after
53 // 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.
54 // 330us = 140 ssp_clk cycles @ 423,75kHz when simulating.
55 // 56,64us = 24 ssp_clk_cycles
56 #define DELAY_ICLASS_VCD_TO_VICC_SIM (140 - 26) // (140 - 24)
58 // times in ssp_clk_cycles @ 3,3625MHz when acting as reader
59 #define DELAY_ICLASS_VICC_TO_VCD_READER DELAY_ISO15693_VICC_TO_VCD_READER
61 // times in samples @ 212kHz when acting as reader
62 #define ICLASS_READER_TIMEOUT_ACTALL 330 // 1558us, nominal 330us + 7slots*160us = 1450us
63 #define ICLASS_READER_TIMEOUT_UPDATE 3390 // 16000us, nominal 4-15ms
64 #define ICLASS_READER_TIMEOUT_OTHERS 80 // 380us, nominal 330us
66 #define AddCrc(data, len) compute_crc(CRC_ICLASS, (data), (len), (data)+(len), (data)+(len)+1)
71 * in ISO15693-2 mode - Manchester
72 * in ISO 14443b - BPSK coding
76 * Tout = 330 µs, Tprog 1 = 4 to 15 ms, Tslot = 330 µs + (number of slots x 160 µs)
78 * Tout = 100 µs, Tprog = 4 to 15 ms, Tslot = 100 µs+ (number of slots x 80 µs)
80 Tout = 76 µs, Tprog = 4 to 15 ms, Tslot = 119 µs+ (number of slots x 150 µs)
83 * So for current implementation in ISO15693, its 330 µs from end of reader, to start of card.
86 //=============================================================================
87 // a `sniffer' for iClass communication
88 // Both sides of communication!
89 //=============================================================================
90 void SniffIClass(uint8_t jam_search_len
, uint8_t *jam_search_string
) {
91 SniffIso15693(jam_search_len
, jam_search_string
);
94 static void rotateCSN(uint8_t *original_csn
, uint8_t *rotated_csn
) {
95 for (uint8_t i
= 0; i
< 8; i
++) {
96 rotated_csn
[i
] = (original_csn
[i
] >> 3) | (original_csn
[(i
+ 1) % 8] << 5);
101 static void CodeIClassTagSOF(void) {
103 tosend_t
*ts
= get_tosend();
104 ts
->buf
[++ts
->max
] = 0x1D;
109 * SOF comprises 3 parts;
110 * * An unmodulated time of 56.64 us
111 * * 24 pulses of 423.75 kHz (fc/32)
112 * * A logic 1, which starts with an unmodulated time of 18.88us
113 * followed by 8 pulses of 423.75kHz (fc/32)
116 * EOF comprises 3 parts:
117 * - A logic 0 (which starts with 8 pulses of fc/32 followed by an unmodulated
119 * - 24 pulses of fc/32
120 * - An unmodulated time of 56.64 us
123 * A logic 0 starts with 8 pulses of fc/32
124 * followed by an unmodulated time of 256/fc (~18,88us).
126 * A logic 0 starts with unmodulated time of 256/fc (~18,88us) followed by
127 * 8 pulses of fc/32 (also 18.88us)
129 * The mode FPGA_HF_SIMULATOR_MODULATE_424K_8BIT which we use to simulate tag,
131 * - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us).
132 * - A 0-bit input to the FPGA becomes an unmodulated time of 18.88us
135 * SOF can be written as 00011101 = 0x1D
136 * EOF can be written as 10111000 = 0xb8
137 * logic 1 be written as 01 = 0x1
138 * logic 0 be written as 10 = 0x2
144 * @brief SimulateIClass simulates an iClass card.
145 * @param arg0 type of simulation
146 * - 0 uses the first 8 bytes in usb data as CSN
147 * - 2 "dismantling iclass"-attack. This mode iterates through all CSN's specified
148 * in the usb data. This mode collects MAC from the reader, in order to do an offline
149 * attack on the keys. For more info, see "dismantling iclass" and proxclone.com.
150 * - Other : Uses the default CSN (031fec8af7ff12e0)
151 * @param arg1 - number of CSN's contained in datain (applicable for mode 2 only)
155 // turn off afterwards
156 void SimulateIClass(uint32_t arg0
, uint32_t arg1
, uint32_t arg2
, uint8_t *datain
) {
157 iclass_simulate(arg0
, arg1
, arg2
, datain
, NULL
, NULL
);
160 void iclass_simulate(uint8_t sim_type
, uint8_t num_csns
, bool send_reply
, uint8_t *datain
, uint8_t *dataout
, uint16_t *dataoutlen
) {
168 // only logg if we are called from the client.
169 set_tracing(send_reply
);
171 //Use the emulator memory for SIM
172 uint8_t *emulator
= BigBuf_get_EM_addr();
173 uint8_t mac_responses
[PM3_CMD_DATA_SIZE
] = { 0 };
175 if (sim_type
== ICLASS_SIM_MODE_CSN
) {
176 // Use the CSN from commandline
177 memcpy(emulator
, datain
, 8);
178 do_iclass_simulation(ICLASS_SIM_MODE_CSN
, NULL
);
180 } else if (sim_type
== ICLASS_SIM_MODE_CSN_DEFAULT
) {
182 uint8_t csn
[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0 };
183 // Use the CSN from commandline
184 memcpy(emulator
, csn
, 8);
185 do_iclass_simulation(ICLASS_SIM_MODE_CSN
, NULL
);
187 } else if (sim_type
== ICLASS_SIM_MODE_READER_ATTACK
) {
189 Dbprintf("going into attack mode, %d CSNS sent", num_csns
);
190 // In this mode, a number of csns are within datain. We'll simulate each one, one at a time
191 // in order to collect MAC's from the reader. This can later be used in an offlne-attack
192 // in order to obtain the keys, as in the "dismantling iclass"-paper.
193 #define EPURSE_MAC_SIZE 16
195 for (; i
< num_csns
&& i
* EPURSE_MAC_SIZE
+ 8 < PM3_CMD_DATA_SIZE
; i
++) {
197 memcpy(emulator
, datain
+ (i
* 8), 8);
199 if (do_iclass_simulation(ICLASS_SIM_MODE_EXIT_AFTER_MAC
, mac_responses
+ i
* EPURSE_MAC_SIZE
)) {
202 *dataoutlen
= i
* EPURSE_MAC_SIZE
;
206 reply_old(CMD_ACK
, CMD_HF_ICLASS_SIMULATE
, i
, 0, mac_responses
, i
* EPURSE_MAC_SIZE
);
211 *dataoutlen
= i
* EPURSE_MAC_SIZE
;
214 reply_old(CMD_ACK
, CMD_HF_ICLASS_SIMULATE
, i
, 0, mac_responses
, i
* EPURSE_MAC_SIZE
);
216 } else if (sim_type
== ICLASS_SIM_MODE_FULL
) {
218 //This is 'full sim' mode, where we use the emulator storage for data.
219 //ie: BigBuf_get_EM_addr should be previously filled with data from the "eload" command
220 picopass_hdr_t
*hdr
= (picopass_hdr_t
*)BigBuf_get_EM_addr();
221 uint8_t pagemap
= get_pagemap(hdr
);
222 if (pagemap
== PICOPASS_NON_SECURE_PAGEMODE
) {
223 do_iclass_simulation_nonsec();
225 do_iclass_simulation(ICLASS_SIM_MODE_FULL
, NULL
);
228 } else if (sim_type
== ICLASS_SIM_MODE_CONFIG_CARD
) {
231 do_iclass_simulation(ICLASS_SIM_MODE_FULL
, NULL
);
234 } else if (sim_type
== ICLASS_SIM_MODE_READER_ATTACK_KEYROLL
) {
236 // This is the KEYROLL version of sim 2.
237 // the collected data (mac_response) is doubled out since we are trying to collect both keys in the keyroll process.
238 // Keyroll iceman 9 csns * 8 * 2 = 144
239 // keyroll CARL55 15csns * 8 * 2 = 15 * 8 * 2 = 240
240 Dbprintf("going into attack keyroll mode, %d CSNS sent", num_csns
);
241 // In this mode, a number of csns are within datain. We'll simulate each one, one at a time
242 // in order to collect MAC's from the reader. This can later be used in an offlne-attack
243 // in order to obtain the keys, as in the "dismantling iclass"-paper.
245 // keyroll mode, reader swaps between old key and new key alternatively when fail a authentication.
246 // attack below is same as SIM 2, but we run the CSN twice to collected the mac for both keys.
248 // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. iceman fork uses 9 CSNS
249 for (; i
< num_csns
&& i
* EPURSE_MAC_SIZE
+ 8 < PM3_CMD_DATA_SIZE
; i
++) {
251 memcpy(emulator
, datain
+ (i
* 8), 8);
254 if (do_iclass_simulation(ICLASS_SIM_MODE_EXIT_AFTER_MAC
, mac_responses
+ i
* EPURSE_MAC_SIZE
)) {
257 *dataoutlen
= i
* EPURSE_MAC_SIZE
* 2;
260 reply_old(CMD_ACK
, CMD_HF_ICLASS_SIMULATE
, i
* 2, 0, mac_responses
, i
* EPURSE_MAC_SIZE
* 2);
267 if (do_iclass_simulation(ICLASS_SIM_MODE_EXIT_AFTER_MAC
, mac_responses
+ (i
+ num_csns
) * EPURSE_MAC_SIZE
)) {
270 *dataoutlen
= i
* EPURSE_MAC_SIZE
* 2;
273 reply_old(CMD_ACK
, CMD_HF_ICLASS_SIMULATE
, i
* 2, 0, mac_responses
, i
* EPURSE_MAC_SIZE
* 2);
281 *dataoutlen
= i
* EPURSE_MAC_SIZE
* 2;
283 // double the amount of collected data.
285 reply_old(CMD_ACK
, CMD_HF_ICLASS_SIMULATE
, i
* 2, 0, mac_responses
, i
* EPURSE_MAC_SIZE
* 2);
288 // We may want a mode here where we hardcode the csns to use (from proxclone).
289 // That will speed things up a little, but not required just yet.
290 DbpString("the mode is not implemented, reserved for future use");
294 if (dataout
&& dataoutlen
)
295 memcpy(dataout
, mac_responses
, *dataoutlen
);
298 BigBuf_free_keep_EM();
302 * Simulation assumes a SECURE PAGE simulation with authentication and application areas.
305 * @brief Does the actual simulation
306 * @param csn - csn to use
307 * @param breakAfterMacReceived if true, returns after reader MAC has been received.
309 int do_iclass_simulation(int simulationMode
, uint8_t *reader_mac_buf
) {
311 // free eventually allocated BigBuf memory
312 BigBuf_free_keep_EM();
314 uint16_t page_size
= 32 * 8;
315 uint8_t current_page
= 0;
317 // maintain cipher states for both credit and debit key for each page
318 State cipher_state_KD
[8];
319 State cipher_state_KC
[8];
320 State
*cipher_state
= &cipher_state_KD
[0];
322 uint8_t *emulator
= BigBuf_get_EM_addr();
323 uint8_t *csn
= emulator
;
325 // CSN followed by two CRC bytes
326 uint8_t anticoll_data
[10] = { 0 };
327 uint8_t csn_data
[10] = { 0 };
328 memcpy(csn_data
, csn
, sizeof(csn_data
));
330 // Construct anticollision-CSN
331 rotateCSN(csn_data
, anticoll_data
);
333 // Compute CRC on both CSNs
334 AddCrc(anticoll_data
, 8);
337 uint8_t diversified_kd
[8] = { 0 };
338 uint8_t diversified_kc
[8] = { 0 };
339 uint8_t *diversified_key
= diversified_kd
;
341 // configuration block
342 uint8_t conf_block
[10] = {0x12, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xFF, 0x3C, 0x00, 0x00};
345 uint8_t card_challenge_data
[8] = { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
348 uint8_t aia_data
[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00};
350 if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
352 memcpy(conf_block
, emulator
+ (8 * 1), 8); // blk 1
353 memcpy(card_challenge_data
, emulator
+ (8 * 2), 8); // e-purse, blk 2
354 memcpy(diversified_kd
, emulator
+ (8 * 3), 8); // Kd, blk 3
355 memcpy(diversified_kc
, emulator
+ (8 * 4), 8); // Kc, blk 4
357 // (iceman) this only works for 2KS / 16KS tags.
358 // Use application data from block 5
359 memcpy(aia_data
, emulator
+ (8 * 5), 8);
362 AddCrc(conf_block
, 8);
365 // set epurse of sim2,4 attack
366 if (reader_mac_buf
!= NULL
) {
367 memcpy(reader_mac_buf
, card_challenge_data
, 8);
370 if ((conf_block
[5] & 0x80) == 0x80) {
375 // When the page is in personalization mode this bit is equal to 1.
376 // Once the application issuer has personalized and coded its dedicated areas, this bit must be set to 0:
377 // the page is then "in application mode".
378 bool personalization_mode
= conf_block
[7] & 0x80;
380 uint8_t block_wr_lock
= conf_block
[3];
382 // chip memory may be divided in 8 pages
383 uint8_t max_page
= ((conf_block
[4] & 0x10) == 0x10) ? 0 : 7;
385 // pre-calculate the cipher states, feeding it the CC
386 cipher_state_KD
[0] = opt_doTagMAC_1(card_challenge_data
, diversified_kd
);
387 cipher_state_KC
[0] = opt_doTagMAC_1(card_challenge_data
, diversified_kc
);
389 if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
391 for (int i
= 1; i
< max_page
; i
++) {
393 uint8_t *epurse
= emulator
+ (i
* page_size
) + (8 * 2);
394 uint8_t *kd
= emulator
+ (i
* page_size
) + (8 * 3);
395 uint8_t *kc
= emulator
+ (i
* page_size
) + (8 * 4);
397 cipher_state_KD
[i
] = opt_doTagMAC_1(epurse
, kd
);
398 cipher_state_KC
[i
] = opt_doTagMAC_1(epurse
, kc
);
402 // Anti-collision process:
407 // Reader 81 anticoll. CSN
410 uint8_t *modulated_response
= NULL
;
411 int modulated_response_size
;
412 uint8_t *trace_data
= NULL
;
415 // Respond SOF -- takes 1 bytes
416 uint8_t *resp_sof
= BigBuf_malloc(1);
419 // Anticollision CSN (rotated CSN)
420 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
421 uint8_t *resp_anticoll
= BigBuf_malloc(22);
422 int resp_anticoll_len
;
425 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
426 uint8_t *resp_csn
= BigBuf_malloc(22);
429 // configuration (blk 1) PICOPASS 2ks
430 uint8_t *resp_conf
= BigBuf_malloc(22);
434 // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
435 uint8_t *resp_cc
= BigBuf_malloc(18);
438 // Kd, Kc (blocks 3 and 4). Cannot be read. Always respond with 0xff bytes only
439 uint8_t *resp_ff
= BigBuf_malloc(22);
441 uint8_t ff_data
[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00};
444 // Application Issuer Area (blk 5)
445 uint8_t *resp_aia
= BigBuf_malloc(22);
449 uint8_t *receivedCmd
= BigBuf_malloc(MAX_FRAME_SIZE
);
451 // Prepare card messages
452 tosend_t
*ts
= get_tosend();
454 // First card answer: SOF
456 memcpy(resp_sof
, ts
->buf
, ts
->max
);
457 resp_sof_len
= ts
->max
;
460 CodeIso15693AsTag(anticoll_data
, sizeof(anticoll_data
));
461 memcpy(resp_anticoll
, ts
->buf
, ts
->max
);
462 resp_anticoll_len
= ts
->max
;
465 CodeIso15693AsTag(csn_data
, sizeof(csn_data
));
466 memcpy(resp_csn
, ts
->buf
, ts
->max
);
467 resp_csn_len
= ts
->max
;
469 // Configuration (block 1)
470 CodeIso15693AsTag(conf_block
, sizeof(conf_block
));
471 memcpy(resp_conf
, ts
->buf
, ts
->max
);
472 resp_conf_len
= ts
->max
;
475 CodeIso15693AsTag(card_challenge_data
, sizeof(card_challenge_data
));
476 memcpy(resp_cc
, ts
->buf
, ts
->max
);
477 resp_cc_len
= ts
->max
;
479 // Kd, Kc (blocks 3 and 4)
480 CodeIso15693AsTag(ff_data
, sizeof(ff_data
));
481 memcpy(resp_ff
, ts
->buf
, ts
->max
);
482 resp_ff_len
= ts
->max
;
484 // Application Issuer Area (block 5)
485 CodeIso15693AsTag(aia_data
, sizeof(aia_data
));
486 memcpy(resp_aia
, ts
->buf
, ts
->max
);
487 resp_aia_len
= ts
->max
;
489 //This is used for responding to READ-block commands or other data which is dynamically generated
490 //First the 'trace'-data, not encoded for FPGA
491 uint8_t *data_generic_trace
= BigBuf_malloc(34); // 32 bytes data + 2byte CRC is max tag answer
493 //Then storage for the modulated data
494 //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes)
495 uint8_t *data_response
= BigBuf_malloc((34 * 2) + 3);
497 enum { IDLE
, ACTIVATED
, SELECTED
, HALTED
} chip_state
= IDLE
;
499 bool button_pressed
= false;
500 uint8_t cmd
, options
, block
;
501 int len
, kc_attempt
= 0;
502 bool exit_loop
= false;
503 bool using_kc
= false;
505 while (exit_loop
== false) {
508 // Now look at the reader command and provide appropriate responses
509 // default is no response:
510 modulated_response
= NULL
;
511 modulated_response_size
= 0;
515 uint32_t reader_eof_time
= 0;
516 len
= GetIso15693CommandFromReader(receivedCmd
, MAX_FRAME_SIZE
, &reader_eof_time
);
518 button_pressed
= true;
523 // extra response data
524 cmd
= receivedCmd
[0] & 0xF;
525 options
= (receivedCmd
[0] >> 4) & 0xFF;
526 block
= receivedCmd
[1];
528 if (cmd
== ICLASS_CMD_ACTALL
&& len
== 1) { // 0x0A
529 // Reader in anti collision phase
530 modulated_response
= resp_sof
;
531 modulated_response_size
= resp_sof_len
;
532 chip_state
= ACTIVATED
;
535 } else if (cmd
== ICLASS_CMD_READ_OR_IDENTIFY
&& len
== 1) { // 0x0C
536 // Reader asks for anti collision CSN
537 if (chip_state
== SELECTED
|| chip_state
== ACTIVATED
) {
538 modulated_response
= resp_anticoll
;
539 modulated_response_size
= resp_anticoll_len
;
540 trace_data
= anticoll_data
;
541 trace_data_size
= sizeof(anticoll_data
);
545 } else if (cmd
== ICLASS_CMD_SELECT
&& len
== 9) {
546 // Reader selects anticollision CSN.
547 // Tag sends the corresponding real CSN
548 if (chip_state
== ACTIVATED
|| chip_state
== SELECTED
) {
549 if (!memcmp(receivedCmd
+ 1, anticoll_data
, 8)) {
550 modulated_response
= resp_csn
;
551 modulated_response_size
= resp_csn_len
;
552 trace_data
= csn_data
;
553 trace_data_size
= sizeof(csn_data
);
554 chip_state
= SELECTED
;
558 } else if (chip_state
== HALTED
|| chip_state
== IDLE
) {
560 if (!memcmp(receivedCmd
+ 1, csn_data
, 8)) {
561 modulated_response
= resp_csn
;
562 modulated_response_size
= resp_csn_len
;
563 trace_data
= csn_data
;
564 trace_data_size
= sizeof(csn_data
);
565 chip_state
= SELECTED
;
571 } else if (cmd
== ICLASS_CMD_READ_OR_IDENTIFY
&& len
== 4) { // 0x0C
573 if (chip_state
!= SELECTED
) {
576 if (simulationMode
== ICLASS_SIM_MODE_EXIT_AFTER_MAC
) {
577 // provide defaults for blocks 0 ... 5
579 // block0,1,2,5 is always readable.
581 case 0: { // csn (0c 00)
582 modulated_response
= resp_csn
;
583 modulated_response_size
= resp_csn_len
;
584 trace_data
= csn_data
;
585 trace_data_size
= sizeof(csn_data
);
588 case 1: { // configuration (0c 01)
589 modulated_response
= resp_conf
;
590 modulated_response_size
= resp_conf_len
;
591 trace_data
= conf_block
;
592 trace_data_size
= sizeof(conf_block
);
595 case 2: {// e-purse (0c 02)
596 modulated_response
= resp_cc
;
597 modulated_response_size
= resp_cc_len
;
598 trace_data
= card_challenge_data
;
599 trace_data_size
= sizeof(card_challenge_data
);
600 // set epurse of sim2,4 attack
601 if (reader_mac_buf
!= NULL
) {
602 memcpy(reader_mac_buf
, card_challenge_data
, 8);
607 case 4: { // Kd, Kc, always respond with 0xff bytes
608 modulated_response
= resp_ff
;
609 modulated_response_size
= resp_ff_len
;
610 trace_data
= ff_data
;
611 trace_data_size
= sizeof(ff_data
);
614 case 5: { // Application Issuer Area (0c 05)
615 modulated_response
= resp_aia
;
616 modulated_response_size
= resp_aia_len
;
617 trace_data
= aia_data
;
618 trace_data_size
= sizeof(aia_data
);
622 } else if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
623 if (block
== 3 || block
== 4) { // Kd, Kc, always respond with 0xff bytes
624 modulated_response
= resp_ff
;
625 modulated_response_size
= resp_ff_len
;
626 trace_data
= ff_data
;
627 trace_data_size
= sizeof(ff_data
);
628 } else { // use data from emulator memory
629 memcpy(data_generic_trace
, emulator
+ (current_page
* page_size
) + (block
* 8), 8);
630 AddCrc(data_generic_trace
, 8);
631 trace_data
= data_generic_trace
;
632 trace_data_size
= 10;
633 CodeIso15693AsTag(trace_data
, trace_data_size
);
634 memcpy(data_response
, ts
->buf
, ts
->max
);
635 modulated_response
= data_response
;
636 modulated_response_size
= ts
->max
;
641 } else if (cmd
== ICLASS_CMD_READCHECK
&& block
== 0x02 && len
== 2) { // 0x88
642 // Read e-purse KD (88 02) KC (18 02)
643 if (chip_state
!= SELECTED
) {
648 if (receivedCmd
[0] == 0x88) {
649 cipher_state
= &cipher_state_KD
[current_page
];
650 diversified_key
= diversified_kd
;
653 cipher_state
= &cipher_state_KC
[current_page
];
654 diversified_key
= diversified_kc
;
658 modulated_response
= resp_cc
;
659 modulated_response_size
= resp_cc_len
;
660 trace_data
= card_challenge_data
;
661 trace_data_size
= sizeof(card_challenge_data
);
664 } else if (cmd
== ICLASS_CMD_CHECK
&& len
== 9) { // 0x05
666 // Reader random and reader MAC!!!
667 if (chip_state
!= SELECTED
) {
671 if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
672 // NR, from reader, is in receivedCmd +1
673 opt_doTagMAC_2(*cipher_state
, receivedCmd
+ 1, data_generic_trace
, diversified_key
);
676 uint8_t _mac[4] = {0};
677 opt_doReaderMAC_2(*cipher_state, receivedCmd + 1, _mac, diversified_key);
679 if (_mac[0] != receivedCmd[5] || _mac[1] != receivedCmd[6] || _mac[2] != receivedCmd[7] || _mac[3] != receivedCmd[8]) {
680 Dbprintf("reader auth " _RED_("failed"));
681 Dbprintf("hf iclass lookup --csn %02x%02x%02x%02x%02x%02x%02x%02x --epurse %02x%02x%02x%02x%02x%02x%02x%02x --macs %02x%02x%02x%02x%02x%02x%02x%02x f iclass_default_keys.dic",
682 csn_data[0], csn_data[1], csn_data[2], csn_data[3], csn_data[4], csn_data[5], csn_data[6], csn_data[7],
683 card_challenge_data[0], card_challenge_data[1], card_challenge_data[2], card_challenge_data[3],
684 card_challenge_data[4], card_challenge_data[5], card_challenge_data[6], card_challenge_data[7],
685 receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4],
686 receivedCmd[5], receivedCmd[6], receivedCmd[7], receivedCmd[8]
693 trace_data
= data_generic_trace
;
695 CodeIso15693AsTag(trace_data
, trace_data_size
);
696 memcpy(data_response
, ts
->buf
, ts
->max
);
697 modulated_response
= data_response
;
698 modulated_response_size
= ts
->max
;
704 // Not fullsim, we don't respond
707 if (simulationMode
== ICLASS_SIM_MODE_EXIT_AFTER_MAC
) {
709 if (DBGLEVEL
== DBG_EXTENDED
) {
710 Dbprintf("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]);
711 Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x", len
,
712 receivedCmd
[0], receivedCmd
[1], receivedCmd
[2],
713 receivedCmd
[3], receivedCmd
[4], receivedCmd
[5],
714 receivedCmd
[6], receivedCmd
[7], receivedCmd
[8]);
716 Dbprintf("CSN: %02x .... %02x OK", csn
[0], csn
[7]);
718 if (reader_mac_buf
!= NULL
) {
719 // save NR and MAC for sim 2,4
720 memcpy(reader_mac_buf
+ 8, receivedCmd
+ 1, 8);
727 } else if (cmd
== ICLASS_CMD_HALT
&& options
== 0 && len
== 1) {
729 if (chip_state
!= SELECTED
) {
732 // Reader ends the session
733 modulated_response
= resp_sof
;
734 modulated_response_size
= resp_sof_len
;
738 } else if (simulationMode
== ICLASS_SIM_MODE_FULL
&& cmd
== ICLASS_CMD_READ4
&& len
== 4) { // 0x06
740 if (chip_state
!= SELECTED
) {
744 memcpy(data_generic_trace
, emulator
+ (current_page
* page_size
) + (block
* 8), 32);
745 AddCrc(data_generic_trace
, 32);
746 trace_data
= data_generic_trace
;
747 trace_data_size
= 34;
748 CodeIso15693AsTag(trace_data
, trace_data_size
);
749 memcpy(data_response
, ts
->buf
, ts
->max
);
750 modulated_response
= data_response
;
751 modulated_response_size
= ts
->max
;
754 } else if (cmd
== ICLASS_CMD_UPDATE
&& (len
== 12 || len
== 14)) {
756 // We're expected to respond with the data+crc, exactly what's already in the receivedCmd
757 // receivedCmd is now UPDATE 1b | ADDRESS 1b | DATA 8b | Signature 4b or CRC 2b
758 if (chip_state
!= SELECTED
) {
761 // is chip in ReadOnly (RO)
762 if ((block_wr_lock
& 0x80) == 0) goto send
;
764 if (block
== 12 && (block_wr_lock
& 0x40) == 0) goto send
;
765 if (block
== 11 && (block_wr_lock
& 0x20) == 0) goto send
;
766 if (block
== 10 && (block_wr_lock
& 0x10) == 0) goto send
;
767 if (block
== 9 && (block_wr_lock
& 0x08) == 0) goto send
;
768 if (block
== 8 && (block_wr_lock
& 0x04) == 0) goto send
;
769 if (block
== 7 && (block_wr_lock
& 0x02) == 0) goto send
;
770 if (block
== 6 && (block_wr_lock
& 0x01) == 0) goto send
;
772 if (block
== 2) { // update e-purse
773 memcpy(card_challenge_data
, receivedCmd
+ 2, 8);
774 CodeIso15693AsTag(card_challenge_data
, sizeof(card_challenge_data
));
775 memcpy(resp_cc
, ts
->buf
, ts
->max
);
776 resp_cc_len
= ts
->max
;
777 cipher_state_KD
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_kd
);
778 cipher_state_KC
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_kc
);
779 if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
780 memcpy(emulator
+ (current_page
* page_size
) + (8 * 2), card_challenge_data
, 8);
782 } else if (block
== 3) { // update Kd
783 for (int i
= 0; i
< 8; i
++) {
784 if (personalization_mode
) {
785 diversified_kd
[i
] = receivedCmd
[2 + i
];
787 diversified_kd
[i
] ^= receivedCmd
[2 + i
];
790 cipher_state_KD
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_kd
);
791 if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
792 memcpy(emulator
+ (current_page
* page_size
) + (8 * 3), diversified_kd
, 8);
794 } else if (block
== 4) { // update Kc
795 for (int i
= 0; i
< 8; i
++) {
796 if (personalization_mode
) {
797 diversified_kc
[i
] = receivedCmd
[2 + i
];
799 diversified_kc
[i
] ^= receivedCmd
[2 + i
];
802 cipher_state_KC
[current_page
] = opt_doTagMAC_1(card_challenge_data
, diversified_kc
);
803 if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
804 memcpy(emulator
+ (current_page
* page_size
) + (8 * 4), diversified_kc
, 8);
806 } else if (simulationMode
== ICLASS_SIM_MODE_FULL
) {
807 // update emulator memory
808 memcpy(emulator
+ (current_page
* page_size
) + (8 * block
), receivedCmd
+ 2, 8);
811 memcpy(data_generic_trace
, receivedCmd
+ 2, 8);
812 AddCrc(data_generic_trace
, 8);
813 trace_data
= data_generic_trace
;
814 trace_data_size
= 10;
815 CodeIso15693AsTag(trace_data
, trace_data_size
);
816 memcpy(data_response
, ts
->buf
, ts
->max
);
817 modulated_response
= data_response
;
818 modulated_response_size
= ts
->max
;
821 } else if (cmd
== ICLASS_CMD_PAGESEL
&& len
== 4) { // 0x84
823 // - enables to select a page in the selected chip memory and return its configuration block
824 // Chips with a single page will not answer to this command
825 // Otherwise, we should answer 8bytes (conf block 1) + 2bytes CRC
826 if (chip_state
!= SELECTED
) {
830 if (simulationMode
== ICLASS_SIM_MODE_FULL
&& max_page
> 0) {
832 // if on 2k, always ignore 3msb, & 0x1F)
833 uint8_t page
= receivedCmd
[1] & 0x1F;
834 if (page
> max_page
) {
840 memcpy(data_generic_trace
, emulator
+ (current_page
* page_size
) + (8 * 1), 8);
841 memcpy(diversified_kd
, emulator
+ (current_page
* page_size
) + (8 * 3), 8);
842 memcpy(diversified_kc
, emulator
+ (current_page
* page_size
) + (8 * 4), 8);
844 cipher_state
= &cipher_state_KD
[current_page
];
846 personalization_mode
= data_generic_trace
[7] & 0x80;
847 block_wr_lock
= data_generic_trace
[3];
849 AddCrc(data_generic_trace
, 8);
851 trace_data
= data_generic_trace
;
852 trace_data_size
= 10;
854 CodeIso15693AsTag(trace_data
, trace_data_size
);
855 memcpy(data_response
, ts
->buf
, ts
->max
);
856 modulated_response
= data_response
;
857 modulated_response_size
= ts
->max
;
861 } else if (cmd
== ICLASS_CMD_DETECT
) { // 0x0F
862 // not supported yet, ignore
863 // } else if (cmd == 0x26 && len == 5) {
864 // standard ISO15693 INVENTORY command. Ignore.
866 // Never seen this command before
867 if (DBGLEVEL
>= DBG_EXTENDED
)
868 print_result("Unhandled command received ", receivedCmd
, len
);
873 A legit tag has about 330us delay between reader EOT and tag SOF.
875 if (modulated_response_size
> 0) {
876 uint32_t response_time
= reader_eof_time
+ DELAY_ICLASS_VCD_TO_VICC_SIM
;
877 TransmitTo15693Reader(modulated_response
, modulated_response_size
, &response_time
, 0, false);
878 LogTrace_ISO15693(trace_data
, trace_data_size
, response_time
* 32, (response_time
* 32) + (modulated_response_size
* 32 * 64), NULL
, false);
881 if (chip_state
== HALTED
) {
882 uint32_t wait_time
= GetCountSspClk() + ICLASS_READER_TIMEOUT_ACTALL
;
883 while (GetCountSspClk() < wait_time
) {};
887 // wait to trigger the reader bug, then wait 1000ms
888 if (kc_attempt
> 3) {
889 uint32_t wait_time
= GetCountSspClk() + (16000 * 100);
890 while (GetCountSspClk() < wait_time
) {};
899 DbpString("button pressed");
901 return button_pressed
;
904 int do_iclass_simulation_nonsec(void) {
905 // free eventually allocated BigBuf memory
906 BigBuf_free_keep_EM();
908 uint16_t page_size
= 32 * 8;
909 uint8_t current_page
= 0;
911 uint8_t *emulator
= BigBuf_get_EM_addr();
912 uint8_t *csn
= emulator
;
914 // CSN followed by two CRC bytes
915 uint8_t anticoll_data
[10] = { 0 };
916 uint8_t csn_data
[10] = { 0 };
917 memcpy(csn_data
, csn
, sizeof(csn_data
));
919 // Construct anticollision-CSN
920 rotateCSN(csn_data
, anticoll_data
);
922 // Compute CRC on both CSNs
923 AddCrc(anticoll_data
, 8);
926 // configuration block
927 uint8_t conf_block
[10] = {0x12, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xFF, 0x3C, 0x00, 0x00};
930 uint8_t aia_data
[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00};
932 memcpy(conf_block
, emulator
+ (8 * 1), 8);
933 memcpy(aia_data
, emulator
+ (8 * 2), 8);
935 AddCrc(conf_block
, 8);
938 if ((conf_block
[5] & 0x80) == 0x80) {
942 // chip memory may be divided in 8 pages
943 uint8_t max_page
= ((conf_block
[4] & 0x10) == 0x10) ? 0 : 7;
945 // Anti-collision process:
950 // Reader 81 anticoll. CSN
953 uint8_t *modulated_response
= NULL
;
954 int modulated_response_size
= 0;
955 uint8_t *trace_data
= NULL
;
956 int trace_data_size
= 0;
958 // Respond SOF -- takes 1 bytes
959 uint8_t *resp_sof
= BigBuf_malloc(2);
962 // Anticollision CSN (rotated CSN)
963 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
964 uint8_t *resp_anticoll
= BigBuf_malloc(28);
965 int resp_anticoll_len
;
968 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
969 uint8_t *resp_csn
= BigBuf_malloc(28);
972 // configuration (blk 1) PICOPASS 2ks
973 uint8_t *resp_conf
= BigBuf_malloc(28);
976 // Application Issuer Area (blk 5)
977 uint8_t *resp_aia
= BigBuf_malloc(28);
981 uint8_t *receivedCmd
= BigBuf_malloc(MAX_FRAME_SIZE
);
983 // Prepare card messages
984 tosend_t
*ts
= get_tosend();
987 // First card answer: SOF
989 memcpy(resp_sof
, ts
->buf
, ts
->max
);
990 resp_sof_len
= ts
->max
;
993 CodeIso15693AsTag(anticoll_data
, sizeof(anticoll_data
));
994 memcpy(resp_anticoll
, ts
->buf
, ts
->max
);
995 resp_anticoll_len
= ts
->max
;
998 CodeIso15693AsTag(csn_data
, sizeof(csn_data
));
999 memcpy(resp_csn
, ts
->buf
, ts
->max
);
1000 resp_csn_len
= ts
->max
;
1002 // Configuration (block 1)
1003 CodeIso15693AsTag(conf_block
, sizeof(conf_block
));
1004 memcpy(resp_conf
, ts
->buf
, ts
->max
);
1005 resp_conf_len
= ts
->max
;
1007 // Application Issuer Area (block 2)
1008 CodeIso15693AsTag(aia_data
, sizeof(aia_data
));
1009 memcpy(resp_aia
, ts
->buf
, ts
->max
);
1010 resp_aia_len
= ts
->max
;
1012 //This is used for responding to READ-block commands or other data which is dynamically generated
1013 //First the 'trace'-data, not encoded for FPGA
1014 uint8_t *data_generic_trace
= BigBuf_malloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer
1016 //Then storage for the modulated data
1017 //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes)
1018 uint8_t *data_response
= BigBuf_malloc((32 + 2) * 2 + 2);
1020 enum { IDLE
, ACTIVATED
, SELECTED
, HALTED
} chip_state
= IDLE
;
1022 bool button_pressed
= false;
1023 uint8_t cmd
, options
, block
;
1026 bool exit_loop
= false;
1027 while (exit_loop
== false) {
1030 uint32_t reader_eof_time
= 0;
1031 len
= GetIso15693CommandFromReader(receivedCmd
, MAX_FRAME_SIZE
, &reader_eof_time
);
1033 button_pressed
= true;
1038 // Now look at the reader command and provide appropriate responses
1039 // default is no response:
1040 modulated_response
= NULL
;
1041 modulated_response_size
= 0;
1043 trace_data_size
= 0;
1045 // extra response data
1046 cmd
= receivedCmd
[0] & 0xF;
1047 options
= (receivedCmd
[0] >> 4) & 0xFF;
1048 block
= receivedCmd
[1];
1050 if (cmd
== ICLASS_CMD_ACTALL
&& len
== 1) { // 0x0A
1051 // Reader in anti collision phase
1052 if (chip_state
!= HALTED
) {
1053 modulated_response
= resp_sof
;
1054 modulated_response_size
= resp_sof_len
;
1055 chip_state
= ACTIVATED
;
1059 } else if (cmd
== ICLASS_CMD_READ_OR_IDENTIFY
&& len
== 1) { // 0x0C
1060 // Reader asks for anti collision CSN
1061 if (chip_state
== SELECTED
|| chip_state
== ACTIVATED
) {
1062 modulated_response
= resp_anticoll
;
1063 modulated_response_size
= resp_anticoll_len
;
1064 trace_data
= anticoll_data
;
1065 trace_data_size
= sizeof(anticoll_data
);
1069 } else if (cmd
== ICLASS_CMD_SELECT
&& len
== 9) {
1070 // Reader selects anticollision CSN.
1071 // Tag sends the corresponding real CSN
1072 if (chip_state
== ACTIVATED
|| chip_state
== SELECTED
) {
1073 if (!memcmp(receivedCmd
+ 1, anticoll_data
, 8)) {
1074 modulated_response
= resp_csn
;
1075 modulated_response_size
= resp_csn_len
;
1076 trace_data
= csn_data
;
1077 trace_data_size
= sizeof(csn_data
);
1078 chip_state
= SELECTED
;
1082 } else if (chip_state
== HALTED
) {
1083 // RESELECT with CSN
1084 if (!memcmp(receivedCmd
+ 1, csn_data
, 8)) {
1085 modulated_response
= resp_csn
;
1086 modulated_response_size
= resp_csn_len
;
1087 trace_data
= csn_data
;
1088 trace_data_size
= sizeof(csn_data
);
1089 chip_state
= SELECTED
;
1095 } else if (cmd
== ICLASS_CMD_READ_OR_IDENTIFY
&& len
== 4) { // 0x0C
1097 if (chip_state
!= SELECTED
) {
1102 case 0: { // csn (0c 00)
1103 modulated_response
= resp_csn
;
1104 modulated_response_size
= resp_csn_len
;
1105 trace_data
= csn_data
;
1106 trace_data_size
= sizeof(csn_data
);
1109 case 1: { // configuration (0c 01)
1110 modulated_response
= resp_conf
;
1111 modulated_response_size
= resp_conf_len
;
1112 trace_data
= conf_block
;
1113 trace_data_size
= sizeof(conf_block
);
1116 case 2: { // Application Issuer Area (0c 02)
1117 modulated_response
= resp_aia
;
1118 modulated_response_size
= resp_aia_len
;
1119 trace_data
= aia_data
;
1120 trace_data_size
= sizeof(aia_data
);
1124 memcpy(data_generic_trace
, emulator
+ (block
<< 3), 8);
1125 AddCrc(data_generic_trace
, 8);
1126 trace_data
= data_generic_trace
;
1127 trace_data_size
= 10;
1128 CodeIso15693AsTag(trace_data
, trace_data_size
);
1129 memcpy(data_response
, ts
->buf
, ts
->max
);
1130 modulated_response
= data_response
;
1131 modulated_response_size
= ts
->max
;
1136 } else if (cmd
== ICLASS_CMD_READCHECK
) { // 0x88
1139 } else if (cmd
== ICLASS_CMD_CHECK
&& len
== 9) { // 0x05
1142 } else if (cmd
== ICLASS_CMD_HALT
&& options
== 0 && len
== 1) {
1144 if (chip_state
!= SELECTED
) {
1147 // Reader ends the session
1148 modulated_response
= resp_sof
;
1149 modulated_response_size
= resp_sof_len
;
1150 chip_state
= HALTED
;
1153 } else if (cmd
== ICLASS_CMD_READ4
&& len
== 4) { // 0x06
1155 if (chip_state
!= SELECTED
) {
1159 memcpy(data_generic_trace
, emulator
+ (current_page
* page_size
) + (block
* 8), 8 * 4);
1160 AddCrc(data_generic_trace
, 8 * 4);
1161 trace_data
= data_generic_trace
;
1162 trace_data_size
= 34;
1163 CodeIso15693AsTag(trace_data
, trace_data_size
);
1164 memcpy(data_response
, ts
->buf
, ts
->max
);
1165 modulated_response
= data_response
;
1166 modulated_response_size
= ts
->max
;
1169 } else if (cmd
== ICLASS_CMD_UPDATE
&& (len
== 12 || len
== 14)) {
1171 // We're expected to respond with the data+crc, exactly what's already in the receivedCmd
1172 // receivedCmd is now UPDATE 1b | ADDRESS 1b | DATA 8b | Signature 4b or CRC 2b
1173 if (chip_state
!= SELECTED
) {
1177 // update emulator memory
1178 memcpy(emulator
+ (current_page
* page_size
) + (8 * block
), receivedCmd
+ 2, 8);
1180 memcpy(data_generic_trace
, receivedCmd
+ 2, 8);
1181 AddCrc(data_generic_trace
, 8);
1182 trace_data
= data_generic_trace
;
1183 trace_data_size
= 10;
1184 CodeIso15693AsTag(trace_data
, trace_data_size
);
1185 memcpy(data_response
, ts
->buf
, ts
->max
);
1186 modulated_response
= data_response
;
1187 modulated_response_size
= ts
->max
;
1190 } else if (cmd
== ICLASS_CMD_PAGESEL
&& len
== 4) { // 0x84
1192 // - enables to select a page in the selected chip memory and return its configuration block
1193 // Chips with a single page will not answer to this command
1194 // Otherwise, we should answer 8bytes (conf block 1) + 2bytes CRC
1195 if (chip_state
!= SELECTED
) {
1201 current_page
= receivedCmd
[1];
1203 memcpy(data_generic_trace
, emulator
+ (current_page
* page_size
) + (8 * 1), 8);
1204 AddCrc(data_generic_trace
, 8);
1205 trace_data
= data_generic_trace
;
1206 trace_data_size
= 10;
1208 CodeIso15693AsTag(trace_data
, trace_data_size
);
1209 memcpy(data_response
, ts
->buf
, ts
->max
);
1210 modulated_response
= data_response
;
1211 modulated_response_size
= ts
->max
;
1215 // } else if(cmd == ICLASS_CMD_DETECT) { // 0x0F
1216 // } else if (cmd == 0x26 && len == 5) {
1217 // standard ISO15693 INVENTORY command. Ignore.
1219 // Never seen this command before
1220 if (DBGLEVEL
>= DBG_EXTENDED
)
1221 print_result("Unhandled command received ", receivedCmd
, len
);
1226 A legit tag has about 330us delay between reader EOT and tag SOF.
1228 if (modulated_response_size
> 0) {
1229 uint32_t response_time
= reader_eof_time
+ DELAY_ICLASS_VCD_TO_VICC_SIM
;
1230 TransmitTo15693Reader(modulated_response
, modulated_response_size
, &response_time
, 0, false);
1231 LogTrace_ISO15693(trace_data
, trace_data_size
, response_time
* 32, (response_time
* 32) + (modulated_response_size
* 32 * 64), NULL
, false);
1238 DbpString("button pressed");
1240 return button_pressed
;
1245 static void iclass_send_as_reader(uint8_t *frame
, int len
, uint32_t *start_time
, uint32_t *end_time
) {
1246 CodeIso15693AsReader(frame
, len
);
1247 tosend_t
*ts
= get_tosend();
1248 TransmitTo15693Tag(ts
->buf
, ts
->max
, start_time
);
1249 *end_time
= *start_time
+ (32 * ((8 * ts
->max
) - 4)); // substract the 4 padding bits after EOF
1250 LogTrace_ISO15693(frame
, len
, (*start_time
* 4), (*end_time
* 4), NULL
, true);
1253 static bool iclass_send_cmd_with_retries(uint8_t *cmd
, size_t cmdsize
, uint8_t *resp
, size_t max_resp_size
,
1254 uint8_t expected_size
, uint8_t tries
, uint32_t *start_time
,
1255 uint16_t timeout
, uint32_t *eof_time
) {
1256 while (tries
-- > 0) {
1258 iclass_send_as_reader(cmd
, cmdsize
, start_time
, eof_time
);
1264 if (expected_size
== GetIso15693AnswerFromTag(resp
, max_resp_size
, timeout
, eof_time
)) {
1272 * @brief Talks to an iclass tag, sends the commands to get CSN and CC.
1273 * @param card_data where the CSN, CONFIG, CC are stored for return
1274 * 8 bytes csn + 8 bytes config + 8 bytes CC
1275 * @return false = fail
1278 static bool select_iclass_tag_ex(picopass_hdr_t
*hdr
, bool use_credit_key
, uint32_t *eof_time
, uint8_t *status
) {
1280 static uint8_t act_all
[] = { ICLASS_CMD_ACTALL
};
1281 static uint8_t identify
[] = { ICLASS_CMD_READ_OR_IDENTIFY
, 0x00, 0x73, 0x33 };
1282 static uint8_t read_conf
[] = { ICLASS_CMD_READ_OR_IDENTIFY
, 0x01, 0xfa, 0x22 };
1283 uint8_t select
[] = { 0x80 | ICLASS_CMD_SELECT
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1284 uint8_t read_aia
[] = { ICLASS_CMD_READ_OR_IDENTIFY
, 0x05, 0xde, 0x64};
1285 uint8_t read_check_cc
[] = { 0x80 | ICLASS_CMD_READCHECK
, 0x02 };
1286 uint8_t resp
[ICLASS_BUFFER_SIZE
] = {0};
1288 // Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) will be used
1291 read_check_cc
[0] = 0x10 | ICLASS_CMD_READCHECK
;
1294 uint32_t start_time
= GetCountSspClk();
1295 iclass_send_as_reader(act_all
, 1, &start_time
, eof_time
);
1296 int len
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_ACTALL
, eof_time
);
1301 start_time
= *eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1302 iclass_send_as_reader(identify
, 1, &start_time
, eof_time
);
1304 // expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
1305 len
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1309 // copy the Anti-collision CSN to our select-packet
1310 memcpy(&select
[1], resp
, 8);
1313 start_time
= *eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1314 iclass_send_as_reader(select
, sizeof(select
), &start_time
, eof_time
);
1316 // expect a 10-byte response here, 8 byte CSN and 2 byte CRC
1317 len
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1322 memcpy(hdr
->csn
, resp
, sizeof(hdr
->csn
));
1324 // card selected, now read config (block1) (only 8 bytes no CRC)
1325 start_time
= *eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1326 iclass_send_as_reader(read_conf
, sizeof(read_conf
), &start_time
, eof_time
);
1328 // expect a 8-byte response here
1329 len
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1334 memcpy((uint8_t *)&hdr
->conf
, resp
, sizeof(hdr
->conf
));
1337 *status
|= (FLAG_ICLASS_CSN
| FLAG_ICLASS_CONF
);
1339 uint8_t pagemap
= get_pagemap(hdr
);
1340 if (pagemap
!= PICOPASS_NON_SECURE_PAGEMODE
) {
1342 // read App Issuer Area block 5
1343 start_time
= *eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1344 iclass_send_as_reader(read_aia
, sizeof(read_aia
), &start_time
, eof_time
);
1346 // expect a 10-byte response here
1347 len
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1352 *status
|= FLAG_ICLASS_AIA
;
1353 memcpy(hdr
->app_issuer_area
, resp
, sizeof(hdr
->app_issuer_area
));
1356 // card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
1357 start_time
= *eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1358 iclass_send_as_reader(read_check_cc
, sizeof(read_check_cc
), &start_time
, eof_time
);
1360 // expect a 8-byte response here
1361 len
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1365 memcpy(hdr
->epurse
, resp
, sizeof(hdr
->epurse
));
1368 *status
|= FLAG_ICLASS_CC
;
1372 // on NON_SECURE_PAGEMODE cards, AIA is on block2..
1374 // read App Issuer Area block 2
1379 start_time
= *eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1380 iclass_send_as_reader(read_aia
, sizeof(read_aia
), &start_time
, eof_time
);
1382 // expect a 10-byte response here
1383 len
= GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1388 *status
|= FLAG_ICLASS_AIA
;
1389 memcpy(hdr
->epurse
, resp
, sizeof(hdr
->epurse
));
1396 bool select_iclass_tag(picopass_hdr_t
*hdr
, bool use_credit_key
, uint32_t *eof_time
) {
1398 return select_iclass_tag_ex(hdr
, use_credit_key
, eof_time
, &result
);
1401 // Reader iClass Anticollission
1402 // turn off afterwards
1403 void ReaderIClass(uint8_t flags
) {
1405 picopass_hdr_t hdr
= {0};
1406 // uint8_t last_csn[8] = {0, 0, 0, 0, 0, 0, 0, 0};
1407 uint8_t resp
[ICLASS_BUFFER_SIZE
] = {0};
1408 memset(resp
, 0xFF, sizeof(resp
));
1410 // bool flag_readonce = flags & FLAG_ICLASS_READER_ONLY_ONCE; // flag to read until one tag is found successfully
1411 bool use_credit_key
= flags
& FLAG_ICLASS_READER_CREDITKEY
; // flag to use credit key
1413 if ((flags
& FLAG_ICLASS_READER_INIT
) == FLAG_ICLASS_READER_INIT
) {
1414 Iso15693InitReader();
1417 if ((flags
& FLAG_ICLASS_READER_CLEARTRACE
) == FLAG_ICLASS_READER_CLEARTRACE
) {
1421 uint8_t result_status
= 0;
1422 uint32_t eof_time
= 0;
1423 bool status
= select_iclass_tag_ex(&hdr
, use_credit_key
, &eof_time
, &result_status
);
1424 if (status
== false) {
1425 reply_mix(CMD_ACK
, 0xFF, 0, 0, NULL
, 0);
1430 // Page mapping for secure mode
1432 // 1 : Configuration
1434 // 3 : kd / debit / aa2 (write-only)
1435 // 4 : kc / credit / aa1 (write-only)
1436 // 5 : AIA, Application issuer area
1438 // Page mapping for non secure mode
1440 // 1 : Configuration
1441 // 2 : AIA, Application issuer area
1443 // Return to client, e 6 * 8 bytes of data.
1444 // with 0xFF:s in block 3 and 4.
1447 reply_mix(CMD_ACK
, result_status
, 0, 0, (uint8_t *)&hdr
, sizeof(hdr
));
1449 //Send back to client, but don't bother if we already sent this -
1450 // only useful if looping in arm (not try_once && not abort_after_read)
1452 if (memcmp(last_csn, card_data, 8) != 0) {
1454 reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
1455 if (flag_readonce) {
1463 // if (userCancelled) {
1464 // reply_mix(CMD_ACK, 0xFF, 0, 0, card_data, 0);
1467 // reply_mix(CMD_ACK, result_status, 0, 0, card_data, 0);
1473 bool authenticate_iclass_tag(iclass_auth_req_t
*payload
, picopass_hdr_t
*hdr
, uint32_t *start_time
, uint32_t *eof_time
, uint8_t *mac_out
) {
1475 uint8_t cmd_check
[9] = { ICLASS_CMD_CHECK
};
1476 uint8_t mac
[4] = {0};
1477 uint8_t resp_auth
[4] = {0};
1478 uint8_t ccnr
[12] = {0};
1480 uint8_t *pmac
= mac
;
1484 memcpy(ccnr
, hdr
->epurse
, sizeof(hdr
->epurse
));
1486 if (payload
->use_replay
) {
1488 memcpy(pmac
, payload
->key
+ 4, 4);
1489 memcpy(cmd_check
+ 1, payload
->key
, 8);
1493 uint8_t div_key
[8] = {0};
1494 if (payload
->use_raw
)
1495 memcpy(div_key
, payload
->key
, 8);
1497 iclass_calc_div_key(hdr
->csn
, payload
->key
, div_key
, payload
->use_elite
);
1499 if (payload
->use_credit_key
)
1500 memcpy(hdr
->key_c
, div_key
, sizeof(hdr
->key_c
));
1502 memcpy(hdr
->key_d
, div_key
, sizeof(hdr
->key_d
));
1504 opt_doReaderMAC(ccnr
, div_key
, pmac
);
1506 // copy MAC to check command (readersignature)
1507 cmd_check
[5] = pmac
[0];
1508 cmd_check
[6] = pmac
[1];
1509 cmd_check
[7] = pmac
[2];
1510 cmd_check
[8] = pmac
[3];
1512 return iclass_send_cmd_with_retries(cmd_check
, sizeof(cmd_check
), resp_auth
, sizeof(resp_auth
), 4, 2, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1516 /* this function works on the following assumptions.
1517 * - one select first, to get CSN / CC (e-purse)
1518 * - calculate before diversified keys and precalc mac based on CSN/KEY.
1519 * - data in contains of diversified keys, mac
1520 * - key loop only test one type of authtication key. Ie two calls needed
1521 * to cover debit and credit key. (AA1/AA2)
1523 void iClass_Authentication_fast(iclass_chk_t
*p
) {
1526 reply_ng(CMD_HF_ICLASS_CHKKEYS
, PM3_ESOFT
, NULL
, 0);
1530 uint8_t check
[9] = { ICLASS_CMD_CHECK
};
1531 uint8_t resp
[ICLASS_BUFFER_SIZE
] = {0};
1532 uint8_t readcheck_cc
[] = { 0x80 | ICLASS_CMD_READCHECK
, 0x02 };
1534 if (p
->use_credit_key
)
1535 readcheck_cc
[0] = 0x10 | ICLASS_CMD_READCHECK
;
1537 // select card / e-purse
1538 picopass_hdr_t hdr
= {0};
1539 iclass_premac_t
*keys
= p
->items
;
1546 Iso15693InitReader();
1550 uint32_t start_time
= 0, eof_time
= 0;
1551 if (select_iclass_tag(&hdr
, p
->use_credit_key
, &eof_time
) == false)
1554 start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1556 // since select_iclass_tag call sends s readcheck, we start with sending first response.
1557 uint16_t checked
= 0;
1561 for (i
= 0; i
< p
->count
; i
++) {
1563 // Allow button press / usb cmd to interrupt device
1564 if (checked
== 1000) {
1565 if (BUTTON_PRESS() || data_available()) goto out
;
1573 // copy MAC to check command (readersignature)
1574 check
[5] = keys
[i
].mac
[0];
1575 check
[6] = keys
[i
].mac
[1];
1576 check
[7] = keys
[i
].mac
[2];
1577 check
[8] = keys
[i
].mac
[3];
1579 // expect 4bytes, 3 retries times..
1580 isOK
= iclass_send_cmd_with_retries(check
, sizeof(check
), resp
, sizeof(resp
), 4, 2, &start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
);
1584 start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1585 // Auth Sequence MUST begin with reading e-purse. (block2)
1586 // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
1587 iclass_send_as_reader(readcheck_cc
, sizeof(readcheck_cc
), &start_time
, &eof_time
);
1593 reply_ng(CMD_HF_ICLASS_CHKKEYS
, (isOK
) ? PM3_SUCCESS
: PM3_ESOFT
, (uint8_t *)&i
, sizeof(i
));
1597 // Tries to read block.
1599 // reply 8 bytes block
1600 bool iclass_read_block(uint16_t blockno
, uint8_t *data
, uint32_t *start_time
, uint32_t *eof_time
) {
1602 uint8_t c
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, blockno
, 0x00, 0x00};
1604 bool isOK
= iclass_send_cmd_with_retries(c
, sizeof(c
), resp
, sizeof(resp
), 10, 2, start_time
, ICLASS_READER_TIMEOUT_OTHERS
, eof_time
);
1606 memcpy(data
, resp
, 8);
1610 // turn off afterwards
1611 // send in authentication needed data, if to use auth.
1612 // reply 8 bytes block if send_reply (for client)
1613 void iClass_ReadBlock(uint8_t *msg
) {
1615 iclass_auth_req_t
*payload
= (iclass_auth_req_t
*)msg
;
1617 iclass_readblock_resp_t response
= { .isOK
= true };
1618 memset(response
.data
, 0, sizeof(response
.data
));
1620 uint8_t cmd_read
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, payload
->blockno
, 0x00, 0x00};
1621 AddCrc(cmd_read
+ 1, 1);
1623 Iso15693InitReader();
1626 uint32_t eof_time
= 0;
1627 picopass_hdr_t hdr
= {0};
1628 bool res
= select_iclass_tag(&hdr
, payload
->use_credit_key
, &eof_time
);
1630 if (payload
->send_reply
) {
1631 response
.isOK
= res
;
1632 reply_ng(CMD_HF_ICLASS_READBL
, PM3_ETIMEOUT
, (uint8_t *)&response
, sizeof(response
));
1637 uint32_t start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1640 if (payload
->do_auth
) {
1642 res
= authenticate_iclass_tag(payload
, &hdr
, &start_time
, &eof_time
, NULL
);
1644 if (payload
->send_reply
) {
1645 response
.isOK
= res
;
1646 reply_ng(CMD_HF_ICLASS_READBL
, PM3_ETIMEOUT
, (uint8_t *)&response
, sizeof(response
));
1652 start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1656 res
= iclass_send_cmd_with_retries(cmd_read
, sizeof(cmd_read
), resp
, sizeof(resp
), 10, 3, &start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
);
1658 memcpy(response
.data
, resp
, sizeof(response
.data
));
1659 if (payload
->send_reply
) {
1660 reply_ng(CMD_HF_ICLASS_READBL
, PM3_SUCCESS
, (uint8_t *)&response
, sizeof(response
));
1663 if (payload
->send_reply
) {
1664 response
.isOK
= res
;
1665 reply_ng(CMD_HF_ICLASS_READBL
, PM3_ETIMEOUT
, (uint8_t *)&response
, sizeof(response
));
1673 // Dump command seems to dump a block related portion of card memory.
1674 // I suppose it will need to do an authentatication to AA1, read its blocks by calling this.
1675 // then authenticate AA2, and read those blocks by calling this.
1676 // By the looks at it only 2K cards is supported, or first page dumps on larger cards.
1677 // turn off afterwards
1678 void iClass_Dump(uint8_t *msg
) {
1682 iclass_dump_req_t
*cmd
= (iclass_dump_req_t
*)msg
;
1683 iclass_auth_req_t
*req
= &cmd
->req
;
1685 uint8_t *dataout
= BigBuf_malloc(ICLASS_16KS_SIZE
);
1686 if (dataout
== NULL
) {
1687 DbpString("fail to allocate memory");
1688 if (req
->send_reply
) {
1689 reply_ng(CMD_HF_ICLASS_DUMP
, PM3_EMALLOC
, NULL
, 0);
1694 memset(dataout
, 0xFF, ICLASS_16KS_SIZE
);
1696 Iso15693InitReader();
1699 uint32_t eof_time
= 0;
1700 picopass_hdr_t hdr
= {0};
1701 memset(&hdr
, 0xff, sizeof(picopass_hdr_t
));
1703 bool res
= select_iclass_tag(&hdr
, req
->use_credit_key
, &eof_time
);
1705 if (req
->send_reply
) {
1706 reply_ng(CMD_HF_ICLASS_DUMP
, PM3_ETIMEOUT
, NULL
, 0);
1712 uint32_t start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1716 res
= authenticate_iclass_tag(req
, &hdr
, &start_time
, &eof_time
, NULL
);
1718 if (req
->send_reply
) {
1719 reply_ng(CMD_HF_ICLASS_DUMP
, PM3_ETIMEOUT
, NULL
, 0);
1726 start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1728 bool dumpsuccess
= true;
1732 for (i
= cmd
->start_block
; i
<= cmd
->end_block
; i
++) {
1735 uint8_t c
[] = {ICLASS_CMD_READ_OR_IDENTIFY
, i
, 0x00, 0x00};
1738 res
= iclass_send_cmd_with_retries(c
, sizeof(c
), resp
, sizeof(resp
), 10, 3, &start_time
, ICLASS_READER_TIMEOUT_OTHERS
, &eof_time
);
1740 memcpy(dataout
+ (8 * i
), resp
, 8);
1742 Dbprintf("failed to read block %u ( 0x%02x)", i
, i
);
1743 dumpsuccess
= false;
1749 // copy diversified key back.
1751 if (req
->use_credit_key
)
1752 memcpy(dataout
+ (8 * 4), hdr
.key_c
, 8);
1754 memcpy(dataout
+ (8 * 3), hdr
.key_d
, 8);
1757 if (req
->send_reply
) {
1764 response
.isOK
= dumpsuccess
;
1765 response
.block_cnt
= i
;
1766 response
.bb_offset
= dataout
- BigBuf_get_addr();
1767 reply_ng(CMD_HF_ICLASS_DUMP
, PM3_SUCCESS
, (uint8_t *)&response
, sizeof(response
));
1773 static bool iclass_writeblock_ext(uint8_t blockno
, uint8_t *data
, uint8_t *mac
, bool use_mac
) {
1775 // write command: cmd, 1 blockno, 8 data, 4 mac
1776 uint8_t write
[14] = { 0x80 | ICLASS_CMD_UPDATE
, blockno
};
1777 uint8_t write_len
= 14;
1778 memcpy(write
+ 2, data
, 8);
1781 memcpy(write
+ 10, mac
, 4);
1783 AddCrc(write
+ 1, 9);
1787 uint8_t resp
[10] = {0};
1788 uint32_t eof_time
= 0, start_time
= 0;
1789 bool isOK
= iclass_send_cmd_with_retries(write
, write_len
, resp
, sizeof(resp
), 10, 3, &start_time
, ICLASS_READER_TIMEOUT_UPDATE
, &eof_time
);
1790 if (isOK
== false) {
1794 uint8_t all_ff
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1796 // check response. e-purse update swaps first and second half
1797 if (memcmp(data
+ 4, resp
, 4) || memcmp(data
, resp
+ 4, 4)) {
1800 } else if (blockno
== 3 || blockno
== 4) {
1801 // check response. Key updates always return 0xffffffffffffffff
1802 if (memcmp(all_ff
, resp
, 8)) {
1806 // check response. All other updates return unchanged data
1807 if (memcmp(data
, resp
, 8)) {
1815 // turn off afterwards
1816 void iClass_WriteBlock(uint8_t *msg
) {
1820 iclass_writeblock_req_t
*payload
= (iclass_writeblock_req_t
*)msg
;
1822 uint8_t write
[14] = { 0x80 | ICLASS_CMD_UPDATE
, payload
->req
.blockno
};
1823 uint8_t write_len
= 14;
1825 Iso15693InitReader();
1828 uint32_t eof_time
= 0;
1829 picopass_hdr_t hdr
= {0};
1830 uint8_t res
= select_iclass_tag(&hdr
, payload
->req
.use_credit_key
, &eof_time
);
1835 uint32_t start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1837 uint8_t mac
[4] = {0};
1840 if (payload
->req
.do_auth
) {
1842 res
= authenticate_iclass_tag(&payload
->req
, &hdr
, &start_time
, &eof_time
, mac
);
1849 memcpy(write
+ 2, payload
->data
, 8);
1851 uint8_t pagemap
= get_pagemap(&hdr
);
1852 if (pagemap
== PICOPASS_NON_SECURE_PAGEMODE
) {
1853 // Unsecured tags uses CRC16, but don't include the UPDATE operation code
1854 // byte0 = update op
1856 // byte2..9 = new block data
1857 AddCrc(write
+ 1, 9);
1860 // Secure tags uses MAC
1862 wb
[0] = payload
->req
.blockno
;
1863 memcpy(wb
+ 1, payload
->data
, 8);
1865 if (payload
->req
.use_credit_key
)
1866 doMAC_N(wb
, sizeof(wb
), hdr
.key_c
, mac
);
1868 doMAC_N(wb
, sizeof(wb
), hdr
.key_d
, mac
);
1870 memcpy(write
+ 10, mac
, sizeof(mac
));
1873 start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1875 uint8_t resp
[10] = {0};
1878 while (tries
-- > 0) {
1880 iclass_send_as_reader(write
, write_len
, &start_time
, &eof_time
);
1882 if (tearoff_hook() == PM3_ETEAROFF
) { // tearoff occurred
1885 if (payload
->req
.send_reply
)
1886 reply_ng(CMD_HF_ICLASS_WRITEBL
, PM3_ETEAROFF
, (uint8_t *)&res
, sizeof(uint8_t));
1890 if (GetIso15693AnswerFromTag(resp
, sizeof(resp
), ICLASS_READER_TIMEOUT_UPDATE
, &eof_time
) == 10) {
1903 uint8_t all_ff
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1904 if (payload
->req
.blockno
== 2) {
1905 // check response. e-purse update swaps first and second half
1906 if (memcmp(payload
->data
+ 4, resp
, 4) || memcmp(payload
->data
, resp
+ 4, 4)) {
1910 } else if (payload
->req
.blockno
== 3 || payload
->req
.blockno
== 4) {
1911 // check response. Key updates always return 0xffffffffffffffff
1912 if (memcmp(all_ff
, resp
, 8)) {
1917 // check response. All other updates return unchanged data
1918 if (memcmp(payload
->data
, resp
, 8)) {
1927 if (payload
->req
.send_reply
)
1928 reply_ng(CMD_HF_ICLASS_WRITEBL
, PM3_SUCCESS
, (uint8_t *)&res
, sizeof(uint8_t));
1931 void iClass_Restore(iclass_restore_req_t
*msg
) {
1935 reply_ng(CMD_HF_ICLASS_RESTORE
, PM3_ESOFT
, NULL
, 0);
1939 if (msg
->item_cnt
== 0) {
1940 if (msg
->req
.send_reply
) {
1941 reply_ng(CMD_HF_ICLASS_RESTORE
, PM3_ESOFT
, NULL
, 0);
1947 Iso15693InitReader();
1949 uint16_t written
= 0;
1950 uint32_t eof_time
= 0;
1951 picopass_hdr_t hdr
= {0};
1954 bool res
= select_iclass_tag(&hdr
, msg
->req
.use_credit_key
, &eof_time
);
1960 uint8_t mac
[4] = {0};
1961 uint32_t start_time
= eof_time
+ DELAY_ICLASS_VICC_TO_VCD_READER
;
1964 if (msg
->req
.do_auth
) {
1965 res
= authenticate_iclass_tag(&msg
->req
, &hdr
, &start_time
, &eof_time
, mac
);
1973 for (uint8_t i
= 0; i
< msg
->item_cnt
; i
++) {
1975 iclass_restore_item_t item
= msg
->blocks
[i
];
1977 uint8_t pagemap
= get_pagemap(&hdr
);
1978 if (pagemap
== PICOPASS_NON_SECURE_PAGEMODE
) {
1979 // Unsecured tags uses CRC16
1982 // Secure tags uses MAC
1984 uint8_t wb
[9] = {0};
1985 wb
[0] = item
.blockno
;
1986 memcpy(wb
+ 1, item
.data
, 8);
1988 if (msg
->req
.use_credit_key
)
1989 doMAC_N(wb
, sizeof(wb
), hdr
.key_c
, mac
);
1991 doMAC_N(wb
, sizeof(wb
), hdr
.key_d
, mac
);
1995 if (iclass_writeblock_ext(item
.blockno
, item
.data
, mac
, use_mac
)) {
1996 Dbprintf("Write block [%3d/0x%02X] " _GREEN_("successful"), item
.blockno
, item
.blockno
);
1999 Dbprintf("Write block [%3d/0x%02X] " _RED_("failed"), item
.blockno
, item
.blockno
);
2006 if (msg
->req
.send_reply
) {
2007 int isOK
= (written
== msg
->item_cnt
) ? PM3_SUCCESS
: PM3_ESOFT
;
2008 reply_ng(CMD_HF_ICLASS_RESTORE
, isOK
, NULL
, 0);