]> cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14b.c
CHG: no parity tests for ISO_7816_4 annotation
[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 #define TIMEOUT 2000
18 static int CmdHelp(const char *Cmd);
19
20 int usage_hf_14b_info(void){
21 PrintAndLog("Usage: hf 14b info [-h] [-s]");
22 PrintAndLog(" -h this help");
23 PrintAndLog(" -s silently");
24 return 0;
25 }
26 int usage_hf_14b_reader(void){
27 PrintAndLog("Usage: hf 14b reader [-h] [-s]");
28 PrintAndLog(" -h this help");
29 PrintAndLog(" -s silently");
30 return 0;
31 }
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");
40 return 0;
41 }
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");
48 return 0;
49 }
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");
55 return 0;
56 }
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");
64 return 0;
65 }
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");
77 return 0;
78 }
79
80 static int rawClose(){
81 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}};
82 clearCommandBuffer();
83 SendCommand(&c);
84 return 1;
85 }
86
87 int CmdHF14BList(const char *Cmd) {
88 CmdHFList("14b");
89 return 0;
90 }
91
92 int CmdHF14BSim(const char *Cmd) {
93 char cmdp = param_getchar(Cmd, 0);
94 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_sim();
95
96 UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B, {0, 0, 0}};
97 clearCommandBuffer();
98 SendCommand(&c);
99 return 0;
100 }
101
102 int CmdHF14BSnoop(const char *Cmd) {
103
104 char cmdp = param_getchar(Cmd, 0);
105 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_snoop();
106
107 UsbCommand c = {CMD_SNOOP_ISO_14443B, {0, 0, 0}};
108 clearCommandBuffer();
109 SendCommand(&c);
110 return 0;
111 }
112
113 int CmdHF14BCmdRaw (const char *Cmd) {
114 bool reply = TRUE;
115 bool power = FALSE;
116 bool select = FALSE;
117 char buf[5]="";
118
119 int i = 0;
120 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
121 uint16_t datalen = 0;
122 uint32_t flags = 0;
123 uint32_t temp = 0;
124
125 if (strlen(Cmd)<3) return usage_hf_14b_raw();
126
127 // strip
128 while (*Cmd==' ' || *Cmd=='\t') ++Cmd;
129
130 while (Cmd[i]!='\0') {
131 if (Cmd[i]==' ' || Cmd[i]=='\t') { ++i; continue; }
132 if (Cmd[i]=='-') {
133 switch (Cmd[i+1]) {
134 case 'H':
135 case 'h':
136 return usage_hf_14b_raw();
137 case 'r':
138 case 'R':
139 reply = FALSE;
140 break;
141 case 'c':
142 case 'C':
143 flags |= ISO14B_APPEND_CRC;
144 break;
145 case 'p':
146 case 'P':
147 power = TRUE;
148 break;
149 case 's':
150 case 'S':
151 flags |= ISO14B_CONNECT;
152 select = TRUE;
153 if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
154 flags |= ISO14B_SELECT_SR;
155 ++i;
156 } else {
157 flags |= ISO14B_SELECT_STD;
158 }
159 break;
160 default:
161 return usage_hf_14b_raw();
162 }
163 i+=2;
164 continue;
165 }
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];
171 i++;
172
173 if (strlen(buf)>=2) {
174 sscanf(buf,"%x",&temp);
175 data[datalen++] = (uint8_t)(temp & 0xff);
176 *buf=0;
177 memset(buf, 0x00, sizeof(buf));
178 }
179 continue;
180 }
181 PrintAndLog("Invalid char on input");
182 return 0;
183 }
184
185 if(!power)
186 flags |= ISO14B_DISCONNECT;
187
188 if(datalen>0)
189 flags |= ISO14B_RAW;
190
191 // Max buffer is USB_CMD_DATA_SIZE
192 datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen;
193
194 UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
195 memcpy(c.d.asBytes, data, datalen);
196 clearCommandBuffer();
197 SendCommand(&c);
198
199 if (!reply) return 1;
200
201 bool success = TRUE;
202 // get back iso14b_card_select_t, don't print it.
203 if(select)
204 success = waitCmd(FALSE);
205
206 // get back response from the raw bytes you sent.
207 if(success && datalen>0) waitCmd(TRUE);
208
209 return 1;
210 }
211
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");
226
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;
233 else maxFrame = 257;
234
235 PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
236
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);
246 return;
247 }
248
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));
254
255 switch (data) {
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;
264 }
265 return retStr;
266 }
267
268 // REMAKE:
269 int print_ST_Lock_info(uint8_t model){
270
271 // PrintAndLog("Chip Write Protection Bits:");
272 // // now interpret the data
273 // switch (model){
274 // case 0x0: //fall through (SRIX4K special)
275 // case 0x3: //fall through (SRIx4K)
276 // case 0x7: // (SRI4K)
277 // //only need data[3]
278 // blk1 = 9;
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 " : " " );
283 // blk1++;
284 // }
285 // break;
286 // case 0x4: //fall through (SRIX512)
287 // case 0x6: //fall through (SRI512)
288 // case 0xC: // (SRT512)
289 // //need data[2] and data[3]
290 // blk1 = 0;
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 " : " " );
295 // blk1++;
296 // }
297 // }
298 // break;
299 // case 0x2: // (SR176)
300 // //need data[2]
301 // blk1 = 0;
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 " );
305 // blk1+=2;
306 // }
307 // break;
308 // default:
309 // return rawClose();
310 // }
311 return 1;
312 }
313
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));
320 return;
321 }
322
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])
340
341 // 14b get and print Full Info (as much as we know)
342 bool HF14B_Std_Info(bool verbose){
343 //add more info here
344 return FALSE;
345 }
346
347 // SRx get and print full info (needs more info...)
348 bool HF14B_ST_Info(bool verbose){
349
350 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
351 clearCommandBuffer();
352 SendCommand(&c);
353 UsbCommand resp;
354
355 if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
356 if (verbose) PrintAndLog("timeout while waiting for reply.");
357 return FALSE;
358 }
359
360 iso14b_card_select_t card;
361 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
362
363 uint64_t status = resp.arg[0];
364 if ( status > 0 ) {
365 rawClose();
366 return FALSE;
367 }
368
369 //add locking bit information here. uint8_t data[16] = {0x00};
370 // uint8_t datalen = 2;
371 // uint8_t resplen;
372 // uint8_t blk1;
373 // data[0] = 0x08;
374
375 //
376 // if (model == 0x2) { //SR176 has special command:
377 // data[1] = 0xf;
378 // resplen = 4;
379 // } else {
380 // data[1] = 0xff;
381 // resplen = 6;
382 // }
383
384 // //std read cmd
385 // if (HF14BCmdRaw(true, true, data, &datalen, false)==0)
386 // return rawClose();
387
388 // if (datalen != resplen || !crc) return rawClose();
389 //print_ST_Lock_info(data[5]>>2);
390 rawClose();
391 return TRUE;
392 }
393
394 // get and print all info known about any known 14b tag
395 bool HF14BInfo(bool verbose){
396
397 // try std 14b (atqb)
398 if (HF14B_Std_Info(verbose)) return TRUE;
399
400 // try st 14b
401 if (HF14B_ST_Info(verbose)) return TRUE;
402
403 // try unknown 14b read commands (to be identified later)
404 // could be read of calypso, CEPAS, moneo, or pico pass.
405
406 if (verbose) PrintAndLog("no 14443B tag found");
407 return FALSE;
408 }
409
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();
414
415 bool verbose = !((cmdp == 's') || (cmdp == 'S'));
416 return HF14BInfo(verbose);
417 }
418
419 bool HF14B_ST_Reader(bool verbose){
420
421 bool isSuccess = FALSE;
422
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();
426 SendCommand(&c);
427 UsbCommand resp;
428
429 if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
430 if (verbose) PrintAndLog("timeout while waiting for reply.");
431 return FALSE;
432 }
433
434
435 iso14b_card_select_t card;
436 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
437
438 uint64_t status = resp.arg[0];
439
440 switch( status ){
441 case 0:
442 print_st_general_info(card.uid, card.uidlen);
443 isSuccess = TRUE;
444 break;
445 case 1:
446 if (verbose) PrintAndLog("iso14443-3 random chip id fail");
447 break;
448 case 2:
449 if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
450 break;
451 case 3:
452 if (verbose) PrintAndLog("iso14443-3 CRC fail");
453 break;
454 default:
455 if (verbose) PrintAndLog("iso14443b card select SRx failed");
456 break;
457 }
458
459 rawClose();
460 return isSuccess;
461 }
462
463 bool HF14B_Std_Reader(bool verbose){
464
465 bool isSuccess = FALSE;
466
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();
470 SendCommand(&c);
471 UsbCommand resp;
472
473 if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
474 if (verbose) PrintAndLog("timeout while waiting for reply.");
475 return FALSE;
476 }
477
478 iso14b_card_select_t card;
479 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
480
481 uint64_t status = resp.arg[0];
482
483 switch( status ){
484 case 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);
489 isSuccess = TRUE;
490 break;
491 case 2:
492 if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
493 break;
494 case 3:
495 if (verbose) PrintAndLog("iso14443-3 CRC fail");
496 break;
497 default:
498 if (verbose) PrintAndLog("iso14443b card select failed");
499 break;
500 }
501
502 rawClose();
503 return isSuccess;
504 }
505
506 // test for other 14b type tags (mimic another reader - don't have tags to identify)
507 bool HF14B_Other_Reader(){
508
509 // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
510 // uint8_t datalen = 4;
511
512 // // 14b get and print UID only (general info)
513 // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
514
515 // UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
516 // memcpy(c.d.asBytes, data, datalen);
517
518 // clearCommandBuffer();
519 // SendCommand(&c);
520 // UsbCommand resp;
521 // WaitForResponse(CMD_ACK,&resp);
522
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));
527 // rawclose();
528 // return true;
529 // }
530
531 // c.arg1 = 1;
532 // c.d.asBytes[0] = ISO14443B_AUTHENTICATE;
533 // clearCommandBuffer();
534 // SendCommand(&c);
535 // UsbCommand resp;
536 // WaitForResponse(CMD_ACK, &resp);
537
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));
542 // rawClose();
543 // return TRUE;
544 // }
545
546 // c.arg1 = 1;
547 // c.d.asBytes[0] = ISO14443B_RESET;
548 // clearCommandBuffer();
549 // SendCommand(&c);
550 // UsbCommand resp;
551 // WaitForResponse(CMD_ACK, &resp);
552
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));
557 // rawClose();
558 // return TRUE;
559 // }
560
561 // rawClose();
562 return FALSE;
563 }
564
565 // get and print general info about all known 14b chips
566 bool HF14BReader(bool verbose){
567
568 // try std 14b (atqb)
569 if (HF14B_Std_Reader(verbose)) return TRUE;
570
571 // try ST Microelectronics 14b
572 if (HF14B_ST_Reader(verbose)) return TRUE;
573
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;
577
578 if (verbose) PrintAndLog("no 14443B tag found");
579 return FALSE;
580 }
581
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();
586
587 bool verbose = !((cmdp == 's') || (cmdp == 'S'));
588 return HF14BReader(verbose);
589 }
590
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/
594 */
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();
598
599 uint8_t tagtype = param_get8(Cmd, 0);
600 uint8_t blocks = (tagtype == 1) ? 0x7F : 0x0F;
601
602 UsbCommand c = {CMD_READ_SRI_TAG, {blocks, 0, 0}};
603 clearCommandBuffer();
604 SendCommand(&c);
605 return 0;
606 }
607 // New command to write a SRI512/SRIX4K tag.
608 int CmdHF14BWriteSri(const char *Cmd){
609 /*
610 * For SRIX4K blocks 00 - 7F
611 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
612 *
613 * For SR512 blocks 00 - 0F
614 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
615 *
616 * Special block FF = otp_lock_reg block.
617 * Data len 4 bytes-
618 */
619 char cmdp = param_getchar(Cmd, 0);
620 uint8_t blockno = -1;
621 uint8_t data[4] = {0x00};
622 bool isSrix4k = true;
623 char str[30];
624 memset(str, 0x00, sizeof(str));
625
626 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_write_srx();
627
628 if ( cmdp == '2' )
629 isSrix4k = false;
630
631 //blockno = param_get8(Cmd, 1);
632
633 if ( param_gethex(Cmd, 1, &blockno, 2) ) {
634 PrintAndLog("Block number must include 2 HEX symbols");
635 return 0;
636 }
637
638 if ( isSrix4k ){
639 if ( blockno > 0x7f && blockno != 0xff ){
640 PrintAndLog("Block number out of range");
641 return 0;
642 }
643 } else {
644 if ( blockno > 0x0f && blockno != 0xff ){
645 PrintAndLog("Block number out of range");
646 return 0;
647 }
648 }
649
650 if (param_gethex(Cmd, 2, data, 8)) {
651 PrintAndLog("Data must include 8 HEX symbols");
652 return 0;
653 }
654
655 if ( blockno == 0xff) {
656 PrintAndLog("[%s] Write special block %02X [ %s ]",
657 (isSrix4k) ? "SRIX4K":"SRI512",
658 blockno,
659 sprint_hex(data,4)
660 );
661 } else {
662 PrintAndLog("[%s] Write block %02X [ %s ]",
663 (isSrix4k) ? "SRIX4K":"SRI512",
664 blockno,
665 sprint_hex(data,4)
666 );
667 }
668
669 sprintf(str, "-ss -c %02x %02x %02x%02x%02x%02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]);
670 CmdHF14BCmdRaw(str);
671 return 0;
672 }
673
674 uint32_t srix4kEncode(uint32_t value) {
675 /*
676 // vv = value
677 // pp = position
678 // vv vv vv pp
679 4 bytes : 00 1A 20 01
680 */
681 // only the lower crumbs.
682 uint8_t block = (value & 0xFF);
683 uint8_t i = 0;
684 uint8_t valuebytes[] = {0,0,0};
685
686 num_to_bytes(value, 3, valuebytes);
687
688 // Scrambled part
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);
695
696 // chksum part
697 uint32_t chksum = 0xFF - block;
698
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]);
703 }
704
705 // base4 conversion and left shift twice
706 i = 3;
707 uint8_t base4[] = {0,0,0,0};
708 while( chksum !=0 ){
709 base4[i--] = (chksum % 4 << 2);
710 chksum /= 4;
711 }
712
713 // merge scambled and chksum parts
714 uint32_t encvalue =
715 ( NIBBLE_LOW ( base4[0]) << 28 ) |
716 ( NIBBLE_HIGH( temp[0]) << 24 ) |
717
718 ( NIBBLE_LOW ( base4[1]) << 20 ) |
719 ( NIBBLE_LOW ( temp[0]) << 16 ) |
720
721 ( NIBBLE_LOW ( base4[2]) << 12 ) |
722 ( NIBBLE_HIGH( temp[1]) << 8 ) |
723
724 ( NIBBLE_LOW ( base4[3]) << 4 ) |
725 NIBBLE_LOW ( temp[1] );
726
727 PrintAndLog("ICE encoded | %08X -> %08X", value, encvalue);
728 return encvalue;
729 }
730 uint32_t srix4kDecode(uint32_t value) {
731 switch(value) {
732 case 0xC04F42C5: return 0x003139;
733 case 0xC1484807: return 0x002943;
734 case 0xC0C60848: return 0x001A20;
735 }
736 return 0;
737 }
738 uint32_t srix4kDecodeCounter(uint32_t num) {
739 uint32_t value = ~num;
740 ++value;
741 return value;
742 }
743
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;
751
752 uint32_t result = (uid32 * doubleBlock * counter) & MASK;
753 PrintAndLog("Magic bytes | %08X", result);
754 return result;
755 }
756 int srix4kValid(const char *Cmd){
757
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;
763
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 , "");
768
769 uint32_t magic = srix4kGetMagicbytes(uid, block6, block18, block19);
770 PrintAndLog("BLOCK 21 | %08X -> %08X (no XOR)", block21, magic ^ block21);
771 return 0;
772 }
773
774 int CmdteaSelfTest(const char *Cmd){
775
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;
780
781 uint8_t cmdlen = strlen(Cmd);
782 cmdlen = ( sizeof(v)<<2 < cmdlen ) ? sizeof(v)<<2 : cmdlen;
783
784 if ( param_gethex(Cmd, 0, v, cmdlen) > 0 ){
785 PrintAndLog("can't read hex chars, uneven? :: %u", cmdlen);
786 return 1;
787 }
788
789 SwapEndian64ex(v , 8, 4, v_ptr);
790
791 // ENCRYPTION KEY:
792 uint8_t key[16] = {0x55,0xFE,0xF6,0x30,0x62,0xBF,0x0B,0xC1,0xC9,0xB3,0x7C,0x34,0x97,0x3E,0x29,0xFB };
793 uint8_t keyle[16];
794 uint8_t* key_ptr = keyle;
795 SwapEndian64ex(key , sizeof(key), 4, key_ptr);
796
797 PrintAndLog("TEST LE enc| %s", sprint_hex(v_ptr, 8));
798
799 tea_decrypt(v_ptr, key_ptr);
800 PrintAndLog("TEST LE dec | %s", sprint_hex_ascii(v_ptr, 8));
801
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));
805
806 return 0;
807 }
808
809 bool waitCmd(bool verbose) {
810
811 bool crc = FALSE;
812 uint8_t b1 = 0, b2 = 0;
813 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
814 uint8_t status = 0;
815 uint16_t len = 0;
816 UsbCommand resp;
817
818 if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
819
820 status = (resp.arg[0] & 0xFFFF);
821 if ( status > 0 ) return FALSE;
822
823 len = (resp.arg[1] & 0xFFFF);
824 memcpy(data, resp.d.asBytes, len);
825
826 if (verbose) {
827
828 ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
829 crc = ( data[len-2] == b1 && data[len-1] == b2);
830
831 PrintAndLog("[LEN %u] %s[%02X %02X] %s",
832 len,
833 sprint_hex(data, len-2),
834 data[len-2],
835 data[len-1],
836 (crc) ? "OK" : "FAIL"
837 );
838 }
839 return TRUE;
840 } else {
841 PrintAndLog("timeout while waiting for reply.");
842 return FALSE;
843 }
844 }
845
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}
859 };
860
861 int CmdHF14B(const char *Cmd) {
862 clearCommandBuffer();
863 CmdsParse(CommandTable, Cmd);
864 return 0;
865 }
866
867 int CmdHelp(const char *Cmd) {
868 CmdsHelp(CommandTable);
869 return 0;
870 }
Impressum, Datenschutz