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