]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf15.c
708bacddb039b48930ba8dbe17b6d0f56ba775da
[proxmark3-svn] / client / cmdhf15.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
3 // Modified 2010 by <adrian -at- atrox.at>
4 // Modified 2010, 2011 by <adrian -at- atrox.at>
5 // Modified 2012 by <vsza at vsza.hu>
6 //
7 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
8 // at your option, any later version. See the LICENSE.txt file for the text of
9 // the license.
10 //-----------------------------------------------------------------------------
11 // High frequency ISO15693 commands
12 //-----------------------------------------------------------------------------
13 // There are three basic operation modes, depending on which device (proxmark/pc)
14 // the signal processing, (de)modulation, transmission protocol and logic is done.
15 // Mode 1:
16 // All steps are done on the proxmark, the output of the commands is returned via
17 // USB-debug-print commands.
18 // Mode 2:
19 // The protocol is done on the PC, passing only Iso15693 data frames via USB. This
20 // allows direct communication with a tag on command level
21 // Mode 3:
22 // The proxmark just samples the antenna and passes this "analog" data via USB to
23 // the client. Signal Processing & decoding is done on the pc. This is the slowest
24 // variant, but offers the possibility to analyze the waveforms directly.
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdint.h>
30 #include "proxusb.h"
31 #include "data.h"
32 #include "graph.h"
33 #include "ui.h"
34 #include "cmdparser.h"
35 #include "cmdhf15.h"
36 #include "iso15693tools.h"
37 #include "cmdmain.h"
38
39 #define FrameSOF Iso15693FrameSOF
40 #define Logic0 Iso15693Logic0
41 #define Logic1 Iso15693Logic1
42 #define FrameEOF Iso15693FrameEOF
43
44 #define Crc(data,datalen) Iso15693Crc(data,datalen)
45 #define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
46 #define sprintUID(target,uid) Iso15693sprintUID(target,uid)
47
48 static int CmdHelp(const char *Cmd);
49
50 // structure and database for uid -> tagtype lookups
51 typedef struct {
52 uint64_t uid;
53 int mask; // how many MSB bits used
54 char* desc;
55 } productName;
56
57
58 const productName uidmapping[] = {
59 { 0xE001000000000000LL, 16, "Motorola" },
60 { 0xE002000000000000LL, 16, "ST Microelectronics" },
61 { 0xE003000000000000LL, 16, "Hitachi" },
62 { 0xE004000000000000LL, 16, "Philips" },
63 { 0xE004010000000000LL, 24, "Philips; IC SL2 ICS20" },
64 { 0xE005000000000000LL, 16, "Infineon" },
65 { 0xE005400000000000LL, 24, "Infineon; 56x32bit" },
66 { 0xE006000000000000LL, 16, "Cylinc" },
67 { 0xE007000000000000LL, 16, "Texas Instrument; " },
68 { 0xE007000000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Inlay; 64x32bit" },
69 { 0xE007100000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Chip; 64x32bit" },
70 { 0xE007C00000000000LL, 23, "Texas Instrument; Tag-it HF-I Standard; 8x32bit" },
71 { 0xE007C40000000000LL, 23, "Texas Instrument; Tag-it HF-I Pro; 8x23bit; password" },
72 { 0xE008000000000000LL, 16, "Fujitsu" },
73 { 0xE009000000000000LL, 16, "Matsushita" },
74 { 0xE00A000000000000LL, 16, "NEC" },
75 { 0xE00B000000000000LL, 16, "Oki Electric" },
76 { 0xE00C000000000000LL, 16, "Toshiba" },
77 { 0xE00D000000000000LL, 16, "Mitsubishi" },
78 { 0xE00E000000000000LL, 16, "Samsung" },
79 { 0xE00F000000000000LL, 16, "Hyundai" },
80 { 0xE010000000000000LL, 16, "LG-Semiconductors" },
81 { 0xE012000000000000LL, 16, "HID Corporation" },
82 { 0xE016000000000000LL, 16, "EM-Marin SA (Skidata)" },
83 { 0xE016040000000000LL, 24, "EM-Marin SA (Skidata Keycard-eco); no memory" },
84 { 0xE016100000000000LL, 24, "EM-Marin SA (Skidata); EM4135; 36x64bit start page 13" },
85 { 0,0,"no tag-info available" } // must be the last entry
86 };
87
88
89 // fast method to just read the UID of a tag (collission detection not supported)
90 // *buf should be large enough to fit the 64bit uid
91 // returns 1 if suceeded
92 int getUID(uint8_t *buf)
93 {
94 UsbCommand *r;
95 uint8_t *recv;
96 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
97 uint8_t *req=c.d.asBytes;
98 int reqlen=0;
99
100 for (int retry=0;retry<3; retry++) { // don't give up the at the first try
101
102 req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
103 ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
104 req[1]=ISO15_CMD_INVENTORY;
105 req[2]=0; // mask length
106 reqlen=AddCrc(req,3);
107 c.arg[0]=reqlen;
108
109 SendCommand(&c);
110
111 r=WaitForResponseTimeout(CMD_ACK,1000);
112
113 if (r!=NULL) {
114 recv = r->d.asBytes;
115 if (r->arg[0]>=12 && ISO15_CRC_CHECK==Crc(recv,12)) {
116 memcpy(buf,&recv[2],8);
117 return 1;
118 }
119 }
120 } // retry
121 return 0;
122 }
123
124
125
126 // get a product description based on the UID
127 // uid[8] tag uid
128 // returns description of the best match
129 static char* getTagInfo(uint8_t *uid) {
130 uint64_t myuid,mask;
131 int i=0, best=-1;
132 memcpy(&myuid,uid,sizeof(uint64_t));
133 while (uidmapping[i].mask>0) {
134 mask=(~0LL) <<(64-uidmapping[i].mask);
135 if ((myuid & mask) == uidmapping[i].uid) {
136 if (best==-1) {
137 best=i;
138 } else {
139 if (uidmapping[i].mask>uidmapping[best].mask) {
140 best=i;
141 }
142 }
143 }
144 i++;
145 }
146
147 if (best>=0) return uidmapping[best].desc;
148
149 return uidmapping[i].desc;
150 }
151
152
153 // return a clear-text message to an errorcode
154 static char* TagErrorStr(uint8_t error) {
155 switch (error) {
156 case 0x01: return "The command is not supported";
157 case 0x02: return "The command is not recognised";
158 case 0x03: return "The option is not supported.";
159 case 0x0f: return "Unknown error.";
160 case 0x10: return "The specified block is not available (doesn’t exist).";
161 case 0x11: return "The specified block is already -locked and thus cannot be locked again";
162 case 0x12: return "The specified block is locked and its content cannot be changed.";
163 case 0x13: return "The specified block was not successfully programmed.";
164 case 0x14: return "The specified block was not successfully locked.";
165 default: return "Reserved for Future Use or Custom command error.";
166 }
167 }
168
169
170 // Mode 3
171 int CmdHF15Demod(const char *Cmd)
172 {
173 // The sampling rate is 106.353 ksps/s, for T = 18.8 us
174
175 int i, j;
176 int max = 0, maxPos = 0;
177
178 int skip = 4;
179
180 if (GraphTraceLen < 1000) return 0;
181
182 // First, correlate for SOF
183 for (i = 0; i < 100; i++) {
184 int corr = 0;
185 for (j = 0; j < arraylen(FrameSOF); j += skip) {
186 corr += FrameSOF[j] * GraphBuffer[i + (j / skip)];
187 }
188 if (corr > max) {
189 max = corr;
190 maxPos = i;
191 }
192 }
193 PrintAndLog("SOF at %d, correlation %d", maxPos,
194 max / (arraylen(FrameSOF) / skip));
195
196 i = maxPos + arraylen(FrameSOF) / skip;
197 int k = 0;
198 uint8_t outBuf[20];
199 memset(outBuf, 0, sizeof(outBuf));
200 uint8_t mask = 0x01;
201 for (;;) {
202 int corr0 = 0, corr1 = 0, corrEOF = 0;
203 for (j = 0; j < arraylen(Logic0); j += skip) {
204 corr0 += Logic0[j] * GraphBuffer[i + (j / skip)];
205 }
206 for (j = 0; j < arraylen(Logic1); j += skip) {
207 corr1 += Logic1[j] * GraphBuffer[i + (j / skip)];
208 }
209 for (j = 0; j < arraylen(FrameEOF); j += skip) {
210 corrEOF += FrameEOF[j] * GraphBuffer[i + (j / skip)];
211 }
212 // Even things out by the length of the target waveform.
213 corr0 *= 4;
214 corr1 *= 4;
215
216 if (corrEOF > corr1 && corrEOF > corr0) {
217 PrintAndLog("EOF at %d", i);
218 break;
219 } else if (corr1 > corr0) {
220 i += arraylen(Logic1) / skip;
221 outBuf[k] |= mask;
222 } else {
223 i += arraylen(Logic0) / skip;
224 }
225 mask <<= 1;
226 if (mask == 0) {
227 k++;
228 mask = 0x01;
229 }
230 if ((i + (int)arraylen(FrameEOF)) >= GraphTraceLen) {
231 PrintAndLog("ran off end!");
232 break;
233 }
234 }
235 if (mask != 0x01) {
236 PrintAndLog("error, uneven octet! (discard extra bits!)");
237 PrintAndLog(" mask=%02x", mask);
238 }
239 PrintAndLog("%d octets", k);
240
241 for (i = 0; i < k; i++) {
242 PrintAndLog("# %2d: %02x ", i, outBuf[i]);
243 }
244 PrintAndLog("CRC=%04x", Iso15693Crc(outBuf, k - 2));
245 return 0;
246 }
247
248
249
250 // * Acquire Samples as Reader (enables carrier, sends inquiry)
251 int CmdHF15Read(const char *Cmd)
252 {
253 UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693};
254 SendCommand(&c);
255 return 0;
256 }
257
258 // Record Activity without enabeling carrier
259 int CmdHF15Record(const char *Cmd)
260 {
261 UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693};
262 SendCommand(&c);
263 return 0;
264 }
265
266 int CmdHF15Reader(const char *Cmd)
267 {
268 UsbCommand c = {CMD_READER_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
269 SendCommand(&c);
270 return 0;
271 }
272
273 // Simulation is still not working very good
274 int CmdHF15Sim(const char *Cmd)
275 {
276 UsbCommand c = {CMD_SIMTAG_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
277 SendCommand(&c);
278 return 0;
279 }
280
281 // finds the AFI (Application Family Idendifier) of a card, by trying all values
282 // (There is no standard way of reading the AFI, allthough some tags support this)
283 int CmdHF15Afi(const char *Cmd)
284 {
285 UsbCommand c = {CMD_ISO_15693_FIND_AFI, {strtol(Cmd, NULL, 0), 0, 0}};
286 SendCommand(&c);
287 return 0;
288 }
289
290 // Reads all memory pages
291 int CmdHF15DumpMem(const char*Cmd) {
292 UsbCommand *r;
293 uint8_t uid[8];
294 uint8_t *recv=NULL;
295 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
296 uint8_t *req=c.d.asBytes;
297 int reqlen=0;
298 int blocknum=0;
299 char output[80];
300
301 if (!getUID(uid)) {
302 PrintAndLog("No Tag found.");
303 return 0;
304 }
305
306 PrintAndLog("Reading memory from tag UID=%s",sprintUID(NULL,uid));
307 PrintAndLog("Tag Info: %s",getTagInfo(uid));
308
309 for (int retry=0; retry<5; retry++) {
310
311 req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
312 ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
313 req[1]=ISO15_CMD_READ;
314 memcpy(&req[2],uid,8);
315 req[10]=blocknum;
316 reqlen=AddCrc(req,11);
317 c.arg[0]=reqlen;
318
319 SendCommand(&c);
320
321 r=WaitForResponseTimeout(CMD_ACK,1000);
322
323 if (r!=NULL) {
324 recv = r->d.asBytes;
325 if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
326 if (!(recv[0] & ISO15_RES_ERROR)) {
327 retry=0;
328 *output=0; // reset outputstring
329 sprintf(output, "Block %2i ",blocknum);
330 for ( int i=1; i<r->arg[0]-2; i++) { // data in hex
331 sprintf(output+strlen(output),"%02hX ",recv[i]);
332 }
333 strcat(output," ");
334 for ( int i=1; i<r->arg[0]-2; i++) { // data in cleaned ascii
335 sprintf(output+strlen(output),"%c",(recv[i]>31 && recv[i]<127)?recv[i]:'.');
336 }
337 PrintAndLog("%s",output);
338 blocknum++;
339 // PrintAndLog("bn=%i",blocknum);
340 } else {
341 PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
342 return 0;
343 }
344 } // else PrintAndLog("crc");
345 } // else PrintAndLog("r null");
346
347 } // retry
348 if (r && r->arg[0]<3)
349 PrintAndLog("Lost Connection");
350 else if (r && ISO15_CRC_CHECK!=Crc(r->d.asBytes,r->arg[0]))
351 PrintAndLog("CRC Failed");
352 else
353 PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
354 return 0;
355 }
356
357
358 // "HF 15" interface
359
360 static command_t CommandTable15[] =
361 {
362 {"help", CmdHF15Help, 1, "This help"},
363 {"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
364 {"read", CmdHF15Read, 0, "Read HF tag (ISO 15693)"},
365 {"record", CmdHF15Record, 0, "Record Samples (ISO 15693)"}, // atrox
366 {"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
367 {"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
368 {"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
369 {"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"},
370 {"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"},
371 {NULL, NULL, 0, NULL}
372 };
373
374 int CmdHF15(const char *Cmd)
375 {
376 CmdsParse(CommandTable15, Cmd);
377 return 0;
378 }
379
380 int CmdHF15Help(const char *Cmd)
381 {
382 CmdsHelp(CommandTable15);
383 return 0;
384 }
385
386
387 // "HF 15 Cmd" Interface
388 // Allows direct communication with the tag on command level
389
390 int CmdHF15CmdInquiry(const char *Cmd)
391 {
392 UsbCommand *r;
393 uint8_t *recv;
394 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
395 uint8_t *req=c.d.asBytes;
396 int reqlen=0;
397
398 req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
399 ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
400 req[1]=ISO15_CMD_INVENTORY;
401 req[2]=0; // mask length
402 reqlen=AddCrc(req,3);
403 c.arg[0]=reqlen;
404
405 SendCommand(&c);
406
407 r=WaitForResponseTimeout(CMD_ACK,1000);
408
409 if (r!=NULL) {
410 if (r->arg[0]>=12) {
411 recv = r->d.asBytes;
412 PrintAndLog("UID=%s",sprintUID(NULL,&recv[2]));
413 PrintAndLog("Tag Info: %s",getTagInfo(&recv[2]));
414 } else {
415 PrintAndLog("Response to short, just %i bytes. No tag?\n",r->arg[0]);
416 }
417 } else {
418 PrintAndLog("timeout.");
419 }
420 return 0;
421 }
422
423
424 // Turns debugging on(1)/off(0)
425 int CmdHF15CmdDebug( const char *cmd) {
426 int debug=atoi(cmd);
427 if (strlen(cmd)<1) {
428 PrintAndLog("Usage: hf 15 cmd debug <0/1>");
429 PrintAndLog(" 0..no debugging output 1..turn debugging on");
430 return 0;
431 }
432
433 UsbCommand c = {CMD_ISO_15693_DEBUG, {debug, 0, 0}};
434 SendCommand(&c);
435 return 0;
436 }
437
438
439 int CmdHF15CmdRaw (const char *cmd) {
440 UsbCommand *r;
441 uint8_t *recv;
442 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
443 int reply=1;
444 int fast=1;
445 int crc=0;
446 char buf[5]="";
447 int i=0;
448 uint8_t data[100];
449 unsigned int datalen=0, temp;
450 char *hexout;
451
452
453 if (strlen(cmd)<3) {
454 PrintAndLog("Usage: hf 15 cmd raw [-r] [-2] [-c] <0A 0B 0C ... hex>");
455 PrintAndLog(" -r do not read response");
456 PrintAndLog(" -2 use slower '1 out of 256' mode");
457 PrintAndLog(" -c calculate and append CRC");
458 PrintAndLog(" Tip: turn on debugging for verbose output");
459 return 0;
460 }
461
462 // strip
463 while (*cmd==' ' || *cmd=='\t') cmd++;
464
465 while (cmd[i]!='\0') {
466 if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
467 if (cmd[i]=='-') {
468 switch (cmd[i+1]) {
469 case 'r':
470 case 'R':
471 reply=0;
472 break;
473 case '2':
474 fast=0;
475 break;
476 case 'c':
477 case 'C':
478 crc=1;
479 break;
480 default:
481 PrintAndLog("Invalid option");
482 return 0;
483 }
484 i+=2;
485 continue;
486 }
487 if ((cmd[i]>='0' && cmd[i]<='9') ||
488 (cmd[i]>='a' && cmd[i]<='f') ||
489 (cmd[i]>='A' && cmd[i]<='F') ) {
490 buf[strlen(buf)+1]=0;
491 buf[strlen(buf)]=cmd[i];
492 i++;
493
494 if (strlen(buf)>=2) {
495 sscanf(buf,"%x",&temp);
496 data[datalen]=(uint8_t)(temp & 0xff);
497 datalen++;
498 *buf=0;
499 }
500 continue;
501 }
502 PrintAndLog("Invalid char on input");
503 return 0;
504 }
505 if (crc) datalen=AddCrc(data,datalen);
506
507 c.arg[0]=datalen;
508 c.arg[1]=fast;
509 c.arg[2]=reply;
510 memcpy(c.d.asBytes,data,datalen);
511
512 SendCommand(&c);
513
514 if (reply) {
515 r=WaitForResponseTimeout(CMD_ACK,1000);
516
517 if (r!=NULL) {
518 recv = r->d.asBytes;
519 PrintAndLog("received %i octets",r->arg[0]);
520 hexout = (char *)malloc(r->arg[0] * 3 + 1);
521 if (hexout != NULL) {
522 for (int i = 0; i < r->arg[0]; i++) { // data in hex
523 sprintf(&hexout[i * 3], "%02hX ", recv[i]);
524 }
525 PrintAndLog("%s", hexout);
526 free(hexout);
527 }
528 } else {
529 PrintAndLog("timeout while waiting for reply.");
530 }
531
532 } // if reply
533 return 0;
534 }
535
536
537 int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdlen) {
538 int temp;
539 uint8_t *req=c->d.asBytes, uid[8];
540 uint32_t reqlen=0;
541
542 // strip
543 while (**cmd==' ' || **cmd=='\t') (*cmd)++;
544
545 if (strstr(*cmd,"-2")==*cmd) {
546 c->arg[1]=0; // use 1of256
547 (*cmd)+=2;
548 }
549
550 // strip
551 while (**cmd==' ' || **cmd=='\t') (*cmd)++;
552
553 if (strstr(*cmd,"-o")==*cmd) {
554 req[reqlen]=ISO15_REQ_OPTION;
555 (*cmd)+=2;
556 }
557
558 // strip
559 while (**cmd==' ' || **cmd=='\t') (*cmd)++;
560
561 switch (**cmd) {
562 case 0:
563 PrintAndLog("missing addr");
564 return 0;
565 break;
566 case 's':
567 case 'S':
568 // you must have selected the tag earlier
569 req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
570 ISO15_REQ_NONINVENTORY | ISO15_REQ_SELECT;
571 memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
572 reqlen+=iso15cmdlen;
573 break;
574 case 'u':
575 case 'U':
576 // unaddressed mode may not be supported by all vendors
577 req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
578 ISO15_REQ_NONINVENTORY;
579 memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
580 reqlen+=iso15cmdlen;
581 break;
582 case '*':
583 // we scan for the UID ourself
584 req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
585 ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
586 memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
587 reqlen+=iso15cmdlen;
588 if (!getUID(uid)) {
589 PrintAndLog("No Tag found");
590 return 0;
591 }
592 memcpy(req+reqlen,uid,8);
593 PrintAndLog("Detected UID %s",sprintUID(NULL,uid));
594 reqlen+=8;
595 break;
596 default:
597 req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
598 ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
599 memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
600 reqlen+=iso15cmdlen;
601
602 /* sscanf(cmd,"%hX%hX%hX%hX%hX%hX%hX%hX",
603 (short unsigned int *)&uid[7],(short unsigned int *)&uid[6],
604 (short unsigned int *)&uid[5],(short unsigned int *)&uid[4],
605 (short unsigned int *)&uid[3],(short unsigned int *)&uid[2],
606 (short unsigned int *)&uid[1],(short unsigned int *)&uid[0]); */
607 for (int i=0;i<8 && (*cmd)[i*2] && (*cmd)[i*2+1];i++) { // parse UID
608 sscanf((char[]){(*cmd)[i*2],(*cmd)[i*2+1],0},"%X",&temp);
609 uid[7-i]=temp&0xff;
610 }
611
612 PrintAndLog("Using UID %s",sprintUID(NULL,uid));
613 memcpy(&req[reqlen],&uid[0],8);
614 reqlen+=8;
615 }
616 // skip to next space
617 while (**cmd!=' ' && **cmd!='\t') (*cmd)++;
618 // skip over the space
619 while (**cmd==' ' || **cmd=='\t') (*cmd)++;
620
621 c->arg[0]=reqlen;
622 return 1;
623 }
624
625
626
627 /**
628 * Commandline handling: HF15 CMD SYSINFO
629 * get system information from tag/VICC
630 */
631 int CmdHF15CmdSysinfo(const char *Cmd) {
632 UsbCommand *r;
633 uint8_t *recv;
634 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
635 uint8_t *req=c.d.asBytes;
636 int reqlen=0;
637 char cmdbuf[100];
638 char *cmd=cmdbuf;
639 char output[2048]="";
640 int i;
641
642 strncpy(cmd,Cmd,99);
643
644 // usage:
645 if (strlen(cmd)<1) {
646 PrintAndLog("Usage: hf 15 cmd sysinfo [options] <uid|s|*>");
647 PrintAndLog(" options:");
648 PrintAndLog(" -2 use slower '1 out of 256' mode");
649 PrintAndLog(" uid (either): ");
650 PrintAndLog(" <8B hex> full UID eg E011223344556677");
651 PrintAndLog(" s selected tag");
652 PrintAndLog(" u unaddressed mode");
653 PrintAndLog(" * scan for tag");
654 PrintAndLog(" start#: page number to start 0-255");
655 PrintAndLog(" count#: number of pages");
656 return 0;
657 }
658
659 prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_SYSINFO},1);
660 reqlen=c.arg[0];
661
662 reqlen=AddCrc(req,reqlen);
663 c.arg[0]=reqlen;
664
665 SendCommand(&c);
666
667 r=WaitForResponseTimeout(CMD_ACK,1000);
668
669 if (r!=NULL && r->arg[0]>2) {
670 recv = r->d.asBytes;
671 if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
672 if (!(recv[0] & ISO15_RES_ERROR)) {
673 *output=0; // reset outputstring
674 for ( i=1; i<r->arg[0]-2; i++) {
675 sprintf(output+strlen(output),"%02hX ",recv[i]);
676 }
677 strcat(output,"\n\r");
678 strcat(output,"UID = ");
679 strcat(output,sprintUID(NULL,recv+2));
680 strcat(output,"\n\r");
681 strcat(output,getTagInfo(recv+2)); //ABC
682 strcat(output,"\n\r");
683 i=10;
684 if (recv[1] & 0x01)
685 sprintf(output+strlen(output),"DSFID supported, set to %02hX\n\r",recv[i++]);
686 else
687 strcat(output,"DSFID not supported\n\r");
688 if (recv[1] & 0x02)
689 sprintf(output+strlen(output),"AFI supported, set to %03hX\n\r",recv[i++]);
690 else
691 strcat(output,"AFI not supported\n\r");
692 if (recv[1] & 0x04) {
693 strcat(output,"Tag provides info on memory layout (vendor dependent)\n\r");
694 sprintf(output+strlen(output)," %i (or %i) bytes/page x %i pages \n\r",
695 (recv[i+1]&0x1F)+1, (recv[i+1]&0x1F), recv[i]+1);
696 i+=2;
697 } else
698 strcat(output,"Tag does not provide information on memory layout\n\r");
699 if (recv[1] & 0x08) sprintf(output+strlen(output),"IC reference given: %02hX\n\r",recv[i++]);
700 else strcat(output,"IC reference not given\n\r");
701
702
703 PrintAndLog("%s",output);
704 } else {
705 PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
706 }
707 } else {
708 PrintAndLog("CRC failed");
709 }
710 } else {
711 PrintAndLog("timeout: no answer");
712 }
713
714 return 0;
715 }
716
717
718
719 /**
720 * Commandline handling: HF15 CMD READ
721 * Reads a single Block
722 */
723 int CmdHF15CmdRead(const char *Cmd) {
724 UsbCommand *r;
725 uint8_t *recv;
726 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
727 uint8_t *req=c.d.asBytes;
728 int reqlen=0, pagenum;
729 char cmdbuf[100];
730 char *cmd=cmdbuf;
731 char output[100]="";
732
733 strncpy(cmd,Cmd,99);
734
735 // usage:
736 if (strlen(cmd)<3) {
737 PrintAndLog("Usage: hf 15 cmd read [options] <uid|s|*> <page#>");
738 PrintAndLog(" options:");
739 PrintAndLog(" -2 use slower '1 out of 256' mode");
740 PrintAndLog(" uid (either): ");
741 PrintAndLog(" <8B hex> full UID eg E011223344556677");
742 PrintAndLog(" s selected tag");
743 PrintAndLog(" u unaddressed mode");
744 PrintAndLog(" * scan for tag");
745 PrintAndLog(" page#: page number 0-255");
746 return 0;
747 }
748
749 prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_READ},1);
750 reqlen=c.arg[0];
751
752 pagenum=strtol(cmd,NULL,0);
753 /*if (pagenum<0) {
754 PrintAndLog("invalid pagenum");
755 return 0;
756 } */
757
758 req[reqlen++]=(uint8_t)pagenum;
759
760 reqlen=AddCrc(req,reqlen);
761
762 c.arg[0]=reqlen;
763
764 SendCommand(&c);
765
766 r=WaitForResponseTimeout(CMD_ACK,1000);
767
768 if (r!=NULL && r->arg[0]>2) {
769 recv = r->d.asBytes;
770 if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
771 if (!(recv[0] & ISO15_RES_ERROR)) {
772 *output=0; // reset outputstring
773 //sprintf(output, "Block %2i ",blocknum);
774 for ( int i=1; i<r->arg[0]-2; i++) {
775 sprintf(output+strlen(output),"%02hX ",recv[i]);
776 }
777 strcat(output," ");
778 for ( int i=1; i<r->arg[0]-2; i++) {
779 sprintf(output+strlen(output),"%c",recv[i]>31 && recv[i]<127?recv[i]:'.');
780 }
781 PrintAndLog("%s",output);
782 } else {
783 PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
784 }
785 } else {
786 PrintAndLog("CRC failed");
787 }
788 } else {
789 PrintAndLog("no answer");
790 }
791
792 return 0;
793 }
794
795
796 /**
797 * Commandline handling: HF15 CMD WRITE
798 * Writes a single Block - might run into timeout, even when successful
799 */
800 int CmdHF15CmdWrite(const char *Cmd) {
801 UsbCommand *r;
802 uint8_t *recv;
803 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
804 uint8_t *req=c.d.asBytes;
805 int reqlen=0, pagenum, temp;
806 char cmdbuf[100];
807 char *cmd=cmdbuf;
808 char *cmd2;
809
810 strncpy(cmd,Cmd,99);
811
812 // usage:
813 if (strlen(cmd)<3) {
814 PrintAndLog("Usage: hf 15 cmd write [options] <uid|s|*> <page#> <hexdata>");
815 PrintAndLog(" options:");
816 PrintAndLog(" -2 use slower '1 out of 256' mode");
817 PrintAndLog(" -o set OPTION Flag (needed for TI)");
818 PrintAndLog(" uid (either): ");
819 PrintAndLog(" <8B hex> full UID eg E011223344556677");
820 PrintAndLog(" s selected tag");
821 PrintAndLog(" u unaddressed mode");
822 PrintAndLog(" * scan for tag");
823 PrintAndLog(" page#: page number 0-255");
824 PrintAndLog(" hexdata: data to be written eg AA BB CC DD");
825 return 0;
826 }
827
828 prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_WRITE},1);
829 reqlen=c.arg[0];
830
831 // *cmd -> page num ; *cmd2 -> data
832 cmd2=cmd;
833 while (*cmd2!=' ' && *cmd2!='\t' && *cmd2) cmd2++;
834 *cmd2=0;
835 cmd2++;
836
837 pagenum=strtol(cmd,NULL,0);
838 /*if (pagenum<0) {
839 PrintAndLog("invalid pagenum");
840 return 0;
841 } */
842 req[reqlen++]=(uint8_t)pagenum;
843
844
845 while (cmd2[0] && cmd2[1]) { // hexdata, read by 2 hexchars
846 if (*cmd2==' ') {
847 cmd2++;
848 continue;
849 }
850 sscanf((char[]){cmd2[0],cmd2[1],0},"%X",&temp);
851 req[reqlen++]=temp & 0xff;
852 cmd2+=2;
853 }
854
855 reqlen=AddCrc(req,reqlen);
856
857 c.arg[0]=reqlen;
858
859 SendCommand(&c);
860
861 r=WaitForResponseTimeout(CMD_ACK,2000);
862
863 if (r!=NULL && r->arg[0]>2) {
864 recv = r->d.asBytes;
865 if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
866 if (!(recv[0] & ISO15_RES_ERROR)) {
867 PrintAndLog("OK");
868 } else {
869 PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
870 }
871 } else {
872 PrintAndLog("CRC failed");
873 }
874 } else {
875 PrintAndLog("timeout: no answer - data may be written anyway");
876 }
877
878 return 0;
879 }
880
881
882
883 static command_t CommandTable15Cmd[] =
884 {
885 {"help", CmdHF15CmdHelp, 1, "This Help"},
886 {"inquiry", CmdHF15CmdInquiry, 0, "Search for tags in range"},
887 /*
888 {"select", CmdHF15CmdSelect, 0, "Select an tag with a specific UID for further commands"},
889 */
890 {"read", CmdHF15CmdRead, 0, "Read a block"},
891 {"write", CmdHF15CmdWrite, 0, "Write a block"},
892 /*
893 {"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
894 */
895 {"sysinfo", CmdHF15CmdSysinfo, 0, "Get Card Information"},
896 {"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
897 {"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"},
898 {NULL, NULL, 0, NULL}
899 };
900
901 int CmdHF15Cmd(const char *Cmd)
902 {
903 CmdsParse(CommandTable15Cmd, Cmd);
904 return 0;
905 }
906
907 int CmdHF15CmdHelp(const char *Cmd)
908 {
909 CmdsHelp(CommandTable15Cmd);
910 return 0;
911 }
912
Impressum, Datenschutz