]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf15.c
Merge pull request #969 from pwpiwi/gcc10_fixes
[proxmark3-svn] / client / cmdhf15.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
3 // Modified 2010-2012 by <adrian -at- atrox.at>
4 // Modified 2012 by <vsza at vsza.hu>
5 //
6 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
7 // at your option, any later version. See the LICENSE.txt file for the text of
8 // the license.
9 //-----------------------------------------------------------------------------
10 // High frequency ISO15693 commands
11 //-----------------------------------------------------------------------------
12 // There are three basic operation modes, depending on which device (proxmark/pc)
13 // the signal processing, (de)modulation, transmission protocol and logic is done.
14 // Mode 1:
15 // All steps are done on the proxmark, the output of the commands is returned via
16 // USB-debug-print commands.
17 // Mode 2:
18 // The protocol is done on the PC, passing only Iso15693 data frames via USB. This
19 // allows direct communication with a tag on command level
20 // Mode 3:
21 // The proxmark just samples the antenna and passes this "analog" data via USB to
22 // the client. Signal Processing & decoding is done on the pc. This is the slowest
23 // variant, but offers the possibility to analyze the waveforms directly.
24
25 #include "cmdhf15.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdint.h>
31
32 #include "comms.h"
33 #include "graph.h"
34 #include "ui.h"
35 #include "util.h"
36 #include "cmdparser.h"
37 #include "iso15693tools.h"
38 #include "protocols.h"
39 #include "cmdmain.h"
40 #include "taginfo.h"
41
42 #define Crc(data,datalen) Iso15693Crc(data,datalen)
43 #define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
44 #define sprintUID(target,uid) Iso15693sprintUID(target,uid)
45
46 // SOF defined as
47 // 1) Unmodulated time of 56.64us
48 // 2) 24 pulses of 423.75khz
49 // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
50
51 static const int Iso15693FrameSOF[] = {
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
53 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
54 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
55 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
56 -1, -1, -1, -1,
57 -1, -1, -1, -1,
58 1, 1, 1, 1,
59 1, 1, 1, 1
60 };
61 static const int Iso15693Logic0[] = {
62 1, 1, 1, 1,
63 1, 1, 1, 1,
64 -1, -1, -1, -1,
65 -1, -1, -1, -1
66 };
67 static const int Iso15693Logic1[] = {
68 -1, -1, -1, -1,
69 -1, -1, -1, -1,
70 1, 1, 1, 1,
71 1, 1, 1, 1
72 };
73
74 // EOF defined as
75 // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
76 // 2) 24 pulses of 423.75khz
77 // 3) Unmodulated time of 56.64us
78
79 static const int Iso15693FrameEOF[] = {
80 1, 1, 1, 1,
81 1, 1, 1, 1,
82 -1, -1, -1, -1,
83 -1, -1, -1, -1,
84 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
85 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
86 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
87 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
88 };
89
90
91 // fast method to just read the UID of a tag (collission detection not supported)
92 // *buf should be large enough to fit the 64bit uid
93 // returns true if suceeded
94 static bool getUID(uint8_t *buf) {
95 UsbCommand resp;
96 uint8_t *recv;
97 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
98 uint8_t *req = c.d.asBytes;
99 int reqlen=0;
100
101 for (int retry = 0;retry < 3; retry++) { // don't give up the at the first try
102 req[0] = ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_INVENTORY | ISO15693_REQINV_SLOT1;
103 req[1] = ISO15693_INVENTORY;
104 req[2] = 0; // mask length
105 reqlen = AddCrc(req, 3);
106 c.arg[0] = reqlen;
107
108 SendCommand(&c);
109
110 if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
111 recv = resp.d.asBytes;
112 if (resp.arg[0] >= 12 && ISO15693_CRC_CHECK == Crc(recv, 12)) {
113 memcpy(buf, &recv[2], 8);
114 return true;
115 }
116 }
117 } // retry
118 return false;
119 }
120
121
122 // return a clear-text message to an errorcode
123 static char* TagErrorStr(uint8_t error) {
124 switch (error) {
125 case 0x01: return "The command is not supported";
126 case 0x02: return "The command is not recognised";
127 case 0x03: return "The option is not supported.";
128 case 0x0f: return "Unknown error.";
129 case 0x10: return "The specified block is not available (doesn't exist).";
130 case 0x11: return "The specified block is already -locked and thus cannot be locked again";
131 case 0x12: return "The specified block is locked and its content cannot be changed.";
132 case 0x13: return "The specified block was not successfully programmed.";
133 case 0x14: return "The specified block was not successfully locked.";
134 default: return "Reserved for Future Use or Custom command error.";
135 }
136 }
137
138
139 // Mode 3
140 static int CmdHF15Demod(const char *Cmd) {
141 // The sampling rate is 106.353 ksps/s, for T = 18.8 us
142
143 int i, j;
144 int max = 0, maxPos = 0;
145
146 int skip = 2;
147
148 if (GraphTraceLen < 2000) return 0;
149
150 // First, correlate for SOF
151 for (i = 0; i < 200; i++) {
152 int corr = 0;
153 for (j = 0; j < arraylen(Iso15693FrameSOF); j += skip) {
154 corr += Iso15693FrameSOF[j] * GraphBuffer[i + (j / skip)];
155 }
156 if (corr > max) {
157 max = corr;
158 maxPos = i;
159 }
160 }
161 PrintAndLog("SOF at %d, correlation %d", maxPos,
162 max / (arraylen(Iso15693FrameSOF) / skip));
163
164 i = maxPos + arraylen(Iso15693FrameSOF) / skip;
165 int k = 0;
166 uint8_t outBuf[20];
167 memset(outBuf, 0, sizeof(outBuf));
168 uint8_t mask = 0x01;
169 for (;;) {
170 int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
171 for(j = 0; j < arraylen(Iso15693Logic0); j += skip) {
172 corr0 += Iso15693Logic0[j]*GraphBuffer[i+(j/skip)];
173 }
174 corr01 = corr00 = corr0;
175 for(j = 0; j < arraylen(Iso15693Logic0); j += skip) {
176 corr00 += Iso15693Logic0[j]*GraphBuffer[i+arraylen(Iso15693Logic0)/skip+(j/skip)];
177 corr01 += Iso15693Logic1[j]*GraphBuffer[i+arraylen(Iso15693Logic0)/skip+(j/skip)];
178 }
179 for(j = 0; j < arraylen(Iso15693Logic1); j += skip) {
180 corr1 += Iso15693Logic1[j]*GraphBuffer[i+(j/skip)];
181 }
182 for(j = 0; j < arraylen(Iso15693FrameEOF); j += skip) {
183 corrEOF += Iso15693FrameEOF[j]*GraphBuffer[i+(j/skip)];
184 }
185 // Even things out by the length of the target waveform.
186 corr00 *= 2;
187 corr01 *= 2;
188 corr0 *= 4;
189 corr1 *= 4;
190
191 if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
192 PrintAndLog("EOF at %d", i);
193 break;
194 } else if (corr1 > corr0) {
195 i += arraylen(Iso15693Logic1) / skip;
196 outBuf[k] |= mask;
197 } else {
198 i += arraylen(Iso15693Logic0) / skip;
199 }
200 mask <<= 1;
201 if (mask == 0) {
202 k++;
203 mask = 0x01;
204 }
205 if ((i + (int)arraylen(Iso15693FrameEOF)) >= GraphTraceLen) {
206 PrintAndLog("ran off end!");
207 break;
208 }
209 }
210 if (mask != 0x01) {
211 PrintAndLog("error, uneven octet! (discard extra bits!)");
212 PrintAndLog(" mask=%02x", mask);
213 }
214 PrintAndLog("%d octets", k);
215
216 for (i = 0; i < k; i++) {
217 PrintAndLog("# %2d: %02x ", i, outBuf[i]);
218 }
219 PrintAndLog("CRC=%04x", Iso15693Crc(outBuf, k - 2));
220 return 0;
221 }
222
223
224 // * Acquire Samples as Reader (enables carrier, sends inquiry)
225 static int CmdHF15Read(const char *Cmd) {
226 UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693};
227 SendCommand(&c);
228 return 0;
229 }
230
231
232 // Record Activity without enabling carrier
233 static int CmdHF15Snoop(const char *Cmd) {
234 UsbCommand c = {CMD_SNOOP_ISO_15693};
235 SendCommand(&c);
236 return 0;
237 }
238
239
240 int HF15Reader(const char *Cmd, bool verbose) {
241 uint8_t uid[8];
242
243 if (!getUID(uid)) {
244 if (verbose) PrintAndLog("No Tag found.");
245 return 0;
246 }
247
248 PrintAndLog("UID: %s", sprintUID(NULL,uid));
249 PrintAndLog("Manufacturer byte: %02X, %s", uid[6], getManufacturerName(uid[6]));
250 PrintAndLog("Chip ID: %02X, %s", uid[5], getChipInfo(uid[6], uid[5]));
251 return 1;
252 }
253
254
255 static int CmdHF15Reader(const char *Cmd) {
256 UsbCommand c = {CMD_READER_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
257 SendCommand(&c);
258 return 0;
259 }
260
261
262 // Simulation is still not working very good
263 static int CmdHF15Sim(const char *Cmd) {
264 char cmdp = param_getchar(Cmd, 0);
265 uint8_t uid[8] = {0x00};
266
267 //E0 16 24 00 00 00 00 00
268 if (cmdp == 'h' || cmdp == 'H') {
269 PrintAndLog("Usage: hf 15 sim <UID>");
270 PrintAndLog("");
271 PrintAndLog(" sample: hf 15 sim E016240000000000");
272 return 0;
273 }
274
275 if (param_gethex(Cmd, 0, uid, 16)) {
276 PrintAndLog("UID must include 16 HEX symbols");
277 return 0;
278 }
279
280 PrintAndLog("Starting simulating UID %02X %02X %02X %02X %02X %02X %02X %02X",
281 uid[0],uid[1],uid[2],uid[3],uid[4], uid[5], uid[6], uid[7]);
282 PrintAndLog("Press the button to stop simulation");
283
284 UsbCommand c = {CMD_SIMTAG_ISO_15693, {0, 0, 0}};
285 memcpy(c.d.asBytes,uid,8);
286
287 SendCommand(&c);
288 return 0;
289 }
290
291
292 // finds the AFI (Application Family Idendifier) of a card, by trying all values
293 // (There is no standard way of reading the AFI, allthough some tags support this)
294 static int CmdHF15Afi(const char *Cmd) {
295 UsbCommand c = {CMD_ISO_15693_FIND_AFI, {strtol(Cmd, NULL, 0), 0, 0}};
296 SendCommand(&c);
297 return 0;
298 }
299
300
301 // Reads all memory pages
302 static int CmdHF15DumpMem(const char*Cmd) {
303 UsbCommand resp;
304 uint8_t uid[8];
305 uint8_t *recv=NULL;
306 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
307 uint8_t *req=c.d.asBytes;
308 int reqlen=0;
309 int blocknum=0;
310 char output[80];
311
312 if (!getUID(uid)) {
313 PrintAndLog("No Tag found.");
314 return 0;
315 }
316
317 PrintAndLog("Reading memory from tag");
318 PrintAndLog("UID: %s", sprintUID(NULL,uid));
319 PrintAndLog("Manufacturer byte: %02X, %s", uid[6], getManufacturerName(uid[6]));
320 PrintAndLog("Chip ID: %02X, %s", uid[5], getChipInfo(uid[6], uid[5]));
321
322 for (int retry=0; retry<5; retry++) {
323
324 req[0]= ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_ADDRESS;
325 req[1] = ISO15693_READBLOCK;
326 memcpy(&req[2],uid,8);
327 req[10] = blocknum;
328 reqlen = AddCrc(req,11);
329 c.arg[0] = reqlen;
330
331 SendCommand(&c);
332
333 if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
334 recv = resp.d.asBytes;
335 if (ISO15693_CRC_CHECK==Crc(recv,resp.arg[0])) {
336 if (!(recv[0] & ISO15693_RES_ERROR)) {
337 retry=0;
338 *output=0; // reset outputstring
339 sprintf(output, "Block %02x ",blocknum);
340 for ( int i=1; i<resp.arg[0]-2; i++) { // data in hex
341 sprintf(output+strlen(output),"%02X ",recv[i]);
342 }
343 strcat(output," ");
344 for ( int i=1; i<resp.arg[0]-2; i++) { // data in cleaned ascii
345 sprintf(output+strlen(output),"%c",(recv[i]>31 && recv[i]<127)?recv[i]:'.');
346 }
347 PrintAndLog("%s",output);
348 blocknum++;
349 // PrintAndLog("bn=%i",blocknum);
350 } else {
351 PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
352 return 1;
353 }
354 } // else PrintAndLog("crc");
355 } // else PrintAndLog("r null");
356 } // retry
357 // TODO: need fix
358 // if (resp.arg[0]<3)
359 // PrintAndLog("Lost Connection");
360 // else if (ISO15693_CRC_CHECK!=Crc(resp.d.asBytes,resp.arg[0]))
361 // PrintAndLog("CRC Failed");
362 // else
363 // PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
364 return 1;
365 }
366
367
368 static int CmdHF15CmdInquiry(const char *Cmd) {
369 UsbCommand resp;
370 uint8_t *recv;
371 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
372 uint8_t *req=c.d.asBytes;
373 int reqlen=0;
374
375 req[0] = ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_INVENTORY | ISO15693_REQINV_SLOT1;
376 req[1] = ISO15693_INVENTORY;
377 req[2] = 0; // mask length
378 reqlen=AddCrc(req,3);
379 c.arg[0] = reqlen;
380
381 SendCommand(&c);
382
383 if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
384 if (resp.arg[0]>=12) {
385 recv = resp.d.asBytes;
386 PrintAndLog("UID: %s", sprintUID(NULL,recv+2));
387 PrintAndLog("Manufacturer byte: %02X, %s", recv[8], getManufacturerName(recv[8]));
388 PrintAndLog("Chip ID: %02X, %s", recv[7], getChipInfo(recv[8], recv[7]));
389 } else {
390 PrintAndLog("Response to short, just %i bytes. No tag?\n",resp.arg[0]);
391 }
392 } else {
393 PrintAndLog("timeout.");
394 }
395 return 0;
396 }
397
398
399 // Turns debugging on(1)/off(0)
400 static int CmdHF15CmdDebug( const char *cmd) {
401 int debug = atoi(cmd);
402 if (strlen(cmd) < 1) {
403 PrintAndLog("Usage: hf 15 debug <0|1>");
404 PrintAndLog(" 0 no debugging");
405 PrintAndLog(" 1 turn debugging on");
406 return 0;
407 }
408
409 UsbCommand c = {CMD_ISO_15693_DEBUG, {debug, 0, 0}};
410 SendCommand(&c);
411 return 0;
412 }
413
414
415 static int CmdHF15CmdRaw (const char *cmd) {
416 UsbCommand resp;
417 uint8_t *recv;
418 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
419 int reply=1;
420 int fast=1;
421 int crc=0;
422 char buf[5]="";
423 int i=0;
424 uint8_t data[100];
425 unsigned int datalen=0, temp;
426 char *hexout;
427
428
429 if (strlen(cmd)<2) {
430 PrintAndLog("Usage: hf 15 cmd raw [-r] [-2] [-c] <0A 0B 0C ... hex>");
431 PrintAndLog(" -r do not read response");
432 PrintAndLog(" -2 use slower '1 out of 256' mode");
433 PrintAndLog(" -c calculate and append CRC");
434 PrintAndLog(" Tip: turn on debugging for verbose output");
435 return 0;
436 }
437
438 // strip
439 while (*cmd==' ' || *cmd=='\t') cmd++;
440
441 while (cmd[i]!='\0') {
442 if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
443 if (cmd[i]=='-') {
444 switch (cmd[i+1]) {
445 case 'r':
446 case 'R':
447 reply=0;
448 break;
449 case '2':
450 fast=0;
451 break;
452 case 'c':
453 case 'C':
454 crc=1;
455 break;
456 default:
457 PrintAndLog("Invalid option");
458 return 0;
459 }
460 i+=2;
461 continue;
462 }
463 if ((cmd[i]>='0' && cmd[i]<='9') ||
464 (cmd[i]>='a' && cmd[i]<='f') ||
465 (cmd[i]>='A' && cmd[i]<='F') ) {
466 buf[strlen(buf)+1]=0;
467 buf[strlen(buf)]=cmd[i];
468 i++;
469
470 if (strlen(buf)>=2) {
471 sscanf(buf,"%x",&temp);
472 data[datalen]=(uint8_t)(temp & 0xff);
473 datalen++;
474 *buf=0;
475 }
476 continue;
477 }
478 PrintAndLog("Invalid char on input");
479 return 0;
480 }
481 if (crc) datalen=AddCrc(data,datalen);
482
483 c.arg[0]=datalen;
484 c.arg[1]=fast;
485 c.arg[2]=reply;
486 memcpy(c.d.asBytes,data,datalen);
487
488 SendCommand(&c);
489
490 if (reply) {
491 if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
492 recv = resp.d.asBytes;
493 int recv_len = resp.arg[0];
494 if (recv_len == 0) {
495 PrintAndLog("received SOF only. Maybe Picopass/iCLASS?");
496 } else if (recv_len > 0) {
497 PrintAndLog("received %i octets", recv_len);
498 hexout = (char *)malloc(resp.arg[0] * 3 + 1);
499 if (hexout != NULL) {
500 for (int i = 0; i < resp.arg[0]; i++) { // data in hex
501 sprintf(&hexout[i * 3], "%02X ", recv[i]);
502 }
503 PrintAndLog("%s", hexout);
504 free(hexout);
505 }
506 } else if (recv_len == -1) {
507 PrintAndLog("card didn't respond");
508 } else if (recv_len == -2) {
509 PrintAndLog("receive buffer overflow");
510 }
511 } else {
512 PrintAndLog("timeout while waiting for reply.");
513 }
514 }
515
516 return 0;
517 }
518
519
520 /**
521 * parses common HF 15 CMD parameters and prepares some data structures
522 * Parameters:
523 * **cmd command line
524 */
525 static int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdlen) {
526 int temp;
527 uint8_t *req = c->d.asBytes;
528 uint8_t uid[8] = {0x00};
529 uint32_t reqlen = 0;
530
531 // strip
532 while (**cmd==' ' || **cmd=='\t') (*cmd)++;
533
534 if (strstr(*cmd, "-2") == *cmd) {
535 c->arg[1] = 0; // use 1of256
536 (*cmd) += 2;
537 }
538
539 // strip
540 while (**cmd == ' ' || **cmd == '\t') (*cmd)++;
541
542 if (strstr(*cmd, "-o") == *cmd) {
543 req[reqlen] = ISO15693_REQ_OPTION;
544 (*cmd) += 2;
545 }
546
547 // strip
548 while (**cmd == ' ' || **cmd == '\t') (*cmd)++;
549
550 switch (**cmd) {
551 case 0:
552 PrintAndLog("missing addr");
553 return 0;
554 break;
555 case 's':
556 case 'S':
557 // you must have selected the tag earlier
558 req[reqlen++] |= ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_SELECT;
559 memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
560 reqlen += iso15cmdlen;
561 break;
562 case 'u':
563 case 'U':
564 // unaddressed mode may not be supported by all vendors
565 req[reqlen++] |= ISO15693_REQ_DATARATE_HIGH;
566 memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
567 reqlen += iso15cmdlen;
568 break;
569 case '*':
570 // we scan for the UID ourself
571 req[reqlen++] |= ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_ADDRESS;
572 memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
573 reqlen += iso15cmdlen;
574 if (!getUID(uid)) {
575 PrintAndLog("No Tag found");
576 return 0;
577 }
578 memcpy(req+reqlen ,uid, 8);
579 PrintAndLog("Detected UID %s",sprintUID(NULL,uid));
580 reqlen += 8;
581 break;
582 default:
583 req[reqlen++] |= ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_ADDRESS;
584 memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
585 reqlen += iso15cmdlen;
586
587 /* sscanf(cmd,"%hX%hX%hX%hX%hX%hX%hX%hX",
588 (short unsigned int *)&uid[7],(short unsigned int *)&uid[6],
589 (short unsigned int *)&uid[5],(short unsigned int *)&uid[4],
590 (short unsigned int *)&uid[3],(short unsigned int *)&uid[2],
591 (short unsigned int *)&uid[1],(short unsigned int *)&uid[0]); */
592 for (int i=0; i<8 && (*cmd)[i*2] && (*cmd)[i*2+1]; i++) { // parse UID
593 sscanf((char[]){(*cmd)[i*2],(*cmd)[i*2+1],0},"%X",&temp);
594 uid[7-i]=temp&0xff;
595 }
596
597 PrintAndLog("Using UID %s", sprintUID(NULL, uid));
598 memcpy(&req[reqlen], &uid[0], 8);
599 reqlen += 8;
600 }
601 // skip to next space
602 while (**cmd != ' ' && **cmd != '\t') (*cmd)++;
603 // skip over the space
604 while (**cmd == ' ' || **cmd == '\t') (*cmd)++;
605
606 c->arg[0] = reqlen;
607 return 1;
608 }
609
610 /**
611 * Commandline handling: HF15 CMD SYSINFO
612 * get system information from tag/VICC
613 */
614 static int CmdHF15CmdSysinfo(const char *Cmd) {
615 UsbCommand resp;
616 uint8_t *recv;
617 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
618 uint8_t *req=c.d.asBytes;
619 int reqlen=0;
620 char cmdbuf[100];
621 char *cmd=cmdbuf;
622 char output[2048]="";
623 int i;
624
625 strncpy(cmd,Cmd,99);
626
627 // usage:
628 if (strlen(cmd)<1) {
629 PrintAndLog("Usage: hf 15 cmd sysinfo [options] <uid|s|u|*>");
630 PrintAndLog(" options:");
631 PrintAndLog(" -2 use slower '1 out of 256' mode");
632 PrintAndLog(" uid (either): ");
633 PrintAndLog(" <8B hex> full UID eg E011223344556677");
634 PrintAndLog(" s selected tag");
635 PrintAndLog(" u unaddressed mode");
636 PrintAndLog(" * scan for tag");
637 PrintAndLog(" start#: page number to start 0-255");
638 PrintAndLog(" count#: number of pages");
639 return 0;
640 }
641
642 prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15693_GET_SYSTEM_INFO},1);
643 reqlen=c.arg[0];
644
645 reqlen=AddCrc(req,reqlen);
646 c.arg[0]=reqlen;
647
648 SendCommand(&c);
649
650 if (WaitForResponseTimeout(CMD_ACK, &resp, 1000) && resp.arg[0] > 2) {
651 recv = resp.d.asBytes;
652 if (ISO15693_CRC_CHECK == Crc(recv, resp.arg[0])) {
653 if (!(recv[0] & ISO15693_RES_ERROR)) {
654 *output=0; // reset outputstring
655 PrintAndLog("UID: %s", sprintUID(NULL,recv+2));
656 PrintAndLog("Manufacturer byte: %02X, %s", recv[8], getManufacturerName(recv[8]));
657 PrintAndLog("Chip ID: %02X, %s", recv[7], getChipInfo(recv[8], recv[7]));
658 i=10;
659 if (recv[1] & 0x01)
660 sprintf(output+strlen(output),"DSFID supported, set to %02X\n\r",recv[i++]);
661 else
662 strcat(output,"DSFID not supported\n\r");
663 if (recv[1] & 0x02)
664 sprintf(output+strlen(output),"AFI supported, set to %03X\n\r",recv[i++]);
665 else
666 strcat(output,"AFI not supported\n\r");
667 if (recv[1] & 0x04) {
668 strcat(output,"Tag provides info on memory layout (vendor dependent)\n\r");
669 sprintf(output+strlen(output)," %i (or %i) bytes/page x %i pages \n\r",
670 (recv[i+1]&0x1F)+1, (recv[i+1]&0x1F), recv[i]+1);
671 i+=2;
672 } else
673 strcat(output,"Tag does not provide information on memory layout\n\r");
674 if (recv[1] & 0x08) sprintf(output+strlen(output),"IC reference given: %02X\n\r",recv[i++]);
675 else strcat(output,"IC reference not given\n\r");
676
677
678 PrintAndLog("%s",output);
679 } else {
680 PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
681 }
682 } else {
683 PrintAndLog("CRC failed");
684 }
685 } else {
686 PrintAndLog("timeout: no answer");
687 }
688
689 return 0;
690 }
691
692
693 /**
694 * Commandline handling: HF15 CMD READMULTI
695 * Read multiple blocks at once (not all tags support this)
696 */
697 static int CmdHF15CmdReadmulti(const char *Cmd) {
698 UsbCommand resp;
699 uint8_t *recv;
700 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
701 uint8_t *req=c.d.asBytes;
702 int reqlen=0, pagenum,pagecount;
703 char cmdbuf[100];
704 char *cmd=cmdbuf;
705 char output[2048]="";
706
707 strncpy(cmd,Cmd,99);
708
709 // usage:
710 if (strlen(cmd)<3) {
711 PrintAndLog("Usage: hf 15 cmd readmulti [options] <uid|s|u|*> <start#> <count#>");
712 PrintAndLog(" options:");
713 PrintAndLog(" -2 use slower '1 out of 256' mode");
714 PrintAndLog(" uid (either): ");
715 PrintAndLog(" <8B hex> full UID eg E011223344556677");
716 PrintAndLog(" s selected tag");
717 PrintAndLog(" u unaddressed mode");
718 PrintAndLog(" * scan for tag");
719 PrintAndLog(" start#: page number to start 0-255");
720 PrintAndLog(" count#: number of pages");
721 return 0;
722 }
723
724 prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15693_READ_MULTI_BLOCK},1);
725 reqlen=c.arg[0];
726
727 pagenum=strtol(cmd,NULL,0);
728
729 // skip to next space
730 while (*cmd!=' ' && *cmd!='\t') cmd++;
731 // skip over the space
732 while (*cmd==' ' || *cmd=='\t') cmd++;
733
734 pagecount=strtol(cmd,NULL,0);
735 if (pagecount>0) pagecount--; // 0 means 1 page, 1 means 2 pages, ...
736
737 req[reqlen++]=(uint8_t)pagenum;
738 req[reqlen++]=(uint8_t)pagecount;
739
740 reqlen=AddCrc(req,reqlen);
741
742 c.arg[0]=reqlen;
743
744 SendCommand(&c);
745
746 if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
747 recv = resp.d.asBytes;
748 if (ISO15693_CRC_CHECK==Crc(recv,resp.arg[0])) {
749 if (!(recv[0] & ISO15693_RES_ERROR)) {
750 *output=0; // reset outputstring
751 for ( int i=1; i<resp.arg[0]-2; i++) {
752 sprintf(output+strlen(output),"%02X ",recv[i]);
753 }
754 strcat(output," ");
755 for ( int i=1; i<resp.arg[0]-2; i++) {
756 sprintf(output+strlen(output),"%c",recv[i]>31 && recv[i]<127?recv[i]:'.');
757 }
758 PrintAndLog("%s",output);
759 } else {
760 PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
761 }
762 } else {
763 PrintAndLog("CRC failed");
764 }
765 } else {
766 PrintAndLog("no answer");
767 }
768
769 return 0;
770 }
771
772
773 /**
774 * Commandline handling: HF15 CMD READ
775 * Reads a single Block
776 */
777 static int CmdHF15CmdRead(const char *Cmd) {
778 UsbCommand resp;
779 uint8_t *recv;
780 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
781 uint8_t *req=c.d.asBytes;
782 int reqlen=0, pagenum;
783 char cmdbuf[100];
784 char *cmd=cmdbuf;
785 char output[100]="";
786
787 strncpy(cmd,Cmd,99);
788
789 // usage:
790 if (strlen(cmd)<3) {
791 PrintAndLog("Usage: hf 15 cmd read [options] <uid|s|u|*> <page#>");
792 PrintAndLog(" options:");
793 PrintAndLog(" -2 use slower '1 out of 256' mode");
794 PrintAndLog(" uid (either): ");
795 PrintAndLog(" <8B hex> full UID eg E011223344556677");
796 PrintAndLog(" s selected tag");
797 PrintAndLog(" u unaddressed mode");
798 PrintAndLog(" * scan for tag");
799 PrintAndLog(" page#: page number 0-255");
800 return 0;
801 }
802
803 prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15693_READBLOCK},1);
804 reqlen=c.arg[0];
805
806 pagenum=strtol(cmd,NULL,0);
807 /*if (pagenum<0) {
808 PrintAndLog("invalid pagenum");
809 return 0;
810 } */
811
812 req[reqlen++]=(uint8_t)pagenum;
813
814 reqlen=AddCrc(req,reqlen);
815
816 c.arg[0]=reqlen;
817
818 SendCommand(&c);
819
820 if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
821 recv = resp.d.asBytes;
822 if (ISO15693_CRC_CHECK==Crc(recv,resp.arg[0])) {
823 if (!(recv[0] & ISO15693_RES_ERROR)) {
824 *output=0; // reset outputstring
825 //sprintf(output, "Block %2i ",blocknum);
826 for ( int i=1; i<resp.arg[0]-2; i++) {
827 sprintf(output+strlen(output),"%02X ",recv[i]);
828 }
829 strcat(output," ");
830 for ( int i=1; i<resp.arg[0]-2; i++) {
831 sprintf(output+strlen(output),"%c",recv[i]>31 && recv[i]<127?recv[i]:'.');
832 }
833 PrintAndLog("%s",output);
834 } else {
835 PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
836 }
837 } else {
838 PrintAndLog("CRC failed");
839 }
840 } else {
841 PrintAndLog("no answer");
842 }
843
844 return 0;
845 }
846
847
848 /**
849 * Commandline handling: HF15 CMD WRITE
850 * Writes a single Block
851 **/
852 static int CmdHF15CmdWrite(const char *Cmd) {
853 UsbCommand resp;
854 UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len, speed, recv
855 uint8_t *req = c.d.asBytes;
856 int reqlen = 0, pagenum, temp;
857 char cmdbuf[100];
858 char *cmd = cmdbuf;
859 char *cmd2;
860
861 strncpy(cmd, Cmd, 99);
862
863 // usage:
864 if (strlen(cmd) < 3) {
865 PrintAndLog("Usage: hf 15 cmd write [options] <uid|s|u|*> <page#> <hexdata>");
866 PrintAndLog(" options:");
867 PrintAndLog(" -2 use slower '1 out of 256' mode");
868 PrintAndLog(" -o set OPTION Flag (needed for TI)");
869 PrintAndLog(" uid (either): ");
870 PrintAndLog(" <8B hex> full UID eg E011223344556677");
871 PrintAndLog(" s selected tag");
872 PrintAndLog(" u unaddressed mode");
873 PrintAndLog(" * scan for tag");
874 PrintAndLog(" page#: page number 0-255");
875 PrintAndLog(" hexdata: data to be written eg AA BB CC DD");
876 return 0;
877 }
878
879 prepareHF15Cmd(&cmd, &c, (uint8_t[]){ISO15693_WRITEBLOCK}, 1);
880 reqlen = c.arg[0];
881
882 // *cmd -> page num ; *cmd2 -> data
883 cmd2 = cmd;
884 while (*cmd2 != ' ' && *cmd2 != '\t' && *cmd2) cmd2++;
885 *cmd2 = 0;
886 cmd2++;
887
888 pagenum = strtol(cmd, NULL, 0);
889 /*if (pagenum<0) {
890 PrintAndLog("invalid pagenum");
891 return 0;
892 } */
893 req[reqlen++] = (uint8_t)pagenum;
894
895
896 while (cmd2[0] && cmd2[1]) { // hexdata, read by 2 hexchars
897 if (*cmd2 == ' ') {
898 cmd2++;
899 continue;
900 }
901 sscanf((char[]){cmd2[0], cmd2[1], 0}, "%X", &temp);
902 req[reqlen++] = temp & 0xff;
903 cmd2 += 2;
904 }
905
906 reqlen = AddCrc(req, reqlen);
907 c.arg[0] = reqlen;
908
909 SendCommand(&c);
910
911 if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
912 int recv_len = resp.arg[0];
913 uint8_t *recv = resp.d.asBytes;
914 if (recv_len == 0) {
915 PrintAndLog("Received SOF only. Maybe Picopass/iCLASS?");
916 } else if (recv_len == -1) {
917 PrintAndLog("Tag didn't respond");
918 } else if (recv_len == -2) {
919 PrintAndLog("Receive buffer overflow");
920 } else if (ISO15693_CRC_CHECK != Crc(recv, resp.arg[0])) {
921 PrintAndLog("CRC check failed on Tag response");
922 } else if (!(recv[0] & ISO15693_RES_ERROR)) {
923 PrintAndLog("Tag returned OK");
924 } else {
925 PrintAndLog("Tag returned Error %i: %s", recv[1], TagErrorStr(recv[1]));
926 }
927 } else {
928 PrintAndLog("No answer from Proxmark");
929 }
930
931 return 0;
932 }
933
934
935 static int CmdHF15CSetUID(const char *Cmd) {
936 uint8_t uid[8] = {0x00};
937 uint8_t oldUid[8], newUid[8] = {0x00};
938
939 uint8_t needHelp = 0;
940 char cmdp = 1;
941
942 if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 16)) {
943 PrintAndLog("UID must include 16 HEX symbols");
944 return 1;
945 }
946
947 if (uid[0] != 0xe0) {
948 PrintAndLog("UID must begin with the byte 'E0'");
949 return 1;
950 }
951
952 while (param_getchar(Cmd, cmdp) != 0x00) {
953 switch (param_getchar(Cmd, cmdp)) {
954 case 'h':
955 case 'H':
956 needHelp = 1;
957 break;
958 default:
959 PrintAndLog("ERROR: Unknown parameter '%c'", param_getchar(Cmd, cmdp));
960 needHelp = 1;
961 break;
962 }
963 cmdp++;
964 }
965
966 if (strlen(Cmd) < 1 || needHelp) {
967 PrintAndLog("");
968 PrintAndLog("Usage: hf 15 csetuid <UID 16 hex symbols>");
969 PrintAndLog("sample: hf 15 csetuid E004013344556677");
970 PrintAndLog("Set UID for magic Chinese card (only works with such cards)");
971 return 0;
972 }
973
974 PrintAndLog("Using backdoor Magic tag function");
975
976 if (!getUID(oldUid)) {
977 PrintAndLog("Can't get old UID.");
978 return 1;
979 }
980
981 UsbCommand c = {CMD_CSETUID_ISO_15693, {0, 0, 0}};
982 memcpy(c.d.asBytes, uid, 8);
983
984 SendCommand(&c);
985
986 UsbCommand resp;
987 if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
988 int recv_len = resp.arg[0];
989 uint8_t *recv = resp.d.asBytes;
990 if (recv_len == 0) {
991 PrintAndLog("Received SOF only. Maybe Picopass/iCLASS?");
992 } else if (recv_len == -1) {
993 PrintAndLog("Tag didn't respond");
994 } else if (recv_len == -2) {
995 PrintAndLog("Receive buffer overflow");
996 } else if (ISO15693_CRC_CHECK != Crc(recv, recv_len)) {
997 PrintAndLog("CRC check failed on Tag response");
998 } else if (!(recv[0] & ISO15693_RES_ERROR)) {
999 PrintAndLog("Tag returned OK");
1000 } else {
1001 PrintAndLog("Tag returned Error %i: %s", recv[1], TagErrorStr(recv[1]));
1002 }
1003 } else {
1004 PrintAndLog("No answer from Proxmark");
1005 }
1006
1007 if (!getUID(newUid)) {
1008 PrintAndLog("Can't get new UID.");
1009 return 1;
1010 }
1011
1012 PrintAndLog("");
1013 PrintAndLog("old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]);
1014 PrintAndLog("new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]);
1015 return 0;
1016 }
1017
1018
1019 // "HF 15 Cmd" Interface
1020 // Allows direct communication with the tag on command level
1021
1022 static int CmdHF15CmdHelp(const char*Cmd);
1023
1024 static command_t CommandTable15Cmd[] = {
1025 {"help", CmdHF15CmdHelp, 1, "This Help"},
1026 {"inquiry", CmdHF15CmdInquiry, 0, "Search for tags in range"},
1027 /*
1028 {"select", CmdHF15CmdSelect, 0, "Select an tag with a specific UID for further commands"},
1029 */
1030 {"read", CmdHF15CmdRead, 0, "Read a block"},
1031 {"write", CmdHF15CmdWrite, 0, "Write a block"},
1032 {"readmulti", CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
1033 {"sysinfo", CmdHF15CmdSysinfo, 0, "Get Card Information"},
1034 {"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
1035 {"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"},
1036 {NULL, NULL, 0, NULL}
1037 };
1038
1039
1040 static int CmdHF15Cmd(const char *Cmd) {
1041 CmdsParse(CommandTable15Cmd, Cmd);
1042 return 0;
1043 }
1044
1045
1046 static int CmdHF15CmdHelp(const char *Cmd) {
1047 CmdsHelp(CommandTable15Cmd);
1048 return 0;
1049 }
1050
1051
1052 // "HF 15" interface
1053
1054 static int CmdHF15Help(const char*Cmd);
1055
1056 static command_t CommandTable15[] = {
1057 {"help", CmdHF15Help, 1, "This help"},
1058 {"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
1059 {"read", CmdHF15Read, 0, "Read HF tag (ISO 15693)"},
1060 {"snoop", CmdHF15Snoop, 0, "Eavesdrop ISO 15693 communications"},
1061 {"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
1062 {"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
1063 {"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
1064 {"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"},
1065 {"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"},
1066 {"csetuid", CmdHF15CSetUID, 0, "Set UID for magic Chinese card"},
1067 {NULL, NULL, 0, NULL}
1068 };
1069
1070
1071 int CmdHF15(const char *Cmd) {
1072 CmdsParse(CommandTable15, Cmd);
1073 return 0;
1074 }
1075
1076
1077 static int CmdHF15Help(const char *Cmd) {
1078 CmdsHelp(CommandTable15);
1079 return 0;
1080 }
1081
1082
Impressum, Datenschutz