]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14b.c
ADD: @marshmellow42 's 14b changes.
[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 <string.h>
15 #include <stdint.h>
16 #include "iso14443crc.h"
17 #include "proxmark3.h"
18 #include "data.h"
19 #include "graph.h"
20 #include "util.h"
21 #include "ui.h"
22 #include "cmdparser.h"
23 #include "cmdhf14b.h"
24 #include "cmdmain.h"
25 #include "cmdhf14a.h"
26 #include "sleep.h"
27
28 static int CmdHelp(const char *Cmd);
29
30 int CmdHF14BDemod(const char *Cmd)
31 {
32 int i, j, iold;
33 int isum, qsum;
34 int outOfWeakAt;
35 bool negateI, negateQ;
36
37 uint8_t data[256];
38 int dataLen = 0;
39
40 // As received, the samples are pairs, correlations against I and Q
41 // square waves. So estimate angle of initial carrier (or just
42 // quadrant, actually), and then do the demod.
43
44 // First, estimate where the tag starts modulating.
45 for (i = 0; i < GraphTraceLen; i += 2) {
46 if (abs(GraphBuffer[i]) + abs(GraphBuffer[i + 1]) > 40) {
47 break;
48 }
49 }
50 if (i >= GraphTraceLen) {
51 PrintAndLog("too weak to sync");
52 return 0;
53 }
54 PrintAndLog("out of weak at %d", i);
55 outOfWeakAt = i;
56
57 // Now, estimate the phase in the initial modulation of the tag
58 isum = 0;
59 qsum = 0;
60 for (; i < (outOfWeakAt + 16); i += 2) {
61 isum += GraphBuffer[i + 0];
62 qsum += GraphBuffer[i + 1];
63 }
64 negateI = (isum < 0);
65 negateQ = (qsum < 0);
66
67 // Turn the correlation pairs into soft decisions on the bit.
68 j = 0;
69 for (i = 0; i < GraphTraceLen / 2; i++) {
70 int si = GraphBuffer[j];
71 int sq = GraphBuffer[j + 1];
72 if (negateI) si = -si;
73 if (negateQ) sq = -sq;
74 GraphBuffer[i] = si + sq;
75 j += 2;
76 }
77 GraphTraceLen = i;
78
79 i = outOfWeakAt / 2;
80 while (GraphBuffer[i] > 0 && i < GraphTraceLen)
81 i++;
82 if (i >= GraphTraceLen) goto demodError;
83
84 iold = i;
85 while (GraphBuffer[i] < 0 && i < GraphTraceLen)
86 i++;
87 if (i >= GraphTraceLen) goto demodError;
88 if ((i - iold) > 23) goto demodError;
89
90 PrintAndLog("make it to demod loop");
91
92 for (;;) {
93 iold = i;
94 while (GraphBuffer[i] >= 0 && i < GraphTraceLen)
95 i++;
96 if (i >= GraphTraceLen) goto demodError;
97 if ((i - iold) > 6) goto demodError;
98
99 uint16_t shiftReg = 0;
100 if (i + 20 >= GraphTraceLen) goto demodError;
101
102 for (j = 0; j < 10; j++) {
103 int soft = GraphBuffer[i] + GraphBuffer[i + 1];
104
105 if (abs(soft) < (abs(isum) + abs(qsum)) / 20) {
106 PrintAndLog("weak bit");
107 }
108
109 shiftReg >>= 1;
110 if(GraphBuffer[i] + GraphBuffer[i+1] >= 0) {
111 shiftReg |= 0x200;
112 }
113
114 i+= 2;
115 }
116
117 if ((shiftReg & 0x200) && !(shiftReg & 0x001))
118 {
119 // valid data byte, start and stop bits okay
120 PrintAndLog(" %02x", (shiftReg >> 1) & 0xff);
121 data[dataLen++] = (shiftReg >> 1) & 0xff;
122 if (dataLen >= sizeof(data)) {
123 return 0;
124 }
125 } else if (shiftReg == 0x000) {
126 // this is EOF
127 break;
128 } else {
129 goto demodError;
130 }
131 }
132
133 uint8_t first, second;
134 ComputeCrc14443(CRC_14443_B, data, dataLen-2, &first, &second);
135 PrintAndLog("CRC: %02x %02x (%s)\n", first, second,
136 (first == data[dataLen-2] && second == data[dataLen-1]) ?
137 "ok" : "****FAIL****");
138
139 RepaintGraphWindow();
140 return 0;
141
142 demodError:
143 PrintAndLog("demod error");
144 RepaintGraphWindow();
145 return 0;
146 }
147
148 int CmdHF14BList(const char *Cmd)
149 {
150 PrintAndLog("Deprecated command, use 'hf list 14b' instead");
151
152 return 0;
153 }
154
155 int CmdHF14Sim(const char *Cmd)
156 {
157 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443};
158 SendCommand(&c);
159 return 0;
160 }
161
162 int CmdHFSimlisten(const char *Cmd)
163 {
164 UsbCommand c = {CMD_SIMULATE_TAG_HF_LISTEN};
165 SendCommand(&c);
166 return 0;
167 }
168
169 int CmdHF14BSnoop(const char *Cmd)
170 {
171 UsbCommand c = {CMD_SNOOP_ISO_14443};
172 SendCommand(&c);
173 return 0;
174 }
175
176 /* New command to read the contents of a SRI512 tag
177 * SRI512 tags are ISO14443-B modulated memory tags,
178 * this command just dumps the contents of the memory
179 */
180 int CmdSri512Read(const char *Cmd)
181 {
182 UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
183 SendCommand(&c);
184 return 0;
185 }
186
187 /* New command to read the contents of a SRIX4K tag
188 * SRIX4K tags are ISO14443-B modulated memory tags,
189 * this command just dumps the contents of the memory/
190 */
191 int CmdSrix4kRead(const char *Cmd)
192 {
193 UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
194 SendCommand(&c);
195 return 0;
196 }
197
198 int rawClose(void){
199 UsbCommand resp;
200 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
201 SendCommand(&c);
202 if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
203 return 0;
204 }
205 return 0;
206 }
207
208 int HF14BCmdRaw(bool reply, bool *crc, uint8_t power_trace, uint8_t *data, uint8_t *datalen, bool verbose){
209 UsbCommand resp;
210 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv,power
211 if(*crc)
212 {
213 uint8_t first, second;
214 ComputeCrc14443(CRC_14443_B, data, *datalen, &first, &second);
215 data[*datalen] = first;
216 data[*datalen + 1] = second;
217 *datalen += 2;
218 }
219
220 c.arg[0] = *datalen;
221 c.arg[1] = reply;
222 c.arg[2] = power_trace;
223 memcpy(c.d.asBytes,data,*datalen);
224 SendCommand(&c);
225
226 if (!reply) return 1;
227
228 if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
229 if (verbose) PrintAndLog("timeout while waiting for reply.");
230 return 0;
231 }
232 *datalen = resp.arg[0];
233 if (verbose) PrintAndLog("received %u octets", *datalen);
234 if(!*datalen)
235 return 0;
236
237 memcpy(data, resp.d.asBytes, *datalen);
238 if (verbose) PrintAndLog("%s", sprint_hex(data, *datalen));
239
240 uint8_t first, second;
241 ComputeCrc14443(CRC_14443_B, data, *datalen-2, &first, &second);
242 if(data[*datalen-2] == first && data[*datalen-1] == second) {
243 if (verbose) PrintAndLog("CRC OK");
244 *crc = true;
245 } else {
246 if (verbose) PrintAndLog("CRC failed");
247 *crc = false;
248 }
249 return 1;
250 }
251
252 int CmdHF14BCmdRaw (const char *Cmd) {
253 bool reply = true;
254 bool crc = false;
255 uint8_t power_trace = 0;
256 char buf[5]="";
257 uint8_t data[100] = {0x00};
258 uint8_t datalen = 0;
259 unsigned int temp;
260 int i = 0;
261 if (strlen(Cmd)<3) {
262 PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
263 PrintAndLog(" -r do not read response");
264 PrintAndLog(" -c calculate and append CRC");
265 PrintAndLog(" -p leave the field on after receive");
266 return 0;
267 }
268
269 // strip
270 while (*Cmd==' ' || *Cmd=='\t') Cmd++;
271
272 while (Cmd[i]!='\0') {
273 if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
274 if (Cmd[i]=='-') {
275 switch (Cmd[i+1]) {
276 case 'r':
277 case 'R':
278 reply = false;
279 break;
280 case 'c':
281 case 'C':
282 crc = true;
283 break;
284 case 'p':
285 case 'P':
286 power_trace |= 1;
287 break;
288 default:
289 PrintAndLog("Invalid option");
290 return 0;
291 }
292 i+=2;
293 continue;
294 }
295 if ((Cmd[i]>='0' && Cmd[i]<='9') ||
296 (Cmd[i]>='a' && Cmd[i]<='f') ||
297 (Cmd[i]>='A' && Cmd[i]<='F') ) {
298 buf[strlen(buf)+1]=0;
299 buf[strlen(buf)]=Cmd[i];
300 i++;
301
302 if (strlen(buf)>=2) {
303 sscanf(buf,"%x",&temp);
304 data[datalen++]=(uint8_t)(temp & 0xff);
305 *buf=0;
306 }
307 continue;
308 }
309 PrintAndLog("Invalid char on input");
310 return 1;
311 }
312 if (datalen == 0)
313 {
314 PrintAndLog("Missing data input");
315 return 0;
316 }
317
318 return HF14BCmdRaw(reply, &crc, power_trace, data, &datalen, true);
319 }
320
321 static void print_atqb_resp(uint8_t *data){
322 PrintAndLog (" UID: %s", sprint_hex(data+1,4));
323 PrintAndLog (" App Data: %s", sprint_hex(data+5,4));
324 PrintAndLog (" Protocol: %s", sprint_hex(data+9,3));
325 uint8_t BitRate = data[9];
326 if (!BitRate)
327 PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD");
328 if (BitRate & 0x10)
329 PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported");
330 if (BitRate & 0x20)
331 PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported");
332 if (BitRate & 0x40)
333 PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported");
334 if (BitRate & 0x01)
335 PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported");
336 if (BitRate & 0x02)
337 PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported");
338 if (BitRate & 0x04)
339 PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported");
340 if (BitRate & 0x80)
341 PrintAndLog (" Same bit rate <-> required");
342
343 uint16_t maxFrame = data[10]>>4;
344 if (maxFrame < 5)
345 maxFrame = 8*maxFrame + 16;
346 else if (maxFrame == 5)
347 maxFrame = 64;
348 else if (maxFrame == 6)
349 maxFrame = 96;
350 else if (maxFrame == 7)
351 maxFrame = 128;
352 else if (maxFrame == 8)
353 maxFrame = 256;
354 else
355 maxFrame = 257;
356
357 PrintAndLog ("Max Frame Size: %d%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
358
359 uint8_t protocolT = data[10] & 0xF;
360 PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
361 PrintAndLog ("Frame Wait Int: %d", data[11]>>4);
362 PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
363 PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
364 PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
365
366 return;
367 }
368
369 char *get_ST_Chip_Model(uint8_t data){
370 static char model[20];
371 char *retStr = model;
372 memset(model,0, sizeof(model));
373
374 switch (data) {
375 case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
376 case 0x2: sprintf(retStr, "SR176"); break;
377 case 0x3: sprintf(retStr, "SRIX4K"); break;
378 case 0x4: sprintf(retStr, "SRIX512"); break;
379 case 0x6: sprintf(retStr, "SRI512"); break;
380 case 0x7: sprintf(retStr, "SRI4K"); break;
381 case 0xC: sprintf(retStr, "SRT512"); break;
382 default: sprintf(retStr, "Unknown"); break;
383 }
384 return retStr;
385 }
386
387 static void print_st_info(uint8_t *data){
388 //uid = first 8 bytes in data
389 PrintAndLog(" UID: %s", sprint_hex(data,8));
390 PrintAndLog(" MFG: %02X, %s", data[1], getTagInfo(data[1]));
391 PrintAndLog("Chip: %02X, %s", data[2]>>2, get_ST_Chip_Model(data[2]>>2));
392 return;
393 }
394
395 int HF14BStdRead(uint8_t *data, uint8_t *datalen){
396 bool crc = true;
397 *datalen = 3;
398 //std read cmd
399 data[0] = 0x05;
400 data[1] = 0x00;
401 data[2] = 0x08;
402
403 int ans = HF14BCmdRaw(true, &crc, 2, data, datalen, false);
404
405 if (!ans) return 0;
406 if (data[0] != 0x50 || *datalen < 14 || !crc) return 0;
407
408 PrintAndLog ("\n14443-3b tag found:");
409 print_atqb_resp(data);
410
411 return 1;
412 }
413
414
415
416 int HF14B_ST_Read(uint8_t *data, uint8_t *datalen){
417 bool crc = true;
418 *datalen = 2;
419 //wake cmd
420 data[0] = 0x06;
421 data[1] = 0x00;
422 //power on and reset tracing
423 int ans = HF14BCmdRaw(true, &crc, 3, data, datalen, true);
424
425 if (!ans) return rawClose();
426 if (*datalen < 3 || !crc) return rawClose();
427
428 uint8_t chipID = data[0];
429 // select
430 data[0] = 0x0E;
431 data[1] = chipID;
432 *datalen = 2;
433 msleep(100);
434 //power on
435 ans = HF14BCmdRaw(true, &crc, 1, data, datalen, true);
436
437 if (!ans) return rawClose();
438 if (*datalen < 3 || !crc) return rawClose();
439
440 // get uid
441 data[0] = 0x0B;
442 *datalen = 1;
443 msleep(100);
444 //power off
445 ans = HF14BCmdRaw(true, &crc, 0, data, datalen, true);
446
447 if (!ans) return 0;
448 if (*datalen < 10 || !crc) return 0;
449
450 PrintAndLog("\n14443-3b ST tag found:");
451 print_st_info(data);
452 return 1;
453
454 }
455
456 int HF14BReader(bool verbose){
457 uint8_t data[100];
458 uint8_t datalen = 5;
459
460 // try std 14b (atqb)
461 int ans = HF14BStdRead(data, &datalen);
462 if (ans) return 1;
463
464 // try st 14b
465 ans = HF14B_ST_Read(data, &datalen);
466 if (ans) return 1;
467 if (verbose) PrintAndLog("no 14443B tag found");
468 return 0;
469
470 }
471
472 int CmdHF14BReader(const char *Cmd)
473 {
474 return HF14BReader(true);
475 //UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
476 //SendCommand(&c);
477 }
478
479 int CmdHF14BWrite( const char *Cmd){
480
481 /*
482 * For SRIX4K blocks 00 - 7F
483 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
484 *
485 * For SR512 blocks 00 - 0F
486 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
487 *
488 * Special block FF = otp_lock_reg block.
489 * Data len 4 bytes-
490 */
491 char cmdp = param_getchar(Cmd, 0);
492 uint8_t blockno = -1;
493 uint8_t data[4] = {0x00};
494 bool isSrix4k = true;
495 char str[20];
496
497 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
498 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
499 PrintAndLog(" [1 = SRIX4K]");
500 PrintAndLog(" [2 = SRI512]");
501 PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
502 PrintAndLog(" sample: hf 14b write 1 7F 11223344");
503 PrintAndLog(" : hf 14b write 1 FF 11223344");
504 PrintAndLog(" : hf 14b write 2 15 11223344");
505 PrintAndLog(" : hf 14b write 2 FF 11223344");
506 return 0;
507 }
508
509 if ( cmdp == '2' )
510 isSrix4k = false;
511
512 //blockno = param_get8(Cmd, 1);
513
514 if ( param_gethex(Cmd,1, &blockno, 2) ) {
515 PrintAndLog("Block number must include 2 HEX symbols");
516 return 0;
517 }
518
519 if ( isSrix4k ){
520 if ( blockno > 0x7f && blockno != 0xff ){
521 PrintAndLog("Block number out of range");
522 return 0;
523 }
524 } else {
525 if ( blockno > 0x0f && blockno != 0xff ){
526 PrintAndLog("Block number out of range");
527 return 0;
528 }
529 }
530
531 if (param_gethex(Cmd, 2, data, 8)) {
532 PrintAndLog("Data must include 8 HEX symbols");
533 return 0;
534 }
535
536 if ( blockno == 0xff)
537 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
538 else
539 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
540
541 sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
542
543 CmdHF14BCmdRaw(str);
544 return 0;
545 }
546
547 static command_t CommandTable[] =
548 {
549 {"help", CmdHelp, 1, "This help"},
550 {"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
551 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
552 {"reader", CmdHF14BReader, 0, "Find 14b tag (HF ISO 14443b)"},
553 {"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
554 {"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
555 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443"},
556 {"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},
557 {"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"},
558 {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
559 {"write", CmdHF14BWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
560 {NULL, NULL, 0, NULL}
561 };
562
563 int CmdHF14B(const char *Cmd)
564 {
565 CmdsParse(CommandTable, Cmd);
566 return 0;
567 }
568
569 int CmdHelp(const char *Cmd)
570 {
571 CmdsHelp(CommandTable);
572 return 0;
573 }
Impressum, Datenschutz