hf seos - added the skeleton for future use
[RRG-proxmark3.git] / armsrc / iclass.c
blob55c479235ae4625134498a36a92ab09b5d291539
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
6 // piwi - 2019
7 //
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
10 // the license.
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 //-----------------------------------------------------------------------------
18 #include "iclass.h"
20 #include "proxmark3_arm.h"
21 #include "cmd.h"
22 // Needed for CRC in emulation mode;
23 // same construction as in ISO 14443;
24 // different initial value (CRC_ICLASS)
25 #include "crc16.h"
26 #include "optimized_cipher.h"
28 #include "appmain.h"
29 #include "BigBuf.h"
30 #include "fpgaloader.h"
31 #include "string.h"
32 #include "util.h"
33 #include "dbprint.h"
34 #include "protocols.h"
35 #include "ticks.h"
36 #include "iso15693.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
46 #endif
48 #ifndef ICLASS_16KS_SIZE
49 #define ICLASS_16KS_SIZE 0x100 * 8
50 #endif
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)
70 * CARD TO READER
71 * in ISO15693-2 mode - Manchester
72 * in ISO 14443b - BPSK coding
74 * Timings:
75 * ISO 15693-2
76 * Tout = 330 µs, Tprog 1 = 4 to 15 ms, Tslot = 330 µs + (number of slots x 160 µs)
77 * ISO 14443a
78 * Tout = 100 µs, Tprog = 4 to 15 ms, Tslot = 100 µs+ (number of slots x 80 µs)
79 * ISO 14443b
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);
100 // Encode SOF only
101 static void CodeIClassTagSOF(void) {
102 tosend_reset();
103 tosend_t *ts = get_tosend();
104 ts->buf[++ts->max] = 0x1D;
105 ts->max++;
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
118 * time of 18.88us.
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,
130 * works like this.
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
134 * In this mode
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)
152 * @param arg2
153 * @param datain
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) {
162 LEDsoff();
164 Iso15693InitTag();
166 clear_trace();
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) {
181 //Default CSN
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
194 int i = 0;
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)) {
201 if (dataoutlen)
202 *dataoutlen = i * EPURSE_MAC_SIZE;
204 // Button pressed
205 if (send_reply)
206 reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE);
207 goto out;
210 if (dataoutlen)
211 *dataoutlen = i * EPURSE_MAC_SIZE;
213 if (send_reply)
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();
224 } else {
225 do_iclass_simulation(ICLASS_SIM_MODE_FULL, NULL);
228 } else if (sim_type == ICLASS_SIM_MODE_CONFIG_CARD) {
230 // config card
231 do_iclass_simulation(ICLASS_SIM_MODE_FULL, NULL);
232 // swap bin
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.
247 int i = 0;
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);
253 // keyroll 1
254 if (do_iclass_simulation(ICLASS_SIM_MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE)) {
256 if (dataoutlen)
257 *dataoutlen = i * EPURSE_MAC_SIZE * 2;
259 if (send_reply)
260 reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
262 // Button pressed
263 goto out;
266 // keyroll 2
267 if (do_iclass_simulation(ICLASS_SIM_MODE_EXIT_AFTER_MAC, mac_responses + (i + num_csns) * EPURSE_MAC_SIZE)) {
269 if (dataoutlen)
270 *dataoutlen = i * EPURSE_MAC_SIZE * 2;
272 if (send_reply)
273 reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
275 // Button pressed
276 goto out;
280 if (dataoutlen)
281 *dataoutlen = i * EPURSE_MAC_SIZE * 2;
283 // double the amount of collected data.
284 if (send_reply)
285 reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
287 } else {
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");
293 out:
294 if (dataout && dataoutlen)
295 memcpy(dataout, mac_responses, *dataoutlen);
297 switch_off();
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);
335 AddCrc(csn_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};
344 // e-Purse
345 uint8_t card_challenge_data[8] = { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
347 // AIA
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);
363 AddCrc(aia_data, 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) {
371 page_size = 256 * 8;
374 // From PicoPass DS:
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:
403 // Reader 0a
404 // Tag 0f
405 // Reader 0c
406 // Tag anticoll. CSN
407 // Reader 81 anticoll. CSN
408 // Tag CSN
410 uint8_t *modulated_response = NULL;
411 int modulated_response_size;
412 uint8_t *trace_data = NULL;
413 int trace_data_size;
415 // Respond SOF -- takes 1 bytes
416 uint8_t *resp_sof = BigBuf_malloc(1);
417 int resp_sof_len;
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;
424 // CSN (block 0)
425 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
426 uint8_t *resp_csn = BigBuf_malloc(22);
427 int resp_csn_len;
429 // configuration (blk 1) PICOPASS 2ks
430 uint8_t *resp_conf = BigBuf_malloc(22);
431 int resp_conf_len;
433 // e-Purse (blk 2)
434 // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
435 uint8_t *resp_cc = BigBuf_malloc(18);
436 int resp_cc_len;
438 // Kd, Kc (blocks 3 and 4). Cannot be read. Always respond with 0xff bytes only
439 uint8_t *resp_ff = BigBuf_malloc(22);
440 int resp_ff_len;
441 uint8_t ff_data[10] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00};
442 AddCrc(ff_data, 8);
444 // Application Issuer Area (blk 5)
445 uint8_t *resp_aia = BigBuf_malloc(22);
446 int resp_aia_len;
448 // receive command
449 uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
451 // Prepare card messages
452 tosend_t *ts = get_tosend();
454 // First card answer: SOF
455 CodeIClassTagSOF();
456 memcpy(resp_sof, ts->buf, ts->max);
457 resp_sof_len = ts->max;
459 // Anticollision CSN
460 CodeIso15693AsTag(anticoll_data, sizeof(anticoll_data));
461 memcpy(resp_anticoll, ts->buf, ts->max);
462 resp_anticoll_len = ts->max;
464 // CSN (block 0)
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;
474 // e-Purse (block 2)
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) {
506 WDT_HIT();
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;
512 trace_data = NULL;
513 trace_data_size = 0;
515 uint32_t reader_eof_time = 0;
516 len = GetIso15693CommandFromReader(receivedCmd, MAX_FRAME_SIZE, &reader_eof_time);
517 if (len < 0) {
518 button_pressed = true;
519 exit_loop = true;
520 continue;
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;
533 goto send;
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);
543 goto send;
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;
555 } else {
556 chip_state = IDLE;
558 } else if (chip_state == HALTED || chip_state == IDLE) {
559 // RESELECT with CSN
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;
568 goto send;
571 } else if (cmd == ICLASS_CMD_READ_OR_IDENTIFY && len == 4) { // 0x0C
573 if (chip_state != SELECTED) {
574 goto send;
576 if (simulationMode == ICLASS_SIM_MODE_EXIT_AFTER_MAC) {
577 // provide defaults for blocks 0 ... 5
579 // block0,1,2,5 is always readable.
580 switch (block) {
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);
586 goto send;
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);
593 goto send;
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);
604 goto send;
606 case 3:
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);
612 goto send;
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);
619 goto send;
621 } // switch
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;
638 goto send;
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) {
644 goto send;
647 // debit key
648 if (receivedCmd[0] == 0x88) {
649 cipher_state = &cipher_state_KD[current_page];
650 diversified_key = diversified_kd;
651 using_kc = false;
652 } else {
653 cipher_state = &cipher_state_KC[current_page];
654 diversified_key = diversified_kc;
655 using_kc = true;
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);
662 goto send;
664 } else if (cmd == ICLASS_CMD_CHECK && len == 9) { // 0x05
666 // Reader random and reader MAC!!!
667 if (chip_state != SELECTED) {
668 goto send;
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]
689 goto send;
693 trace_data = data_generic_trace;
694 trace_data_size = 4;
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;
700 if (using_kc)
701 kc_attempt++;
703 } else {
704 // Not fullsim, we don't respond
705 chip_state = HALTED;
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]);
715 } else {
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);
722 exit_loop = true;
725 goto send;
727 } else if (cmd == ICLASS_CMD_HALT && options == 0 && len == 1) {
729 if (chip_state != SELECTED) {
730 goto send;
732 // Reader ends the session
733 modulated_response = resp_sof;
734 modulated_response_size = resp_sof_len;
735 chip_state = HALTED;
736 goto send;
738 } else if (simulationMode == ICLASS_SIM_MODE_FULL && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06
740 if (chip_state != SELECTED) {
741 goto send;
743 //Read block
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;
752 goto send;
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) {
759 goto send;
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];
786 } else {
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];
798 } else {
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;
819 goto send;
821 } else if (cmd == ICLASS_CMD_PAGESEL && len == 4) { // 0x84
822 // Pagesel,
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) {
827 goto send;
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) {
835 goto send;
838 current_page = 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;
859 goto send;
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.
865 } else {
866 // Never seen this command before
867 if (DBGLEVEL >= DBG_EXTENDED)
868 print_result("Unhandled command received ", receivedCmd, len);
871 send:
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) {};
886 // CC attack
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) {};
891 kc_attempt = 0;
892 exit_loop = true;
896 LEDsoff();
898 if (button_pressed)
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);
924 AddCrc(csn_data, 8);
926 // configuration block
927 uint8_t conf_block[10] = {0x12, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xFF, 0x3C, 0x00, 0x00};
929 // AIA
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);
936 AddCrc(aia_data, 8);
938 if ((conf_block[5] & 0x80) == 0x80) {
939 page_size = 256 * 8;
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:
946 // Reader 0a
947 // Tag 0f
948 // Reader 0c
949 // Tag anticoll. CSN
950 // Reader 81 anticoll. CSN
951 // Tag 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);
960 int resp_sof_len;
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;
967 // CSN
968 // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
969 uint8_t *resp_csn = BigBuf_malloc(28);
970 int resp_csn_len;
972 // configuration (blk 1) PICOPASS 2ks
973 uint8_t *resp_conf = BigBuf_malloc(28);
974 int resp_conf_len;
976 // Application Issuer Area (blk 5)
977 uint8_t *resp_aia = BigBuf_malloc(28);
978 int resp_aia_len;
980 // receive command
981 uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
983 // Prepare card messages
984 tosend_t *ts = get_tosend();
985 ts->max = 0;
987 // First card answer: SOF
988 CodeIClassTagSOF();
989 memcpy(resp_sof, ts->buf, ts->max);
990 resp_sof_len = ts->max;
992 // Anticollision CSN
993 CodeIso15693AsTag(anticoll_data, sizeof(anticoll_data));
994 memcpy(resp_anticoll, ts->buf, ts->max);
995 resp_anticoll_len = ts->max;
997 // CSN (block 0)
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;
1024 int len;
1026 bool exit_loop = false;
1027 while (exit_loop == false) {
1028 WDT_HIT();
1030 uint32_t reader_eof_time = 0;
1031 len = GetIso15693CommandFromReader(receivedCmd, MAX_FRAME_SIZE, &reader_eof_time);
1032 if (len < 0) {
1033 button_pressed = true;
1034 exit_loop = true;
1035 continue;
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;
1042 trace_data = NULL;
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;
1057 goto send;
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);
1067 goto send;
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;
1079 } else {
1080 chip_state = IDLE;
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;
1092 goto send;
1095 } else if (cmd == ICLASS_CMD_READ_OR_IDENTIFY && len == 4) { // 0x0C
1097 if (chip_state != SELECTED) {
1098 goto send;
1101 switch (block) {
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);
1107 goto send;
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);
1114 goto send;
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);
1121 goto send;
1123 default : {
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;
1132 goto send;
1134 } // swith
1136 } else if (cmd == ICLASS_CMD_READCHECK) { // 0x88
1137 goto send;
1139 } else if (cmd == ICLASS_CMD_CHECK && len == 9) { // 0x05
1140 goto send;
1142 } else if (cmd == ICLASS_CMD_HALT && options == 0 && len == 1) {
1144 if (chip_state != SELECTED) {
1145 goto send;
1147 // Reader ends the session
1148 modulated_response = resp_sof;
1149 modulated_response_size = resp_sof_len;
1150 chip_state = HALTED;
1151 goto send;
1153 } else if (cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06
1155 if (chip_state != SELECTED) {
1156 goto send;
1158 //Read block
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;
1167 goto send;
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) {
1174 goto send;
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;
1188 goto send;
1190 } else if (cmd == ICLASS_CMD_PAGESEL && len == 4) { // 0x84
1191 // Pagesel,
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) {
1196 goto send;
1199 if (max_page > 0) {
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;
1213 goto send;
1215 // } else if(cmd == ICLASS_CMD_DETECT) { // 0x0F
1216 // } else if (cmd == 0x26 && len == 5) {
1217 // standard ISO15693 INVENTORY command. Ignore.
1218 } else {
1219 // Never seen this command before
1220 if (DBGLEVEL >= DBG_EXTENDED)
1221 print_result("Unhandled command received ", receivedCmd, len);
1224 send:
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);
1235 LEDsoff();
1237 if (button_pressed)
1238 DbpString("button pressed");
1240 return button_pressed;
1244 // THE READER CODE
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);
1260 if (resp == NULL) {
1261 return true;
1264 if (expected_size == GetIso15693AnswerFromTag(resp, max_resp_size, timeout, eof_time)) {
1265 return true;
1268 return false;
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
1276 * true = Got all.
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
1289 // bit 7: parity.
1290 if (use_credit_key)
1291 read_check_cc[0] = 0x10 | ICLASS_CMD_READCHECK;
1293 // wakeup
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);
1297 if (len < 0)
1298 return false;
1300 // send Identify
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);
1306 if (len != 10)
1307 return false;
1309 // copy the Anti-collision CSN to our select-packet
1310 memcpy(&select[1], resp, 8);
1312 // select the card
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);
1318 if (len != 10)
1319 return false;
1321 // save CSN
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);
1330 if (len != 10)
1331 return false;
1333 // save CONF
1334 memcpy((uint8_t *)&hdr->conf, resp, sizeof(hdr->conf));
1336 if (status)
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);
1348 if (len != 10)
1349 return false;
1351 if (status) {
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);
1362 if (len != 8)
1363 return false;
1365 memcpy(hdr->epurse, resp, sizeof(hdr->epurse));
1367 if (status)
1368 *status |= FLAG_ICLASS_CC;
1370 } else {
1372 // on NON_SECURE_PAGEMODE cards, AIA is on block2..
1374 // read App Issuer Area block 2
1375 read_aia[1] = 0x02;
1376 read_aia[2] = 0x61;
1377 read_aia[3] = 0x10;
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);
1384 if (len != 10)
1385 return false;
1387 if (status) {
1388 *status |= FLAG_ICLASS_AIA;
1389 memcpy(hdr->epurse, resp, sizeof(hdr->epurse));
1393 return true;
1396 bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time) {
1397 uint8_t result = 0;
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) {
1418 clear_trace();
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);
1426 switch_off();
1427 return;
1430 // Page mapping for secure mode
1431 // 0 : CSN
1432 // 1 : Configuration
1433 // 2 : e-purse
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
1439 // 0 : CSN
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.
1446 LED_B_ON();
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) {
1456 LED_B_OFF();
1457 return;
1459 LED_B_OFF();
1463 // if (userCancelled) {
1464 // reply_mix(CMD_ACK, 0xFF, 0, 0, card_data, 0);
1465 // switch_off();
1466 // } else {
1467 // reply_mix(CMD_ACK, result_status, 0, 0, card_data, 0);
1468 // }
1470 switch_off();
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;
1481 if (mac_out)
1482 pmac = mac_out;
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);
1491 } else {
1493 uint8_t div_key[8] = {0};
1494 if (payload->use_raw)
1495 memcpy(div_key, payload->key, 8);
1496 else
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));
1501 else
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) {
1524 // sanitation
1525 if (p == NULL) {
1526 reply_ng(CMD_HF_ICLASS_CHKKEYS, PM3_ESOFT, NULL, 0);
1527 return;
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;
1541 LED_A_ON();
1543 // fresh start
1544 switch_off();
1545 SpinDelay(20);
1546 Iso15693InitReader();
1548 bool isOK = false;
1550 uint32_t start_time = 0, eof_time = 0;
1551 if (select_iclass_tag(&hdr, p->use_credit_key, &eof_time) == false)
1552 goto out;
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;
1559 // Keychunk loop
1560 uint8_t i = 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;
1566 checked = 0;
1568 ++checked;
1570 WDT_HIT();
1571 LED_B_ON();
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);
1581 if (isOK)
1582 goto out;
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);
1588 LED_B_OFF();
1591 out:
1592 // send keyindex.
1593 reply_ng(CMD_HF_ICLASS_CHKKEYS, (isOK) ? PM3_SUCCESS : PM3_ESOFT, (uint8_t *)&i, sizeof(i));
1594 switch_off();
1597 // Tries to read block.
1598 // retries 3times.
1599 // reply 8 bytes block
1600 bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time) {
1601 uint8_t resp[10];
1602 uint8_t c[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockno, 0x00, 0x00};
1603 AddCrc(c + 1, 1);
1604 bool isOK = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time);
1605 if (isOK)
1606 memcpy(data, resp, 8);
1607 return isOK;
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();
1625 // select tag.
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);
1629 if (res == false) {
1630 if (payload->send_reply) {
1631 response.isOK = res;
1632 reply_ng(CMD_HF_ICLASS_READBL, PM3_ETIMEOUT, (uint8_t *)&response, sizeof(response));
1634 goto out;
1637 uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
1639 // authenticate
1640 if (payload->do_auth) {
1642 res = authenticate_iclass_tag(payload, &hdr, &start_time, &eof_time, NULL);
1643 if (res == false) {
1644 if (payload->send_reply) {
1645 response.isOK = res;
1646 reply_ng(CMD_HF_ICLASS_READBL, PM3_ETIMEOUT, (uint8_t *)&response, sizeof(response));
1648 goto out;
1652 start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
1654 // read data
1655 uint8_t resp[10];
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);
1657 if (res) {
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));
1662 } else {
1663 if (payload->send_reply) {
1664 response.isOK = res;
1665 reply_ng(CMD_HF_ICLASS_READBL, PM3_ETIMEOUT, (uint8_t *)&response, sizeof(response));
1669 out:
1670 switch_off();
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) {
1680 BigBuf_free();
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);
1691 switch_off();
1692 return;
1694 memset(dataout, 0xFF, ICLASS_16KS_SIZE);
1696 Iso15693InitReader();
1698 // select tag.
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);
1704 if (res == false) {
1705 if (req->send_reply) {
1706 reply_ng(CMD_HF_ICLASS_DUMP, PM3_ETIMEOUT, NULL, 0);
1708 switch_off();
1709 return;
1712 uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
1714 // authenticate
1715 if (req->do_auth) {
1716 res = authenticate_iclass_tag(req, &hdr, &start_time, &eof_time, NULL);
1717 if (res == false) {
1718 if (req->send_reply) {
1719 reply_ng(CMD_HF_ICLASS_DUMP, PM3_ETIMEOUT, NULL, 0);
1721 switch_off();
1722 return;
1726 start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
1728 bool dumpsuccess = true;
1730 // main read loop
1731 uint16_t i;
1732 for (i = cmd->start_block; i <= cmd->end_block; i++) {
1734 uint8_t resp[10];
1735 uint8_t c[] = {ICLASS_CMD_READ_OR_IDENTIFY, i, 0x00, 0x00};
1736 AddCrc(c + 1, 1);
1738 res = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time);
1739 if (res) {
1740 memcpy(dataout + (8 * i), resp, 8);
1741 } else {
1742 Dbprintf("failed to read block %u ( 0x%02x)", i, i);
1743 dumpsuccess = false;
1747 switch_off();
1749 // copy diversified key back.
1750 if (req->do_auth) {
1751 if (req->use_credit_key)
1752 memcpy(dataout + (8 * 4), hdr.key_c, 8);
1753 else
1754 memcpy(dataout + (8 * 3), hdr.key_d, 8);
1757 if (req->send_reply) {
1758 struct p {
1759 bool isOK;
1760 uint16_t block_cnt;
1761 uint32_t bb_offset;
1762 } PACKED response;
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));
1770 BigBuf_free();
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);
1780 if (use_mac) {
1781 memcpy(write + 10, mac, 4);
1782 } else {
1783 AddCrc(write + 1, 9);
1784 write_len -= 2;
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) {
1791 return false;
1794 uint8_t all_ff[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1795 if (blockno == 2) {
1796 // check response. e-purse update swaps first and second half
1797 if (memcmp(data + 4, resp, 4) || memcmp(data, resp + 4, 4)) {
1798 return false;
1800 } else if (blockno == 3 || blockno == 4) {
1801 // check response. Key updates always return 0xffffffffffffffff
1802 if (memcmp(all_ff, resp, 8)) {
1803 return false;
1805 } else {
1806 // check response. All other updates return unchanged data
1807 if (memcmp(data, resp, 8)) {
1808 return false;
1812 return true;
1815 // turn off afterwards
1816 void iClass_WriteBlock(uint8_t *msg) {
1818 LED_A_ON();
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();
1827 // select tag.
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);
1831 if (res == false) {
1832 goto out;
1835 uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
1837 uint8_t mac[4] = {0};
1839 // authenticate
1840 if (payload->req.do_auth) {
1842 res = authenticate_iclass_tag(&payload->req, &hdr, &start_time, &eof_time, mac);
1843 if (res == false) {
1844 goto out;
1848 // new block data
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
1855 // byte1 = block no
1856 // byte2..9 = new block data
1857 AddCrc(write + 1, 9);
1858 write_len -= 2;
1859 } else {
1860 // Secure tags uses MAC
1861 uint8_t wb[9];
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);
1867 else
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};
1877 uint8_t tries = 3;
1878 while (tries-- > 0) {
1880 iclass_send_as_reader(write, write_len, &start_time, &eof_time);
1882 if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
1883 res = false;
1884 switch_off();
1885 if (payload->req.send_reply)
1886 reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_ETEAROFF, (uint8_t *)&res, sizeof(uint8_t));
1887 return;
1888 } else {
1890 if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_UPDATE, &eof_time) == 10) {
1891 res = true;
1892 break;
1897 if (tries == 0) {
1898 res = false;
1899 goto out;
1902 // verify write
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)) {
1907 res = false;
1908 goto out;
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)) {
1913 res = false;
1914 goto out;
1916 } else {
1917 // check response. All other updates return unchanged data
1918 if (memcmp(payload->data, resp, 8)) {
1919 res = false;
1920 goto out;
1924 out:
1925 switch_off();
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) {
1933 // sanitation
1934 if (msg == NULL) {
1935 reply_ng(CMD_HF_ICLASS_RESTORE, PM3_ESOFT, NULL, 0);
1936 return;
1939 if (msg->item_cnt == 0) {
1940 if (msg->req.send_reply) {
1941 reply_ng(CMD_HF_ICLASS_RESTORE, PM3_ESOFT, NULL, 0);
1943 return;
1946 LED_A_ON();
1947 Iso15693InitReader();
1949 uint16_t written = 0;
1950 uint32_t eof_time = 0;
1951 picopass_hdr_t hdr = {0};
1953 // select
1954 bool res = select_iclass_tag(&hdr, msg->req.use_credit_key, &eof_time);
1955 if (res == false) {
1956 goto out;
1959 // authenticate
1960 uint8_t mac[4] = {0};
1961 uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
1963 // authenticate
1964 if (msg->req.do_auth) {
1965 res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac);
1966 if (res == false) {
1967 goto out;
1971 // main loop
1972 bool use_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
1980 use_mac = false;
1981 } else {
1982 // Secure tags uses MAC
1983 use_mac = true;
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);
1990 else
1991 doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
1994 // data + 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);
1997 written++;
1998 } else {
1999 Dbprintf("Write block [%3d/0x%02X] " _RED_("failed"), item.blockno, item.blockno);
2003 out:
2005 switch_off();
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);