]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14b.c
ADD: added @marshmellow42 's changes to "lfdemod"
[proxmark3-svn] / client / cmdhf14b.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
3 //
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
6 // the license.
7 //-----------------------------------------------------------------------------
8 // High frequency ISO14443B commands
9 //-----------------------------------------------------------------------------
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include "cmdhf14b.h"
16
17 static int CmdHelp(const char *Cmd);
18
19 int usage_hf_14b_info(void){
20 PrintAndLog("Usage: hf 14b info [-h] [-s]");
21 PrintAndLog(" -h this help");
22 PrintAndLog(" -s silently");
23 return 0;
24 }
25 int usage_hf_14b_reader(void){
26 PrintAndLog("Usage: hf 14b reader [-h] [-s]");
27 PrintAndLog(" -h this help");
28 PrintAndLog(" -s silently");
29 return 0;
30 }
31 int usage_hf_14b_raw(void){
32 PrintAndLog("Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
33 PrintAndLog(" -h this help");
34 PrintAndLog(" -r do not read response");
35 PrintAndLog(" -c calculate and append CRC");
36 PrintAndLog(" -p leave the field on after receive");
37 PrintAndLog(" -s active signal field ON with select");
38 PrintAndLog(" -ss active signal field ON with select for SRx ST Microelectronics tags");
39 return 0;
40 }
41 int usage_hf_14b_snoop(void){
42 PrintAndLog("It get data from the field and saves it into command buffer.");
43 PrintAndLog("Buffer accessible from command 'hf list 14b'");
44 PrintAndLog("Usage: hf 14b snoop [-h]");
45 PrintAndLog(" -h this help");
46 PrintAndLog("sample: hf 14b snoop");
47 return 0;
48 }
49 int usage_hf_14b_sim(void){
50 PrintAndLog("Emulating ISO/IEC 14443 type B tag with 4 UID");
51 PrintAndLog("Usage: hf 14b sim [-h]");
52 PrintAndLog(" -h this help");
53 PrintAndLog("sample: hf 14b sim");
54 return 0;
55 }
56 int usage_hf_14b_read_srx(void){
57 PrintAndLog("Usage: hf 14b read [h] <1|2>");
58 PrintAndLog("Options:");
59 PrintAndLog(" h this help");
60 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
61 PrintAndLog("sample: hf 14b read 1");
62 PrintAndLog(" : hf 14b read 2");
63 return 0;
64 }
65 int usage_hf_14b_write_srx(void){
66 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
67 PrintAndLog("Options:");
68 PrintAndLog(" h this help");
69 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
70 PrintAndLog(" <block> BLOCK number depends on tag, special block == FF");
71 PrintAndLog(" <data> hex bytes of data to be written");
72 PrintAndLog("sample : hf 14b write 1 7F 11223344");
73 PrintAndLog(" : hf 14b write 1 FF 11223344");
74 PrintAndLog(" : hf 14b write 2 15 11223344");
75 PrintAndLog(" : hf 14b write 2 FF 11223344");
76 return 0;
77 }
78
79 static int rawClose(){
80 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}};
81 clearCommandBuffer();
82 SendCommand(&c);
83 return 1;
84 }
85
86 int CmdHF14BList(const char *Cmd) {
87 CmdHFList("14b");
88 return 0;
89 }
90
91 int CmdHF14BSim(const char *Cmd) {
92 char cmdp = param_getchar(Cmd, 0);
93 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_sim();
94
95 UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B, {0, 0, 0}};
96 clearCommandBuffer();
97 SendCommand(&c);
98 return 0;
99 }
100
101 int CmdHF14BSnoop(const char *Cmd) {
102
103 char cmdp = param_getchar(Cmd, 0);
104 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_snoop();
105
106 UsbCommand c = {CMD_SNOOP_ISO_14443B, {0, 0, 0}};
107 clearCommandBuffer();
108 SendCommand(&c);
109 return 0;
110 }
111
112 int CmdHF14BCmdRaw (const char *Cmd) {
113 bool reply = TRUE;
114 bool power = FALSE;
115 bool select = FALSE;
116 char buf[5]="";
117
118 int i = 0;
119 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
120 uint16_t datalen = 0;
121 uint32_t flags = 0;
122 uint32_t temp = 0;
123
124 if (strlen(Cmd)<3) return usage_hf_14b_raw();
125
126 // strip
127 while (*Cmd==' ' || *Cmd=='\t') ++Cmd;
128
129 while (Cmd[i]!='\0') {
130 if (Cmd[i]==' ' || Cmd[i]=='\t') { ++i; continue; }
131 if (Cmd[i]=='-') {
132 switch (Cmd[i+1]) {
133 case 'H':
134 case 'h':
135 return usage_hf_14b_raw();
136 case 'r':
137 case 'R':
138 reply = FALSE;
139 break;
140 case 'c':
141 case 'C':
142 flags |= ISO14B_APPEND_CRC;
143 break;
144 case 'p':
145 case 'P':
146 power = TRUE;
147 break;
148 case 's':
149 case 'S':
150 flags |= ISO14B_CONNECT;
151 select = TRUE;
152 if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
153 flags |= ISO14B_SELECT_SR;
154 ++i;
155 } else {
156 flags |= ISO14B_SELECT_STD;
157 }
158 break;
159 default:
160 return usage_hf_14b_raw();
161 }
162 i+=2;
163 continue;
164 }
165 if ((Cmd[i]>='0' && Cmd[i]<='9') ||
166 (Cmd[i]>='a' && Cmd[i]<='f') ||
167 (Cmd[i]>='A' && Cmd[i]<='F') ) {
168 buf[strlen(buf)+1]=0;
169 buf[strlen(buf)]=Cmd[i];
170 i++;
171
172 if (strlen(buf)>=2) {
173 sscanf(buf,"%x",&temp);
174 data[datalen++] = (uint8_t)(temp & 0xff);
175 *buf=0;
176 memset(buf, 0x00, sizeof(buf));
177 }
178 continue;
179 }
180 PrintAndLog("Invalid char on input");
181 return 0;
182 }
183
184 if(!power)
185 flags |= ISO14B_DISCONNECT;
186
187 if(datalen>0)
188 flags |= ISO14B_RAW;
189
190 // Max buffer is USB_CMD_DATA_SIZE
191 datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen;
192
193 UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
194 memcpy(c.d.asBytes, data, datalen);
195 clearCommandBuffer();
196 SendCommand(&c);
197
198 if (!reply) return 1;
199
200 bool success = TRUE;
201 // get back iso14b_card_select_t, don't print it.
202 if(select)
203 success = waitCmd(FALSE);
204
205 // get back response from the raw bytes you sent.
206 if(success && datalen>0) waitCmd(TRUE);
207
208 return 1;
209 }
210
211 // print full atqb info
212 static void print_atqb_resp(uint8_t *data, uint8_t cid){
213 //PrintAndLog (" UID: %s", sprint_hex(data+1,4));
214 PrintAndLog (" App Data: %s", sprint_hex(data,4));
215 PrintAndLog (" Protocol: %s", sprint_hex(data+4,3));
216 uint8_t BitRate = data[4];
217 if (!BitRate) PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD");
218 if (BitRate & 0x10) PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported");
219 if (BitRate & 0x20) PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported");
220 if (BitRate & 0x40) PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported");
221 if (BitRate & 0x01) PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported");
222 if (BitRate & 0x02) PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported");
223 if (BitRate & 0x04) PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported");
224 if (BitRate & 0x80) PrintAndLog (" Same bit rate <-> required");
225
226 uint16_t maxFrame = data[5]>>4;
227 if (maxFrame < 5) maxFrame = 8 * maxFrame + 16;
228 else if (maxFrame == 5) maxFrame = 64;
229 else if (maxFrame == 6) maxFrame = 96;
230 else if (maxFrame == 7) maxFrame = 128;
231 else if (maxFrame == 8) maxFrame = 256;
232 else maxFrame = 257;
233
234 PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
235
236 uint8_t protocolT = data[5] & 0xF;
237 PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
238 PrintAndLog ("Frame Wait Int: %u", data[6]>>4);
239 PrintAndLog (" App Data Code: Application is %s",(data[6]&4) ? "Standard" : "Proprietary");
240 PrintAndLog (" Frame Options: NAD is %ssupported",(data[6]&2) ? "" : "not ");
241 PrintAndLog (" Frame Options: CID is %ssupported",(data[6]&1) ? "" : "not ");
242 PrintAndLog ("Tag :");
243 PrintAndLog (" Max Buf Length: %u (MBLI) %s",cid>>4, (cid & 0xF0) ? "" : "not supported");
244 PrintAndLog (" Cid : %u", cid & 0x0f);
245 return;
246 }
247
248 // get SRx chip model (from UID) // from ST Microelectronics
249 char *get_ST_Chip_Model(uint8_t data){
250 static char model[20];
251 char *retStr = model;
252 memset(model,0, sizeof(model));
253
254 switch (data) {
255 case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
256 case 0x2: sprintf(retStr, "SR176"); break;
257 case 0x3: sprintf(retStr, "SRIX4K"); break;
258 case 0x4: sprintf(retStr, "SRIX512"); break;
259 case 0x6: sprintf(retStr, "SRI512"); break;
260 case 0x7: sprintf(retStr, "SRI4K"); break;
261 case 0xC: sprintf(retStr, "SRT512"); break;
262 default : sprintf(retStr, "Unknown"); break;
263 }
264 return retStr;
265 }
266
267 // REMAKE:
268 int print_ST_Lock_info(uint8_t model){
269
270 // PrintAndLog("Chip Write Protection Bits:");
271 // // now interpret the data
272 // switch (model){
273 // case 0x0: //fall through (SRIX4K special)
274 // case 0x3: //fall through (SRIx4K)
275 // case 0x7: // (SRI4K)
276 // //only need data[3]
277 // blk1 = 9;
278 // PrintAndLog(" raw: %s", sprint_bin(data+3, 1));
279 // PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
280 // for (uint8_t i = 1; i<8; i++){
281 // PrintAndLog(" %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
282 // blk1++;
283 // }
284 // break;
285 // case 0x4: //fall through (SRIX512)
286 // case 0x6: //fall through (SRI512)
287 // case 0xC: // (SRT512)
288 // //need data[2] and data[3]
289 // blk1 = 0;
290 // PrintAndLog(" raw: %s", sprint_bin(data+2, 2));
291 // for (uint8_t b=2; b<4; b++){
292 // for (uint8_t i=0; i<8; i++){
293 // PrintAndLog(" %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
294 // blk1++;
295 // }
296 // }
297 // break;
298 // case 0x2: // (SR176)
299 // //need data[2]
300 // blk1 = 0;
301 // PrintAndLog(" raw: %s", sprint_bin(data+2, 1));
302 // for (uint8_t i = 0; i<8; i++){
303 // PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
304 // blk1+=2;
305 // }
306 // break;
307 // default:
308 // return rawClose();
309 // }
310 return 1;
311 }
312
313 // print UID info from SRx chips (ST Microelectronics)
314 static void print_st_general_info(uint8_t *data, uint8_t len){
315 //uid = first 8 bytes in data
316 PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8), len));
317 PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
318 PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
319 return;
320 }
321
322 //05 00 00 = find one tag in field
323 //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
324 //a3 = ? (resp 03 [e2 c2])
325 //02 = ? (resp 02 [6a d3])
326 // 022b (resp 02 67 00 [29 5b])
327 // 0200a40400 (resp 02 67 00 [29 5b])
328 // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
329 // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
330 // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
331 // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
332 // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
333 // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
334 // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
335 //03 = ? (resp 03 [e3 c2])
336 //c2 = ? (resp c2 [66 15])
337 //b2 = ? (resp a3 [e9 67])
338 //a2 = ? (resp 02 [6a d3])
339
340 // 14b get and print Full Info (as much as we know)
341 bool HF14B_Std_Info(bool verbose){
342 //add more info here
343 return FALSE;
344 }
345
346 // SRx get and print full info (needs more info...)
347 bool HF14B_ST_Info(bool verbose){
348
349 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
350 clearCommandBuffer();
351 SendCommand(&c);
352 UsbCommand resp;
353
354 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
355 if (verbose) PrintAndLog("timeout while waiting for reply.");
356 return FALSE;
357 }
358
359 iso14b_card_select_t card;
360 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
361
362 uint64_t status = resp.arg[0];
363 if ( status > 0 ) {
364 rawClose();
365 return FALSE;
366 }
367
368 //add locking bit information here. uint8_t data[16] = {0x00};
369 // uint8_t datalen = 2;
370 // uint8_t resplen;
371 // uint8_t blk1;
372 // data[0] = 0x08;
373
374 //
375 // if (model == 0x2) { //SR176 has special command:
376 // data[1] = 0xf;
377 // resplen = 4;
378 // } else {
379 // data[1] = 0xff;
380 // resplen = 6;
381 // }
382
383 // //std read cmd
384 // if (HF14BCmdRaw(true, true, data, &datalen, false)==0)
385 // return rawClose();
386
387 // if (datalen != resplen || !crc) return rawClose();
388 //print_ST_Lock_info(data[5]>>2);
389 rawClose();
390 return TRUE;
391 }
392
393 // get and print all info known about any known 14b tag
394 bool HF14BInfo(bool verbose){
395
396 // try std 14b (atqb)
397 if (HF14B_Std_Info(verbose)) return TRUE;
398
399 // try st 14b
400 if (HF14B_ST_Info(verbose)) return TRUE;
401
402 // try unknown 14b read commands (to be identified later)
403 // could be read of calypso, CEPAS, moneo, or pico pass.
404
405 if (verbose) PrintAndLog("no 14443B tag found");
406 return FALSE;
407 }
408
409 // menu command to get and print all info known about any known 14b tag
410 int CmdHF14Binfo(const char *Cmd){
411 char cmdp = param_getchar(Cmd, 0);
412 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_info();
413
414 bool verbose = !((cmdp == 's') || (cmdp == 'S'));
415 return HF14BInfo(verbose);
416 }
417
418 bool HF14B_ST_Reader(bool verbose){
419
420 bool isSuccess = FALSE;
421
422 // SRx get and print general info about SRx chip from UID
423 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
424 clearCommandBuffer();
425 SendCommand(&c);
426 UsbCommand resp;
427
428 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
429 if (verbose) PrintAndLog("timeout while waiting for reply.");
430 return FALSE;
431 }
432
433
434 iso14b_card_select_t card;
435 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
436
437 uint64_t status = resp.arg[0];
438
439 switch( status ){
440 case 0:
441 print_st_general_info(card.uid, card.uidlen);
442 isSuccess = TRUE;
443 break;
444 case 1:
445 if (verbose) PrintAndLog("iso14443-3 random chip id fail");
446 break;
447 case 2:
448 if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
449 break;
450 case 3:
451 if (verbose) PrintAndLog("iso14443-3 CRC fail");
452 break;
453 default:
454 if (verbose) PrintAndLog("iso14443b card select SRx failed");
455 break;
456 }
457
458 rawClose();
459 return isSuccess;
460 }
461
462 bool HF14B_Std_Reader(bool verbose){
463
464 bool isSuccess = FALSE;
465
466 // 14b get and print UID only (general info)
467 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0}};
468 clearCommandBuffer();
469 SendCommand(&c);
470 UsbCommand resp;
471
472 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
473 if (verbose) PrintAndLog("timeout while waiting for reply.");
474 return FALSE;
475 }
476
477 iso14b_card_select_t card;
478 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
479
480 uint64_t status = resp.arg[0];
481
482 switch( status ){
483 case 0:
484 PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
485 PrintAndLog(" ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
486 PrintAndLog(" CHIPID : %02X", card.chipid);
487 print_atqb_resp(card.atqb, card.cid);
488 isSuccess = TRUE;
489 break;
490 case 2:
491 if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
492 break;
493 case 3:
494 if (verbose) PrintAndLog("iso14443-3 CRC fail");
495 break;
496 default:
497 if (verbose) PrintAndLog("iso14443b card select failed");
498 break;
499 }
500
501 rawClose();
502 return isSuccess;
503 }
504
505 // test for other 14b type tags (mimic another reader - don't have tags to identify)
506 bool HF14B_Other_Reader(){
507
508 // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
509 // uint8_t datalen = 4;
510
511 // // 14b get and print UID only (general info)
512 // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
513
514 // UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
515 // memcpy(c.d.asBytes, data, datalen);
516
517 // clearCommandBuffer();
518 // SendCommand(&c);
519 // UsbCommand resp;
520 // WaitForResponse(CMD_ACK,&resp);
521
522 // if (datalen > 2 ) {
523 // printandlog ("\n14443-3b tag found:");
524 // printandlog ("unknown tag type answered to a 0x000b3f80 command ans:");
525 // //printandlog ("%s", sprint_hex(data, datalen));
526 // rawclose();
527 // return true;
528 // }
529
530 // c.arg1 = 1;
531 // c.d.asBytes[0] = ISO14443B_AUTHENTICATE;
532 // clearCommandBuffer();
533 // SendCommand(&c);
534 // UsbCommand resp;
535 // WaitForResponse(CMD_ACK, &resp);
536
537 // if (datalen > 0) {
538 // PrintAndLog ("\n14443-3b tag found:");
539 // PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
540 // // PrintAndLog ("%s", sprint_hex(data, datalen));
541 // rawClose();
542 // return TRUE;
543 // }
544
545 // c.arg1 = 1;
546 // c.d.asBytes[0] = ISO14443B_RESET;
547 // clearCommandBuffer();
548 // SendCommand(&c);
549 // UsbCommand resp;
550 // WaitForResponse(CMD_ACK, &resp);
551
552 // if (datalen > 0) {
553 // PrintAndLog ("\n14443-3b tag found:");
554 // PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
555 // PrintAndLog ("%s", sprint_hex(data, datalen));
556 // rawClose();
557 // return TRUE;
558 // }
559
560 // rawClose();
561 return FALSE;
562 }
563
564 // get and print general info about all known 14b chips
565 bool HF14BReader(bool verbose){
566
567 // try std 14b (atqb)
568 if (HF14B_Std_Reader(verbose)) return TRUE;
569
570 // try ST Microelectronics 14b
571 if (HF14B_ST_Reader(verbose)) return TRUE;
572
573 // try unknown 14b read commands (to be identified later)
574 // could be read of calypso, CEPAS, moneo, or pico pass.
575 if (HF14B_Other_Reader()) return TRUE;
576
577 if (verbose) PrintAndLog("no 14443B tag found");
578 return FALSE;
579 }
580
581 // menu command to get and print general info about all known 14b chips
582 int CmdHF14BReader(const char *Cmd){
583 char cmdp = param_getchar(Cmd, 0);
584 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_reader();
585
586 bool verbose = !((cmdp == 's') || (cmdp == 'S'));
587 return HF14BReader(verbose);
588 }
589
590 /* New command to read the contents of a SRI512|SRIX4K tag
591 * SRI* tags are ISO14443-B modulated memory tags,
592 * this command just dumps the contents of the memory/
593 */
594 int CmdHF14BReadSri(const char *Cmd){
595 char cmdp = param_getchar(Cmd, 0);
596 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_read_srx();
597
598 uint8_t tagtype = param_get8(Cmd, 0);
599 uint8_t blocks = (tagtype == 1) ? 0x7F : 0x0F;
600
601 UsbCommand c = {CMD_READ_SRI_TAG, {blocks, 0, 0}};
602 clearCommandBuffer();
603 SendCommand(&c);
604 return 0;
605 }
606 // New command to write a SRI512/SRIX4K tag.
607 int CmdHF14BWriteSri(const char *Cmd){
608 /*
609 * For SRIX4K blocks 00 - 7F
610 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
611 *
612 * For SR512 blocks 00 - 0F
613 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
614 *
615 * Special block FF = otp_lock_reg block.
616 * Data len 4 bytes-
617 */
618 char cmdp = param_getchar(Cmd, 0);
619 uint8_t blockno = -1;
620 uint8_t data[4] = {0x00};
621 bool isSrix4k = true;
622 char str[30];
623 memset(str, 0x00, sizeof(str));
624
625 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_write_srx();
626
627 if ( cmdp == '2' )
628 isSrix4k = false;
629
630 //blockno = param_get8(Cmd, 1);
631
632 if ( param_gethex(Cmd, 1, &blockno, 2) ) {
633 PrintAndLog("Block number must include 2 HEX symbols");
634 return 0;
635 }
636
637 if ( isSrix4k ){
638 if ( blockno > 0x7f && blockno != 0xff ){
639 PrintAndLog("Block number out of range");
640 return 0;
641 }
642 } else {
643 if ( blockno > 0x0f && blockno != 0xff ){
644 PrintAndLog("Block number out of range");
645 return 0;
646 }
647 }
648
649 if (param_gethex(Cmd, 2, data, 8)) {
650 PrintAndLog("Data must include 8 HEX symbols");
651 return 0;
652 }
653
654 if ( blockno == 0xff) {
655 PrintAndLog("[%s] Write special block %02X [ %s ]",
656 (isSrix4k) ? "SRIX4K":"SRI512",
657 blockno,
658 sprint_hex(data,4)
659 );
660 } else {
661 PrintAndLog("[%s] Write block %02X [ %s ]",
662 (isSrix4k) ? "SRIX4K":"SRI512",
663 blockno,
664 sprint_hex(data,4)
665 );
666 }
667
668 sprintf(str, "-ss -c %02x %02x %02x%02x%02x%02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]);
669 CmdHF14BCmdRaw(str);
670 return 0;
671 }
672
673 uint32_t srix4kEncode(uint32_t value) {
674 /*
675 // vv = value
676 // pp = position
677 // vv vv vv pp
678 4 bytes : 00 1A 20 01
679 */
680 // only the lower crumbs.
681 uint8_t block = (value & 0xFF);
682 uint8_t i = 0;
683 uint8_t valuebytes[] = {0,0,0};
684
685 num_to_bytes(value, 3, valuebytes);
686
687 // Scrambled part
688 // Crumb swapping of value.
689 uint8_t temp[] = {0,0};
690 temp[0] = (CRUMB(value, 22) << 4 | CRUMB(value, 14 ) << 2 | CRUMB(value, 6)) << 4;
691 temp[0] |= CRUMB(value, 20) << 4 | CRUMB(value, 12 ) << 2 | CRUMB(value, 4);
692 temp[1] = (CRUMB(value, 18) << 4 | CRUMB(value, 10 ) << 2 | CRUMB(value, 2)) << 4;
693 temp[1] |= CRUMB(value, 16) << 4 | CRUMB(value, 8 ) << 2 | CRUMB(value, 0);
694
695 // chksum part
696 uint32_t chksum = 0xFF - block;
697
698 // chksum is reduced by each nibbles of value.
699 for (i = 0; i < 3; ++i){
700 chksum -= NIBBLE_HIGH(valuebytes[i]);
701 chksum -= NIBBLE_LOW(valuebytes[i]);
702 }
703
704 // base4 conversion and left shift twice
705 i = 3;
706 uint8_t base4[] = {0,0,0,0};
707 while( chksum !=0 ){
708 base4[i--] = (chksum % 4 << 2);
709 chksum /= 4;
710 }
711
712 // merge scambled and chksum parts
713 uint32_t encvalue =
714 ( NIBBLE_LOW ( base4[0]) << 28 ) |
715 ( NIBBLE_HIGH( temp[0]) << 24 ) |
716
717 ( NIBBLE_LOW ( base4[1]) << 20 ) |
718 ( NIBBLE_LOW ( temp[0]) << 16 ) |
719
720 ( NIBBLE_LOW ( base4[2]) << 12 ) |
721 ( NIBBLE_HIGH( temp[1]) << 8 ) |
722
723 ( NIBBLE_LOW ( base4[3]) << 4 ) |
724 NIBBLE_LOW ( temp[1] );
725
726 PrintAndLog("ICE encoded | %08X -> %08X", value, encvalue);
727 return encvalue;
728 }
729 uint32_t srix4kDecode(uint32_t value) {
730 switch(value) {
731 case 0xC04F42C5: return 0x003139;
732 case 0xC1484807: return 0x002943;
733 case 0xC0C60848: return 0x001A20;
734 }
735 return 0;
736 }
737 uint32_t srix4kDecodeCounter(uint32_t num) {
738 uint32_t value = ~num;
739 ++value;
740 return value;
741 }
742
743 uint32_t srix4kGetMagicbytes( uint64_t uid, uint32_t block6, uint32_t block18, uint32_t block19 ){
744 #define MASK 0xFFFFFFFF;
745 uint32_t uid32 = uid & MASK;
746 uint32_t counter = srix4kDecodeCounter(block6);
747 uint32_t decodedBlock18 = srix4kDecode(block18);
748 uint32_t decodedBlock19 = srix4kDecode(block19);
749 uint32_t doubleBlock = (decodedBlock18 << 16 | decodedBlock19) + 1;
750
751 uint32_t result = (uid32 * doubleBlock * counter) & MASK;
752 PrintAndLog("Magic bytes | %08X", result);
753 return result;
754 }
755 int srix4kValid(const char *Cmd){
756
757 uint64_t uid = 0xD00202501A4532F9;
758 uint32_t block6 = 0xFFFFFFFF;
759 uint32_t block18 = 0xC04F42C5;
760 uint32_t block19 = 0xC1484807;
761 uint32_t block21 = 0xD1BCABA4;
762
763 uint32_t test_b18 = 0x00313918;
764 uint32_t test_b18_enc = srix4kEncode(test_b18);
765 //uint32_t test_b18_dec = srix4kDecode(test_b18_enc);
766 PrintAndLog("ENCODE & CHECKSUM | %08X -> %08X (%s)", test_b18, test_b18_enc , "");
767
768 uint32_t magic = srix4kGetMagicbytes(uid, block6, block18, block19);
769 PrintAndLog("BLOCK 21 | %08X -> %08X (no XOR)", block21, magic ^ block21);
770 return 0;
771 }
772
773 int CmdteaSelfTest(const char *Cmd){
774
775 uint8_t v[8], v_le[8];
776 memset(v, 0x00, sizeof(v));
777 memset(v_le, 0x00, sizeof(v_le));
778 uint8_t* v_ptr = v_le;
779
780 uint8_t cmdlen = strlen(Cmd);
781 cmdlen = ( sizeof(v)<<2 < cmdlen ) ? sizeof(v)<<2 : cmdlen;
782
783 if ( param_gethex(Cmd, 0, v, cmdlen) > 0 ){
784 PrintAndLog("can't read hex chars, uneven? :: %u", cmdlen);
785 return 1;
786 }
787
788 SwapEndian64ex(v , 8, 4, v_ptr);
789
790 // ENCRYPTION KEY:
791 uint8_t key[16] = {0x55,0xFE,0xF6,0x30,0x62,0xBF,0x0B,0xC1,0xC9,0xB3,0x7C,0x34,0x97,0x3E,0x29,0xFB };
792 uint8_t keyle[16];
793 uint8_t* key_ptr = keyle;
794 SwapEndian64ex(key , sizeof(key), 4, key_ptr);
795
796 PrintAndLog("TEST LE enc| %s", sprint_hex(v_ptr, 8));
797
798 tea_decrypt(v_ptr, key_ptr);
799 PrintAndLog("TEST LE dec | %s", sprint_hex_ascii(v_ptr, 8));
800
801 tea_encrypt(v_ptr, key_ptr);
802 tea_encrypt(v_ptr, key_ptr);
803 PrintAndLog("TEST enc2 | %s", sprint_hex_ascii(v_ptr, 8));
804
805 return 0;
806 }
807
808 bool waitCmd(bool verbose) {
809
810 bool crc = FALSE;
811 uint8_t b1 = 0, b2 = 0;
812 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
813 uint8_t status = 0;
814 uint16_t len = 0;
815 UsbCommand resp;
816
817 if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
818
819 status = (resp.arg[0] & 0xFFFF);
820 if ( status > 0 ) return FALSE;
821
822 len = (resp.arg[1] & 0xFFFF);
823 memcpy(data, resp.d.asBytes, len);
824
825 if (verbose) {
826
827 ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
828 crc = ( data[len-2] == b1 && data[len-1] == b2);
829
830 PrintAndLog("[LEN %u] %s[%02X %02X] %s",
831 len,
832 sprint_hex(data, len-2),
833 data[len-2],
834 data[len-1],
835 (crc) ? "OK" : "FAIL"
836 );
837 }
838 return TRUE;
839 } else {
840 PrintAndLog("timeout while waiting for reply.");
841 return FALSE;
842 }
843 }
844
845 static command_t CommandTable[] = {
846 {"help", CmdHelp, 1, "This help"},
847 {"info", CmdHF14Binfo, 0, "Find and print details about a 14443B tag"},
848 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443B history"},
849 {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
850 {"reader", CmdHF14BReader, 0, "Act as a 14443B reader to identify a tag"},
851 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
852 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
853 {"sriread", CmdHF14BReadSri, 0, "Read contents of a SRI512 | SRIX4K tag"},
854 {"sriwrite", CmdHF14BWriteSri, 0, "Write data to a SRI512 | SRIX4K tag"},
855 //{"valid", srix4kValid, 1, "srix4k checksum test"},
856 //{"valid", CmdteaSelfTest, 1, "tea test"},
857 {NULL, NULL, 0, NULL}
858 };
859
860 int CmdHF14B(const char *Cmd) {
861 clearCommandBuffer();
862 CmdsParse(CommandTable, Cmd);
863 return 0;
864 }
865
866 int CmdHelp(const char *Cmd) {
867 CmdsHelp(CommandTable);
868 return 0;
869 }
Impressum, Datenschutz