]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhf14b.c
coverity fixes for my latest changes.
[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>
7fe9b0b7 14#include <stdint.h>
7fe9b0b7 15#include "cmdhf14b.h"
16
5de71ee6 17#define TIMEOUT 2000
7fe9b0b7 18static int CmdHelp(const char *Cmd);
19
6fc68747 20int usage_hf_14b_info(void){
21 PrintAndLog("Usage: hf 14b info [-h] [-s]");
22 PrintAndLog(" -h this help");
23 PrintAndLog(" -s silently");
388c92bd 24 return 0;
7fe9b0b7 25}
6fc68747 26int usage_hf_14b_reader(void){
27 PrintAndLog("Usage: hf 14b reader [-h] [-s]");
28 PrintAndLog(" -h this help");
29 PrintAndLog(" -s silently");
22e24700 30 return 0;
7fe9b0b7 31}
6fc68747 32int usage_hf_14b_raw(void){
33 PrintAndLog("Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
34 PrintAndLog(" -h this help");
35 PrintAndLog(" -r do not read response");
36 PrintAndLog(" -c calculate and append CRC");
37 PrintAndLog(" -p leave the field on after receive");
38 PrintAndLog(" -s active signal field ON with select");
39 PrintAndLog(" -ss active signal field ON with select for SRx ST Microelectronics tags");
40 return 0;
7fe9b0b7 41}
6fc68747 42int usage_hf_14b_snoop(void){
43 PrintAndLog("It get data from the field and saves it into command buffer.");
44 PrintAndLog("Buffer accessible from command 'hf list 14b'");
45 PrintAndLog("Usage: hf 14b snoop [-h]");
46 PrintAndLog(" -h this help");
47 PrintAndLog("sample: hf 14b snoop");
48 return 0;
49}
50int usage_hf_14b_sim(void){
51 PrintAndLog("Emulating ISO/IEC 14443 type B tag with 4 UID");
52 PrintAndLog("Usage: hf 14b sim [-h]");
53 PrintAndLog(" -h this help");
54 PrintAndLog("sample: hf 14b sim");
55 return 0;
56}
57int usage_hf_14b_read_srx(void){
58 PrintAndLog("Usage: hf 14b read [h] <1|2>");
59 PrintAndLog("Options:");
60 PrintAndLog(" h this help");
61 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
62 PrintAndLog("sample: hf 14b read 1");
63 PrintAndLog(" : hf 14b read 2");
22e24700 64 return 0;
7fe9b0b7 65}
6fc68747 66int usage_hf_14b_write_srx(void){
67 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
68 PrintAndLog("Options:");
69 PrintAndLog(" h this help");
70 PrintAndLog(" <1|2> 1 = SRIX4K , 2 = SRI512");
71 PrintAndLog(" <block> BLOCK number depends on tag, special block == FF");
72 PrintAndLog(" <data> hex bytes of data to be written");
73 PrintAndLog("sample : hf 14b write 1 7F 11223344");
74 PrintAndLog(" : hf 14b write 1 FF 11223344");
75 PrintAndLog(" : hf 14b write 2 15 11223344");
76 PrintAndLog(" : hf 14b write 2 FF 11223344");
22e24700 77 return 0;
7fe9b0b7 78}
79
6fc68747 80static int rawClose(){
81 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}};
abb21530 82 clearCommandBuffer();
d71d59db 83 SendCommand(&c);
3607b5a9 84 return 1;
85}
d71d59db 86
6fc68747 87int CmdHF14BList(const char *Cmd) {
88 CmdHFList("14b");
89 return 0;
90}
22e24700 91
6fc68747 92int CmdHF14BSim(const char *Cmd) {
93 char cmdp = param_getchar(Cmd, 0);
94 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_sim();
95
96 UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B, {0, 0, 0}};
abb21530 97 clearCommandBuffer();
22e24700 98 SendCommand(&c);
6fc68747 99 return 0;
100}
22e24700 101
6fc68747 102int CmdHF14BSnoop(const char *Cmd) {
6de14cec 103
6fc68747 104 char cmdp = param_getchar(Cmd, 0);
105 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_snoop();
6de14cec 106
6fc68747 107 UsbCommand c = {CMD_SNOOP_ISO_14443B, {0, 0, 0}};
108 clearCommandBuffer();
109 SendCommand(&c);
110 return 0;
1299c798 111}
112
113int CmdHF14BCmdRaw (const char *Cmd) {
6fc68747 114 bool reply = TRUE;
115 bool power = FALSE;
116 bool select = FALSE;
117 char buf[5]="";
118
119 int i = 0;
120 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
121 uint16_t datalen = 0;
122 uint32_t flags = 0;
123 uint32_t temp = 0;
124
125 if (strlen(Cmd)<3) return usage_hf_14b_raw();
7cf3ef20 126
127 // strip
6fc68747 128 while (*Cmd==' ' || *Cmd=='\t') ++Cmd;
7cf3ef20 129
1299c798 130 while (Cmd[i]!='\0') {
6fc68747 131 if (Cmd[i]==' ' || Cmd[i]=='\t') { ++i; continue; }
1299c798 132 if (Cmd[i]=='-') {
133 switch (Cmd[i+1]) {
6fc68747 134 case 'H':
135 case 'h':
136 return usage_hf_14b_raw();
7cf3ef20 137 case 'r':
138 case 'R':
6fc68747 139 reply = FALSE;
7cf3ef20 140 break;
141 case 'c':
142 case 'C':
6fc68747 143 flags |= ISO14B_APPEND_CRC;
7cf3ef20 144 break;
145 case 'p':
146 case 'P':
6fc68747 147 power = TRUE;
7cf3ef20 148 break;
b10a759f 149 case 's':
150 case 'S':
6fc68747 151 flags |= ISO14B_CONNECT;
152 select = TRUE;
b10a759f 153 if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
6fc68747 154 flags |= ISO14B_SELECT_SR;
155 ++i;
156 } else {
157 flags |= ISO14B_SELECT_STD;
b10a759f 158 }
159 break;
7cf3ef20 160 default:
6fc68747 161 return usage_hf_14b_raw();
7cf3ef20 162 }
163 i+=2;
164 continue;
165 }
1299c798 166 if ((Cmd[i]>='0' && Cmd[i]<='9') ||
167 (Cmd[i]>='a' && Cmd[i]<='f') ||
168 (Cmd[i]>='A' && Cmd[i]<='F') ) {
7cf3ef20 169 buf[strlen(buf)+1]=0;
1299c798 170 buf[strlen(buf)]=Cmd[i];
7cf3ef20 171 i++;
172
173 if (strlen(buf)>=2) {
174 sscanf(buf,"%x",&temp);
6fc68747 175 data[datalen++] = (uint8_t)(temp & 0xff);
7cf3ef20 176 *buf=0;
b10a759f 177 memset(buf, 0x00, sizeof(buf));
7cf3ef20 178 }
179 continue;
180 }
181 PrintAndLog("Invalid char on input");
b10a759f 182 return 0;
7cf3ef20 183 }
b10a759f 184
6fc68747 185 if(!power)
186 flags |= ISO14B_DISCONNECT;
187
188 if(datalen>0)
189 flags |= ISO14B_RAW;
190
191 // Max buffer is USB_CMD_DATA_SIZE
192 datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen;
193
194 UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
195 memcpy(c.d.asBytes, data, datalen);
196 clearCommandBuffer();
197 SendCommand(&c);
198
199 if (!reply) return 1;
200
201 bool success = TRUE;
202 // get back iso14b_card_select_t, don't print it.
203 if(select)
204 success = waitCmd(FALSE);
205
206 // get back response from the raw bytes you sent.
207 if(success && datalen>0) waitCmd(TRUE);
208
209 return 1;
1299c798 210}
211
6de14cec 212// print full atqb info
6fc68747 213static void print_atqb_resp(uint8_t *data, uint8_t cid){
b10a759f 214 //PrintAndLog (" UID: %s", sprint_hex(data+1,4));
6fc68747 215 PrintAndLog (" App Data: %s", sprint_hex(data,4));
216 PrintAndLog (" Protocol: %s", sprint_hex(data+4,3));
217 uint8_t BitRate = data[4];
22e24700 218 if (!BitRate) PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD");
219 if (BitRate & 0x10) PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported");
220 if (BitRate & 0x20) PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported");
221 if (BitRate & 0x40) PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported");
222 if (BitRate & 0x01) PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported");
223 if (BitRate & 0x02) PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported");
224 if (BitRate & 0x04) PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported");
225 if (BitRate & 0x80) PrintAndLog (" Same bit rate <-> required");
226
6fc68747 227 uint16_t maxFrame = data[5]>>4;
22e24700 228 if (maxFrame < 5) maxFrame = 8 * maxFrame + 16;
229 else if (maxFrame == 5) maxFrame = 64;
230 else if (maxFrame == 6) maxFrame = 96;
231 else if (maxFrame == 7) maxFrame = 128;
232 else if (maxFrame == 8) maxFrame = 256;
233 else maxFrame = 257;
234
b10a759f 235 PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
22e24700 236
6fc68747 237 uint8_t protocolT = data[5] & 0xF;
22e24700 238 PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
6fc68747 239 PrintAndLog ("Frame Wait Int: %u", data[6]>>4);
240 PrintAndLog (" App Data Code: Application is %s",(data[6]&4) ? "Standard" : "Proprietary");
241 PrintAndLog (" Frame Options: NAD is %ssupported",(data[6]&2) ? "" : "not ");
242 PrintAndLog (" Frame Options: CID is %ssupported",(data[6]&1) ? "" : "not ");
243 PrintAndLog ("Tag :");
244 PrintAndLog (" Max Buf Length: %u (MBLI) %s",cid>>4, (cid & 0xF0) ? "" : "not supported");
245 PrintAndLog (" Cid : %u", cid & 0x0f);
22e24700 246 return;
1299c798 247}
248
6de14cec 249// get SRx chip model (from UID) // from ST Microelectronics
d71d59db 250char *get_ST_Chip_Model(uint8_t data){
251 static char model[20];
252 char *retStr = model;
253 memset(model,0, sizeof(model));
254
255 switch (data) {
256 case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
257 case 0x2: sprintf(retStr, "SR176"); break;
258 case 0x3: sprintf(retStr, "SRIX4K"); break;
259 case 0x4: sprintf(retStr, "SRIX512"); break;
260 case 0x6: sprintf(retStr, "SRI512"); break;
261 case 0x7: sprintf(retStr, "SRI4K"); break;
262 case 0xC: sprintf(retStr, "SRT512"); break;
5636ee8c 263 default : sprintf(retStr, "Unknown"); break;
d71d59db 264 }
17ad0e09 265 return retStr;
266}
267
6fc68747 268// REMAKE:
b10a759f 269int print_ST_Lock_info(uint8_t model){
b10a759f 270
6fc68747 271 // PrintAndLog("Chip Write Protection Bits:");
272 // // now interpret the data
273 // switch (model){
274 // case 0x0: //fall through (SRIX4K special)
275 // case 0x3: //fall through (SRIx4K)
276 // case 0x7: // (SRI4K)
277 // //only need data[3]
278 // blk1 = 9;
279 // PrintAndLog(" raw: %s", sprint_bin(data+3, 1));
280 // PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
281 // for (uint8_t i = 1; i<8; i++){
282 // PrintAndLog(" %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
283 // blk1++;
284 // }
285 // break;
286 // case 0x4: //fall through (SRIX512)
287 // case 0x6: //fall through (SRI512)
288 // case 0xC: // (SRT512)
289 // //need data[2] and data[3]
290 // blk1 = 0;
291 // PrintAndLog(" raw: %s", sprint_bin(data+2, 2));
292 // for (uint8_t b=2; b<4; b++){
293 // for (uint8_t i=0; i<8; i++){
294 // PrintAndLog(" %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
295 // blk1++;
296 // }
297 // }
298 // break;
299 // case 0x2: // (SR176)
300 // //need data[2]
301 // blk1 = 0;
302 // PrintAndLog(" raw: %s", sprint_bin(data+2, 1));
303 // for (uint8_t i = 0; i<8; i++){
304 // PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
305 // blk1+=2;
306 // }
307 // break;
308 // default:
309 // return rawClose();
310 // }
b10a759f 311 return 1;
312}
313
6de14cec 314// print UID info from SRx chips (ST Microelectronics)
6fc68747 315static void print_st_general_info(uint8_t *data, uint8_t len){
17ad0e09 316 //uid = first 8 bytes in data
6fc68747 317 PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8), len));
17ad0e09 318 PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
319 PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
320 return;
321}
322
6fc68747 323//05 00 00 = find one tag in field
324//1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
325//a3 = ? (resp 03 [e2 c2])
326//02 = ? (resp 02 [6a d3])
327// 022b (resp 02 67 00 [29 5b])
328// 0200a40400 (resp 02 67 00 [29 5b])
329// 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
330// 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b])
331// 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c])
332// 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b])
333// 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c])
334// 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c])
335// 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
336//03 = ? (resp 03 [e3 c2])
337//c2 = ? (resp c2 [66 15])
338//b2 = ? (resp a3 [e9 67])
339//a2 = ? (resp 02 [6a d3])
6de14cec 340
341// 14b get and print Full Info (as much as we know)
6fc68747 342bool HF14B_Std_Info(bool verbose){
6de14cec 343 //add more info here
6fc68747 344 return FALSE;
17ad0e09 345}
346
6fc68747 347// SRx get and print full info (needs more info...)
348bool HF14B_ST_Info(bool verbose){
349
350 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
351 clearCommandBuffer();
352 SendCommand(&c);
353 UsbCommand resp;
17ad0e09 354
5de71ee6 355 if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
6fc68747 356 if (verbose) PrintAndLog("timeout while waiting for reply.");
357 return FALSE;
358 }
17ad0e09 359
6fc68747 360 iso14b_card_select_t card;
361 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
362
363 uint64_t status = resp.arg[0];
364 if ( status > 0 ) {
365 rawClose();
366 return FALSE;
367 }
17ad0e09 368
6fc68747 369 //add locking bit information here. uint8_t data[16] = {0x00};
370 // uint8_t datalen = 2;
371 // uint8_t resplen;
372 // uint8_t blk1;
373 // data[0] = 0x08;
374
375 //
376 // if (model == 0x2) { //SR176 has special command:
377 // data[1] = 0xf;
378 // resplen = 4;
379 // } else {
380 // data[1] = 0xff;
381 // resplen = 6;
382 // }
383
384 // //std read cmd
385 // if (HF14BCmdRaw(true, true, data, &datalen, false)==0)
386 // return rawClose();
387
388 // if (datalen != resplen || !crc) return rawClose();
389 //print_ST_Lock_info(data[5]>>2);
390 rawClose();
391 return TRUE;
392}
17ad0e09 393
6fc68747 394// get and print all info known about any known 14b tag
395bool HF14BInfo(bool verbose){
17ad0e09 396
6fc68747 397 // try std 14b (atqb)
398 if (HF14B_Std_Info(verbose)) return TRUE;
17ad0e09 399
6fc68747 400 // try st 14b
401 if (HF14B_ST_Info(verbose)) return TRUE;
b10a759f 402
6fc68747 403 // try unknown 14b read commands (to be identified later)
404 // could be read of calypso, CEPAS, moneo, or pico pass.
b10a759f 405
6fc68747 406 if (verbose) PrintAndLog("no 14443B tag found");
407 return FALSE;
408}
17ad0e09 409
6fc68747 410// menu command to get and print all info known about any known 14b tag
411int CmdHF14Binfo(const char *Cmd){
412 char cmdp = param_getchar(Cmd, 0);
413 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_info();
414
415 bool verbose = !((cmdp == 's') || (cmdp == 'S'));
416 return HF14BInfo(verbose);
6de14cec 417}
418
6fc68747 419bool HF14B_ST_Reader(bool verbose){
420
421 bool isSuccess = FALSE;
422
423 // SRx get and print general info about SRx chip from UID
424 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
425 clearCommandBuffer();
426 SendCommand(&c);
427 UsbCommand resp;
6de14cec 428
5de71ee6 429 if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
6fc68747 430 if (verbose) PrintAndLog("timeout while waiting for reply.");
431 return FALSE;
432 }
6de14cec 433
6fc68747 434
435 iso14b_card_select_t card;
436 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
17ad0e09 437
6fc68747 438 uint64_t status = resp.arg[0];
22e24700 439
6fc68747 440 switch( status ){
441 case 0:
442 print_st_general_info(card.uid, card.uidlen);
443 isSuccess = TRUE;
444 break;
445 case 1:
446 if (verbose) PrintAndLog("iso14443-3 random chip id fail");
447 break;
448 case 2:
449 if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
450 break;
451 case 3:
452 if (verbose) PrintAndLog("iso14443-3 CRC fail");
453 break;
454 default:
455 if (verbose) PrintAndLog("iso14443b card select SRx failed");
456 break;
22e24700 457 }
458
6fc68747 459 rawClose();
460 return isSuccess;
1299c798 461}
462
6fc68747 463bool HF14B_Std_Reader(bool verbose){
22e24700 464
6fc68747 465 bool isSuccess = FALSE;
22e24700 466
6fc68747 467 // 14b get and print UID only (general info)
468 UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0}};
469 clearCommandBuffer();
470 SendCommand(&c);
471 UsbCommand resp;
472
5de71ee6 473 if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
6fc68747 474 if (verbose) PrintAndLog("timeout while waiting for reply.");
475 return FALSE;
476 }
477
478 iso14b_card_select_t card;
479 memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
480
481 uint64_t status = resp.arg[0];
482
483 switch( status ){
484 case 0:
485 PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
486 PrintAndLog(" ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
487 PrintAndLog(" CHIPID : %02X", card.chipid);
488 print_atqb_resp(card.atqb, card.cid);
489 isSuccess = TRUE;
490 break;
491 case 2:
492 if (verbose) PrintAndLog("iso14443-3 ATTRIB fail");
493 break;
494 case 3:
495 if (verbose) PrintAndLog("iso14443-3 CRC fail");
496 break;
497 default:
498 if (verbose) PrintAndLog("iso14443b card select failed");
499 break;
500 }
501
502 rawClose();
503 return isSuccess;
504}
1299c798 505
6fc68747 506// test for other 14b type tags (mimic another reader - don't have tags to identify)
507bool HF14B_Other_Reader(){
abb21530 508
6fc68747 509 // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
510 // uint8_t datalen = 4;
d71d59db 511
6fc68747 512 // // 14b get and print UID only (general info)
513 // uint32_t flags = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_RAW | ISO14B_APPEND_CRC;
514
515 // UsbCommand c = {CMD_ISO_14443B_COMMAND, {flags, datalen, 0}};
516 // memcpy(c.d.asBytes, data, datalen);
517
518 // clearCommandBuffer();
519 // SendCommand(&c);
520 // UsbCommand resp;
521 // WaitForResponse(CMD_ACK,&resp);
522
523 // if (datalen > 2 ) {
524 // printandlog ("\n14443-3b tag found:");
525 // printandlog ("unknown tag type answered to a 0x000b3f80 command ans:");
526 // //printandlog ("%s", sprint_hex(data, datalen));
527 // rawclose();
528 // return true;
529 // }
530
531 // c.arg1 = 1;
532 // c.d.asBytes[0] = ISO14443B_AUTHENTICATE;
533 // clearCommandBuffer();
534 // SendCommand(&c);
535 // UsbCommand resp;
536 // WaitForResponse(CMD_ACK, &resp);
537
538 // if (datalen > 0) {
539 // PrintAndLog ("\n14443-3b tag found:");
540 // PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
541 // // PrintAndLog ("%s", sprint_hex(data, datalen));
542 // rawClose();
543 // return TRUE;
544 // }
545
546 // c.arg1 = 1;
547 // c.d.asBytes[0] = ISO14443B_RESET;
548 // clearCommandBuffer();
549 // SendCommand(&c);
550 // UsbCommand resp;
551 // WaitForResponse(CMD_ACK, &resp);
552
553 // if (datalen > 0) {
554 // PrintAndLog ("\n14443-3b tag found:");
555 // PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
556 // PrintAndLog ("%s", sprint_hex(data, datalen));
557 // rawClose();
558 // return TRUE;
559 // }
560
561 // rawClose();
562 return FALSE;
7cf3ef20 563}
564
6de14cec 565// get and print general info about all known 14b chips
6fc68747 566bool HF14BReader(bool verbose){
6de14cec 567
568 // try std 14b (atqb)
6fc68747 569 if (HF14B_Std_Reader(verbose)) return TRUE;
6de14cec 570
6fc68747 571 // try ST Microelectronics 14b
572 if (HF14B_ST_Reader(verbose)) return TRUE;
6de14cec 573
574 // try unknown 14b read commands (to be identified later)
575 // could be read of calypso, CEPAS, moneo, or pico pass.
6fc68747 576 if (HF14B_Other_Reader()) return TRUE;
6de14cec 577
578 if (verbose) PrintAndLog("no 14443B tag found");
6fc68747 579 return FALSE;
6de14cec 580}
581
582// menu command to get and print general info about all known 14b chips
583int CmdHF14BReader(const char *Cmd){
6fc68747 584 char cmdp = param_getchar(Cmd, 0);
585 if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_reader();
586
587 bool verbose = !((cmdp == 's') || (cmdp == 'S'));
588 return HF14BReader(verbose);
6de14cec 589}
590
6fc68747 591/* New command to read the contents of a SRI512|SRIX4K tag
592 * SRI* tags are ISO14443-B modulated memory tags,
593 * this command just dumps the contents of the memory/
594 */
595int CmdHF14BReadSri(const char *Cmd){
596 char cmdp = param_getchar(Cmd, 0);
597 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_read_srx();
598
599 uint8_t tagtype = param_get8(Cmd, 0);
600 uint8_t blocks = (tagtype == 1) ? 0x7F : 0x0F;
601
602 UsbCommand c = {CMD_READ_SRI_TAG, {blocks, 0, 0}};
603 clearCommandBuffer();
604 SendCommand(&c);
605 return 0;
606}
607// New command to write a SRI512/SRIX4K tag.
608int CmdHF14BWriteSri(const char *Cmd){
3fe4ff4f 609/*
610 * For SRIX4K blocks 00 - 7F
611 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
612 *
613 * For SR512 blocks 00 - 0F
614 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
615 *
616 * Special block FF = otp_lock_reg block.
617 * Data len 4 bytes-
618 */
619 char cmdp = param_getchar(Cmd, 0);
620 uint8_t blockno = -1;
621 uint8_t data[4] = {0x00};
622 bool isSrix4k = true;
6fc68747 623 char str[30];
624 memset(str, 0x00, sizeof(str));
625
626 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_write_srx();
3fe4ff4f 627
b5be31f9 628 if ( cmdp == '2' )
3fe4ff4f 629 isSrix4k = false;
630
b5be31f9 631 //blockno = param_get8(Cmd, 1);
632
6fc68747 633 if ( param_gethex(Cmd, 1, &blockno, 2) ) {
b5be31f9 634 PrintAndLog("Block number must include 2 HEX symbols");
635 return 0;
636 }
3fe4ff4f 637
638 if ( isSrix4k ){
639 if ( blockno > 0x7f && blockno != 0xff ){
640 PrintAndLog("Block number out of range");
641 return 0;
642 }
643 } else {
644 if ( blockno > 0x0f && blockno != 0xff ){
645 PrintAndLog("Block number out of range");
646 return 0;
647 }
648 }
649
650 if (param_gethex(Cmd, 2, data, 8)) {
651 PrintAndLog("Data must include 8 HEX symbols");
652 return 0;
653 }
654
6fc68747 655 if ( blockno == 0xff) {
656 PrintAndLog("[%s] Write special block %02X [ %s ]",
657 (isSrix4k) ? "SRIX4K":"SRI512",
658 blockno,
659 sprint_hex(data,4)
660 );
661 } else {
662 PrintAndLog("[%s] Write block %02X [ %s ]",
663 (isSrix4k) ? "SRIX4K":"SRI512",
664 blockno,
665 sprint_hex(data,4)
666 );
667 }
668
669 sprintf(str, "-ss -c %02x %02x %02x%02x%02x%02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]);
3fe4ff4f 670 CmdHF14BCmdRaw(str);
671 return 0;
672}
673
341fd1de 674uint32_t srix4kEncode(uint32_t value) {
5636ee8c 675/*
676// vv = value
677// pp = position
678// vv vv vv pp
6794 bytes : 00 1A 20 01
680*/
5636ee8c 681 // only the lower crumbs.
682 uint8_t block = (value & 0xFF);
683 uint8_t i = 0;
684 uint8_t valuebytes[] = {0,0,0};
685
5636ee8c 686 num_to_bytes(value, 3, valuebytes);
687
688 // Scrambled part
689 // Crumb swapping of value.
690 uint8_t temp[] = {0,0};
ff3e0744 691 temp[0] = (CRUMB(value, 22) << 4 | CRUMB(value, 14 ) << 2 | CRUMB(value, 6)) << 4;
692 temp[0] |= CRUMB(value, 20) << 4 | CRUMB(value, 12 ) << 2 | CRUMB(value, 4);
693 temp[1] = (CRUMB(value, 18) << 4 | CRUMB(value, 10 ) << 2 | CRUMB(value, 2)) << 4;
694 temp[1] |= CRUMB(value, 16) << 4 | CRUMB(value, 8 ) << 2 | CRUMB(value, 0);
5636ee8c 695
696 // chksum part
697 uint32_t chksum = 0xFF - block;
698
699 // chksum is reduced by each nibbles of value.
700 for (i = 0; i < 3; ++i){
ff3e0744 701 chksum -= NIBBLE_HIGH(valuebytes[i]);
702 chksum -= NIBBLE_LOW(valuebytes[i]);
5636ee8c 703 }
704
341fd1de 705 // base4 conversion and left shift twice
5636ee8c 706 i = 3;
707 uint8_t base4[] = {0,0,0,0};
708 while( chksum !=0 ){
709 base4[i--] = (chksum % 4 << 2);
710 chksum /= 4;
711 }
712
713 // merge scambled and chksum parts
714 uint32_t encvalue =
ff3e0744 715 ( NIBBLE_LOW ( base4[0]) << 28 ) |
716 ( NIBBLE_HIGH( temp[0]) << 24 ) |
5636ee8c 717
ff3e0744 718 ( NIBBLE_LOW ( base4[1]) << 20 ) |
719 ( NIBBLE_LOW ( temp[0]) << 16 ) |
5636ee8c 720
ff3e0744 721 ( NIBBLE_LOW ( base4[2]) << 12 ) |
722 ( NIBBLE_HIGH( temp[1]) << 8 ) |
5636ee8c 723
ff3e0744 724 ( NIBBLE_LOW ( base4[3]) << 4 ) |
725 NIBBLE_LOW ( temp[1] );
5636ee8c 726
341fd1de 727 PrintAndLog("ICE encoded | %08X -> %08X", value, encvalue);
728 return encvalue;
729}
730uint32_t srix4kDecode(uint32_t value) {
731 switch(value) {
732 case 0xC04F42C5: return 0x003139;
733 case 0xC1484807: return 0x002943;
734 case 0xC0C60848: return 0x001A20;
735 }
5636ee8c 736 return 0;
737}
341fd1de 738uint32_t srix4kDecodeCounter(uint32_t num) {
739 uint32_t value = ~num;
740 ++value;
741 return value;
742}
743
744uint32_t srix4kGetMagicbytes( uint64_t uid, uint32_t block6, uint32_t block18, uint32_t block19 ){
745#define MASK 0xFFFFFFFF;
746 uint32_t uid32 = uid & MASK;
747 uint32_t counter = srix4kDecodeCounter(block6);
748 uint32_t decodedBlock18 = srix4kDecode(block18);
749 uint32_t decodedBlock19 = srix4kDecode(block19);
750 uint32_t doubleBlock = (decodedBlock18 << 16 | decodedBlock19) + 1;
751
752 uint32_t result = (uid32 * doubleBlock * counter) & MASK;
753 PrintAndLog("Magic bytes | %08X", result);
754 return result;
755}
756int srix4kValid(const char *Cmd){
757
758 uint64_t uid = 0xD00202501A4532F9;
759 uint32_t block6 = 0xFFFFFFFF;
760 uint32_t block18 = 0xC04F42C5;
761 uint32_t block19 = 0xC1484807;
762 uint32_t block21 = 0xD1BCABA4;
763
764 uint32_t test_b18 = 0x00313918;
765 uint32_t test_b18_enc = srix4kEncode(test_b18);
766 //uint32_t test_b18_dec = srix4kDecode(test_b18_enc);
767 PrintAndLog("ENCODE & CHECKSUM | %08X -> %08X (%s)", test_b18, test_b18_enc , "");
768
769 uint32_t magic = srix4kGetMagicbytes(uid, block6, block18, block19);
770 PrintAndLog("BLOCK 21 | %08X -> %08X (no XOR)", block21, magic ^ block21);
5636ee8c 771 return 0;
772}
341fd1de 773
774int CmdteaSelfTest(const char *Cmd){
775
776 uint8_t v[8], v_le[8];
777 memset(v, 0x00, sizeof(v));
778 memset(v_le, 0x00, sizeof(v_le));
779 uint8_t* v_ptr = v_le;
780
781 uint8_t cmdlen = strlen(Cmd);
782 cmdlen = ( sizeof(v)<<2 < cmdlen ) ? sizeof(v)<<2 : cmdlen;
783
784 if ( param_gethex(Cmd, 0, v, cmdlen) > 0 ){
785 PrintAndLog("can't read hex chars, uneven? :: %u", cmdlen);
786 return 1;
787 }
788
789 SwapEndian64ex(v , 8, 4, v_ptr);
790
e994394a 791 // ENCRYPTION KEY:
ff3e0744 792 uint8_t key[16] = {0x55,0xFE,0xF6,0x30,0x62,0xBF,0x0B,0xC1,0xC9,0xB3,0x7C,0x34,0x97,0x3E,0x29,0xFB };
e994394a 793 uint8_t keyle[16];
794 uint8_t* key_ptr = keyle;
795 SwapEndian64ex(key , sizeof(key), 4, key_ptr);
341fd1de 796
e994394a 797 PrintAndLog("TEST LE enc| %s", sprint_hex(v_ptr, 8));
798
799 tea_decrypt(v_ptr, key_ptr);
800 PrintAndLog("TEST LE dec | %s", sprint_hex_ascii(v_ptr, 8));
801
802 tea_encrypt(v_ptr, key_ptr);
803 tea_encrypt(v_ptr, key_ptr);
804 PrintAndLog("TEST enc2 | %s", sprint_hex_ascii(v_ptr, 8));
341fd1de 805
5636ee8c 806 return 0;
807}
808
6fc68747 809bool waitCmd(bool verbose) {
810
811 bool crc = FALSE;
812 uint8_t b1 = 0, b2 = 0;
813 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
814 uint8_t status = 0;
815 uint16_t len = 0;
816 UsbCommand resp;
817
5de71ee6 818 if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
6fc68747 819
820 status = (resp.arg[0] & 0xFFFF);
821 if ( status > 0 ) return FALSE;
822
823 len = (resp.arg[1] & 0xFFFF);
824 memcpy(data, resp.d.asBytes, len);
825
826 if (verbose) {
827
828 ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
829 crc = ( data[len-2] == b1 && data[len-1] == b2);
830
831 PrintAndLog("[LEN %u] %s[%02X %02X] %s",
832 len,
833 sprint_hex(data, len-2),
834 data[len-2],
835 data[len-1],
836 (crc) ? "OK" : "FAIL"
837 );
838 }
839 return TRUE;
840 } else {
841 PrintAndLog("timeout while waiting for reply.");
842 return FALSE;
843 }
844}
845
e994394a 846static command_t CommandTable[] = {
22e24700 847 {"help", CmdHelp, 1, "This help"},
6de14cec 848 {"info", CmdHF14Binfo, 0, "Find and print details about a 14443B tag"},
849 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443B history"},
6fc68747 850 {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
6de14cec 851 {"reader", CmdHF14BReader, 0, "Act as a 14443B reader to identify a tag"},
852 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
853 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
6fc68747 854 {"sriread", CmdHF14BReadSri, 0, "Read contents of a SRI512 | SRIX4K tag"},
855 {"sriwrite", CmdHF14BWriteSri, 0, "Write data to a SRI512 | SRIX4K tag"},
341fd1de 856 //{"valid", srix4kValid, 1, "srix4k checksum test"},
6fc68747 857 //{"valid", CmdteaSelfTest, 1, "tea test"},
22e24700 858 {NULL, NULL, 0, NULL}
7fe9b0b7 859};
860
e994394a 861int CmdHF14B(const char *Cmd) {
862 clearCommandBuffer();
22e24700 863 CmdsParse(CommandTable, Cmd);
864 return 0;
7fe9b0b7 865}
866
e994394a 867int CmdHelp(const char *Cmd) {
22e24700 868 CmdsHelp(CommandTable);
869 return 0;
7fe9b0b7 870}
Impressum, Datenschutz