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
213 static void print_atqb_resp(uint8_t *data
, uint8_t cid
){
214 //PrintAndLog (" UID: %s", sprint_hex(data+1,4));
215 PrintAndLog (" App Data: %s", sprint_hex(data
,4));
216 PrintAndLog (" Protocol: %s", sprint_hex(data
+4,3));
217 uint8_t BitRate
= data
[4];
218 if (!BitRate
) PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD");
219 if (BitRate
& 0x10) PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported");
220 if (BitRate
& 0x20) PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported");
221 if (BitRate
& 0x40) PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported");
222 if (BitRate
& 0x01) PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported");
223 if (BitRate
& 0x02) PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported");
224 if (BitRate
& 0x04) PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported");
225 if (BitRate
& 0x80) PrintAndLog (" Same bit rate <-> required");
227 uint16_t maxFrame
= data
[5]>>4;
228 if (maxFrame
< 5) maxFrame
= 8 * maxFrame
+ 16;
229 else if (maxFrame
== 5) maxFrame
= 64;
230 else if (maxFrame
== 6) maxFrame
= 96;
231 else if (maxFrame
== 7) maxFrame
= 128;
232 else if (maxFrame
== 8) maxFrame
= 256;
235 PrintAndLog ("Max Frame Size: %u%s",maxFrame
, (maxFrame
== 257) ? "+ RFU" : "");
237 uint8_t protocolT
= data
[5] & 0xF;
238 PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT
) ? "" : "not " );
239 PrintAndLog ("Frame Wait Int: %u", data
[6]>>4);
240 PrintAndLog (" App Data Code: Application is %s",(data
[6]&4) ? "Standard" : "Proprietary");
241 PrintAndLog (" Frame Options: NAD is %ssupported",(data
[6]&2) ? "" : "not ");
242 PrintAndLog (" Frame Options: CID is %ssupported",(data
[6]&1) ? "" : "not ");
243 PrintAndLog ("Tag :");
244 PrintAndLog (" Max Buf Length: %u (MBLI) %s",cid
>>4, (cid
& 0xF0) ? "" : "not supported");
245 PrintAndLog (" Cid : %u", cid
& 0x0f);
249 // get SRx chip model (from UID) // from ST Microelectronics
250 char *get_ST_Chip_Model(uint8_t data
){
251 static char model
[20];
252 char *retStr
= model
;
253 memset(model
,0, sizeof(model
));
256 case 0x0: sprintf(retStr
, "SRIX4K (Special)"); break;
257 case 0x2: sprintf(retStr
, "SR176"); break;
258 case 0x3: sprintf(retStr
, "SRIX4K"); break;
259 case 0x4: sprintf(retStr
, "SRIX512"); break;
260 case 0x6: sprintf(retStr
, "SRI512"); break;
261 case 0x7: sprintf(retStr
, "SRI4K"); break;
262 case 0xC: sprintf(retStr
, "SRT512"); break;
263 default : sprintf(retStr
, "Unknown"); break;
269 int print_ST_Lock_info(uint8_t model
){
271 // PrintAndLog("Chip Write Protection Bits:");
272 // // now interpret the data
274 // case 0x0: //fall through (SRIX4K special)
275 // case 0x3: //fall through (SRIx4K)
276 // case 0x7: // (SRI4K)
277 // //only need data[3]
279 // PrintAndLog(" raw: %s", sprint_bin(data+3, 1));
280 // PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
281 // for (uint8_t i = 1; i<8; i++){
282 // PrintAndLog(" %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
286 // case 0x4: //fall through (SRIX512)
287 // case 0x6: //fall through (SRI512)
288 // case 0xC: // (SRT512)
289 // //need data[2] and data[3]
291 // PrintAndLog(" raw: %s", sprint_bin(data+2, 2));
292 // for (uint8_t b=2; b<4; b++){
293 // for (uint8_t i=0; i<8; i++){
294 // PrintAndLog(" %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
299 // case 0x2: // (SR176)
302 // PrintAndLog(" raw: %s", sprint_bin(data+2, 1));
303 // for (uint8_t i = 0; i<8; i++){
304 // PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
309 // return rawClose();
314 // print UID info from SRx chips (ST Microelectronics)
315 static void print_st_general_info(uint8_t *data
, uint8_t len
){
316 //uid = first 8 bytes in data
317 PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data
,8,8), len
));
318 PrintAndLog(" MFG: %02X, %s", data
[6], getTagInfo(data
[6]));
319 PrintAndLog("Chip: %02X, %s", data
[5]>>2, get_ST_Chip_Model(data
[5]>>2));
323 //05 00 00 = find one tag in field
324 //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
325 //a3 = ? (resp 03 [e2 c2])
326 //02 = ? (resp 02 [6a d3])
327 // 022b (resp 02 67 00 [29 5b])
328 // 0200a40400 (resp 02 67 00 [29 5b])
329 // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
330 // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
331 // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
332 // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
333 // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
334 // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
335 // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
336 //03 = ? (resp 03 [e3 c2])
337 //c2 = ? (resp c2 [66 15])
338 //b2 = ? (resp a3 [e9 67])
339 //a2 = ? (resp 02 [6a d3])
341 // 14b get and print Full Info (as much as we know)
342 bool HF14B_Std_Info(bool verbose
){
347 // SRx get and print full info (needs more info...)
348 bool HF14B_ST_Info(bool verbose
){
350 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_SR
| ISO14B_DISCONNECT
, 0, 0}};
351 clearCommandBuffer();
355 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
356 if (verbose
) PrintAndLog("timeout while waiting for reply.");
360 iso14b_card_select_t card
;
361 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
363 uint64_t status
= resp
.arg
[0];
369 //add locking bit information here. uint8_t data[16] = {0x00};
370 // uint8_t datalen = 2;
376 // if (model == 0x2) { //SR176 has special command:
385 // if (HF14BCmdRaw(true, true, data, &datalen, false)==0)
386 // return rawClose();
388 // if (datalen != resplen || !crc) return rawClose();
389 //print_ST_Lock_info(data[5]>>2);
394 // get and print all info known about any known 14b tag
395 bool HF14BInfo(bool verbose
){
397 // try std 14b (atqb)
398 if (HF14B_Std_Info(verbose
)) return TRUE
;
401 if (HF14B_ST_Info(verbose
)) return TRUE
;
403 // try unknown 14b read commands (to be identified later)
404 // could be read of calypso, CEPAS, moneo, or pico pass.
406 if (verbose
) PrintAndLog("no 14443B tag found");
410 // menu command to get and print all info known about any known 14b tag
411 int CmdHF14Binfo(const char *Cmd
){
412 char cmdp
= param_getchar(Cmd
, 0);
413 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_info();
415 bool verbose
= !((cmdp
== 's') || (cmdp
== 'S'));
416 return HF14BInfo(verbose
);
419 bool HF14B_ST_Reader(bool verbose
){
421 bool isSuccess
= FALSE
;
423 // SRx get and print general info about SRx chip from UID
424 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_SR
| ISO14B_DISCONNECT
, 0, 0}};
425 clearCommandBuffer();
429 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
430 if (verbose
) PrintAndLog("timeout while waiting for reply.");
435 iso14b_card_select_t card
;
436 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
438 uint64_t status
= resp
.arg
[0];
442 print_st_general_info(card
.uid
, card
.uidlen
);
446 if (verbose
) PrintAndLog("iso14443-3 random chip id fail");
449 if (verbose
) PrintAndLog("iso14443-3 ATTRIB fail");
452 if (verbose
) PrintAndLog("iso14443-3 CRC fail");
455 if (verbose
) PrintAndLog("iso14443b card select SRx failed");
463 bool HF14B_Std_Reader(bool verbose
){
465 bool isSuccess
= FALSE
;
467 // 14b get and print UID only (general info)
468 UsbCommand c
= {CMD_ISO_14443B_COMMAND
, {ISO14B_CONNECT
| ISO14B_SELECT_STD
| ISO14B_DISCONNECT
, 0, 0}};
469 clearCommandBuffer();
473 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
474 if (verbose
) PrintAndLog("timeout while waiting for reply.");
478 iso14b_card_select_t card
;
479 memcpy(&card
, (iso14b_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14b_card_select_t
));
481 uint64_t status
= resp
.arg
[0];
485 PrintAndLog(" UID : %s", sprint_hex(card
.uid
, card
.uidlen
));
486 PrintAndLog(" ATQB : %s", sprint_hex(card
.atqb
, sizeof(card
.atqb
)));
487 PrintAndLog(" CHIPID : %02X", card
.chipid
);
488 print_atqb_resp(card
.atqb
, card
.cid
);
492 if (verbose
) PrintAndLog("iso14443-3 ATTRIB fail");
495 if (verbose
) PrintAndLog("iso14443-3 CRC fail");
498 if (verbose
) PrintAndLog("iso14443b card select failed");
506 // test for other 14b type tags (mimic another reader - don't have tags to identify)
507 bool HF14B_Other_Reader(){
509 // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
510 // uint8_t datalen = 4;
512 // // 14b get and print UID only (general info)
513 // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
515 // UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
516 // memcpy(c.d.asBytes, data, datalen);
518 // clearCommandBuffer();
521 // WaitForResponse(CMD_ACK,&resp);
523 // if (datalen > 2 ) {
524 // printandlog ("\n14443-3b tag found:");
525 // printandlog ("unknown tag type answered to a 0x000b3f80 command ans:");
526 // //printandlog ("%s", sprint_hex(data, datalen));
532 // c.d.asBytes[0] = ISO14443B_AUTHENTICATE;
533 // clearCommandBuffer();
536 // WaitForResponse(CMD_ACK, &resp);
538 // if (datalen > 0) {
539 // PrintAndLog ("\n14443-3b tag found:");
540 // PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
541 // // PrintAndLog ("%s", sprint_hex(data, datalen));
547 // c.d.asBytes[0] = ISO14443B_RESET;
548 // clearCommandBuffer();
551 // WaitForResponse(CMD_ACK, &resp);
553 // if (datalen > 0) {
554 // PrintAndLog ("\n14443-3b tag found:");
555 // PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
556 // PrintAndLog ("%s", sprint_hex(data, datalen));
565 // get and print general info about all known 14b chips
566 bool HF14BReader(bool verbose
){
568 // try std 14b (atqb)
569 if (HF14B_Std_Reader(verbose
)) return TRUE
;
571 // try ST Microelectronics 14b
572 if (HF14B_ST_Reader(verbose
)) return TRUE
;
574 // try unknown 14b read commands (to be identified later)
575 // could be read of calypso, CEPAS, moneo, or pico pass.
576 if (HF14B_Other_Reader()) return TRUE
;
578 if (verbose
) PrintAndLog("no 14443B tag found");
582 // menu command to get and print general info about all known 14b chips
583 int CmdHF14BReader(const char *Cmd
){
584 char cmdp
= param_getchar(Cmd
, 0);
585 if (cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_reader();
587 bool verbose
= !((cmdp
== 's') || (cmdp
== 'S'));
588 return HF14BReader(verbose
);
591 /* New command to read the contents of a SRI512|SRIX4K tag
592 * SRI* tags are ISO14443-B modulated memory tags,
593 * this command just dumps the contents of the memory/
595 int CmdHF14BReadSri(const char *Cmd
){
596 char cmdp
= param_getchar(Cmd
, 0);
597 if (strlen(Cmd
) < 1 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_read_srx();
599 uint8_t tagtype
= param_get8(Cmd
, 0);
600 uint8_t blocks
= (tagtype
== 1) ? 0x7F : 0x0F;
602 UsbCommand c
= {CMD_READ_SRI_TAG
, {blocks
, 0, 0}};
603 clearCommandBuffer();
607 // New command to write a SRI512/SRIX4K tag.
608 int CmdHF14BWriteSri(const char *Cmd
){
610 * For SRIX4K blocks 00 - 7F
611 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
613 * For SR512 blocks 00 - 0F
614 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
616 * Special block FF = otp_lock_reg block.
619 char cmdp
= param_getchar(Cmd
, 0);
620 uint8_t blockno
= -1;
621 uint8_t data
[4] = {0x00};
622 bool isSrix4k
= true;
624 memset(str
, 0x00, sizeof(str
));
626 if (strlen(Cmd
) < 1 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_14b_write_srx();
631 //blockno = param_get8(Cmd, 1);
633 if ( param_gethex(Cmd
, 1, &blockno
, 2) ) {
634 PrintAndLog("Block number must include 2 HEX symbols");
639 if ( blockno
> 0x7f && blockno
!= 0xff ){
640 PrintAndLog("Block number out of range");
644 if ( blockno
> 0x0f && blockno
!= 0xff ){
645 PrintAndLog("Block number out of range");
650 if (param_gethex(Cmd
, 2, data
, 8)) {
651 PrintAndLog("Data must include 8 HEX symbols");
655 if ( blockno
== 0xff) {
656 PrintAndLog("[%s] Write special block %02X [ %s ]",
657 (isSrix4k
) ? "SRIX4K":"SRI512",
662 PrintAndLog("[%s] Write block %02X [ %s ]",
663 (isSrix4k
) ? "SRIX4K":"SRI512",
669 sprintf(str
, "-ss -c %02x %02x %02x%02x%02x%02x", ISO14443B_WRITE_BLK
, blockno
, data
[0], data
[1], data
[2], data
[3]);
674 uint32_t srix4kEncode(uint32_t value
) {
679 4 bytes : 00 1A 20 01
681 // only the lower crumbs.
682 uint8_t block
= (value
& 0xFF);
684 uint8_t valuebytes
[] = {0,0,0};
686 num_to_bytes(value
, 3, valuebytes
);
689 // Crumb swapping of value.
690 uint8_t temp
[] = {0,0};
691 temp
[0] = (CRUMB(value
, 22) << 4 | CRUMB(value
, 14 ) << 2 | CRUMB(value
, 6)) << 4;
692 temp
[0] |= CRUMB(value
, 20) << 4 | CRUMB(value
, 12 ) << 2 | CRUMB(value
, 4);
693 temp
[1] = (CRUMB(value
, 18) << 4 | CRUMB(value
, 10 ) << 2 | CRUMB(value
, 2)) << 4;
694 temp
[1] |= CRUMB(value
, 16) << 4 | CRUMB(value
, 8 ) << 2 | CRUMB(value
, 0);
697 uint32_t chksum
= 0xFF - block
;
699 // chksum is reduced by each nibbles of value.
700 for (i
= 0; i
< 3; ++i
){
701 chksum
-= NIBBLE_HIGH(valuebytes
[i
]);
702 chksum
-= NIBBLE_LOW(valuebytes
[i
]);
705 // base4 conversion and left shift twice
707 uint8_t base4
[] = {0,0,0,0};
709 base4
[i
--] = (chksum
% 4 << 2);
713 // merge scambled and chksum parts
715 ( NIBBLE_LOW ( base4
[0]) << 28 ) |
716 ( NIBBLE_HIGH( temp
[0]) << 24 ) |
718 ( NIBBLE_LOW ( base4
[1]) << 20 ) |
719 ( NIBBLE_LOW ( temp
[0]) << 16 ) |
721 ( NIBBLE_LOW ( base4
[2]) << 12 ) |
722 ( NIBBLE_HIGH( temp
[1]) << 8 ) |
724 ( NIBBLE_LOW ( base4
[3]) << 4 ) |
725 NIBBLE_LOW ( temp
[1] );
727 PrintAndLog("ICE encoded | %08X -> %08X", value
, encvalue
);
730 uint32_t srix4kDecode(uint32_t value
) {
732 case 0xC04F42C5: return 0x003139;
733 case 0xC1484807: return 0x002943;
734 case 0xC0C60848: return 0x001A20;
738 uint32_t srix4kDecodeCounter(uint32_t num
) {
739 uint32_t value
= ~num
;
744 uint32_t srix4kGetMagicbytes( uint64_t uid
, uint32_t block6
, uint32_t block18
, uint32_t block19
){
745 #define MASK 0xFFFFFFFF;
746 uint32_t uid32
= uid
& MASK
;
747 uint32_t counter
= srix4kDecodeCounter(block6
);
748 uint32_t decodedBlock18
= srix4kDecode(block18
);
749 uint32_t decodedBlock19
= srix4kDecode(block19
);
750 uint32_t doubleBlock
= (decodedBlock18
<< 16 | decodedBlock19
) + 1;
752 uint32_t result
= (uid32
* doubleBlock
* counter
) & MASK
;
753 PrintAndLog("Magic bytes | %08X", result
);
756 int srix4kValid(const char *Cmd
){
758 uint64_t uid
= 0xD00202501A4532F9;
759 uint32_t block6
= 0xFFFFFFFF;
760 uint32_t block18
= 0xC04F42C5;
761 uint32_t block19
= 0xC1484807;
762 uint32_t block21
= 0xD1BCABA4;
764 uint32_t test_b18
= 0x00313918;
765 uint32_t test_b18_enc
= srix4kEncode(test_b18
);
766 //uint32_t test_b18_dec = srix4kDecode(test_b18_enc);
767 PrintAndLog("ENCODE & CHECKSUM | %08X -> %08X (%s)", test_b18
, test_b18_enc
, "");
769 uint32_t magic
= srix4kGetMagicbytes(uid
, block6
, block18
, block19
);
770 PrintAndLog("BLOCK 21 | %08X -> %08X (no XOR)", block21
, magic
^ block21
);
774 int CmdteaSelfTest(const char *Cmd
){
776 uint8_t v
[8], v_le
[8];
777 memset(v
, 0x00, sizeof(v
));
778 memset(v_le
, 0x00, sizeof(v_le
));
779 uint8_t* v_ptr
= v_le
;
781 uint8_t cmdlen
= strlen(Cmd
);
782 cmdlen
= ( sizeof(v
)<<2 < cmdlen
) ? sizeof(v
)<<2 : cmdlen
;
784 if ( param_gethex(Cmd
, 0, v
, cmdlen
) > 0 ){
785 PrintAndLog("can't read hex chars, uneven? :: %u", cmdlen
);
789 SwapEndian64ex(v
, 8, 4, v_ptr
);
792 uint8_t key
[16] = {0x55,0xFE,0xF6,0x30,0x62,0xBF,0x0B,0xC1,0xC9,0xB3,0x7C,0x34,0x97,0x3E,0x29,0xFB };
794 uint8_t* key_ptr
= keyle
;
795 SwapEndian64ex(key
, sizeof(key
), 4, key_ptr
);
797 PrintAndLog("TEST LE enc| %s", sprint_hex(v_ptr
, 8));
799 tea_decrypt(v_ptr
, key_ptr
);
800 PrintAndLog("TEST LE dec | %s", sprint_hex_ascii(v_ptr
, 8));
802 tea_encrypt(v_ptr
, key_ptr
);
803 tea_encrypt(v_ptr
, key_ptr
);
804 PrintAndLog("TEST enc2 | %s", sprint_hex_ascii(v_ptr
, 8));
809 bool waitCmd(bool verbose
) {
812 uint8_t b1
= 0, b2
= 0;
813 uint8_t data
[USB_CMD_DATA_SIZE
] = {0x00};
818 if (WaitForResponseTimeout(CMD_ACK
, &resp
, TIMEOUT
)) {
820 status
= (resp
.arg
[0] & 0xFFFF);
821 if ( status
> 0 ) return FALSE
;
823 len
= (resp
.arg
[1] & 0xFFFF);
824 memcpy(data
, resp
.d
.asBytes
, len
);
828 ComputeCrc14443(CRC_14443_B
, data
, len
-2, &b1
, &b2
);
829 crc
= ( data
[len
-2] == b1
&& data
[len
-1] == b2
);
831 PrintAndLog("[LEN %u] %s[%02X %02X] %s",
833 sprint_hex(data
, len
-2),
836 (crc
) ? "OK" : "FAIL"
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 //{"valid", CmdteaSelfTest, 1, "tea test"},
858 {NULL
, NULL
, 0, NULL
}
861 int CmdHF14B(const char *Cmd
) {
862 clearCommandBuffer();
863 CmdsParse(CommandTable
, Cmd
);
867 int CmdHelp(const char *Cmd
) {
868 CmdsHelp(CommandTable
);