]> git.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/cmdhf14b.c
ADD: @marshmellow42 's 14b fixes.
[proxmark3-svn] / client / cmdhf14b.c
... / ...
CommitLineData
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
27static int CmdHelp(const char *Cmd);
28
29int CmdHF14BList(const char *Cmd)
30{
31 PrintAndLog("Deprecated command, use 'hf list 14b' instead");
32
33 return 0;
34}
35
36int CmdHF14BSim(const char *Cmd)
37{
38 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
39 clearCommandBuffer();
40 SendCommand(&c);
41 return 0;
42}
43
44int CmdHF14BSnoop(const char *Cmd)
45{
46 UsbCommand c = {CMD_SNOOP_ISO_14443B};
47 clearCommandBuffer();
48 SendCommand(&c);
49 return 0;
50}
51
52/* New command to read the contents of a SRI512 tag
53 * SRI512 tags are ISO14443-B modulated memory tags,
54 * this command just dumps the contents of the memory
55 */
56int CmdSri512Read(const char *Cmd)
57{
58 UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
59 clearCommandBuffer();
60 SendCommand(&c);
61 return 0;
62}
63
64/* New command to read the contents of a SRIX4K tag
65 * SRIX4K tags are ISO14443-B modulated memory tags,
66 * this command just dumps the contents of the memory/
67 */
68int CmdSrix4kRead(const char *Cmd)
69{
70 UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
71 clearCommandBuffer();
72 SendCommand(&c);
73 return 0;
74}
75
76int rawClose(void){
77 UsbCommand resp;
78 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
79 clearCommandBuffer();
80 SendCommand(&c);
81 if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
82 return 0;
83 }
84 return 0;
85}
86
87int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
88 UsbCommand resp;
89 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv,power
90 if(*crc)
91 {
92 uint8_t first, second;
93 ComputeCrc14443(CRC_14443_B, data, *datalen, &first, &second);
94 data[*datalen] = first;
95 data[*datalen + 1] = second;
96 *datalen += 2;
97 }
98
99 c.arg[0] = *datalen;
100 c.arg[1] = reply;
101 c.arg[2] = power;
102 memcpy(c.d.asBytes,data,*datalen);
103 clearCommandBuffer();
104 SendCommand(&c);
105
106 if (!reply) return 1;
107
108 if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
109 if (verbose) PrintAndLog("timeout while waiting for reply.");
110 return 0;
111 }
112
113 int len = resp.arg[0];
114 if (verbose) {
115 PrintAndLog("received %u octets", len);
116 }
117 if ( len < 2 ) return 0;
118
119 memcpy(data, resp.d.asBytes, len);
120 if (verbose) PrintAndLog("%s", sprint_hex(data, len));
121
122 uint8_t first, second;
123 ComputeCrc14443(CRC_14443_B, data, len-2, &first, &second);
124 if(data[len-2] == first && data[len-1] == second) {
125 if (verbose) PrintAndLog("CRC OK");
126 *crc = true;
127 } else {
128 if (verbose) PrintAndLog("CRC failed");
129 *crc = false;
130 }
131 return 1;
132}
133
134int CmdHF14BCmdRaw (const char *Cmd) {
135 bool reply = true;
136 bool crc = false;
137 bool power = false;
138 char buf[5]="";
139 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
140 uint8_t datalen = 0;
141 unsigned int temp;
142 int i = 0;
143 if (strlen(Cmd)<3) {
144 PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
145 PrintAndLog(" -r do not read response");
146 PrintAndLog(" -c calculate and append CRC");
147 PrintAndLog(" -p leave the field on after receive");
148 return 0;
149 }
150
151 // strip
152 while (*Cmd==' ' || *Cmd=='\t') Cmd++;
153
154 while (Cmd[i]!='\0') {
155 if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
156 if (Cmd[i]=='-') {
157 switch (Cmd[i+1]) {
158 case 'r':
159 case 'R':
160 reply = false;
161 break;
162 case 'c':
163 case 'C':
164 crc = true;
165 break;
166 case 'p':
167 case 'P':
168 power = true;
169 break;
170 default:
171 PrintAndLog("Invalid option");
172 return 0;
173 }
174 i+=2;
175 continue;
176 }
177 if ((Cmd[i]>='0' && Cmd[i]<='9') ||
178 (Cmd[i]>='a' && Cmd[i]<='f') ||
179 (Cmd[i]>='A' && Cmd[i]<='F') ) {
180 buf[strlen(buf)+1]=0;
181 buf[strlen(buf)]=Cmd[i];
182 i++;
183
184 if (strlen(buf)>=2) {
185 sscanf(buf,"%x",&temp);
186 data[datalen++]=(uint8_t)(temp & 0xff);
187 *buf=0;
188 }
189 continue;
190 }
191 PrintAndLog("Invalid char on input");
192 return 1;
193 }
194 if (datalen == 0)
195 {
196 PrintAndLog("Missing data input");
197 return 0;
198 }
199
200 return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
201}
202
203static void print_atqb_resp(uint8_t *data){
204 PrintAndLog (" UID: %s", sprint_hex(data+1,4));
205 PrintAndLog (" App Data: %s", sprint_hex(data+5,4));
206 PrintAndLog (" Protocol: %s", sprint_hex(data+9,3));
207 uint8_t BitRate = data[9];
208 if (!BitRate) PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD");
209 if (BitRate & 0x10) PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported");
210 if (BitRate & 0x20) PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported");
211 if (BitRate & 0x40) PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported");
212 if (BitRate & 0x01) PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported");
213 if (BitRate & 0x02) PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported");
214 if (BitRate & 0x04) PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported");
215 if (BitRate & 0x80) PrintAndLog (" Same bit rate <-> required");
216
217 uint16_t maxFrame = data[10]>>4;
218 if (maxFrame < 5) maxFrame = 8 * maxFrame + 16;
219 else if (maxFrame == 5) maxFrame = 64;
220 else if (maxFrame == 6) maxFrame = 96;
221 else if (maxFrame == 7) maxFrame = 128;
222 else if (maxFrame == 8) maxFrame = 256;
223 else maxFrame = 257;
224
225 PrintAndLog ("Max Frame Size: %d%s", maxFrame, (maxFrame == 257) ? "+ RFU" : "");
226
227 uint8_t protocolT = data[10] & 0xF;
228 PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
229 PrintAndLog ("Frame Wait Int: %d", data[11]>>4);
230 PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
231 PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
232 PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
233
234 return;
235}
236
237char *get_ST_Chip_Model(uint8_t data){
238 static char model[20];
239 char *retStr = model;
240 memset(model,0, sizeof(model));
241
242 switch (data) {
243 case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
244 case 0x2: sprintf(retStr, "SR176"); break;
245 case 0x3: sprintf(retStr, "SRIX4K"); break;
246 case 0x4: sprintf(retStr, "SRIX512"); break;
247 case 0x6: sprintf(retStr, "SRI512"); break;
248 case 0x7: sprintf(retStr, "SRI4K"); break;
249 case 0xC: sprintf(retStr, "SRT512"); break;
250 default: sprintf(retStr, "Unknown"); break;
251 }
252 return retStr;
253}
254
255static void print_st_info(uint8_t *data){
256 //uid = first 8 bytes in data
257 PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
258 PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
259 PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
260 return;
261}
262
263int HF14BStdInfo(uint8_t *data, uint8_t *datalen){
264
265 //05 00 00 = find one tag in field
266 //1d xx xx xx xx 20 00 08 01 00 = attrib xx=crc
267 //a3 = ? (resp 03 e2 c2)
268 //02 = ? (resp 02 6a d3)
269 // 022b (resp 02 67 00 [29 5b])
270 // 0200a40400 (resp 02 67 00 [29 5b])
271 // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
272 // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
273 // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
274 // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
275 // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
276 // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
277 // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
278 //03 = ? (resp 03 [e3 c2])
279 //c2 = ? (resp c2 [66 15])
280 //b2 = ? (resp a3 [e9 67])
281 bool crc = true;
282 *datalen = 3;
283 //std read cmd
284 data[0] = 0x05;
285 data[1] = 0x00;
286 data[2] = 0x00;
287
288 if (HF14BCmdRaw(true, &crc, false, data, datalen, false)==0) return 0;
289
290 if (data[0] != 0x50 || *datalen != 14 || !crc) return 0;
291
292 PrintAndLog ("\n14443-3b tag found:");
293 print_atqb_resp(data);
294
295 return 1;
296}
297
298int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
299 bool crc = true;
300 *datalen = 2;
301 //wake cmd
302 data[0] = 0x06;
303 data[1] = 0x00;
304
305 //leave power on
306 // verbose on for now for testing - turn off when functional
307 if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
308
309 if (*datalen != 3 || !crc) return rawClose();
310
311 uint8_t chipID = data[0];
312 // select
313 data[0] = 0x0E;
314 data[1] = chipID;
315 *datalen = 2;
316
317 //leave power on
318 // verbose on for now for testing - turn off when functional
319 if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
320
321 if (*datalen != 3 || !crc || data[0] != chipID) return rawClose();
322
323 // get uid
324 data[0] = 0x0B;
325 *datalen = 1;
326
327 //power off
328 // verbose on for now for testing - turn off when functional
329 if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return 0;
330 rawClose();
331 if (*datalen != 10 || !crc) return 0;
332
333 PrintAndLog("\n14443-3b ST tag found:");
334 print_st_info(data);
335 return 1;
336}
337
338// test for other 14b type tags (mimic another reader - don't have tags to identify)
339int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
340 bool crc = true;
341 *datalen = 4;
342 //std read cmd
343 data[0] = 0x00;
344 data[1] = 0x0b;
345 data[2] = 0x3f;
346 data[3] = 0x80;
347
348 if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
349 if (*datalen > 2 || !crc) {
350 PrintAndLog ("\n14443-3b tag found:");
351 PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:");
352 PrintAndLog ("%s",sprint_hex(data,*datalen));
353 return 1;
354 }
355 }
356
357 crc = false;
358 *datalen = 1;
359 data[0] = 0x0a;
360
361 if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
362 if (*datalen > 0) {
363 PrintAndLog ("\n14443-3b tag found:");
364 PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
365 PrintAndLog ("%s",sprint_hex(data,*datalen));
366 return 1;
367 }
368 }
369
370 crc = false;
371 *datalen = 1;
372 data[0] = 0x0c;
373
374 if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
375 if (*datalen > 0) {
376 PrintAndLog ("\n14443-3b tag found:");
377 PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
378 PrintAndLog ("%s",sprint_hex(data,*datalen));
379 return 1;
380 }
381 }
382
383 return 0;
384
385}
386
387int HF14BInfo(bool verbose){
388 uint8_t data[100];
389 uint8_t datalen = 5;
390
391 // try std 14b (atqb)
392 if (HF14BStdInfo(data, &datalen)) return 1;
393
394 // try st 14b
395 if (HF14B_ST_Info(data, &datalen)) return 1;
396
397 // try unknown 14b read commands (to be identified later)
398 // could be read of calypso, CEPAS, moneo, or pico pass.
399 if (HF14B_Other_Info(data, &datalen)) return 1;
400
401 if (verbose) PrintAndLog("no 14443B tag found");
402 return 0;
403}
404
405int CmdHF14Binfo(const char *Cmd){
406 return HF14BInfo(true);
407}
408
409int CmdSriWrite( const char *Cmd){
410/*
411 * For SRIX4K blocks 00 - 7F
412 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
413 *
414 * For SR512 blocks 00 - 0F
415 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
416 *
417 * Special block FF = otp_lock_reg block.
418 * Data len 4 bytes-
419 */
420 char cmdp = param_getchar(Cmd, 0);
421 uint8_t blockno = -1;
422 uint8_t data[4] = {0x00};
423 bool isSrix4k = true;
424 char str[20];
425
426 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
427 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
428 PrintAndLog(" [1 = SRIX4K]");
429 PrintAndLog(" [2 = SRI512]");
430 PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
431 PrintAndLog(" sample: hf 14b write 1 7F 11223344");
432 PrintAndLog(" : hf 14b write 1 FF 11223344");
433 PrintAndLog(" : hf 14b write 2 15 11223344");
434 PrintAndLog(" : hf 14b write 2 FF 11223344");
435 return 0;
436 }
437
438 if ( cmdp == '2' )
439 isSrix4k = false;
440
441 //blockno = param_get8(Cmd, 1);
442
443 if ( param_gethex(Cmd,1, &blockno, 2) ) {
444 PrintAndLog("Block number must include 2 HEX symbols");
445 return 0;
446 }
447
448 if ( isSrix4k ){
449 if ( blockno > 0x7f && blockno != 0xff ){
450 PrintAndLog("Block number out of range");
451 return 0;
452 }
453 } else {
454 if ( blockno > 0x0f && blockno != 0xff ){
455 PrintAndLog("Block number out of range");
456 return 0;
457 }
458 }
459
460 if (param_gethex(Cmd, 2, data, 8)) {
461 PrintAndLog("Data must include 8 HEX symbols");
462 return 0;
463 }
464
465 if ( blockno == 0xff)
466 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
467 else
468 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
469
470 sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
471
472 CmdHF14BCmdRaw(str);
473 return 0;
474}
475
476static command_t CommandTable[] =
477{
478 {"help", CmdHelp, 1, "This help"},
479 {"info", CmdHF14Binfo, 0, "Find and print info about a 14b type tag (HF ISO 14443b)"},
480 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
481 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
482 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
483 {"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},
484 {"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"},
485 {"sriwrite", CmdSriWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
486 {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
487 {NULL, NULL, 0, NULL}
488};
489
490int CmdHF14B(const char *Cmd)
491{
492 CmdsParse(CommandTable, Cmd);
493 return 0;
494}
495
496int CmdHelp(const char *Cmd)
497{
498 CmdsHelp(CommandTable);
499 return 0;
500}
Impressum, Datenschutz