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 //-----------------------------------------------------------------------------
18 static int CmdHelp(const char *Cmd
);
20 int usage_hf_14b_info(void){
21 PrintAndLog("Usage: hf 14b info [-h] [-s]");
22 PrintAndLog(" -h this help");
23 PrintAndLog(" -s silently");
26 int usage_hf_14b_reader(void){
27 PrintAndLog("Usage: hf 14b reader [-h] [-s]");
28 PrintAndLog(" -h this help");
29 PrintAndLog(" -s silently");
32 int usage_hf_14b_raw(void){
33 PrintAndLog("Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
34 PrintAndLog(" -h this help");
35 PrintAndLog(" -r do not read response");
36 PrintAndLog(" -c calculate and append CRC");
37 PrintAndLog(" -p leave the field on after receive");
38 PrintAndLog(" -s active signal field ON with select");
39 PrintAndLog(" -ss active signal field ON with select for SRx ST Microelectronics tags");
42 int usage_hf_14b_snoop(void){
43 PrintAndLog("It get data from the field and saves it into command buffer.");
44 PrintAndLog("Buffer accessible from command 'hf list 14b'");
45 PrintAndLog("Usage: hf 14b snoop [-h]");
46 PrintAndLog(" -h this help");
47 PrintAndLog("sample: hf 14b snoop");
50 int usage_hf_14b_sim(void){
51 PrintAndLog("Emulating ISO/IEC 14443 type B tag with 4 UID");
52 PrintAndLog("Usage: hf 14b sim [-h]");
53 PrintAndLog(" -h this help");
54 PrintAndLog("sample: hf 14b sim");
57 int usage_hf_14b_read_srx(void){
58 PrintAndLog("Usage: hf 14b read [h] <1|2>");
59 PrintAndLog("Options:");
60 PrintAndLog(" h this help");
61 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
62 PrintAndLog("sample: hf 14b read 1");
63 PrintAndLog(" : hf 14b read 2");
66 int usage_hf_14b_write_srx(void){
67 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
68 PrintAndLog("Options:");
69 PrintAndLog(" h this help");
70 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
71 PrintAndLog(" <block> BLOCK number depends on tag, special block == FF");
72 PrintAndLog(" <data> hex bytes of data to be written");
73 PrintAndLog("sample : hf 14b write 1 7F 11223344");
74 PrintAndLog(" : hf 14b write 1 FF 11223344");
75 PrintAndLog(" : hf 14b write 2 15 11223344");
76 PrintAndLog(" : hf 14b write 2 FF 11223344");
80 static int rawClose(){
81 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_DISCONNECT
, 0, 0}};
87 int CmdHF14BList(const char *Cmd
) {
92 int CmdHF14BSim(const char *Cmd
) {
93 char cmdp
= param_getchar(Cmd
, 0);
94 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_sim();
96 UsbCommand c
= {CMD_SIMULATE_TAG_ISO_14443B
, {0, 0, 0}};
102 int CmdHF14BSnoop(const char *Cmd
) {
104 char cmdp
= param_getchar(Cmd
, 0);
105 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_snoop();
107 UsbCommand c
= {CMD_SNOOP_ISO_14443B
, {0, 0, 0}};
108 clearCommandBuffer();
113 int CmdHF14BCmdRaw (const char *Cmd
) {
120 uint8_t data
[USB_CMD_DATA_SIZE
] = {0x00};
121 uint16_t datalen
= 0;
125 if (strlen(Cmd
)<3) return usage_hf_14b_raw();
128 while (*Cmd
==' ' || *Cmd
=='\t') ++Cmd
;
130 while (Cmd
[i
]!='\0') {
131 if (Cmd
[i
]==' ' || Cmd
[i
]=='\t') { ++i
; continue; }
136 return usage_hf_14b_raw();
143 flags
|= ISO14B_APPEND_CRC
;
151 flags
|= ISO14B_CONNECT
;
153 if (Cmd
[i
+2]=='s' || Cmd
[i
+2]=='S') {
154 flags
|= ISO14B_SELECT_SR
;
157 flags
|= ISO14B_SELECT_STD
;
161 return usage_hf_14b_raw();
166 if ((Cmd
[i
]>='0' && Cmd
[i
]<='9') ||
167 (Cmd
[i
]>='a' && Cmd
[i
]<='f') ||
168 (Cmd
[i
]>='A' && Cmd
[i
]<='F') ) {
169 buf
[strlen(buf
)+1]=0;
170 buf
[strlen(buf
)]=Cmd
[i
];
173 if (strlen(buf
)>=2) {
174 sscanf(buf
,"%x",&temp
);
175 data
[datalen
++] = (uint8_t)(temp
& 0xff);
177 memset(buf
, 0x00, sizeof(buf
));
181 PrintAndLog("Invalid char on input");
186 flags
|= ISO14B_DISCONNECT
;
191 // Max buffer is USB_CMD_DATA_SIZE
192 datalen
= (datalen
> USB_CMD_DATA_SIZE
) ? USB_CMD_DATA_SIZE
: datalen
;
194 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {flags
, datalen
, 0}};
195 memcpy(c
.d
.asBytes
, data
, datalen
);
196 clearCommandBuffer();
199 if (!reply
) return 1;
202 // get back iso14b_card_select_t, don't print it.
204 success
= waitCmd(FALSE
);
206 // get back response from the raw bytes you sent.
207 if(success
&& datalen
>0) waitCmd(TRUE
);
212 // print full atqb info
214 // 0,1,2,3 = application data
215 // 4 = bit rate capacity
216 // 5 = max frame size / -4 info
217 // 6 = FWI / Coding options
218 static void print_atqb_resp(uint8_t *data
, uint8_t cid
){
219 //PrintAndLog(" UID: %s", sprint_hex(data+1,4));
220 PrintAndLog(" App Data: %s", sprint_hex(data
,4));
221 PrintAndLog(" Protocol: %s", sprint_hex(data
+4,3));
222 uint8_t BitRate
= data
[4];
223 if (!BitRate
) PrintAndLog(" Bit Rate: 106 kbit/s only PICC <-> PCD");
224 if (BitRate
& 0x10) PrintAndLog(" Bit Rate: 212 kbit/s PICC -> PCD supported");
225 if (BitRate
& 0x20) PrintAndLog(" Bit Rate: 424 kbit/s PICC -> PCD supported");
226 if (BitRate
& 0x40) PrintAndLog(" Bit Rate: 847 kbit/s PICC -> PCD supported");
227 if (BitRate
& 0x01) PrintAndLog(" Bit Rate: 212 kbit/s PICC <- PCD supported");
228 if (BitRate
& 0x02) PrintAndLog(" Bit Rate: 424 kbit/s PICC <- PCD supported");
229 if (BitRate
& 0x04) PrintAndLog(" Bit Rate: 847 kbit/s PICC <- PCD supported");
230 if (BitRate
& 0x80) PrintAndLog(" Same bit rate <-> required");
232 uint16_t maxFrame
= data
[5]>>4;
233 if (maxFrame
< 5) maxFrame
= 8 * maxFrame
+ 16;
234 else if (maxFrame
== 5) maxFrame
= 64;
235 else if (maxFrame
== 6) maxFrame
= 96;
236 else if (maxFrame
== 7) maxFrame
= 128;
237 else if (maxFrame
== 8) maxFrame
= 256;
242 PrintAndLog("Max Frame Size: %u%s bytes",maxFrame
, (maxFrame
== 257) ? "+ RFU" : "");
244 uint8_t protocolT
= data
[5] & 0xF;
245 PrintAndLog(" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT
) ? "" : "not " );
247 uint8_t fwt
= data
[6]>>4;
249 uint32_t etus
= (32 << fwt
);
250 uint32_t fwt_time
= (302 << fwt
);
251 PrintAndLog("Frame Wait Integer: %u - %u ETUs | %u µS", fwt
, etus
, fwt_time
);
253 PrintAndLog("Frame Wait Integer: %u - RFU", fwt
);
256 PrintAndLog(" App Data Code: Application is %s",(data
[6]&4) ? "Standard" : "Proprietary");
257 PrintAndLog(" Frame Options: NAD is %ssupported",(data
[6]&2) ? "" : "not ");
258 PrintAndLog(" Frame Options: CID is %ssupported",(data
[6]&1) ? "" : "not ");
259 PrintAndLog("Tag :");
260 PrintAndLog(" Max Buf Length: %u (MBLI) %s", cid
>>4, (cid
& 0xF0) ? "" : "chained frames not supported");
261 PrintAndLog(" CDI : %u", cid
& 0x0f);
265 // get SRx chip model (from UID) // from ST Microelectronics
266 char *get_ST_Chip_Model(uint8_t data
){
267 static char model
[20];
268 char *retStr
= model
;
269 memset(model
,0, sizeof(model
));
272 case 0x0: sprintf(retStr
, "SRIX4K (Special)"); break;
273 case 0x2: sprintf(retStr
, "SR176"); break;
274 case 0x3: sprintf(retStr
, "SRIX4K"); break;
275 case 0x4: sprintf(retStr
, "SRIX512"); break;
276 case 0x6: sprintf(retStr
, "SRI512"); break;
277 case 0x7: sprintf(retStr
, "SRI4K"); break;
278 case 0xC: sprintf(retStr
, "SRT512"); break;
279 default : sprintf(retStr
, "Unknown"); break;
285 int print_ST_Lock_info(uint8_t model
){
287 // PrintAndLog("Chip Write Protection Bits:");
288 // // now interpret the data
290 // case 0x0: //fall through (SRIX4K special)
291 // case 0x3: //fall through (SRIx4K)
292 // case 0x7: // (SRI4K)
293 // //only need data[3]
295 // PrintAndLog(" raw: %s", sprint_bin(data+3, 1));
296 // PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
297 // for (uint8_t i = 1; i<8; i++){
298 // PrintAndLog(" %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
302 // case 0x4: //fall through (SRIX512)
303 // case 0x6: //fall through (SRI512)
304 // case 0xC: // (SRT512)
305 // //need data[2] and data[3]
307 // PrintAndLog(" raw: %s", sprint_bin(data+2, 2));
308 // for (uint8_t b=2; b<4; b++){
309 // for (uint8_t i=0; i<8; i++){
310 // PrintAndLog(" %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
315 // case 0x2: // (SR176)
318 // PrintAndLog(" raw: %s", sprint_bin(data+2, 1));
319 // for (uint8_t i = 0; i<8; i++){
320 // PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
325 // return rawClose();
330 // print UID info from SRx chips (ST Microelectronics)
331 static void print_st_general_info(uint8_t *data
, uint8_t len
){
332 //uid = first 8 bytes in data
333 PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data
,8,8), len
));
334 PrintAndLog(" MFG: %02X, %s", data
[6], getTagInfo(data
[6]));
335 PrintAndLog("Chip: %02X, %s", data
[5]>>2, get_ST_Chip_Model(data
[5]>>2));
339 //05 00 00 = find one tag in field
340 //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
341 //a3 = ? (resp 03 [e2 c2])
342 //02 = ? (resp 02 [6a d3])
343 // 022b (resp 02 67 00 [29 5b])
344 // 0200a40400 (resp 02 67 00 [29 5b])
345 // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
346 // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
347 // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
348 // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
349 // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
350 // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
351 // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
352 //03 = ? (resp 03 [e3 c2])
353 //c2 = ? (resp c2 [66 15])
354 //b2 = ? (resp a3 [e9 67])
355 //a2 = ? (resp 02 [6a d3])
357 // 14b get and print Full Info (as much as we know)
358 bool HF14B_Std_Info(bool verbose
){
363 // SRx get and print full info (needs more info...)
364 bool HF14B_ST_Info(bool verbose
){
366 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_SR
| ISO14B_DISCONNECT
, 0, 0}};
367 clearCommandBuffer();
371 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
372 if (verbose
) PrintAndLog("timeout while waiting for reply.");
376 iso14b_card_select_t card
;
377 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
379 uint64_t status
= resp
.arg
[0];
385 //add locking bit information here. uint8_t data[16] = {0x00};
386 // uint8_t datalen = 2;
392 // if (model == 0x2) { //SR176 has special command:
401 // if (HF14BCmdRaw(true, true, data, &datalen, false)==0)
402 // return rawClose();
404 // if (datalen != resplen || !crc) return rawClose();
405 //print_ST_Lock_info(data[5]>>2);
410 // get and print all info known about any known 14b tag
411 bool HF14BInfo(bool verbose
){
413 // try std 14b (atqb)
414 if (HF14B_Std_Info(verbose
)) return TRUE
;
417 if (HF14B_ST_Info(verbose
)) return TRUE
;
419 // try unknown 14b read commands (to be identified later)
420 // could be read of calypso, CEPAS, moneo, or pico pass.
422 if (verbose
) PrintAndLog("no 14443B tag found");
426 // menu command to get and print all info known about any known 14b tag
427 int CmdHF14Binfo(const char *Cmd
){
428 char cmdp
= param_getchar(Cmd
, 0);
429 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_info();
431 bool verbose
= !((cmdp
== 's') || (cmdp
== 'S'));
432 return HF14BInfo(verbose
);
435 bool HF14B_ST_Reader(bool verbose
){
437 bool isSuccess
= FALSE
;
439 // SRx get and print general info about SRx chip from UID
440 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_SR
| ISO14B_DISCONNECT
, 0, 0}};
441 clearCommandBuffer();
445 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
446 if (verbose
) PrintAndLog("timeout while waiting for reply.");
451 iso14b_card_select_t card
;
452 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
454 uint64_t status
= resp
.arg
[0];
458 print_st_general_info(card
.uid
, card
.uidlen
);
462 if (verbose
) PrintAndLog("iso14443-3 random chip id fail");
465 if (verbose
) PrintAndLog("iso14443-3 ATTRIB fail");
468 if (verbose
) PrintAndLog("iso14443-3 CRC fail");
471 if (verbose
) PrintAndLog("iso14443b card select SRx failed");
479 bool HF14B_Std_Reader(bool verbose
){
481 bool isSuccess
= FALSE
;
483 // 14b get and print UID only (general info)
484 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_STD
| ISO14B_DISCONNECT
, 0, 0}};
485 clearCommandBuffer();
489 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
490 if (verbose
) PrintAndLog("timeout while waiting for reply.");
494 iso14b_card_select_t card
;
495 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
497 uint64_t status
= resp
.arg
[0];
501 PrintAndLog(" UID : %s", sprint_hex(card
.uid
, card
.uidlen
));
502 PrintAndLog(" ATQB : %s", sprint_hex(card
.atqb
, sizeof(card
.atqb
)));
503 PrintAndLog(" CHIPID : %02X", card
.chipid
);
504 print_atqb_resp(card
.atqb
, card
.cid
);
508 if (verbose
) PrintAndLog("iso14443-3 ATTRIB fail");
511 if (verbose
) PrintAndLog("iso14443-3 CRC fail");
514 if (verbose
) PrintAndLog("iso14443b card select failed");
522 // test for other 14b type tags (mimic another reader - don't have tags to identify)
523 bool HF14B_Other_Reader(){
525 // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
526 // uint8_t datalen = 4;
528 // // 14b get and print UID only (general info)
529 // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
531 // UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
532 // memcpy(c.d.asBytes, data, datalen);
534 // clearCommandBuffer();
537 // WaitForResponse(CMD_ACK,&resp);
539 // if (datalen > 2 ) {
540 // printandlog ("\n14443-3b tag found:");
541 // printandlog ("unknown tag type answered to a 0x000b3f80 command ans:");
542 // //printandlog ("%s", sprint_hex(data, datalen));
548 // c.d.asBytes[0] = ISO14443B_AUTHENTICATE;
549 // clearCommandBuffer();
552 // WaitForResponse(CMD_ACK, &resp);
554 // if (datalen > 0) {
555 // PrintAndLog ("\n14443-3b tag found:");
556 // PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
557 // // PrintAndLog ("%s", sprint_hex(data, datalen));
563 // c.d.asBytes[0] = ISO14443B_RESET;
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 0x0C command ans:");
572 // PrintAndLog ("%s", sprint_hex(data, datalen));
581 // get and print general info about all known 14b chips
582 bool HF14BReader(bool verbose
){
584 // try std 14b (atqb)
585 if (HF14B_Std_Reader(verbose
)) return TRUE
;
587 // try ST Microelectronics 14b
588 if (HF14B_ST_Reader(verbose
)) return TRUE
;
590 // try unknown 14b read commands (to be identified later)
591 // could be read of calypso, CEPAS, moneo, or pico pass.
592 if (HF14B_Other_Reader()) return TRUE
;
594 if (verbose
) PrintAndLog("no 14443B tag found");
598 // menu command to get and print general info about all known 14b chips
599 int CmdHF14BReader(const char *Cmd
){
600 char cmdp
= param_getchar(Cmd
, 0);
601 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_reader();
603 bool verbose
= !((cmdp
== 's') || (cmdp
== 'S'));
604 return HF14BReader(verbose
);
607 /* New command to read the contents of a SRI512|SRIX4K tag
608 * SRI* tags are ISO14443-B modulated memory tags,
609 * this command just dumps the contents of the memory/
611 int CmdHF14BReadSri(const char *Cmd
){
612 char cmdp
= param_getchar(Cmd
, 0);
613 if (strlen(Cmd
) < 1 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_read_srx();
615 uint8_t tagtype
= param_get8(Cmd
, 0);
616 uint8_t blocks
= (tagtype
== 1) ? 0x7F : 0x0F;
618 UsbCommand c
= {CMD_READ_SRI_TAG
, {blocks
, 0, 0}};
619 clearCommandBuffer();
623 // New command to write a SRI512/SRIX4K tag.
624 int CmdHF14BWriteSri(const char *Cmd
){
626 * For SRIX4K blocks 00 - 7F
627 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
629 * For SR512 blocks 00 - 0F
630 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
632 * Special block FF = otp_lock_reg block.
635 char cmdp
= param_getchar(Cmd
, 0);
636 uint8_t blockno
= -1;
637 uint8_t data
[4] = {0x00};
638 bool isSrix4k
= true;
640 memset(str
, 0x00, sizeof(str
));
642 if (strlen(Cmd
) < 1 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_write_srx();
647 //blockno = param_get8(Cmd, 1);
649 if ( param_gethex(Cmd
, 1, &blockno
, 2) ) {
650 PrintAndLog("Block number must include 2 HEX symbols");
655 if ( blockno
> 0x7f && blockno
!= 0xff ){
656 PrintAndLog("Block number out of range");
660 if ( blockno
> 0x0f && blockno
!= 0xff ){
661 PrintAndLog("Block number out of range");
666 if (param_gethex(Cmd
, 2, data
, 8)) {
667 PrintAndLog("Data must include 8 HEX symbols");
671 if ( blockno
== 0xff) {
672 PrintAndLog("[%s] Write special block %02X [ %s ]",
673 (isSrix4k
) ? "SRIX4K":"SRI512",
678 PrintAndLog("[%s] Write block %02X [ %s ]",
679 (isSrix4k
) ? "SRIX4K":"SRI512",
685 sprintf(str
, "-ss -c %02x %02x %02x%02x%02x%02x", ISO14443B_WRITE_BLK
, blockno
, data
[0], data
[1], data
[2], data
[3]);
690 uint32_t srix4kEncode(uint32_t value
) {
695 4 bytes : 00 1A 20 01
697 // only the lower crumbs.
698 uint8_t block
= (value
& 0xFF);
700 uint8_t valuebytes
[] = {0,0,0};
702 num_to_bytes(value
, 3, valuebytes
);
705 // Crumb swapping of value.
706 uint8_t temp
[] = {0,0};
707 temp
[0] = (CRUMB(value
, 22) << 4 | CRUMB(value
, 14 ) << 2 | CRUMB(value
, 6)) << 4;
708 temp
[0] |= CRUMB(value
, 20) << 4 | CRUMB(value
, 12 ) << 2 | CRUMB(value
, 4);
709 temp
[1] = (CRUMB(value
, 18) << 4 | CRUMB(value
, 10 ) << 2 | CRUMB(value
, 2)) << 4;
710 temp
[1] |= CRUMB(value
, 16) << 4 | CRUMB(value
, 8 ) << 2 | CRUMB(value
, 0);
713 uint32_t chksum
= 0xFF - block
;
715 // chksum is reduced by each nibbles of value.
716 for (i
= 0; i
< 3; ++i
){
717 chksum
-= NIBBLE_HIGH(valuebytes
[i
]);
718 chksum
-= NIBBLE_LOW(valuebytes
[i
]);
721 // base4 conversion and left shift twice
723 uint8_t base4
[] = {0,0,0,0};
725 base4
[i
--] = (chksum
% 4 << 2);
729 // merge scambled and chksum parts
731 ( NIBBLE_LOW ( base4
[0]) << 28 ) |
732 ( NIBBLE_HIGH( temp
[0]) << 24 ) |
734 ( NIBBLE_LOW ( base4
[1]) << 20 ) |
735 ( NIBBLE_LOW ( temp
[0]) << 16 ) |
737 ( NIBBLE_LOW ( base4
[2]) << 12 ) |
738 ( NIBBLE_HIGH( temp
[1]) << 8 ) |
740 ( NIBBLE_LOW ( base4
[3]) << 4 ) |
741 NIBBLE_LOW ( temp
[1] );
743 PrintAndLog("ICE encoded | %08X -> %08X", value
, encvalue
);
746 uint32_t srix4kDecode(uint32_t value
) {
748 case 0xC04F42C5: return 0x003139;
749 case 0xC1484807: return 0x002943;
750 case 0xC0C60848: return 0x001A20;
754 uint32_t srix4kDecodeCounter(uint32_t num
) {
755 uint32_t value
= ~num
;
760 uint32_t srix4kGetMagicbytes( uint64_t uid
, uint32_t block6
, uint32_t block18
, uint32_t block19
){
761 #define MASK 0xFFFFFFFF;
762 uint32_t uid32
= uid
& MASK
;
763 uint32_t counter
= srix4kDecodeCounter(block6
);
764 uint32_t decodedBlock18
= srix4kDecode(block18
);
765 uint32_t decodedBlock19
= srix4kDecode(block19
);
766 uint32_t doubleBlock
= (decodedBlock18
<< 16 | decodedBlock19
) + 1;
768 uint32_t result
= (uid32
* doubleBlock
* counter
) & MASK
;
769 PrintAndLog("Magic bytes | %08X", result
);
772 int srix4kValid(const char *Cmd
){
774 uint64_t uid
= 0xD00202501A4532F9;
775 uint32_t block6
= 0xFFFFFFFF;
776 uint32_t block18
= 0xC04F42C5;
777 uint32_t block19
= 0xC1484807;
778 uint32_t block21
= 0xD1BCABA4;
780 uint32_t test_b18
= 0x00313918;
781 uint32_t test_b18_enc
= srix4kEncode(test_b18
);
782 //uint32_t test_b18_dec = srix4kDecode(test_b18_enc);
783 PrintAndLog("ENCODE & CHECKSUM | %08X -> %08X (%s)", test_b18
, test_b18_enc
, "");
785 uint32_t magic
= srix4kGetMagicbytes(uid
, block6
, block18
, block19
);
786 PrintAndLog("BLOCK 21 | %08X -> %08X (no XOR)", block21
, magic
^ block21
);
790 int CmdteaSelfTest(const char *Cmd
){
792 uint8_t v
[8], v_le
[8];
793 memset(v
, 0x00, sizeof(v
));
794 memset(v_le
, 0x00, sizeof(v_le
));
795 uint8_t* v_ptr
= v_le
;
797 uint8_t cmdlen
= strlen(Cmd
);
798 cmdlen
= ( sizeof(v
)<<2 < cmdlen
) ? sizeof(v
)<<2 : cmdlen
;
800 if ( param_gethex(Cmd
, 0, v
, cmdlen
) > 0 ){
801 PrintAndLog("can't read hex chars, uneven? :: %u", cmdlen
);
805 SwapEndian64ex(v
, 8, 4, v_ptr
);
808 uint8_t key
[16] = {0x55,0xFE,0xF6,0x30,0x62,0xBF,0x0B,0xC1,0xC9,0xB3,0x7C,0x34,0x97,0x3E,0x29,0xFB };
810 uint8_t* key_ptr
= keyle
;
811 SwapEndian64ex(key
, sizeof(key
), 4, key_ptr
);
813 PrintAndLog("TEST LE enc| %s", sprint_hex(v_ptr
, 8));
815 tea_decrypt(v_ptr
, key_ptr
);
816 PrintAndLog("TEST LE dec | %s", sprint_hex_ascii(v_ptr
, 8));
818 tea_encrypt(v_ptr
, key_ptr
);
819 tea_encrypt(v_ptr
, key_ptr
);
820 PrintAndLog("TEST enc2 | %s", sprint_hex_ascii(v_ptr
, 8));
825 bool waitCmd(bool verbose
) {
828 uint8_t b1
= 0, b2
= 0;
829 uint8_t data
[USB_CMD_DATA_SIZE
] = {0x00};
834 if (WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
836 status
= (resp
.arg
[0] & 0xFFFF);
837 if ( status
> 0 ) return FALSE
;
839 len
= (resp
.arg
[1] & 0xFFFF);
840 memcpy(data
, resp
.d
.asBytes
, len
);
844 ComputeCrc14443(CRC_14443_B
, data
, len
-2, &b1
, &b2
);
845 crc
= ( data
[len
-2] == b1
&& data
[len
-1] == b2
);
847 PrintAndLog("[LEN %u] %s[%02X %02X] %s",
849 sprint_hex(data
, len
-2),
852 (crc
) ? "OK" : "FAIL"
857 PrintAndLog("timeout while waiting for reply.");
862 static command_t CommandTable
[] = {
863 {"help", CmdHelp
, 1, "This help"},
864 {"info", CmdHF14Binfo
, 0, "Find and print details about a 14443B tag"},
865 {"list", CmdHF14BList
, 0, "[Deprecated] List ISO 14443B history"},
866 {"raw", CmdHF14BCmdRaw
, 0, "Send raw hex data to tag"},
867 {"reader", CmdHF14BReader
, 0, "Act as a 14443B reader to identify a tag"},
868 {"sim", CmdHF14BSim
, 0, "Fake ISO 14443B tag"},
869 {"snoop", CmdHF14BSnoop
, 0, "Eavesdrop ISO 14443B"},
870 {"sriread", CmdHF14BReadSri
, 0, "Read contents of a SRI512 | SRIX4K tag"},
871 {"sriwrite", CmdHF14BWriteSri
, 0, "Write data to a SRI512 | SRIX4K tag"},
872 //{"valid", srix4kValid, 1, "srix4k checksum test"},
873 //{"valid", CmdteaSelfTest, 1, "tea test"},
874 {NULL
, NULL
, 0, NULL
}
877 int CmdHF14B(const char *Cmd
) {
878 clearCommandBuffer();
879 CmdsParse(CommandTable
, Cmd
);
883 int CmdHelp(const char *Cmd
) {
884 CmdsHelp(CommandTable
);