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