1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // High frequency ISO14443B commands
9 //-----------------------------------------------------------------------------
14 static int CmdHelp(const char *Cmd
);
16 int usage_hf_14b_info(void){
17 PrintAndLog("Usage: hf 14b info [h] [s]");
18 PrintAndLog("Options:");
19 PrintAndLog(" h this help");
20 PrintAndLog(" s silently");
21 PrintAndLog("sample:");
22 PrintAndLog(" hf 14b info");
25 int usage_hf_14b_reader(void){
26 PrintAndLog("Usage: hf 14b reader [h] [s]");
27 PrintAndLog("Options:");
28 PrintAndLog(" h this help");
29 PrintAndLog(" s silently");
30 PrintAndLog("sample:");
31 PrintAndLog(" hf 14b reader");
34 int usage_hf_14b_raw(void){
35 PrintAndLog("Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
36 PrintAndLog("Options:");
37 PrintAndLog(" -h this help");
38 PrintAndLog(" -r do not read response");
39 PrintAndLog(" -c calculate and append CRC");
40 PrintAndLog(" -p leave the field on after receive");
41 PrintAndLog(" -s active signal field ON with select");
42 PrintAndLog(" -ss active signal field ON with select for SRx ST Microelectronics tags");
43 PrintAndLog("sample:");
44 PrintAndLog(" hf 14b raw -s -c -p 0200a40400");
47 int usage_hf_14b_snoop(void){
48 PrintAndLog("It get data from the field and saves it into command buffer.");
49 PrintAndLog("Buffer accessible from command 'hf list 14b'");
50 PrintAndLog("Usage: hf 14b snoop [h]");
51 PrintAndLog("Options:");
52 PrintAndLog(" h this help");
53 PrintAndLog("sample:");
54 PrintAndLog(" hf 14b snoop");
57 int usage_hf_14b_sim(void){
58 PrintAndLog("Emulating ISO/IEC 14443 type B tag with 4 UID / PUPI");
59 PrintAndLog("Usage: hf 14b sim [h] u <uid>");
60 PrintAndLog("Options:");
61 PrintAndLog(" h this help");
62 PrintAndLog(" u 4byte UID/PUPI");
63 PrintAndLog("sample:");
64 PrintAndLog(" hf 14b sim");
65 PrintAndLog(" hf 14b sim u 11223344");
68 int usage_hf_14b_read_srx(void){
69 PrintAndLog("Usage: hf 14b read [h] <1|2>");
70 PrintAndLog("Options:");
71 PrintAndLog(" h this help");
72 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
73 PrintAndLog("sample:");
74 PrintAndLog(" hf 14b read 1");
75 PrintAndLog(" hf 14b read 2");
78 int usage_hf_14b_write_srx(void){
79 PrintAndLog("Usage: hf 14b [h] write <1|2> <BLOCK> <DATA>");
80 PrintAndLog("Options:");
81 PrintAndLog(" h this help");
82 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
83 PrintAndLog(" <block> BLOCK number depends on tag, special block == FF");
84 PrintAndLog(" <data> hex bytes of data to be written");
85 PrintAndLog("sample:");
86 PrintAndLog(" hf 14b write 1 7F 11223344");
87 PrintAndLog(" hf 14b write 1 FF 11223344");
88 PrintAndLog(" hf 14b write 2 15 11223344");
89 PrintAndLog(" hf 14b write 2 FF 11223344");
93 static void switch_on_field_14b(void) {
94 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
, 0, 0}};
99 static int switch_off_field_14b(void) {
100 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_DISCONNECT
, 0, 0}};
101 clearCommandBuffer();
106 int CmdHF14BList(const char *Cmd
) {
111 int CmdHF14BSim(const char *Cmd
) {
112 char cmdp
= param_getchar(Cmd
, 0);
113 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_sim();
116 if (cmdp
== 'u' || cmdp
== 'U') {
117 pupi
= param_get32ex(Cmd
, 1, 0, 16);
120 UsbCommand c
= {CMD_SIMULATE_TAG_ISO_14443B
, {pupi
, 0, 0}};
121 clearCommandBuffer();
126 int CmdHF14BSnoop(const char *Cmd
) {
128 char cmdp
= param_getchar(Cmd
, 0);
129 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_snoop();
131 UsbCommand c
= {CMD_SNOOP_ISO_14443B
, {0, 0, 0}};
132 clearCommandBuffer();
137 int CmdHF14BCmdRaw (const char *Cmd
) {
138 bool reply
= TRUE
, power
= FALSE
, select
= FALSE
;
141 uint8_t data
[USB_CMD_DATA_SIZE
] = {0x00};
142 uint16_t datalen
= 0;
143 uint32_t flags
= ISO14B_CONNECT
;
146 if ( strlen(Cmd
) < 3 ) return usage_hf_14b_raw();
149 while (*Cmd
==' ' || *Cmd
=='\t') ++Cmd
;
151 while (Cmd
[i
]!='\0') {
152 if (Cmd
[i
]==' ' || Cmd
[i
]=='\t') { ++i
; continue; }
157 return usage_hf_14b_raw();
164 flags
|= ISO14B_APPEND_CRC
;
173 if (Cmd
[i
+2]=='s' || Cmd
[i
+2]=='S') {
174 flags
|= ISO14B_SELECT_SR
;
177 flags
|= ISO14B_SELECT_STD
;
181 return usage_hf_14b_raw();
186 if ((Cmd
[i
]>='0' && Cmd
[i
]<='9') ||
187 (Cmd
[i
]>='a' && Cmd
[i
]<='f') ||
188 (Cmd
[i
]>='A' && Cmd
[i
]<='F') ) {
189 buf
[strlen(buf
)+1]=0;
190 buf
[strlen(buf
)]=Cmd
[i
];
193 if (strlen(buf
)>=2) {
194 sscanf(buf
,"%x",&temp
);
195 data
[datalen
++] = (uint8_t)(temp
& 0xff);
197 memset(buf
, 0x00, sizeof(buf
));
201 PrintAndLog("Invalid char on input");
206 flags
|= ISO14B_DISCONNECT
;
211 // Max buffer is USB_CMD_DATA_SIZE
212 datalen
= (datalen
> USB_CMD_DATA_SIZE
) ? USB_CMD_DATA_SIZE
: datalen
;
214 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {flags
, datalen
, 0}};
215 memcpy(c
.d
.asBytes
, data
, datalen
);
216 clearCommandBuffer();
219 if (!reply
) return 1;
222 // get back iso14b_card_select_t, don't print it.
224 success
= waitCmd(FALSE
);
226 // get back response from the raw bytes you sent.
227 if (success
&& datalen
>0) waitCmd(TRUE
);
232 // print full atqb info
234 // 0,1,2,3 = application data
235 // 4 = bit rate capacity
236 // 5 = max frame size / -4 info
237 // 6 = FWI / Coding options
238 static void print_atqb_resp(uint8_t *data
, uint8_t cid
){
239 //PrintAndLog(" UID: %s", sprint_hex(data+1,4));
240 PrintAndLog(" App Data: %s", sprint_hex(data
,4));
241 PrintAndLog(" Protocol: %s", sprint_hex(data
+4,3));
242 uint8_t BitRate
= data
[4];
243 if (!BitRate
) PrintAndLog(" Bit Rate: 106 kbit/s only PICC <-> PCD");
244 if (BitRate
& 0x10) PrintAndLog(" Bit Rate: 212 kbit/s PICC -> PCD supported");
245 if (BitRate
& 0x20) PrintAndLog(" Bit Rate: 424 kbit/s PICC -> PCD supported");
246 if (BitRate
& 0x40) PrintAndLog(" Bit Rate: 847 kbit/s PICC -> PCD supported");
247 if (BitRate
& 0x01) PrintAndLog(" Bit Rate: 212 kbit/s PICC <- PCD supported");
248 if (BitRate
& 0x02) PrintAndLog(" Bit Rate: 424 kbit/s PICC <- PCD supported");
249 if (BitRate
& 0x04) PrintAndLog(" Bit Rate: 847 kbit/s PICC <- PCD supported");
250 if (BitRate
& 0x80) PrintAndLog(" Same bit rate <-> required");
252 uint16_t maxFrame
= data
[5]>>4;
253 if (maxFrame
< 5) maxFrame
= 8 * maxFrame
+ 16;
254 else if (maxFrame
== 5) maxFrame
= 64;
255 else if (maxFrame
== 6) maxFrame
= 96;
256 else if (maxFrame
== 7) maxFrame
= 128;
257 else if (maxFrame
== 8) maxFrame
= 256;
260 PrintAndLog("Max Frame Size: %u%s bytes",maxFrame
, (maxFrame
== 257) ? "+ RFU" : "");
262 uint8_t protocolT
= data
[5] & 0xF;
263 PrintAndLog(" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT
) ? "" : "not " );
265 uint8_t fwt
= data
[6]>>4;
267 uint32_t etus
= (32 << fwt
);
268 uint32_t fwt_time
= (302 << fwt
);
269 PrintAndLog("Frame Wait Integer: %u - %u ETUs | %u us", fwt
, etus
, fwt_time
);
271 PrintAndLog("Frame Wait Integer: %u - RFU", fwt
);
274 PrintAndLog(" App Data Code: Application is %s",(data
[6]&4) ? "Standard" : "Proprietary");
275 PrintAndLog(" Frame Options: NAD is %ssupported",(data
[6]&2) ? "" : "not ");
276 PrintAndLog(" Frame Options: CID is %ssupported",(data
[6]&1) ? "" : "not ");
277 PrintAndLog("Tag :");
278 PrintAndLog(" Max Buf Length: %u (MBLI) %s", cid
>>4, (cid
& 0xF0) ? "" : "chained frames not supported");
279 PrintAndLog(" CDI : %u", cid
& 0x0f);
283 // get SRx chip model (from UID) // from ST Microelectronics
284 char *get_ST_Chip_Model(uint8_t data
){
285 static char model
[20];
286 char *retStr
= model
;
287 memset(model
,0, sizeof(model
));
290 case 0x0: sprintf(retStr
, "SRIX4K (Special)"); break;
291 case 0x2: sprintf(retStr
, "SR176"); break;
292 case 0x3: sprintf(retStr
, "SRIX4K"); break;
293 case 0x4: sprintf(retStr
, "SRIX512"); break;
294 case 0x6: sprintf(retStr
, "SRI512"); break;
295 case 0x7: sprintf(retStr
, "SRI4K"); break;
296 case 0xC: sprintf(retStr
, "SRT512"); break;
297 default : sprintf(retStr
, "Unknown"); break;
303 int print_ST_Lock_info(uint8_t model
){
305 // PrintAndLog("Chip Write Protection Bits:");
306 // // now interpret the data
308 // case 0x0: //fall through (SRIX4K special)
309 // case 0x3: //fall through (SRIx4K)
310 // case 0x7: // (SRI4K)
311 // //only need data[3]
313 // PrintAndLog(" raw: %s", sprint_bin(data+3, 1));
314 // PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
315 // for (uint8_t i = 1; i<8; i++){
316 // PrintAndLog(" %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
320 // case 0x4: //fall through (SRIX512)
321 // case 0x6: //fall through (SRI512)
322 // case 0xC: // (SRT512)
323 // //need data[2] and data[3]
325 // PrintAndLog(" raw: %s", sprint_bin(data+2, 2));
326 // for (uint8_t b=2; b<4; b++){
327 // for (uint8_t i=0; i<8; i++){
328 // PrintAndLog(" %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
333 // case 0x2: // (SR176)
336 // PrintAndLog(" raw: %s", sprint_bin(data+2, 1));
337 // for (uint8_t i = 0; i<8; i++){
338 // PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
343 // return rawClose();
348 // print UID info from SRx chips (ST Microelectronics)
349 static void print_st_general_info(uint8_t *data
, uint8_t len
){
350 //uid = first 8 bytes in data
351 PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data
,8,8), len
));
352 PrintAndLog(" MFG: %02X, %s", data
[6], getTagInfo(data
[6]));
353 PrintAndLog("Chip: %02X, %s", data
[5]>>2, get_ST_Chip_Model(data
[5]>>2));
357 //05 00 00 = find one tag in field
358 //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
359 //a3 = ? (resp 03 [e2 c2])
360 //02 = ? (resp 02 [6a d3])
361 // 022b (resp 02 67 00 [29 5b])
362 // 0200a40400 (resp 02 67 00 [29 5b])
363 // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
364 // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
365 // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
366 // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
367 // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
368 // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
369 // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
370 //03 = ? (resp 03 [e3 c2])
371 //c2 = ? (resp c2 [66 15])
372 //b2 = ? (resp a3 [e9 67])
373 //a2 = ? (resp 02 [6a d3])
375 // 14b get and print Full Info (as much as we know)
376 bool HF14B_Std_Info(bool verbose
){
381 // SRx get and print full info (needs more info...)
382 bool HF14B_ST_Info(bool verbose
){
384 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_SR
| ISO14B_DISCONNECT
, 0, 0}};
385 clearCommandBuffer();
389 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
390 if (verbose
) PrintAndLog("timeout while waiting for reply.");
394 iso14b_card_select_t card
;
395 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
397 uint64_t status
= resp
.arg
[0];
398 if ( status
> 0 ) return switch_off_field_14b();
400 //add locking bit information here. uint8_t data[16] = {0x00};
401 // uint8_t datalen = 2;
407 // if (model == 0x2) { //SR176 has special command:
416 // if (HF14BCmdRaw(true, true, data, &datalen, false)==0)
417 // return rawClose();
419 // if (datalen != resplen || !crc) return rawClose();
420 //print_ST_Lock_info(data[5]>>2);
421 switch_off_field_14b();
425 // get and print all info known about any known 14b tag
426 bool HF14BInfo(bool verbose
){
428 // try std 14b (atqb)
429 if (HF14B_Std_Info(verbose
)) return TRUE
;
432 if (HF14B_ST_Info(verbose
)) return TRUE
;
434 // try unknown 14b read commands (to be identified later)
435 // could be read of calypso, CEPAS, moneo, or pico pass.
437 if (verbose
) PrintAndLog("no 14443B tag found");
441 // menu command to get and print all info known about any known 14b tag
442 int CmdHF14Binfo(const char *Cmd
){
443 char cmdp
= param_getchar(Cmd
, 0);
444 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_info();
446 bool verbose
= !((cmdp
== 's') || (cmdp
== 'S'));
447 return HF14BInfo(verbose
);
450 bool HF14B_ST_Reader(bool verbose
){
452 bool isSuccess
= FALSE
;
454 switch_on_field_14b();
456 // SRx get and print general info about SRx chip from UID
457 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_SELECT_SR
, 0, 0}};
458 clearCommandBuffer();
461 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
462 if (verbose
) PrintAndLog("timeout while waiting for reply.");
466 iso14b_card_select_t card
;
467 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
469 uint64_t status
= resp
.arg
[0];
473 print_st_general_info(card
.uid
, card
.uidlen
);
477 if (verbose
) PrintAndLog("iso14443-3 random chip id fail");
480 if (verbose
) PrintAndLog("iso14443-3 ATTRIB fail");
483 if (verbose
) PrintAndLog("iso14443-3 CRC fail");
486 if (verbose
) PrintAndLog("iso14443b card select SRx failed");
490 switch_off_field_14b();
494 bool HF14B_Std_Reader(bool verbose
){
496 bool isSuccess
= FALSE
;
498 // 14b get and print UID only (general info)
499 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_STD
| ISO14B_DISCONNECT
, 0, 0}};
500 clearCommandBuffer();
504 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
505 if (verbose
) PrintAndLog("timeout while waiting for reply.");
509 iso14b_card_select_t card
;
510 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
512 uint64_t status
= resp
.arg
[0];
516 PrintAndLog(" UID : %s", sprint_hex(card
.uid
, card
.uidlen
));
517 PrintAndLog(" ATQB : %s", sprint_hex(card
.atqb
, sizeof(card
.atqb
)));
518 PrintAndLog(" CHIPID : %02X", card
.chipid
);
519 print_atqb_resp(card
.atqb
, card
.cid
);
523 if (verbose
) PrintAndLog("iso14443-3 ATTRIB fail");
526 if (verbose
) PrintAndLog("iso14443-3 CRC fail");
529 if (verbose
) PrintAndLog("iso14443b card select failed");
533 switch_off_field_14b();
537 // test for other 14b type tags (mimic another reader - don't have tags to identify)
538 bool HF14B_Other_Reader(){
540 // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
541 // uint8_t datalen = 4;
543 // // 14b get and print UID only (general info)
544 // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
546 // UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
547 // memcpy(c.d.asBytes, data, datalen);
549 // clearCommandBuffer();
552 // WaitForResponse(CMD_ACK,&resp);
554 // if (datalen > 2 ) {
555 // printandlog ("\n14443-3b tag found:");
556 // printandlog ("unknown tag type answered to a 0x000b3f80 command ans:");
557 // //printandlog ("%s", sprint_hex(data, datalen));
563 // c.d.asBytes[0] = ISO14443B_AUTHENTICATE;
564 // clearCommandBuffer();
567 // WaitForResponse(CMD_ACK, &resp);
569 // if (datalen > 0) {
570 // PrintAndLog ("\n14443-3b tag found:");
571 // PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
572 // // PrintAndLog ("%s", sprint_hex(data, datalen));
578 // c.d.asBytes[0] = ISO14443B_RESET;
579 // clearCommandBuffer();
582 // WaitForResponse(CMD_ACK, &resp);
584 // if (datalen > 0) {
585 // PrintAndLog ("\n14443-3b tag found:");
586 // PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
587 // PrintAndLog ("%s", sprint_hex(data, datalen));
596 // get and print general info about all known 14b chips
597 bool HF14BReader(bool verbose
){
599 // try std 14b (atqb)
600 if (HF14B_Std_Reader(verbose
)) return TRUE
;
602 // try ST Microelectronics 14b
603 if (HF14B_ST_Reader(verbose
)) return TRUE
;
605 // try unknown 14b read commands (to be identified later)
606 // could be read of calypso, CEPAS, moneo, or pico pass.
607 if (HF14B_Other_Reader()) return TRUE
;
609 if (verbose
) PrintAndLog("no 14443B tag found");
613 // menu command to get and print general info about all known 14b chips
614 int CmdHF14BReader(const char *Cmd
){
615 char cmdp
= param_getchar(Cmd
, 0);
616 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_reader();
618 bool verbose
= !((cmdp
== 's') || (cmdp
== 'S'));
619 return HF14BReader(verbose
);
622 /* New command to read the contents of a SRI512|SRIX4K tag
623 * SRI* tags are ISO14443-B modulated memory tags,
624 * this command just dumps the contents of the memory/
626 int CmdHF14BReadSri(const char *Cmd
){
627 char cmdp
= param_getchar(Cmd
, 0);
628 if (strlen(Cmd
) < 1 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_read_srx();
630 uint8_t tagtype
= param_get8(Cmd
, 0);
631 uint8_t blocks
= (tagtype
== 1) ? 0x7F : 0x0F;
633 UsbCommand c
= {CMD_READ_SRI_TAG
, {blocks
, 0, 0}};
634 clearCommandBuffer();
638 // New command to write a SRI512/SRIX4K tag.
639 int CmdHF14BWriteSri(const char *Cmd
){
641 * For SRIX4K blocks 00 - 7F
642 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
644 * For SR512 blocks 00 - 0F
645 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
647 * Special block FF = otp_lock_reg block.
650 char cmdp
= param_getchar(Cmd
, 0);
651 uint8_t blockno
= -1;
652 uint8_t data
[4] = {0x00};
653 bool isSrix4k
= true;
655 memset(str
, 0x00, sizeof(str
));
657 if (strlen(Cmd
) < 1 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_write_srx();
662 //blockno = param_get8(Cmd, 1);
664 if ( param_gethex(Cmd
, 1, &blockno
, 2) ) {
665 PrintAndLog("Block number must include 2 HEX symbols");
670 if ( blockno
> 0x7f && blockno
!= 0xff ){
671 PrintAndLog("Block number out of range");
675 if ( blockno
> 0x0f && blockno
!= 0xff ){
676 PrintAndLog("Block number out of range");
681 if (param_gethex(Cmd
, 2, data
, 8)) {
682 PrintAndLog("Data must include 8 HEX symbols");
686 if ( blockno
== 0xff) {
687 PrintAndLog("[%s] Write special block %02X [ %s ]",
688 (isSrix4k
) ? "SRIX4K":"SRI512",
693 PrintAndLog("[%s] Write block %02X [ %s ]",
694 (isSrix4k
) ? "SRIX4K":"SRI512",
700 sprintf(str
, "-ss -c %02x %02x %02x %02x %02x %02x", ISO14443B_WRITE_BLK
, blockno
, data
[0], data
[1], data
[2], data
[3]);
705 uint32_t srix4kEncode(uint32_t value
) {
710 4 bytes : 00 1A 20 01
712 // only the lower crumbs.
713 uint8_t block
= (value
& 0xFF);
715 uint8_t valuebytes
[] = {0,0,0};
717 num_to_bytes(value
, 3, valuebytes
);
720 // Crumb swapping of value.
721 uint8_t temp
[] = {0,0};
722 temp
[0] = (CRUMB(value
, 22) << 4 | CRUMB(value
, 14 ) << 2 | CRUMB(value
, 6)) << 4;
723 temp
[0] |= CRUMB(value
, 20) << 4 | CRUMB(value
, 12 ) << 2 | CRUMB(value
, 4);
724 temp
[1] = (CRUMB(value
, 18) << 4 | CRUMB(value
, 10 ) << 2 | CRUMB(value
, 2)) << 4;
725 temp
[1] |= CRUMB(value
, 16) << 4 | CRUMB(value
, 8 ) << 2 | CRUMB(value
, 0);
728 uint32_t chksum
= 0xFF - block
;
730 // chksum is reduced by each nibbles of value.
731 for (i
= 0; i
< 3; ++i
){
732 chksum
-= NIBBLE_HIGH(valuebytes
[i
]);
733 chksum
-= NIBBLE_LOW(valuebytes
[i
]);
736 // base4 conversion and left shift twice
738 uint8_t base4
[] = {0,0,0,0};
740 base4
[i
--] = (chksum
% 4 << 2);
744 // merge scambled and chksum parts
746 ( NIBBLE_LOW ( base4
[0]) << 28 ) |
747 ( NIBBLE_HIGH( temp
[0]) << 24 ) |
749 ( NIBBLE_LOW ( base4
[1]) << 20 ) |
750 ( NIBBLE_LOW ( temp
[0]) << 16 ) |
752 ( NIBBLE_LOW ( base4
[2]) << 12 ) |
753 ( NIBBLE_HIGH( temp
[1]) << 8 ) |
755 ( NIBBLE_LOW ( base4
[3]) << 4 ) |
756 NIBBLE_LOW ( temp
[1] );
758 PrintAndLog("ICE encoded | %08X -> %08X", value
, encvalue
);
761 uint32_t srix4kDecode(uint32_t value
) {
763 case 0xC04F42C5: return 0x003139;
764 case 0xC1484807: return 0x002943;
765 case 0xC0C60848: return 0x001A20;
769 uint32_t srix4kDecodeCounter(uint32_t num
) {
770 uint32_t value
= ~num
;
775 uint32_t srix4kGetMagicbytes( uint64_t uid
, uint32_t block6
, uint32_t block18
, uint32_t block19
){
776 #define MASK 0xFFFFFFFF;
777 uint32_t uid32
= uid
& MASK
;
778 uint32_t counter
= srix4kDecodeCounter(block6
);
779 uint32_t decodedBlock18
= srix4kDecode(block18
);
780 uint32_t decodedBlock19
= srix4kDecode(block19
);
781 uint32_t doubleBlock
= (decodedBlock18
<< 16 | decodedBlock19
) + 1;
783 uint32_t result
= (uid32
* doubleBlock
* counter
) & MASK
;
784 PrintAndLog("Magic bytes | %08X", result
);
787 int srix4kValid(const char *Cmd
){
789 uint64_t uid
= 0xD00202501A4532F9;
790 uint32_t block6
= 0xFFFFFFFF;
791 uint32_t block18
= 0xC04F42C5;
792 uint32_t block19
= 0xC1484807;
793 uint32_t block21
= 0xD1BCABA4;
795 uint32_t test_b18
= 0x00313918;
796 uint32_t test_b18_enc
= srix4kEncode(test_b18
);
797 //uint32_t test_b18_dec = srix4kDecode(test_b18_enc);
798 PrintAndLog("ENCODE & CHECKSUM | %08X -> %08X (%s)", test_b18
, test_b18_enc
, "");
800 uint32_t magic
= srix4kGetMagicbytes(uid
, block6
, block18
, block19
);
801 PrintAndLog("BLOCK 21 | %08X -> %08X (no XOR)", block21
, magic
^ block21
);
805 bool waitCmd(bool verbose
) {
808 uint8_t b1
= 0, b2
= 0;
809 uint8_t data
[USB_CMD_DATA_SIZE
] = {0x00};
814 if (WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
816 status
= (resp
.arg
[0] & 0xFF);
817 if ( status
> 0 ) return FALSE
;
819 len
= (resp
.arg
[1] & 0xFFFF);
821 memcpy(data
, resp
.d
.asBytes
, len
);
825 ComputeCrc14443(CRC_14443_B
, data
, len
-2, &b1
, &b2
);
826 crc
= ( data
[len
-2] == b1
&& data
[len
-1] == b2
);
828 PrintAndLog("[LEN %u] %s[%02X %02X] %s",
830 sprint_hex(data
, len
-2),
833 (crc
) ? "OK" : "FAIL"
836 PrintAndLog("[LEN %u] %s", len
, sprint_hex(data
, len
) );
841 PrintAndLog("timeout while waiting for reply.");
846 static command_t CommandTable
[] = {
847 {"help", CmdHelp
, 1, "This help"},
848 {"info", CmdHF14Binfo
, 0, "Find and print details about a 14443B tag"},
849 {"list", CmdHF14BList
, 0, "[Deprecated] List ISO 14443B history"},
850 {"raw", CmdHF14BCmdRaw
, 0, "Send raw hex data to tag"},
851 {"reader", CmdHF14BReader
, 0, "Act as a 14443B reader to identify a tag"},
852 {"sim", CmdHF14BSim
, 0, "Fake ISO 14443B tag"},
853 {"snoop", CmdHF14BSnoop
, 0, "Eavesdrop ISO 14443B"},
854 {"sriread", CmdHF14BReadSri
, 0, "Read contents of a SRI512 | SRIX4K tag"},
855 {"sriwrite", CmdHF14BWriteSri
, 0, "Write data to a SRI512 | SRIX4K tag"},
856 //{"valid", srix4kValid, 1, "srix4k checksum test"},
857 {NULL
, NULL
, 0, NULL
}
860 int CmdHF14B(const char *Cmd
) {
861 clearCommandBuffer();
862 CmdsParse(CommandTable
, Cmd
);
866 int CmdHelp(const char *Cmd
) {
867 CmdsHelp(CommandTable
);