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 commands 
   9 //----------------------------------------------------------------------------- 
  13 #include "proxmark3.h" 
  16 #include "cmdparser.h" 
  22 #include "cmdhflegic.h" 
  23 #include "cmdhficlass.h" 
  26 #include "protocols.h" 
  28 static int CmdHelp(const char *Cmd
); 
  30 int CmdHFTune(const char *Cmd
) 
  32   UsbCommand c
={CMD_MEASURE_ANTENNA_TUNING_HF
}; 
  38 void annotateIso14443a(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
  42         case ISO14443A_CMD_WUPA
:        snprintf(exp
,size
,"WUPA"); break; 
  43         case ISO14443A_CMD_ANTICOLL_OR_SELECT
:{ 
  44                 // 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor) 
  45                 // 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK) 
  48                         snprintf(exp
,size
,"SELECT_UID"); break; 
  51                         snprintf(exp
,size
,"ANTICOLL"); break; 
  54         case ISO14443A_CMD_ANTICOLL_OR_SELECT_2
:{ 
  55                 //95 20 = Anticollision of cascade level2 
  56                 //95 70 = Select of cascade level2 
  59                         snprintf(exp
,size
,"SELECT_UID-2"); break; 
  62                         snprintf(exp
,size
,"ANTICOLL-2"); break; 
  65         case ISO14443A_CMD_REQA
:                snprintf(exp
,size
,"REQA"); break; 
  66         case ISO14443A_CMD_READBLOCK
:   snprintf(exp
,size
,"READBLOCK(%d)",cmd
[1]); break; 
  67         case ISO14443A_CMD_WRITEBLOCK
:  snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]); break; 
  68         case ISO14443A_CMD_HALT
:                snprintf(exp
,size
,"HALT"); break; 
  69         case ISO14443A_CMD_RATS
:                snprintf(exp
,size
,"RATS"); break; 
  70         case MIFARE_CMD_INC
:                    snprintf(exp
,size
,"INC(%d)",cmd
[1]); break; 
  71         case MIFARE_CMD_DEC
:                    snprintf(exp
,size
,"DEC(%d)",cmd
[1]); break; 
  72         case MIFARE_CMD_RESTORE
:                snprintf(exp
,size
,"RESTORE(%d)",cmd
[1]); break; 
  73         case MIFARE_CMD_TRANSFER
:               snprintf(exp
,size
,"TRANSFER(%d)",cmd
[1]); break; 
  74         case MIFARE_AUTH_KEYA
:{ 
  76                         snprintf(exp
,size
,"AUTH-A(%d)",cmd
[1]);  
  78                         //      case MIFARE_ULEV1_VERSION :  both 0x60. 
  79                         snprintf(exp
,size
,"EV1 VERSION"); 
  82         case MIFARE_AUTH_KEYB
:                  snprintf(exp
,size
,"AUTH-B(%d)",cmd
[1]); break; 
  83         case MIFARE_MAGICWUPC1
:                 snprintf(exp
,size
,"MAGIC WUPC1"); break; 
  84         case MIFARE_MAGICWUPC2
:                 snprintf(exp
,size
,"MAGIC WUPC2"); break; 
  85         case MIFARE_MAGICWIPEC
:                 snprintf(exp
,size
,"MAGIC WIPEC"); break; 
  86         case MIFARE_ULC_AUTH_1
:         snprintf(exp
,size
,"AUTH "); break; 
  87         case MIFARE_ULC_AUTH_2
:         snprintf(exp
,size
,"AUTH_ANSW"); break; 
  88         case MIFARE_ULEV1_AUTH
:         snprintf(exp
,size
,"PWD-AUTH"); break; 
  89         case MIFARE_ULEV1_FASTREAD
:{ 
  90                 if ( cmdsize 
>=3 && cmd
[2] < 0x21) 
  91                         snprintf(exp
,size
,"READ RANGE (%d-%d)",cmd
[1],cmd
[2]);  
  93                         snprintf(exp
,size
,"?"); 
  96         case MIFARE_ULC_WRITE
:{ 
  98                         snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]);  
 100                         snprintf(exp
,size
,"?"); 
 103         case MIFARE_ULEV1_READ_CNT
:{ 
 105                         snprintf(exp
,size
,"READ CNT(%d)",cmd
[1]); 
 107                         snprintf(exp
,size
,"?"); 
 110         case MIFARE_ULEV1_INCR_CNT
:{ 
 112                         snprintf(exp
,size
,"INCR(%d)",cmd
[1]); 
 114                         snprintf(exp
,size
,"?"); 
 117         case MIFARE_ULEV1_READSIG
:              snprintf(exp
,size
,"READ_SIG"); break; 
 118         case MIFARE_ULEV1_CHECKTEAR
:    snprintf(exp
,size
,"CHK_TEARING(%d)",cmd
[1]); break; 
 119         case MIFARE_ULEV1_VCSL
:         snprintf(exp
,size
,"VCSL"); break; 
 120         default:                                                snprintf(exp
,size
,"?"); break; 
 125 void annotateIclass(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
 129         case ICLASS_CMD_ACTALL
:      snprintf(exp
,size
,"ACTALL"); break; 
 130         case ICLASS_CMD_READ_OR_IDENTIFY
:{ 
 132                         snprintf(exp
,size
,"READ(%d)",cmd
[1]); 
 134                         snprintf(exp
,size
,"IDENTIFY"); 
 138         case ICLASS_CMD_SELECT
:      snprintf(exp
,size
,"SELECT"); break; 
 139         case ICLASS_CMD_PAGESEL
:     snprintf(exp
,size
,"PAGESEL(%d)", cmd
[1]); break; 
 140         case ICLASS_CMD_READCHECK_KC
:snprintf(exp
,size
,"READCHECK[Kc](%d)", cmd
[1]); break; 
 141         case ICLASS_CMD_READCHECK_KD
:snprintf(exp
,size
,"READCHECK[Kd](%d)", cmd
[1]); break; 
 142         case ICLASS_CMD_CHECK
:       snprintf(exp
,size
,"CHECK"); break; 
 143         case ICLASS_CMD_DETECT
:      snprintf(exp
,size
,"DETECT"); break; 
 144         case ICLASS_CMD_HALT
:        snprintf(exp
,size
,"HALT"); break; 
 145         case ICLASS_CMD_UPDATE
:      snprintf(exp
,size
,"UPDATE(%d)",cmd
[1]); break; 
 146         case ICLASS_CMD_ACT
:         snprintf(exp
,size
,"ACT"); break; 
 147         case ICLASS_CMD_READ4
:       snprintf(exp
,size
,"READ4(%d)",cmd
[1]); break; 
 148         default:                     snprintf(exp
,size
,"?"); break; 
 153 void annotateIso15693(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
 159                 case ISO15693_INVENTORY           
:snprintf(exp
, size
, "INVENTORY");break; 
 160                 case ISO15693_STAYQUIET           
:snprintf(exp
, size
, "STAY_QUIET");break; 
 161                 default:                     snprintf(exp
,size
,"?"); break; 
 164         }else if(cmd
[0] == 0x02) 
 168                 case ISO15693_READBLOCK            
:snprintf(exp
, size
, "READBLOCK");break; 
 169                 case ISO15693_WRITEBLOCK           
:snprintf(exp
, size
, "WRITEBLOCK");break; 
 170                 case ISO15693_LOCKBLOCK            
:snprintf(exp
, size
, "LOCKBLOCK");break; 
 171                 case ISO15693_READ_MULTI_BLOCK     
:snprintf(exp
, size
, "READ_MULTI_BLOCK");break; 
 172                 case ISO15693_SELECT               
:snprintf(exp
, size
, "SELECT");break; 
 173                 case ISO15693_RESET_TO_READY       
:snprintf(exp
, size
, "RESET_TO_READY");break; 
 174                 case ISO15693_WRITE_AFI            
:snprintf(exp
, size
, "WRITE_AFI");break; 
 175                 case ISO15693_LOCK_AFI             
:snprintf(exp
, size
, "LOCK_AFI");break; 
 176                 case ISO15693_WRITE_DSFID          
:snprintf(exp
, size
, "WRITE_DSFID");break; 
 177                 case ISO15693_LOCK_DSFID           
:snprintf(exp
, size
, "LOCK_DSFID");break; 
 178                 case ISO15693_GET_SYSTEM_INFO      
:snprintf(exp
, size
, "GET_SYSTEM_INFO");break; 
 179                 case ISO15693_READ_MULTI_SECSTATUS 
:snprintf(exp
, size
, "READ_MULTI_SECSTATUS");break; 
 180                 default:                            snprintf(exp
,size
,"?"); break; 
 187 0E xx = SELECT ID (xx = Chip-ID) 
 189 08 yy = Read Block (yy = block number) 
 190 09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written) 
 191 0C = Reset to Inventory 
 193 0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate) 
 196 void annotateIso14443b(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
 199         case ISO14443B_REQB   
: snprintf(exp
,size
,"REQB");break; 
 200         case ISO14443B_ATTRIB 
: snprintf(exp
,size
,"ATTRIB");break; 
 201         case ISO14443B_HALT   
: snprintf(exp
,size
,"HALT");break; 
 202         case ISO14443B_INITIATE     
: snprintf(exp
,size
,"INITIATE");break; 
 203         case ISO14443B_SELECT       
: snprintf(exp
,size
,"SELECT(%d)",cmd
[1]);break; 
 204         case ISO14443B_GET_UID      
: snprintf(exp
,size
,"GET UID");break; 
 205         case ISO14443B_READ_BLK     
: snprintf(exp
,size
,"READ_BLK(%d)", cmd
[1]);break; 
 206         case ISO14443B_WRITE_BLK    
: snprintf(exp
,size
,"WRITE_BLK(%d)",cmd
[1]);break; 
 207         case ISO14443B_RESET        
: snprintf(exp
,size
,"RESET");break; 
 208         case ISO14443B_COMPLETION   
: snprintf(exp
,size
,"COMPLETION");break; 
 209         case ISO14443B_AUTHENTICATE 
: snprintf(exp
,size
,"AUTHENTICATE");break; 
 210         default                     : snprintf(exp
,size 
,"?");break; 
 216  * @brief iso14443B_CRC_Ok Checks CRC in command or response 
 220  * @return  0 : CRC-command, CRC not ok 
 221  *          1 : CRC-command, CRC ok 
 222  *          2 : Not crc-command 
 225 uint8_t iso14443B_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
) 
 229         if(len 
<= 2) return 2; 
 231         ComputeCrc14443(CRC_14443_B
, data
, len
-2, &b1
, &b2
); 
 232         if(b1 
!= data
[len
-2] || b2 
!= data
[len
-1]) { 
 239  * @brief iclass_CRC_Ok Checks CRC in command or response 
 243  * @return  0 : CRC-command, CRC not ok 
 244  *              1 : CRC-command, CRC ok 
 245  *          2 : Not crc-command 
 247 uint8_t iclass_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
) 
 249         if(len 
< 4) return 2;//CRC commands (and responses) are all at least 4 bytes 
 253         if(!isResponse
)//Commands to tag 
 256                   These commands should have CRC. Total length leftmost 
 259                   12 UPDATE - unsecured, ends with CRC16 
 260                   14 UPDATE - secured, ends with signature instead 
 263                 if(len 
== 4 || len 
== 12)//Covers three of them 
 265                         //Don't include the command byte 
 266                         ComputeCrc14443(CRC_ICLASS
, (data
+1), len
-3, &b1
, &b2
); 
 267                         return b1 
== data
[len 
-2] && b2 
== data
[len
-1]; 
 272                 These tag responses should have CRC. Total length leftmost 
 274                 10  READ                data[8] crc[2] 
 275                 34  READ4               data[32]crc[2] 
 276                 10  UPDATE      data[8] crc[2] 
 277                 10 SELECT       csn[8] crc[2] 
 278                 10  IDENTIFY  asnb[8] crc[2] 
 279                 10  PAGESEL   block1[8] crc[2] 
 280                 10  DETECT    csn[8] crc[2] 
 284                 4  CHECK                chip_response[4] 
 289                 In conclusion, without looking at the command; any response 
 290                 of length 10 or 34 should have CRC 
 292                 if(len 
!= 10 && len 
!= 34) return true; 
 294                 ComputeCrc14443(CRC_ICLASS
, data
, len
-2, &b1
, &b2
); 
 295                 return b1 
== data
[len 
-2] && b2 
== data
[len
-1]; 
 299 uint16_t printTraceLine(uint16_t tracepos
, uint16_t traceLen
, uint8_t *trace
, uint8_t protocol
, bool showWaitCycles
) 
 302         uint16_t duration
, data_len
, parity_len
; 
 304         uint32_t timestamp
, first_timestamp
, EndOfTransmissionTimestamp
; 
 305         char explanation
[30] = {0}; 
 307         if (tracepos 
+ sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen
) return traceLen
; 
 309         first_timestamp 
= *((uint32_t *)(trace
)); 
 310         timestamp 
= *((uint32_t *)(trace 
+ tracepos
)); 
 313         duration 
= *((uint16_t *)(trace 
+ tracepos
)); 
 315         data_len 
= *((uint16_t *)(trace 
+ tracepos
)); 
 318         if (data_len 
& 0x8000) { 
 324         parity_len 
= (data_len
-1)/8 + 1; 
 326         if (tracepos 
+ data_len 
+ parity_len 
> traceLen
) { 
 329         uint8_t *frame 
= trace 
+ tracepos
; 
 330         tracepos 
+= data_len
; 
 331         uint8_t *parityBytes 
= trace 
+ tracepos
; 
 332         tracepos 
+= parity_len
; 
 334         //Check the CRC status 
 335         uint8_t crcStatus 
= 2; 
 339                 if(protocol 
== ICLASS
) 
 341                         crcStatus 
= iclass_CRC_check(isResponse
, frame
, data_len
); 
 343                 }else if (protocol 
== ISO_14443B
) 
 345                         crcStatus 
= iso14443B_CRC_check(isResponse
, frame
, data_len
); 
 347                 else if (protocol 
== ISO_14443A
){//Iso 14443a 
 349                         ComputeCrc14443(CRC_14443_A
, frame
, data_len
-2, &b1
, &b2
); 
 351                         if (b1 
!= frame
[data_len
-2] || b2 
!= frame
[data_len
-1]) { 
 352                                 if(!(isResponse 
& (data_len 
< 6))) 
 359         //0 CRC-command, CRC not ok 
 360         //1 CRC-command, CRC ok 
 363         //--- Draw the data column 
 364         //char line[16][110]; 
 367         for (int j 
= 0; j 
< data_len 
&& j
/16 < 16; j
++) { 
 369                 int oddparity 
= 0x01; 
 372                 for (k
=0 ; k
<8 ; k
++) { 
 373                         oddparity 
^= (((frame
[j
] & 0xFF) >> k
) & 0x01); 
 375                 uint8_t parityBits 
= parityBytes
[j
>>3]; 
 376                 if (isResponse 
&& (oddparity 
!= ((parityBits 
>> (7-(j
&0x0007))) & 0x01))) { 
 377                         snprintf(line
[j
/16]+(( j 
% 16) * 4),110, "%02x! ", frame
[j
]); 
 380                         snprintf(line
[j
/16]+(( j 
% 16) * 4),110, "%02x  ", frame
[j
]); 
 386                 char *pos1 
= line
[(data_len
-2)/16]+(((data_len
-2) % 16) * 4)-1; 
 388                 char *pos2 
= line
[(data_len
)/16]+(((data_len
) % 16) * 4)-2; 
 394                         sprintf(line
[0],"<empty trace - possible error>"); 
 397         //--- Draw the CRC column 
 399         char *crc 
= (crcStatus 
== 0 ? "!crc" : (crcStatus 
== 1 ? " ok " : "    ")); 
 401         EndOfTransmissionTimestamp 
= timestamp 
+ duration
; 
 405                 if(protocol 
== ICLASS
) 
 406                         annotateIclass(explanation
,sizeof(explanation
),frame
,data_len
); 
 407                 else if (protocol 
== ISO_14443A
) 
 408                         annotateIso14443a(explanation
,sizeof(explanation
),frame
,data_len
); 
 409                 else if(protocol 
== ISO_14443B
) 
 410                         annotateIso14443b(explanation
,sizeof(explanation
),frame
,data_len
); 
 413         int num_lines 
= MIN((data_len 
- 1)/16 + 1, 16); 
 414         for (int j 
= 0; j 
< num_lines 
; j
++) { 
 416                         PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s", 
 417                                 (timestamp 
- first_timestamp
), 
 418                                 (EndOfTransmissionTimestamp 
- first_timestamp
), 
 419                                 (isResponse 
? "Tag" : "Rdr"), 
 421                                 (j 
== num_lines
-1) ? crc 
: "    ", 
 422                                 (j 
== num_lines
-1) ? explanation 
: ""); 
 424                         PrintAndLog("           |           |     | %-64s| %s| %s", 
 426                                 (j 
== num_lines
-1)?crc
:"    ", 
 427                                 (j 
== num_lines
-1) ? explanation 
: ""); 
 431         if (tracepos 
+ sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen
) return traceLen
; 
 433         bool next_isResponse 
= *((uint16_t *)(trace 
+ tracepos 
+ 6)) & 0x8000; 
 435         if (showWaitCycles 
&& !isResponse 
&& next_isResponse
) { 
 436                 uint32_t next_timestamp 
= *((uint32_t *)(trace 
+ tracepos
)); 
 437                 if (next_timestamp 
!= 0x44444444) { 
 438                         PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d", 
 439                                 (EndOfTransmissionTimestamp 
- first_timestamp
), 
 440                                 (next_timestamp 
- first_timestamp
), 
 442                                 (next_timestamp 
- EndOfTransmissionTimestamp
)); 
 450 int CmdHFList(const char *Cmd
) 
 452         bool showWaitCycles 
= false; 
 454         int tlen 
= param_getstr(Cmd
,0,type
); 
 455         char param 
= param_getchar(Cmd
, 1); 
 457         uint8_t protocol 
= 0; 
 463         if(param 
== 'h' || (param 
!=0 && param 
!= 'f')) 
 469                 if(strcmp(type
, "iclass") == 0) 
 472                 }else if(strcmp(type
, "14a") == 0) 
 474                         protocol 
= ISO_14443A
; 
 476                 else if(strcmp(type
, "14b") == 0) 
 478                         protocol 
= ISO_14443B
; 
 479                 }else if(strcmp(type
,"raw")== 0) 
 481                         protocol 
= -1;//No crc, no annotations 
 488                 PrintAndLog("List protocol data in trace buffer."); 
 489                 PrintAndLog("Usage:  hf list <protocol> [f]"); 
 490                 PrintAndLog("    f      - show frame delay times as well"); 
 491                 PrintAndLog("Supported <protocol> values:"); 
 492                 PrintAndLog("    raw    - just show raw data without annotations"); 
 493                 PrintAndLog("    14a    - interpret data as iso14443a communications"); 
 494                 PrintAndLog("    14b    - interpret data as iso14443b communications"); 
 495                 PrintAndLog("    iclass - interpret data as iclass communications"); 
 497                 PrintAndLog("example: hf list 14a f"); 
 498                 PrintAndLog("example: hf list iclass"); 
 504                 showWaitCycles 
= true; 
 509         uint16_t tracepos 
= 0; 
 510         trace 
= malloc(USB_CMD_DATA_SIZE
); 
 512         // Query for the size of the trace 
 514         GetFromBigBuf(trace
, USB_CMD_DATA_SIZE
, 0); 
 515         WaitForResponse(CMD_ACK
, &response
); 
 516         uint16_t traceLen 
= response
.arg
[2]; 
 517         if (traceLen 
> USB_CMD_DATA_SIZE
) { 
 518                 uint8_t *p 
= realloc(trace
, traceLen
); 
 520                         PrintAndLog("Cannot allocate memory for trace"); 
 525                 GetFromBigBuf(trace
, traceLen
, 0); 
 526                 WaitForResponse(CMD_ACK
, NULL
); 
 529         PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen
); 
 531         PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); 
 532         PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)"); 
 533         PrintAndLog("iClass    - Timings are not as accurate"); 
 535         PrintAndLog("     Start |       End | Src | Data (! denotes parity error)                                   | CRC | Annotation         |"); 
 536         PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|"); 
 538         while(tracepos 
< traceLen
) 
 540                 tracepos 
= printTraceLine(tracepos
, traceLen
, trace
, protocol
, showWaitCycles
); 
 547 int CmdHFSearch(const char *Cmd
){ 
 549         ans 
= CmdHF14AReader(Cmd
); 
 550         if (ans 
> 0) return ans
; 
 552         ans 
= CmdHF15Reader(Cmd
); 
 553         //if (ans > 0) return ans;       
 555         ans 
= CmdHF14BRead(Cmd
); 
 556         //if (ans > 0) return ans; 
 558         ans 
= CmdHFiClassReader(Cmd
); 
 559         //if (ans > 0) return ans; 
 563 static command_t CommandTable
[] =  
 565   {"help",        CmdHelp
,          1, "This help"}, 
 566   {"14a",         CmdHF14A
,         1, "{ ISO14443A RFIDs... }"}, 
 567   {"14b",         CmdHF14B
,         1, "{ ISO14443B RFIDs... }"}, 
 568   {"15",          CmdHF15
,          1, "{ ISO15693 RFIDs... }"}, 
 569   {"epa",         CmdHFEPA
,         1, "{ German Identification Card... }"}, 
 570   {"legic",       CmdHFLegic
,       0, "{ LEGIC RFIDs... }"}, 
 571   {"iclass",      CmdHFiClass
,      1, "{ ICLASS RFIDs... }"}, 
 572   {"mf",          CmdHFMF
,          1, "{ MIFARE RFIDs... }"}, 
 573   {"mfu",         CmdHFMFUltra
,     1, "{ MIFARE Ultralight RFIDs... }"}, 
 574   {"tune",        CmdHFTune
,        0, "Continuously measure HF antenna tuning"}, 
 575   {"list",        CmdHFList
,        1, "List protocol data in trace buffer"}, 
 576   {"search",      CmdHFSearch
,      1, "Search for known HF tags"}, 
 577         {NULL
, NULL
, 0, NULL
} 
 580 int CmdHF(const char *Cmd
) 
 582   CmdsParse(CommandTable
, Cmd
); 
 586 int CmdHelp(const char *Cmd
) 
 588   CmdsHelp(CommandTable
);