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}}; 
  78         UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; 
  81         if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1000)) { 
  87 int HF14BCmdRaw(bool reply
, bool *crc
, bool power
, uint8_t *data
, uint8_t *datalen
, bool verbose
){ 
  89         UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; // len,recv,power 
  92                 uint8_t first
, second
; 
  93                 ComputeCrc14443(CRC_14443_B
, data
, *datalen
, &first
, &second
); 
  94                 data
[*datalen
] = first
; 
  95                 data
[*datalen 
+ 1] = second
; 
 102         memcpy(c
.d
.asBytes
,data
,*datalen
); 
 103         clearCommandBuffer(); 
 106         if (!reply
) return 1;  
 108         if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1000)) { 
 109                 if (verbose
) PrintAndLog("timeout while waiting for reply."); 
 112         *datalen 
= resp
.arg
[0]; 
 113         if (verbose
) PrintAndLog("received %u octets", *datalen
); 
 114         if(*datalen
<2) return 0; 
 116         memcpy(data
, resp
.d
.asBytes
, *datalen
); 
 117         if (verbose
) PrintAndLog("%s", sprint_hex(data
, *datalen
)); 
 119         uint8_t first
, second
; 
 120         ComputeCrc14443(CRC_14443_B
, data
, *datalen
-2, &first
, &second
); 
 121         if(data
[*datalen
-2] == first 
&& data
[*datalen
-1] == second
) { 
 122                 if (verbose
) PrintAndLog("CRC OK"); 
 125                 if (verbose
) PrintAndLog("CRC failed"); 
 131 int CmdHF14BCmdRaw (const char *Cmd
) { 
 136         uint8_t data
[100] = {0x00}; 
 141                         PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>"); 
 142                         PrintAndLog("       -r    do not read response"); 
 143                         PrintAndLog("       -c    calculate and append CRC"); 
 144                         PrintAndLog("       -p    leave the field on after receive"); 
 149         while (*Cmd
==' ' || *Cmd
=='\t') Cmd
++; 
 151         while (Cmd
[i
]!='\0') { 
 152                 if (Cmd
[i
]==' ' || Cmd
[i
]=='\t') { i
++; continue; } 
 168                                         PrintAndLog("Invalid option"); 
 174                 if ((Cmd
[i
]>='0' && Cmd
[i
]<='9') || 
 175                     (Cmd
[i
]>='a' && Cmd
[i
]<='f') || 
 176                     (Cmd
[i
]>='A' && Cmd
[i
]<='F') ) { 
 177                         buf
[strlen(buf
)+1]=0; 
 178                         buf
[strlen(buf
)]=Cmd
[i
]; 
 181                         if (strlen(buf
)>=2) { 
 182                                 sscanf(buf
,"%x",&temp
); 
 183                                 data
[datalen
++]=(uint8_t)(temp 
& 0xff); 
 188                 PrintAndLog("Invalid char on input"); 
 193                 PrintAndLog("Missing data input"); 
 197         return HF14BCmdRaw(reply
, &crc
, power
, data
, &datalen
, true); 
 200 // print full atqb info 
 201 static void print_atqb_resp(uint8_t *data
){ 
 202         PrintAndLog ("           UID: %s", sprint_hex(data
+1,4)); 
 203         PrintAndLog ("      App Data: %s", sprint_hex(data
+5,4)); 
 204         PrintAndLog ("      Protocol: %s", sprint_hex(data
+9,3)); 
 205         uint8_t BitRate 
= data
[9]; 
 207                 PrintAndLog ("      Bit Rate: 106 kbit/s only PICC <-> PCD"); 
 209                 PrintAndLog ("      Bit Rate: 212 kbit/s PICC -> PCD supported"); 
 211                 PrintAndLog ("      Bit Rate: 424 kbit/s PICC -> PCD supported");  
 213                 PrintAndLog ("      Bit Rate: 847 kbit/s PICC -> PCD supported");  
 215                 PrintAndLog ("      Bit Rate: 212 kbit/s PICC <- PCD supported"); 
 217                 PrintAndLog ("      Bit Rate: 424 kbit/s PICC <- PCD supported");  
 219                 PrintAndLog ("      Bit Rate: 847 kbit/s PICC <- PCD supported");  
 221                 PrintAndLog ("                Same bit rate <-> required"); 
 223         uint16_t maxFrame 
= data
[10]>>4; 
 225                 maxFrame 
= 8*maxFrame 
+ 16; 
 226         else if (maxFrame 
== 5) 
 228         else if (maxFrame 
== 6) 
 230         else if (maxFrame 
== 7) 
 232         else if (maxFrame 
== 8) 
 237         PrintAndLog ("Max Frame Size: %d%s",maxFrame
, (maxFrame 
== 257) ? "+ RFU" : ""); 
 239         uint8_t protocolT 
= data
[10] & 0xF; 
 240         PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT
) ? "" : "not " ); 
 241         PrintAndLog ("Frame Wait Int: %d", data
[11]>>4); 
 242         PrintAndLog (" App Data Code: Application is %s",(data
[11]&4) ? "Standard" : "Proprietary"); 
 243         PrintAndLog (" Frame Options: NAD is %ssupported",(data
[11]&2) ? "" : "not "); 
 244         PrintAndLog (" Frame Options: CID is %ssupported",(data
[11]&1) ? "" : "not "); 
 249 // get SRx chip model (from UID) // from ST Microelectronics 
 250 char *get_ST_Chip_Model(uint8_t data
){ 
 251         static char model
[20]; 
 252         char *retStr 
= model
; 
 253         memset(model
,0, sizeof(model
)); 
 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; 
 263                 default : sprintf(retStr
, "Unknown"); break; 
 268 // print UID info from SRx chips (ST Microelectronics) 
 269 static void print_st_general_info(uint8_t *data
){ 
 270         //uid = first 8 bytes in data 
 271         PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data
,8,8),8)); 
 272         PrintAndLog(" MFG: %02X, %s", data
[6], getTagInfo(data
[6])); 
 273         PrintAndLog("Chip: %02X, %s", data
[5]>>2, get_ST_Chip_Model(data
[5]>>2)); 
 277 // 14b get and print Full Info (as much as we know) 
 278 int HF14BStdInfo(uint8_t *data
, uint8_t *datalen
){ 
 279         if (!HF14BStdReader(data
,datalen
)) return 0; 
 282         print_atqb_resp(data
); 
 287 // 14b get and print UID only (general info) 
 288 int HF14BStdReader(uint8_t *data
, uint8_t *datalen
){ 
 289         //05 00 00 = find one tag in field 
 290         //1d xx xx xx xx 20 00 08 01 00 = attrib xx=crc 
 291         //a3 = ?  (resp 03 e2 c2) 
 292         //02 = ?  (resp 02 6a d3) 
 293         // 022b (resp 02 67 00 [29  5b]) 
 294         // 0200a40400 (resp 02 67 00 [29 5b]) 
 295         // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b]) 
 296         // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b]) 
 297         // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c]) 
 298         // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b]) 
 299         // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c]) 
 300         // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c]) 
 301         // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c]) 
 302         //03 = ?  (resp 03 [e3 c2]) 
 303         //c2 = ?  (resp c2 [66 15]) 
 304         //b2 = ?  (resp a3 [e9 67]) 
 312         if (HF14BCmdRaw(true, &crc
, false, data
, datalen
, false)==0) return 0; 
 314         if (data
[0] != 0x50  || *datalen 
!= 14 || !crc
) return 0; 
 316         PrintAndLog ("\n14443-3b tag found:"); 
 317         PrintAndLog ("           UID: %s", sprint_hex(data
+1,4)); 
 322 // SRx get and print full info (needs more info...) 
 323 int HF14B_ST_Info(uint8_t *data
, uint8_t *datalen
){ 
 324         if (!HF14B_ST_Reader(data
, datalen
)) return 0; 
 326         //add locking bit information here. 
 332 // SRx get and print general info about SRx chip from UID 
 333 int HF14B_ST_Reader(uint8_t *data
, uint8_t *datalen
){ 
 341         // verbose on for now for testing - turn off when functional 
 342         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 344         if (*datalen 
!= 3 || !crc
) return rawClose(); 
 346         uint8_t chipID 
= data
[0]; 
 353         // verbose on for now for testing - turn off when functional 
 354         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 356         if (*datalen 
!= 3 || !crc 
|| data
[0] != chipID
) return rawClose(); 
 363         // verbose on for now for testing - turn off when functional 
 364         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return 0; 
 366         if (*datalen 
!= 10 || !crc
) return 0; 
 368         PrintAndLog("\n14443-3b ST tag found:"); 
 369         print_st_general_info(data
); 
 373 // test for other 14b type tags (mimic another reader - don't have tags to identify) 
 374 int HF14B_Other_Reader(uint8_t *data
, uint8_t *datalen
){ 
 383         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 384                 if (*datalen 
> 2 || !crc
) { 
 385                         PrintAndLog ("\n14443-3b tag found:"); 
 386                         PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:"); 
 387                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 396         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 398                         PrintAndLog ("\n14443-3b tag found:"); 
 399                         PrintAndLog ("Unknown tag type answered to a 0x0A command ans:"); 
 400                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 409         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 411                         PrintAndLog ("\n14443-3b tag found:"); 
 412                         PrintAndLog ("Unknown tag type answered to a 0x0C command ans:"); 
 413                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 421 // get and print all info known about any known 14b tag 
 422 int HF14BInfo(bool verbose
){ 
 426         // try std 14b (atqb) 
 427         if (HF14BStdInfo(data
, &datalen
)) return 1; 
 430         if (HF14B_ST_Info(data
, &datalen
)) return 1; 
 432         // try unknown 14b read commands (to be identified later) 
 433         //   could be read of calypso, CEPAS, moneo, or pico pass. 
 434         if (HF14B_Other_Reader(data
, &datalen
)) return 1; 
 436         if (verbose
) PrintAndLog("no 14443B tag found"); 
 440 // menu command to get and print all info known about any known 14b tag 
 441 int CmdHF14Binfo(const char *Cmd
){ 
 442         return HF14BInfo(true); 
 445 // get and print general info about all known 14b chips 
 446 int HF14BReader(bool verbose
){ 
 450         // try std 14b (atqb) 
 451         if (HF14BStdReader(data
, &datalen
)) return 1; 
 454         if (HF14B_ST_Reader(data
, &datalen
)) return 1; 
 456         // try unknown 14b read commands (to be identified later) 
 457         //   could be read of calypso, CEPAS, moneo, or pico pass. 
 458         if (HF14B_Other_Reader(data
, &datalen
)) return 1; 
 460         if (verbose
) PrintAndLog("no 14443B tag found"); 
 464 // menu command to get and print general info about all known 14b chips 
 465 int CmdHF14BReader(const char *Cmd
){ 
 466         return HF14BReader(true); 
 469 int CmdSriWrite( const char *Cmd
){ 
 471  * For SRIX4K  blocks 00 - 7F 
 472  * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata 
 474  * For SR512  blocks 00 - 0F 
 475  * hf 14b raw -c -p 09 $sr512wblock $sr512wdata 
 477  * Special block FF =  otp_lock_reg block. 
 480         char cmdp 
= param_getchar(Cmd
, 0); 
 481         uint8_t blockno 
= -1; 
 482         uint8_t data
[4] = {0x00}; 
 483         bool isSrix4k 
= true; 
 486         if (strlen(Cmd
) < 1 || cmdp 
== 'h' || cmdp 
== 'H') { 
 487                 PrintAndLog("Usage:  hf 14b write <1|2> <BLOCK> <DATA>"); 
 488                 PrintAndLog("    [1 = SRIX4K]"); 
 489                 PrintAndLog("    [2 = SRI512]"); 
 490                 PrintAndLog("    [BLOCK number depends on tag, special block == FF]"); 
 491                 PrintAndLog("     sample: hf 14b write 1 7F 11223344"); 
 492                 PrintAndLog("           : hf 14b write 1 FF 11223344"); 
 493                 PrintAndLog("           : hf 14b write 2 15 11223344"); 
 494                 PrintAndLog("           : hf 14b write 2 FF 11223344"); 
 501         //blockno = param_get8(Cmd, 1); 
 503         if ( param_gethex(Cmd
,1, &blockno
, 2) ) { 
 504                 PrintAndLog("Block number must include 2 HEX symbols"); 
 509                 if ( blockno 
> 0x7f && blockno 
!= 0xff ){ 
 510                         PrintAndLog("Block number out of range"); 
 514                 if ( blockno 
> 0x0f && blockno 
!= 0xff ){ 
 515                         PrintAndLog("Block number out of range"); 
 520         if (param_gethex(Cmd
, 2, data
, 8)) { 
 521                 PrintAndLog("Data must include 8 HEX symbols"); 
 525         if ( blockno 
== 0xff) 
 526                 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512" , blockno
,  sprint_hex(data
,4) ); 
 528                 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512", blockno
,  sprint_hex(data
,4) ); 
 530         sprintf(str
, "-c 09 %02x %02x%02x%02x%02x", blockno
, data
[0], data
[1], data
[2], data
[3]); 
 536 static command_t CommandTable
[] =  
 538   {"help",        CmdHelp
,        1, "This help"}, 
 539   {"info",        CmdHF14Binfo
,   0, "Find and print details about a 14443B tag"}, 
 540   {"list",        CmdHF14BList
,   0, "[Deprecated] List ISO 14443B history"}, 
 541   {"reader",      CmdHF14BReader
, 0, "Act as a 14443B reader to identify a tag"}, 
 542   {"sim",         CmdHF14BSim
,    0, "Fake ISO 14443B tag"}, 
 543   {"snoop",       CmdHF14BSnoop
,  0, "Eavesdrop ISO 14443B"}, 
 544   {"sri512read",  CmdSri512Read
,  0, "Read contents of a SRI512 tag"}, 
 545   {"srix4kread",  CmdSrix4kRead
,  0, "Read contents of a SRIX4K tag"}, 
 546   {"sriwrite",    CmdSriWrite
,    0, "Write data to a SRI512 | SRIX4K tag"}, 
 547   {"raw",         CmdHF14BCmdRaw
, 0, "Send raw hex data to tag"}, 
 548   {NULL
, NULL
, 0, NULL
} 
 551 int CmdHF14B(const char *Cmd
) 
 553   CmdsParse(CommandTable
, Cmd
); 
 557 int CmdHelp(const char *Cmd
) 
 559   CmdsHelp(CommandTable
);