]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhf14b.c
ADD: @pwpivi 's latest fixes for bigbuff
[proxmark3-svn] / client / cmdhf14b.c
CommitLineData
a553f267 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
7fe9b0b7 11#include <stdio.h>
12#include <stdlib.h>
13#include <stdbool.h>
17ad0e09 14//#include <string.h>
7fe9b0b7 15#include <stdint.h>
16#include "iso14443crc.h"
902cb3c0 17#include "proxmark3.h"
7fe9b0b7 18#include "data.h"
19#include "graph.h"
3fe4ff4f 20#include "util.h"
7fe9b0b7 21#include "ui.h"
22#include "cmdparser.h"
23#include "cmdhf14b.h"
7cf3ef20 24#include "cmdmain.h"
d71d59db 25#include "cmdhf14a.h"
7fe9b0b7 26
27static int CmdHelp(const char *Cmd);
28
7fe9b0b7 29int CmdHF14BList(const char *Cmd)
30{
388c92bd 31 PrintAndLog("Deprecated command, use 'hf list 14b' instead");
7fe9b0b7 32
388c92bd 33 return 0;
7fe9b0b7 34}
7fe9b0b7 35
22e24700 36int CmdHF14BSim(const char *Cmd)
7fe9b0b7 37{
132a0217 38 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
17ad0e09 39 clearCommandBuffer();
22e24700 40 SendCommand(&c);
41 return 0;
7fe9b0b7 42}
43
44int CmdHF14BSnoop(const char *Cmd)
45{
132a0217 46 UsbCommand c = {CMD_SNOOP_ISO_14443B};
17ad0e09 47 clearCommandBuffer();
22e24700 48 SendCommand(&c);
49 return 0;
7fe9b0b7 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{
22e24700 58 UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
abb21530 59 clearCommandBuffer();
22e24700 60 SendCommand(&c);
61 return 0;
7fe9b0b7 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{
22e24700 70 UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
abb21530 71 clearCommandBuffer();
22e24700 72 SendCommand(&c);
73 return 0;
7fe9b0b7 74}
75
d71d59db 76int rawClose(void){
22e24700 77 UsbCommand resp;
d71d59db 78 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
abb21530 79 clearCommandBuffer();
d71d59db 80 SendCommand(&c);
81 if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
82 return 0;
83 }
84 return 0;
85}
86
22e24700 87int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
d71d59db 88 UsbCommand resp;
22e24700 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);
abb21530 103 clearCommandBuffer();
22e24700 104 SendCommand(&c);
105
106 if (!reply) return 1;
107
17ad0e09 108 if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
22e24700 109 if (verbose) PrintAndLog("timeout while waiting for reply.");
17ad0e09 110 return 0;
111 }
22e24700 112
17ad0e09 113 int len = resp.arg[0];
114 if (verbose) {
115 PrintAndLog("received %u octets", len);
116 }
117 if ( len < 2 ) return 0;
22e24700 118
17ad0e09 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 }
22e24700 131 return 1;
1299c798 132}
133
134int CmdHF14BCmdRaw (const char *Cmd) {
135 bool reply = true;
136 bool crc = false;
22e24700 137 bool power = false;
7cf3ef20 138 char buf[5]="";
17ad0e09 139 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
1299c798 140 uint8_t datalen = 0;
141 unsigned int temp;
142 int i = 0;
143 if (strlen(Cmd)<3) {
7cf3ef20 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
1299c798 152 while (*Cmd==' ' || *Cmd=='\t') Cmd++;
7cf3ef20 153
1299c798 154 while (Cmd[i]!='\0') {
155 if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
156 if (Cmd[i]=='-') {
157 switch (Cmd[i+1]) {
7cf3ef20 158 case 'r':
159 case 'R':
1299c798 160 reply = false;
7cf3ef20 161 break;
162 case 'c':
163 case 'C':
1299c798 164 crc = true;
7cf3ef20 165 break;
166 case 'p':
167 case 'P':
22e24700 168 power = true;
7cf3ef20 169 break;
170 default:
171 PrintAndLog("Invalid option");
172 return 0;
173 }
174 i+=2;
175 continue;
176 }
1299c798 177 if ((Cmd[i]>='0' && Cmd[i]<='9') ||
178 (Cmd[i]>='a' && Cmd[i]<='f') ||
179 (Cmd[i]>='A' && Cmd[i]<='F') ) {
7cf3ef20 180 buf[strlen(buf)+1]=0;
1299c798 181 buf[strlen(buf)]=Cmd[i];
7cf3ef20 182 i++;
183
184 if (strlen(buf)>=2) {
185 sscanf(buf,"%x",&temp);
1299c798 186 data[datalen++]=(uint8_t)(temp & 0xff);
7cf3ef20 187 *buf=0;
188 }
189 continue;
190 }
191 PrintAndLog("Invalid char on input");
5ee70129 192 return 1;
7cf3ef20 193 }
06b82e6a 194 if (datalen == 0)
195 {
196 PrintAndLog("Missing data input");
197 return 0;
198 }
1299c798 199
22e24700 200 return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
1299c798 201}
202
d71d59db 203static void print_atqb_resp(uint8_t *data){
22e24700 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;
1299c798 235}
236
d71d59db 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 }
17ad0e09 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 }
22e24700 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
1299c798 385}
386
17ad0e09 387int HF14BInfo(bool verbose){
22e24700 388 uint8_t data[100];
389 uint8_t datalen = 5;
390
391 // try std 14b (atqb)
17ad0e09 392 if (HF14BStdInfo(data, &datalen)) return 1;
22e24700 393
394 // try st 14b
17ad0e09 395 if (HF14B_ST_Info(data, &datalen)) return 1;
1299c798 396
22e24700 397 // try unknown 14b read commands (to be identified later)
398 // could be read of calypso, CEPAS, moneo, or pico pass.
17ad0e09 399 if (HF14B_Other_Info(data, &datalen)) return 1;
abb21530 400
d71d59db 401 if (verbose) PrintAndLog("no 14443B tag found");
402 return 0;
d71d59db 403}
404
17ad0e09 405int CmdHF14Binfo(const char *Cmd){
406 return HF14BInfo(true);
7cf3ef20 407}
408
17ad0e09 409int CmdSriWrite( const char *Cmd){
3fe4ff4f 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
b5be31f9 426 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
3fe4ff4f 427 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
b5be31f9 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");
3fe4ff4f 435 return 0;
436 }
437
b5be31f9 438 if ( cmdp == '2' )
3fe4ff4f 439 isSrix4k = false;
440
b5be31f9 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 }
3fe4ff4f 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)
b5be31f9 466 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
3fe4ff4f 467 else
b5be31f9 468 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
3fe4ff4f 469
fe5b3a44 470 sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
b5be31f9 471
3fe4ff4f 472 CmdHF14BCmdRaw(str);
473 return 0;
474}
475
7fe9b0b7 476static command_t CommandTable[] =
477{
22e24700 478 {"help", CmdHelp, 1, "This help"},
17ad0e09 479 {"info", CmdHF14Binfo, 0, "Find and print info about a 14b type tag (HF ISO 14443b)"},
22e24700 480 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
132a0217 481 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
482 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
22e24700 483 {"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},
484 {"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"},
17ad0e09 485 {"sriwrite", CmdSriWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
22e24700 486 {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
22e24700 487 {NULL, NULL, 0, NULL}
7fe9b0b7 488};
489
490int CmdHF14B(const char *Cmd)
491{
22e24700 492 CmdsParse(CommandTable, Cmd);
493 return 0;
7fe9b0b7 494}
495
496int CmdHelp(const char *Cmd)
497{
22e24700 498 CmdsHelp(CommandTable);
499 return 0;
7fe9b0b7 500}
Impressum, Datenschutz