1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com> 
   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 
   7 //----------------------------------------------------------------------------- 
   8 // High frequency ISO14443B commands 
   9 //----------------------------------------------------------------------------- 
  16 #include "iso14443crc.h" 
  17 #include "proxmark3.h" 
  22 #include "cmdparser.h" 
  27 static int CmdHelp(const char *Cmd
); 
  29 int CmdHF14BList(const char *Cmd
) 
  31         PrintAndLog("Deprecated command, use 'hf list 14b' instead"); 
  36 int CmdHF14BSim(const char *Cmd
) 
  38         UsbCommand c
={CMD_SIMULATE_TAG_ISO_14443B
}; 
  44 int CmdHF14BSnoop(const char *Cmd
) 
  46   UsbCommand c 
= {CMD_SNOOP_ISO_14443B
}; 
  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 
  56 int CmdSri512Read(const char *Cmd
) 
  58         UsbCommand c 
= {CMD_READ_SRI512_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
  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/ 
  68 int CmdSrix4kRead(const char *Cmd
) 
  70         UsbCommand c 
= {CMD_READ_SRIX4K_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
  77         UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; 
  83 int HF14BCmdRaw(bool reply
, bool *crc
, bool power
, uint8_t *data
, uint8_t *datalen
, bool verbose
){ 
  86                 ComputeCrc14443(CRC_14443_B
, data
, *datalen
, data
+*datalen
, data
+*datalen
+1); 
  90         UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; // len,recv,power 
  94         memcpy(c
.d
.asBytes
, data
, *datalen
); 
 101         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 2000)) { 
 102                 if (verbose
) PrintAndLog("timeout while waiting for reply."); 
 106         *datalen 
= resp
.arg
[0]; 
 107         if (verbose
) PrintAndLog("received %u octets", *datalen
); 
 108         if(*datalen
<3) return 0; 
 110         memcpy(data
, resp
.d
.asBytes
, *datalen
); 
 112         uint8_t first 
= 0, second 
= 0; 
 113         ComputeCrc14443(CRC_14443_B
, data
, *datalen
-2, &first
, &second
); 
 114         *crc 
= ( data
[*datalen
-2] == first 
&& data
[*datalen
-1] == second
); 
 117                 PrintAndLog("[LEN %u] %s[%02X %02X] %s", 
 119                                 sprint_hex(data
, *datalen
-2), 
 128 int CmdHF14BCmdRaw (const char *Cmd
) { 
 135     uint8_t data
[USB_CMD_DATA_SIZE
] = {0x00}; 
 140                 PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>"); 
 141         PrintAndLog("       -r    do not read response"); 
 142         PrintAndLog("       -c    calculate and append CRC"); 
 143         PrintAndLog("       -p    leave the field on after receive"); 
 144                 PrintAndLog("       -s    active signal field ON with select"); 
 145                 PrintAndLog("       -ss   active signal field ON with select for SRx ST Microelectronics tags"); 
 150     while (*Cmd
==' ' || *Cmd
=='\t') Cmd
++; 
 152     while (Cmd
[i
]!='\0') { 
 153         if (Cmd
[i
]==' ' || Cmd
[i
]=='\t') { i
++; continue; } 
 171                                         if (Cmd
[i
+2]=='s' || Cmd
[i
+2]=='S') { 
 177                     PrintAndLog("Invalid option"); 
 183         if ((Cmd
[i
]>='0' && Cmd
[i
]<='9') || 
 184             (Cmd
[i
]>='a' && Cmd
[i
]<='f') || 
 185             (Cmd
[i
]>='A' && Cmd
[i
]<='F') ) { 
 186             buf
[strlen(buf
)+1]=0; 
 187             buf
[strlen(buf
)]=Cmd
[i
]; 
 190             if (strlen(buf
)>=2) { 
 191                 sscanf(buf
,"%x",&temp
); 
 192                 data
[datalen
++]=(uint8_t)(temp 
& 0xff); 
 194                                 memset(buf
, 0x00, sizeof(buf
)); 
 198         PrintAndLog("Invalid char on input"); 
 203       PrintAndLog("Missing data input"); 
 207         if (select
){ //auto select 14b tag 
 226                 if (HF14BCmdRaw(true, &crc2
, true, cmd2
, &cmdLen
, false)==0) return rawClose(); 
 228                 PrintAndLog("REQB   : %s", sprint_hex(cmd2
, 9)); 
 230                 if ( SRx 
&& (cmdLen 
!= 3 || !crc2
) ) return rawClose(); 
 231                 else if (cmd2
[0] != 0x50 || cmdLen 
!= 14 || !crc2
) return rawClose(); 
 243                         // UID from cmd2[1 - 4] 
 253                 if (HF14BCmdRaw(true, &crc2
, true, cmd2
, &cmdLen
, false)==0) return rawClose(); 
 254                 PrintAndLog("ATTRIB : %s", sprint_hex(cmd2
, 3)); 
 256                 if (cmdLen 
!= 3 || !crc2
) return rawClose();             
 257                 if (SRx 
&& cmd2
[0] != chipID
) return rawClose(); 
 260         return HF14BCmdRaw(reply
, &crc
, power
, data
, &datalen
, true); 
 263 // print full atqb info 
 264 static void print_atqb_resp(uint8_t *data
){ 
 265         //PrintAndLog ("           UID: %s", sprint_hex(data+1,4)); 
 266         PrintAndLog ("      App Data: %s", sprint_hex(data
+5,4)); 
 267         PrintAndLog ("      Protocol: %s", sprint_hex(data
+9,3)); 
 268         uint8_t BitRate 
= data
[9]; 
 269         if (!BitRate
) PrintAndLog ("      Bit Rate: 106 kbit/s only PICC <-> PCD"); 
 270         if (BitRate 
& 0x10)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC -> PCD supported"); 
 271         if (BitRate 
& 0x20)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC -> PCD supported");  
 272         if (BitRate 
& 0x40)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC -> PCD supported");  
 273         if (BitRate 
& 0x01)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC <- PCD supported"); 
 274         if (BitRate 
& 0x02)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC <- PCD supported");  
 275         if (BitRate 
& 0x04)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC <- PCD supported");  
 276         if (BitRate 
& 0x80)     PrintAndLog ("                Same bit rate <-> required"); 
 278         uint16_t maxFrame 
= data
[10]>>4; 
 279         if (maxFrame 
< 5)               maxFrame 
= 8 * maxFrame 
+ 16; 
 280         else if (maxFrame 
== 5) maxFrame 
= 64; 
 281         else if (maxFrame 
== 6) maxFrame 
= 96; 
 282         else if (maxFrame 
== 7) maxFrame 
= 128; 
 283         else if (maxFrame 
== 8) maxFrame 
= 256; 
 286         PrintAndLog ("Max Frame Size: %u%s",maxFrame
, (maxFrame 
== 257) ? "+ RFU" : ""); 
 288         uint8_t protocolT 
= data
[10] & 0xF; 
 289         PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT
) ? "" : "not " ); 
 290         PrintAndLog ("Frame Wait Int: %u", data
[11]>>4); 
 291         PrintAndLog (" App Data Code: Application is %s",(data
[11]&4) ? "Standard" : "Proprietary"); 
 292         PrintAndLog (" Frame Options: NAD is %ssupported",(data
[11]&2) ? "" : "not "); 
 293         PrintAndLog (" Frame Options: CID is %ssupported",(data
[11]&1) ? "" : "not "); 
 294         PrintAndLog ("Max Buf Length: %u (MBLI) %s",data
[14]>>4, (data
[14] & 0xF0) ? "" : "not supported"); 
 299 // get SRx chip model (from UID) // from ST Microelectronics 
 300 char *get_ST_Chip_Model(uint8_t data
){ 
 301         static char model
[20]; 
 302         char *retStr 
= model
; 
 303         memset(model
,0, sizeof(model
)); 
 306                 case 0x0: sprintf(retStr
, "SRIX4K (Special)"); break; 
 307                 case 0x2: sprintf(retStr
, "SR176"); break; 
 308                 case 0x3: sprintf(retStr
, "SRIX4K"); break; 
 309                 case 0x4: sprintf(retStr
, "SRIX512"); break; 
 310                 case 0x6: sprintf(retStr
, "SRI512"); break; 
 311                 case 0x7: sprintf(retStr
, "SRI4K"); break; 
 312                 case 0xC: sprintf(retStr
, "SRT512"); break; 
 313                 default: sprintf(retStr
, "Unknown"); break; 
 318 int print_ST_Lock_info(uint8_t model
){ 
 319         //assume connection open and tag selected... 
 320         uint8_t data
[16] = {0x00}; 
 327         if (model 
== 0x2) { //SR176 has special command: 
 336         if (HF14BCmdRaw(true, &crc
, true, data
, &datalen
, false)==0) return rawClose(); 
 338         if (datalen 
!= resplen 
|| !crc
) return rawClose(); 
 340         PrintAndLog("Chip Write Protection Bits:"); 
 341         // now interpret the data 
 343                 case 0x0: //fall through (SRIX4K special) 
 344                 case 0x3: //fall through (SRIx4K) 
 348                         PrintAndLog("   raw: %s",printBits(1,data
+3)); 
 349                         PrintAndLog(" 07/08:%slocked", (data
[3] & 1) ? " not " : " " ); 
 350                         for (uint8_t i 
= 1; i
<8; i
++){ 
 351                                 PrintAndLog("    %02u:%slocked", blk1
, (data
[3] & (1 << i
)) ? " not " : " " ); 
 355                 case 0x4: //fall through (SRIX512) 
 356                 case 0x6: //fall through (SRI512) 
 357                 case 0xC: //             (SRT512) 
 358                         //need data[2] and data[3] 
 360                         PrintAndLog("   raw: %s",printBits(2,data
+2)); 
 361                         for (uint8_t b
=2; b
<4; b
++){ 
 362                                 for (uint8_t i
=0; i
<8; i
++){ 
 363                                         PrintAndLog("    %02u:%slocked", blk1
, (data
[b
] & (1 << i
)) ? " not " : " " ); 
 371                         PrintAndLog("   raw: %s",printBits(1,data
+2)); 
 372                         for (uint8_t i 
= 0; i
<8; i
++){ 
 373                                 PrintAndLog(" %02u/%02u:%slocked", blk1
, blk1
+1, (data
[2] & (1 << i
)) ? " " : " not " ); 
 383 // print UID info from SRx chips (ST Microelectronics) 
 384 static void print_st_general_info(uint8_t *data
){ 
 385         //uid = first 8 bytes in data 
 386         PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data
,8,8),8)); 
 387         PrintAndLog(" MFG: %02X, %s", data
[6], getTagInfo(data
[6])); 
 388         PrintAndLog("Chip: %02X, %s", data
[5]>>2, get_ST_Chip_Model(data
[5]>>2)); 
 392 // 14b get and print UID only (general info) 
 393 int HF14BStdReader(uint8_t *data
, uint8_t *datalen
){ 
 394         //05 00 00 = find one tag in field 
 395         //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0]) 
 396         //a3 = ?  (resp 03 [e2 c2]) 
 397         //02 = ?  (resp 02 [6a d3]) 
 398         // 022b (resp 02 67 00 [29  5b]) 
 399         // 0200a40400 (resp 02 67 00 [29 5b]) 
 400         // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b]) 
 401         // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b]) 
 402         // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c]) 
 403         // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b]) 
 404         // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c]) 
 405         // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c]) 
 406         // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c]) 
 407         //03 = ?  (resp 03 [e3 c2]) 
 408         //c2 = ?  (resp c2 [66 15]) 
 409         //b2 = ?  (resp a3 [e9 67])              
 410         //a2 = ?  (resp 02 [6a d3]) 
 418         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 420         if (data
[0] != 0x50 || *datalen 
!= 14 || !crc
) return rawClose(); 
 422         PrintAndLog ("\n14443-3b tag found:"); 
 423         PrintAndLog ("           UID: %s", sprint_hex(data
+1,4)); 
 430         // UID from data[1 - 4] 
 442         if (HF14BCmdRaw(true, &crc2
, true, cmd2
, &cmdLen
, false)==0) return rawClose(); 
 444         if (cmdLen 
!= 3 || !crc2
) return rawClose(); 
 445         // add attrib responce to data 
 451 // 14b get and print Full Info (as much as we know) 
 452 int HF14BStdInfo(uint8_t *data
, uint8_t *datalen
){ 
 453         if (!HF14BStdReader(data
,datalen
)) return 0; 
 456         print_atqb_resp(data
); 
 462 // SRx get and print general info about SRx chip from UID 
 463 int HF14B_ST_Reader(uint8_t *data
, uint8_t *datalen
, bool closeCon
){ 
 471         // verbose on for now for testing - turn off when functional 
 472         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 474         if (*datalen 
!= 3 || !crc
) return rawClose(); 
 476         uint8_t chipID 
= data
[0]; 
 483         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 485         if (*datalen 
!= 3 || !crc 
|| data
[0] != chipID
) return rawClose(); 
 492         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 494         if (*datalen 
!= 10 || !crc
) return rawClose(); 
 497         if (closeCon
) rawClose(); 
 499         PrintAndLog("\n14443-3b ST tag found:"); 
 500         print_st_general_info(data
); 
 504 // SRx get and print full info (needs more info...) 
 505 int HF14B_ST_Info(uint8_t *data
, uint8_t *datalen
){ 
 506         if (!HF14B_ST_Reader(data
, datalen
, false)) return 0; 
 508         //add locking bit information here. 
 509         if (print_ST_Lock_info(data
[5]>>2))  
 515 // test for other 14b type tags (mimic another reader - don't have tags to identify) 
 516 int HF14B_Other_Reader(uint8_t *data
, uint8_t *datalen
){ 
 525         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 526                 if (*datalen 
> 2 || !crc
) { 
 527                         PrintAndLog ("\n14443-3b tag found:"); 
 528                         PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:"); 
 529                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 539         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 541                         PrintAndLog ("\n14443-3b tag found:"); 
 542                         PrintAndLog ("Unknown tag type answered to a 0x0A command ans:"); 
 543                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 553         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 555                         PrintAndLog ("\n14443-3b tag found:"); 
 556                         PrintAndLog ("Unknown tag type answered to a 0x0C command ans:"); 
 557                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 566 // get and print all info known about any known 14b tag 
 567 int HF14BInfo(bool verbose
){ 
 568         uint8_t data
[USB_CMD_DATA_SIZE
]; 
 571         // try std 14b (atqb) 
 572         if (HF14BStdInfo(data
, &datalen
)) return 1; 
 575         if (HF14B_ST_Info(data
, &datalen
)) return 1; 
 577         // try unknown 14b read commands (to be identified later) 
 578         //   could be read of calypso, CEPAS, moneo, or pico pass. 
 579         if (HF14B_Other_Reader(data
, &datalen
)) return 1; 
 581         if (verbose
) PrintAndLog("no 14443B tag found"); 
 585 // menu command to get and print all info known about any known 14b tag 
 586 int CmdHF14Binfo(const char *Cmd
){ 
 587         return HF14BInfo(true); 
 590 // get and print general info about all known 14b chips 
 591 int HF14BReader(bool verbose
){ 
 592         uint8_t data
[USB_CMD_DATA_SIZE
]; 
 595         // try std 14b (atqb) 
 596         if (HF14BStdReader(data
, &datalen
)) return 1; 
 599         if (HF14B_ST_Reader(data
, &datalen
, true)) return 1; 
 601         // try unknown 14b read commands (to be identified later) 
 602         //   could be read of calypso, CEPAS, moneo, or pico pass. 
 603         if (HF14B_Other_Reader(data
, &datalen
)) return 1; 
 605         if (verbose
) PrintAndLog("no 14443B tag found"); 
 609 // menu command to get and print general info about all known 14b chips 
 610 int CmdHF14BReader(const char *Cmd
){ 
 611         return HF14BReader(true); 
 614 int CmdSriWrite( const char *Cmd
){ 
 616  * For SRIX4K  blocks 00 - 7F 
 617  * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata 
 619  * For SR512  blocks 00 - 0F 
 620  * hf 14b raw -c -p 09 $sr512wblock $sr512wdata 
 622  * Special block FF =  otp_lock_reg block. 
 625         char cmdp 
= param_getchar(Cmd
, 0); 
 626         uint8_t blockno 
= -1; 
 627         uint8_t data
[4] = {0x00}; 
 628         bool isSrix4k 
= true; 
 631         if (strlen(Cmd
) < 1 || cmdp 
== 'h' || cmdp 
== 'H') { 
 632                 PrintAndLog("Usage:  hf 14b write <1|2> <BLOCK> <DATA>"); 
 633                 PrintAndLog("    [1 = SRIX4K]"); 
 634                 PrintAndLog("    [2 = SRI512]"); 
 635                 PrintAndLog("    [BLOCK number depends on tag, special block == FF]"); 
 636                 PrintAndLog("     sample: hf 14b write 1 7F 11223344"); 
 637                 PrintAndLog("           : hf 14b write 1 FF 11223344"); 
 638                 PrintAndLog("           : hf 14b write 2 15 11223344"); 
 639                 PrintAndLog("           : hf 14b write 2 FF 11223344"); 
 646         //blockno = param_get8(Cmd, 1); 
 648         if ( param_gethex(Cmd
,1, &blockno
, 2) ) { 
 649                 PrintAndLog("Block number must include 2 HEX symbols"); 
 654                 if ( blockno 
> 0x7f && blockno 
!= 0xff ){ 
 655                         PrintAndLog("Block number out of range"); 
 659                 if ( blockno 
> 0x0f && blockno 
!= 0xff ){ 
 660                         PrintAndLog("Block number out of range"); 
 665         if (param_gethex(Cmd
, 2, data
, 8)) { 
 666                 PrintAndLog("Data must include 8 HEX symbols"); 
 670         if ( blockno 
== 0xff) 
 671                 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512" , blockno
,  sprint_hex(data
,4) ); 
 673                 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512", blockno
,  sprint_hex(data
,4) ); 
 675         sprintf(str
, "-c 09 %02x %02x%02x%02x%02x", blockno
, data
[0], data
[1], data
[2], data
[3]); 
 681 static command_t CommandTable
[] =  
 683         {"help",        CmdHelp
,        1, "This help"}, 
 684         {"info",        CmdHF14Binfo
,   0, "Find and print details about a 14443B tag"}, 
 685         {"list",        CmdHF14BList
,   0, "[Deprecated] List ISO 14443B history"}, 
 686         {"reader",      CmdHF14BReader
, 0, "Act as a 14443B reader to identify a tag"}, 
 687         {"sim",         CmdHF14BSim
,    0, "Fake ISO 14443B tag"}, 
 688         {"snoop",       CmdHF14BSnoop
,  0, "Eavesdrop ISO 14443B"}, 
 689         {"sri512read",  CmdSri512Read
,  0, "Read contents of a SRI512 tag"}, 
 690         {"srix4kread",  CmdSrix4kRead
,  0, "Read contents of a SRIX4K tag"}, 
 691         {"sriwrite",    CmdSriWrite
,    0, "Write data to a SRI512 | SRIX4K tag"}, 
 692         {"raw",         CmdHF14BCmdRaw
, 0, "Send raw hex data to tag"}, 
 693         {NULL
, NULL
, 0, NULL
} 
 696 int CmdHF14B(const char *Cmd
) 
 698         CmdsParse(CommandTable
, Cmd
); 
 702 int CmdHelp(const char *Cmd
) 
 704         CmdsHelp(CommandTable
);