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 "cmdhfmfdes.h" 
  27 #include "cmdhftopaz.h" 
  28 #include "protocols.h" 
  30 static int CmdHelp(const char *Cmd
); 
  32 int CmdHFTune(const char *Cmd
) 
  34         PrintAndLog("Measuring HF antenna, press button to exit"); 
  35         UsbCommand c 
= {CMD_MEASURE_ANTENNA_TUNING_HF
}; 
  42 void annotateIso14443a(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
  46         case ISO14443A_CMD_WUPA
:        snprintf(exp
,size
,"WUPA"); break; 
  47         case ISO14443A_CMD_ANTICOLL_OR_SELECT
:{ 
  48                 // 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor) 
  49                 // 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK) 
  52                         snprintf(exp
,size
,"SELECT_UID"); break; 
  55                         snprintf(exp
,size
,"ANTICOLL"); break; 
  58         case ISO14443A_CMD_ANTICOLL_OR_SELECT_2
:{ 
  59                 //95 20 = Anticollision of cascade level2 
  60                 //95 70 = Select of cascade level2 
  63                         snprintf(exp
,size
,"SELECT_UID-2"); break; 
  66                         snprintf(exp
,size
,"ANTICOLL-2"); break; 
  69         case ISO14443A_CMD_REQA
:                snprintf(exp
,size
,"REQA"); break; 
  70         case ISO14443A_CMD_READBLOCK
:   snprintf(exp
,size
,"READBLOCK(%d)",cmd
[1]); break; 
  71         case ISO14443A_CMD_WRITEBLOCK
:  snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]); break; 
  72         case ISO14443A_CMD_HALT
:                snprintf(exp
,size
,"HALT"); break; 
  73         case ISO14443A_CMD_RATS
:                snprintf(exp
,size
,"RATS"); break; 
  74         case MIFARE_CMD_INC
:                    snprintf(exp
,size
,"INC(%d)",cmd
[1]); break; 
  75         case MIFARE_CMD_DEC
:                    snprintf(exp
,size
,"DEC(%d)",cmd
[1]); break; 
  76         case MIFARE_CMD_RESTORE
:                snprintf(exp
,size
,"RESTORE(%d)",cmd
[1]); break; 
  77         case MIFARE_CMD_TRANSFER
:               snprintf(exp
,size
,"TRANSFER(%d)",cmd
[1]); break; 
  78         case MIFARE_AUTH_KEYA
:{ 
  80                         snprintf(exp
,size
,"AUTH-A(%d)",cmd
[1]);  
  82                         //      case MIFARE_ULEV1_VERSION :  both 0x60. 
  83                         snprintf(exp
,size
,"EV1 VERSION"); 
  86         case MIFARE_AUTH_KEYB
:                  snprintf(exp
,size
,"AUTH-B(%d)",cmd
[1]); break; 
  87         case MIFARE_MAGICWUPC1
:                 snprintf(exp
,size
,"MAGIC WUPC1"); break; 
  88         case MIFARE_MAGICWUPC2
:                 snprintf(exp
,size
,"MAGIC WUPC2"); break; 
  89         case MIFARE_MAGICWIPEC
:                 snprintf(exp
,size
,"MAGIC WIPEC"); break; 
  90         case MIFARE_ULC_AUTH_1 
:                snprintf(exp
,size
,"AUTH "); break; 
  91         case MIFARE_ULC_AUTH_2 
:                snprintf(exp
,size
,"AUTH_ANSW"); break; 
  92         case MIFARE_ULEV1_AUTH 
:         
  94                         snprintf(exp
,size
,"PWD-AUTH KEY: 0x%02x%02x%02x%02x", cmd
[1], cmd
[2], cmd
[3], cmd
[4] ); 
  96                         snprintf(exp
,size
,"PWD-AUTH"); 
  98         case MIFARE_ULEV1_FASTREAD 
: { 
  99                 if ( cmdsize 
>=3 && cmd
[2] <= 0xE6) 
 100                         snprintf(exp
,size
,"READ RANGE (%d-%d)",cmd
[1],cmd
[2]);  
 102                         snprintf(exp
,size
,"?"); 
 105         case MIFARE_ULC_WRITE 
: { 
 107                         snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]);  
 109                         snprintf(exp
,size
,"?"); 
 112         case MIFARE_ULEV1_READ_CNT 
:{ 
 114                         snprintf(exp
,size
,"READ CNT(%d)",cmd
[1]); 
 116                         snprintf(exp
,size
,"?"); 
 119         case MIFARE_ULEV1_INCR_CNT 
: { 
 121                         snprintf(exp
,size
,"INCR(%d)",cmd
[1]); 
 123                         snprintf(exp
,size
,"?"); 
 126         case MIFARE_ULEV1_READSIG 
:             snprintf(exp
,size
,"READ_SIG"); break; 
 127         case MIFARE_ULEV1_CHECKTEAR 
:   snprintf(exp
,size
,"CHK_TEARING(%d)",cmd
[1]); break; 
 128         case MIFARE_ULEV1_VCSL 
:                snprintf(exp
,size
,"VCSL"); break; 
 129         default:                                                snprintf(exp
,size
,"?"); break; 
 134 void annotateIclass(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
 138         case ICLASS_CMD_ACTALL
:      snprintf(exp
,size
,"ACTALL"); break; 
 139         case ICLASS_CMD_READ_OR_IDENTIFY
:{ 
 141                         snprintf(exp
,size
,"READ(%d)",cmd
[1]); 
 143                         snprintf(exp
,size
,"IDENTIFY"); 
 147         case ICLASS_CMD_SELECT
:      snprintf(exp
,size
,"SELECT"); break; 
 148         case ICLASS_CMD_PAGESEL
:     snprintf(exp
,size
,"PAGESEL(%d)", cmd
[1]); break; 
 149         case ICLASS_CMD_READCHECK_KC
:snprintf(exp
,size
,"READCHECK[Kc](%d)", cmd
[1]); break; 
 150         case ICLASS_CMD_READCHECK_KD
:snprintf(exp
,size
,"READCHECK[Kd](%d)", cmd
[1]); break; 
 151         case ICLASS_CMD_CHECK
:       snprintf(exp
,size
,"CHECK"); break; 
 152         case ICLASS_CMD_DETECT
:      snprintf(exp
,size
,"DETECT"); break; 
 153         case ICLASS_CMD_HALT
:        snprintf(exp
,size
,"HALT"); break; 
 154         case ICLASS_CMD_UPDATE
:      snprintf(exp
,size
,"UPDATE(%d)",cmd
[1]); break; 
 155         case ICLASS_CMD_ACT
:         snprintf(exp
,size
,"ACT"); break; 
 156         case ICLASS_CMD_READ4
:       snprintf(exp
,size
,"READ4(%d)",cmd
[1]); break; 
 157         default:                     snprintf(exp
,size
,"?"); break; 
 162 void annotateIso15693(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
 168                 case ISO15693_INVENTORY           
:snprintf(exp
, size
, "INVENTORY");break; 
 169                 case ISO15693_STAYQUIET           
:snprintf(exp
, size
, "STAY_QUIET");break; 
 170                 default:                     snprintf(exp
,size
,"?"); break; 
 173         }else if(cmd
[0] == 0x02) 
 177                 case ISO15693_READBLOCK            
:snprintf(exp
, size
, "READBLOCK");break; 
 178                 case ISO15693_WRITEBLOCK           
:snprintf(exp
, size
, "WRITEBLOCK");break; 
 179                 case ISO15693_LOCKBLOCK            
:snprintf(exp
, size
, "LOCKBLOCK");break; 
 180                 case ISO15693_READ_MULTI_BLOCK     
:snprintf(exp
, size
, "READ_MULTI_BLOCK");break; 
 181                 case ISO15693_SELECT               
:snprintf(exp
, size
, "SELECT");break; 
 182                 case ISO15693_RESET_TO_READY       
:snprintf(exp
, size
, "RESET_TO_READY");break; 
 183                 case ISO15693_WRITE_AFI            
:snprintf(exp
, size
, "WRITE_AFI");break; 
 184                 case ISO15693_LOCK_AFI             
:snprintf(exp
, size
, "LOCK_AFI");break; 
 185                 case ISO15693_WRITE_DSFID          
:snprintf(exp
, size
, "WRITE_DSFID");break; 
 186                 case ISO15693_LOCK_DSFID           
:snprintf(exp
, size
, "LOCK_DSFID");break; 
 187                 case ISO15693_GET_SYSTEM_INFO      
:snprintf(exp
, size
, "GET_SYSTEM_INFO");break; 
 188                 case ISO15693_READ_MULTI_SECSTATUS 
:snprintf(exp
, size
, "READ_MULTI_SECSTATUS");break; 
 189                 default:                            snprintf(exp
,size
,"?"); break; 
 194 void annotateTopaz(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
 197                 case TOPAZ_REQA                                         
:snprintf(exp
, size
, "REQA");break; 
 198                 case TOPAZ_WUPA                                         
:snprintf(exp
, size
, "WUPA");break; 
 199                 case TOPAZ_RID                                          
:snprintf(exp
, size
, "RID");break; 
 200                 case TOPAZ_RALL                                         
:snprintf(exp
, size
, "RALL");break; 
 201                 case TOPAZ_READ                                         
:snprintf(exp
, size
, "READ");break; 
 202                 case TOPAZ_WRITE_E                                      
:snprintf(exp
, size
, "WRITE-E");break; 
 203                 case TOPAZ_WRITE_NE                                     
:snprintf(exp
, size
, "WRITE-NE");break; 
 204                 case TOPAZ_RSEG                                         
:snprintf(exp
, size
, "RSEG");break; 
 205                 case TOPAZ_READ8                                        
:snprintf(exp
, size
, "READ8");break; 
 206                 case TOPAZ_WRITE_E8                                     
:snprintf(exp
, size
, "WRITE-E8");break; 
 207                 case TOPAZ_WRITE_NE8                            
:snprintf(exp
, size
, "WRITE-NE8");break; 
 208                 default                                                         :snprintf(exp
,size
,"?"); break; 
 213 void annotateIso7816(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
){ 
 215         if ( (cmd
[0] & 0xC0) && (cmdsize 
== 3) ) {               
 216                 switch ( (cmd
[0] & 0x3f)  ) { 
 217                         case 0x00       : snprintf(exp
, size
, "S-block RESYNCH req"); break; 
 218                         case 0x20       : snprintf(exp
, size
, "S-block RESYNCH resp"); break; 
 219                         case 0x01       : snprintf(exp
, size
, "S-block IFS req"); break; 
 220                         case 0x21       : snprintf(exp
, size
, "S-block IFS resp"); break; 
 221                         case 0x02       : snprintf(exp
, size
, "S-block ABORT req"); break; 
 222                         case 0x22       : snprintf(exp
, size
, "S-block ABORT resp"); break; 
 223                         case 0x03       : snprintf(exp
, size
, "S-block WTX reqt"); break; 
 224                         case 0x23       : snprintf(exp
, size
, "S-block WTX resp"); break; 
 225                         default         : snprintf(exp
, size
, "S-block"); break; 
 229         else if ( ((cmd
[0] & 0xD0) == 0x80) && ( cmdsize 
> 2) ) { 
 230                 if ( (cmd
[0] & 0x10) == 0 )  
 231                         snprintf(exp
, size
, "R-block ACK"); 
 233                         snprintf(exp
, size
, "R-block NACK"); 
 238                 int pos 
= (cmd
[0] == 2 ||  cmd
[0] == 3) ? 2 : 3; 
 240                         case ISO7816_READ_BINARY                                
:snprintf(exp
, size
, "READ BIN");break; 
 241                         case ISO7816_WRITE_BINARY                               
:snprintf(exp
, size
, "WRITE BIN");break; 
 242                         case ISO7816_UPDATE_BINARY                              
:snprintf(exp
, size
, "UPDATE BIN");break; 
 243                         case ISO7816_ERASE_BINARY                               
:snprintf(exp
, size
, "ERASE BIN");break; 
 244                         case ISO7816_READ_RECORDS                               
:snprintf(exp
, size
, "READ RECORDS");break; 
 245                         case ISO7816_WRITE_RECORDS                              
:snprintf(exp
, size
, "WRITE RECORDS");break; 
 246                         case ISO7816_APPEND_RECORD                              
:snprintf(exp
, size
, "APPEND RECORD");break; 
 247                         case ISO7816_UPDATE_RECORD                              
:snprintf(exp
, size
, "UPDATE RECORD");break; 
 248                         case ISO7816_GET_DATA                                   
:snprintf(exp
, size
, "GET DATA");break; 
 249                         case ISO7816_PUT_DATA                                   
:snprintf(exp
, size
, "PUT DATA");break; 
 250                         case ISO7816_SELECT_FILE                                
:snprintf(exp
, size
, "SELECT FILE");break; 
 251                         case ISO7816_VERIFY                                             
:snprintf(exp
, size
, "VERIFY");break; 
 252                         case ISO7816_INTERNAL_AUTHENTICATION    
:snprintf(exp
, size
, "INTERNAL AUTH");break; 
 253                         case ISO7816_EXTERNAL_AUTHENTICATION    
:snprintf(exp
, size
, "EXTERNAL AUTH");break; 
 254                         case ISO7816_GET_CHALLENGE                              
:snprintf(exp
, size
, "GET CHALLENGE");break; 
 255                         case ISO7816_MANAGE_CHANNEL                             
:snprintf(exp
, size
, "MANAGE CHANNEL");break; 
 256                         default                                                                 :snprintf(exp
,size
,"?"); break; 
 263 0E xx = SELECT ID (xx = Chip-ID) 
 265 08 yy = Read Block (yy = block number) 
 266 09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written) 
 267 0C = Reset to Inventory 
 269 0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate) 
 272 void annotateIso14443b(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
) 
 275                 case ISO14443B_REQB             
: snprintf(exp
,size
,"REQB");break; 
 276                 case ISO14443B_ATTRIB           
: snprintf(exp
,size
,"ATTRIB");break; 
 277                 case ISO14443B_HALT             
: snprintf(exp
,size
,"HALT");break; 
 278                 case ISO14443B_INITIATE     
: snprintf(exp
,size
,"INITIATE");break; 
 279                 case ISO14443B_SELECT       
: snprintf(exp
,size
,"SELECT(%d)",cmd
[1]);break; 
 280                 case ISO14443B_GET_UID      
: snprintf(exp
,size
,"GET UID");break; 
 281                 case ISO14443B_READ_BLK     
: snprintf(exp
,size
,"READ_BLK(%d)", cmd
[1]);break; 
 282                 case ISO14443B_WRITE_BLK    
: snprintf(exp
,size
,"WRITE_BLK(%d)",cmd
[1]);break; 
 283                 case ISO14443B_RESET        
: snprintf(exp
,size
,"RESET");break; 
 284                 case ISO14443B_COMPLETION   
: snprintf(exp
,size
,"COMPLETION");break; 
 285                 case ISO14443B_AUTHENTICATE 
: snprintf(exp
,size
,"AUTHENTICATE");break; 
 286                 case ISO14443B_PING                     
: snprintf(exp
,size
,"PING");break; 
 287                 case ISO14443B_PONG                     
: snprintf(exp
,size
,"PONG");break; 
 288                 default                     : snprintf(exp
,size 
,"?");break; 
 293  * @brief iso14443A_CRC_check Checks CRC in command or response 
 297  * @return  0 : CRC-command, CRC not ok 
 298  *          1 : CRC-command, CRC ok 
 299  *          2 : Not crc-command 
 302 uint8_t iso14443A_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
) 
 306         if(len 
<= 2) return 2; 
 308         if(isResponse 
& (len 
< 6)) return 2; 
 310         ComputeCrc14443(CRC_14443_A
, data
, len
-2, &b1
, &b2
); 
 311         if (b1 
!= data
[len
-2] || b2 
!= data
[len
-1]) { 
 320  * @brief iso14443B_CRC_check Checks CRC in command or response 
 324  * @return  0 : CRC-command, CRC not ok 
 325  *          1 : CRC-command, CRC ok 
 326  *          2 : Not crc-command 
 329 uint8_t iso14443B_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
) 
 333         if(len 
<= 2) return 2; 
 335         ComputeCrc14443(CRC_14443_B
, data
, len
-2, &b1
, &b2
); 
 336         if(b1 
!= data
[len
-2] || b2 
!= data
[len
-1]) { 
 343  * @brief iclass_CRC_Ok Checks CRC in command or response 
 347  * @return  0 : CRC-command, CRC not ok 
 348  *              1 : CRC-command, CRC ok 
 349  *          2 : Not crc-command 
 351 uint8_t iclass_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
) 
 353         if(len 
< 4) return 2;//CRC commands (and responses) are all at least 4 bytes 
 357         if(!isResponse
)//Commands to tag 
 360                   These commands should have CRC. Total length leftmost 
 363                   12 UPDATE - unsecured, ends with CRC16 
 364                   14 UPDATE - secured, ends with signature instead 
 367                 if(len 
== 4 || len 
== 12)//Covers three of them 
 369                         //Don't include the command byte 
 370                         ComputeCrc14443(CRC_ICLASS
, (data
+1), len
-3, &b1
, &b2
); 
 371                         return b1 
== data
[len 
-2] && b2 
== data
[len
-1]; 
 376                 These tag responses should have CRC. Total length leftmost 
 378                 10  READ                data[8] crc[2] 
 379                 34  READ4               data[32]crc[2] 
 380                 10  UPDATE      data[8] crc[2] 
 381                 10 SELECT       csn[8] crc[2] 
 382                 10  IDENTIFY  asnb[8] crc[2] 
 383                 10  PAGESEL   block1[8] crc[2] 
 384                 10  DETECT    csn[8] crc[2] 
 388                 4  CHECK                chip_response[4] 
 393                 In conclusion, without looking at the command; any response 
 394                 of length 10 or 34 should have CRC 
 396                 if(len 
!= 10 && len 
!= 34) return true; 
 398                 ComputeCrc14443(CRC_ICLASS
, data
, len
-2, &b1
, &b2
); 
 399                 return b1 
== data
[len 
-2] && b2 
== data
[len
-1]; 
 404 bool is_last_record(uint16_t tracepos
, uint8_t *trace
, uint16_t traceLen
) 
 406         return(tracepos 
+ sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) >= traceLen
); 
 410 bool next_record_is_response(uint16_t tracepos
, uint8_t *trace
) 
 412         uint16_t next_records_datalen 
= *((uint16_t *)(trace 
+ tracepos 
+ sizeof(uint32_t) + sizeof(uint16_t))); 
 414         return(next_records_datalen 
& 0x8000); 
 418 bool merge_topaz_reader_frames(uint32_t timestamp
, uint32_t *duration
, uint16_t *tracepos
, uint16_t traceLen
, uint8_t *trace
, uint8_t *frame
, uint8_t *topaz_reader_command
, uint16_t *data_len
) 
 421 #define MAX_TOPAZ_READER_CMD_LEN        16 
 423         uint32_t last_timestamp 
= timestamp 
+ *duration
; 
 425         if ((*data_len 
!= 1) || (frame
[0] == TOPAZ_WUPA
) || (frame
[0] == TOPAZ_REQA
)) return false; 
 427         memcpy(topaz_reader_command
, frame
, *data_len
); 
 429         while (!is_last_record(*tracepos
, trace
, traceLen
) && !next_record_is_response(*tracepos
, trace
)) { 
 430                 uint32_t next_timestamp 
= *((uint32_t *)(trace 
+ *tracepos
)); 
 431                 *tracepos 
+= sizeof(uint32_t); 
 432                 uint16_t next_duration 
= *((uint16_t *)(trace 
+ *tracepos
)); 
 433                 *tracepos 
+= sizeof(uint16_t); 
 434                 uint16_t next_data_len 
= *((uint16_t *)(trace 
+ *tracepos
)) & 0x7FFF; 
 435                 *tracepos 
+= sizeof(uint16_t); 
 436                 uint8_t *next_frame 
= (trace 
+ *tracepos
); 
 437                 *tracepos 
+= next_data_len
; 
 438                 if ((next_data_len 
== 1) && (*data_len 
+ next_data_len 
<= MAX_TOPAZ_READER_CMD_LEN
)) { 
 439                         memcpy(topaz_reader_command 
+ *data_len
, next_frame
, next_data_len
); 
 440                         *data_len 
+= next_data_len
; 
 441                         last_timestamp 
= next_timestamp 
+ next_duration
; 
 444                         *tracepos 
= *tracepos 
- next_data_len 
- sizeof(uint16_t) - sizeof(uint16_t) - sizeof(uint32_t); 
 447                 uint16_t next_parity_len 
= (next_data_len
-1)/8 + 1; 
 448                 *tracepos 
+= next_parity_len
; 
 451         *duration 
= last_timestamp 
- timestamp
; 
 457 uint16_t printTraceLine(uint16_t tracepos
, uint16_t traceLen
, uint8_t *trace
, uint8_t protocol
, bool showWaitCycles
, bool markCRCBytes
) 
 460         uint16_t data_len
, parity_len
; 
 462         uint8_t topaz_reader_command
[9]; 
 463         uint32_t timestamp
, first_timestamp
, EndOfTransmissionTimestamp
; 
 464         char explanation
[30] = {0}; 
 466         if (tracepos 
+ sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen
) return traceLen
; 
 468         first_timestamp 
= *((uint32_t *)(trace
)); 
 469         timestamp 
= *((uint32_t *)(trace 
+ tracepos
)); 
 472         duration 
= *((uint16_t *)(trace 
+ tracepos
)); 
 474         data_len 
= *((uint16_t *)(trace 
+ tracepos
)); 
 477         if (data_len 
& 0x8000) { 
 483         parity_len 
= (data_len
-1)/8 + 1; 
 485         if (tracepos 
+ data_len 
+ parity_len 
> traceLen
) { 
 488         uint8_t *frame 
= trace 
+ tracepos
; 
 489         tracepos 
+= data_len
; 
 490         uint8_t *parityBytes 
= trace 
+ tracepos
; 
 491         tracepos 
+= parity_len
; 
 493         if (protocol 
== TOPAZ 
&& !isResponse
) { 
 494                 // topaz reader commands come in 1 or 9 separate frames with 7 or 8 Bits each. 
 496                 if (merge_topaz_reader_frames(timestamp
, &duration
, &tracepos
, traceLen
, trace
, frame
, topaz_reader_command
, &data_len
)) { 
 497                         frame 
= topaz_reader_command
; 
 501         //Check the CRC status 
 502         uint8_t crcStatus 
= 2; 
 507                                 crcStatus 
= iclass_CRC_check(isResponse
, frame
, data_len
); 
 511                                 crcStatus 
= iso14443B_CRC_check(isResponse
, frame
, data_len
); 
 514                                 crcStatus 
= iso14443A_CRC_check(isResponse
, frame
, data_len
); 
 520         //0 CRC-command, CRC not ok 
 521         //1 CRC-command, CRC ok 
 524         //--- Draw the data column 
 527         for (int j 
= 0; j 
< data_len 
&& j
/16 < 16; j
++) { 
 529                 int oddparity 
= 0x01; 
 532                 for (k
=0 ; k
<8 ; k
++) { 
 533                         oddparity 
^= (((frame
[j
] & 0xFF) >> k
) & 0x01); 
 535                 uint8_t parityBits 
= parityBytes
[j
>>3]; 
 536                 if (protocol 
!= ISO_14443B 
&&  (isResponse 
|| protocol 
== ISO_14443A
)  && (oddparity 
!= ((parityBits 
>> (7-(j
&0x0007))) & 0x01))) { 
 537                         snprintf(line
[j
/16]+(( j 
% 16) * 4),110, "%02x! ", frame
[j
]); 
 540                         snprintf(line
[j
/16]+(( j 
% 16) * 4),110, "%02x  ", frame
[j
]); 
 547                 if(crcStatus 
== 0 || crcStatus 
== 1) { 
 548                         char *pos1 
= line
[(data_len
-2)/16]+(((data_len
-2) % 16) * 4); 
 550                         char *pos2 
= line
[(data_len
)/16]+(((data_len
) % 16) * 4); 
 551                         sprintf(pos2
, "%c", ']'); 
 556                 sprintf(line
[0],"<empty trace - possible error>"); 
 558         //--- Draw the CRC column 
 559         char *crc 
= (crcStatus 
== 0 ? "!crc" : (crcStatus 
== 1 ? " ok " : "    ")); 
 561         EndOfTransmissionTimestamp 
= timestamp 
+ duration
; 
 566                         case ICLASS
:            annotateIclass(explanation
,sizeof(explanation
),frame
,data_len
); break; 
 567                         case ISO_14443A
:        annotateIso14443a(explanation
,sizeof(explanation
),frame
,data_len
); break; 
 568                         case ISO_14443B
:        annotateIso14443b(explanation
,sizeof(explanation
),frame
,data_len
); break; 
 569                         case TOPAZ
:                     annotateTopaz(explanation
,sizeof(explanation
),frame
,data_len
); break; 
 570                         case ISO_7816_4
:        annotateIso7816(explanation
,sizeof(explanation
),frame
,data_len
); break; 
 575         int num_lines 
= MIN((data_len 
- 1)/16 + 1, 16); 
 576         for (int j 
= 0; j 
< num_lines 
; j
++) { 
 578                         PrintAndLog(" %10d | %10d | %s |%-64s | %s| %s", 
 579                                 (timestamp 
- first_timestamp
), 
 580                                 (EndOfTransmissionTimestamp 
- first_timestamp
), 
 581                                 (isResponse 
? "Tag" : "Rdr"), 
 583                                 (j 
== num_lines
-1) ? crc 
: "    ", 
 584                                 (j 
== num_lines
-1) ? explanation 
: ""); 
 586                         PrintAndLog("            |            |     |%-64s | %s| %s", 
 588                                 (j 
== num_lines
-1) ? crc 
: "    ", 
 589                                 (j 
== num_lines
-1) ? explanation 
: ""); 
 593         if (is_last_record(tracepos
, trace
, traceLen
)) return traceLen
; 
 595         if (showWaitCycles 
&& !isResponse 
&& next_record_is_response(tracepos
, trace
)) { 
 596                 uint32_t next_timestamp 
= *((uint32_t *)(trace 
+ tracepos
)); 
 597                         PrintAndLog(" %10d | %10d | %s |fdt (Frame Delay Time): %d", 
 598                                 (EndOfTransmissionTimestamp 
- first_timestamp
), 
 599                                 (next_timestamp 
- first_timestamp
), 
 601                                 (next_timestamp 
- EndOfTransmissionTimestamp
)); 
 608         PrintAndLog("List protocol data in trace buffer."); 
 609         PrintAndLog("Usage:  hf list <protocol> [f][c]"); 
 610         PrintAndLog("    f      - show frame delay times as well"); 
 611         PrintAndLog("    c      - mark CRC bytes"); 
 612         PrintAndLog("Supported <protocol> values:"); 
 613         PrintAndLog("    raw    - just show raw data without annotations"); 
 614         PrintAndLog("    14a    - interpret data as iso14443a communications"); 
 615         PrintAndLog("    14b    - interpret data as iso14443b communications"); 
 616         PrintAndLog("    iclass - interpret data as iclass communications"); 
 617         PrintAndLog("    topaz  - interpret data as topaz communications"); 
 618         PrintAndLog("    7816   - interpret data as iso7816-4 communications"); 
 620         PrintAndLog("example:   hf list 14a f"); 
 621         PrintAndLog("                   hf list iclass"); 
 624 int usage_hf_search(){ 
 625         PrintAndLog("Usage: hf search"); 
 626         PrintAndLog("Will try to find a HF read out of the unknown tag. Stops when found."); 
 627         PrintAndLog("Options:"); 
 628         PrintAndLog("       h   - This help"); 
 632 int usage_hf_snoop(){ 
 633         PrintAndLog("Usage: hf snoop <skip pairs> <skip triggers>"); 
 634         PrintAndLog("The high frequence snoop will assign all available memory on device for snooped data"); 
 635         PrintAndLog("User the 'data samples' command to download from device,  and 'data plot' to look at it"); 
 636         PrintAndLog("Press button to quit the snooping."); 
 637         PrintAndLog("Options:"); 
 638         PrintAndLog("       h                           - This help"); 
 639         PrintAndLog("       <skip pairs>        - skip sample pairs"); 
 640         PrintAndLog("       <skip triggers>     - skip number of triggers"); 
 642         PrintAndLog("example:   hf snoop"); 
 643         PrintAndLog("           hf snoop 1000 0"); 
 647 int CmdHFList(const char *Cmd
) 
 649         clearCommandBuffer(); 
 651         bool showWaitCycles 
= false; 
 652         bool markCRCBytes 
= false; 
 654         //int tlen = param_getstr(Cmd,0,type); 
 655         char param1 
= param_getchar(Cmd
, 1); 
 656         char param2 
= param_getchar(Cmd
, 2); 
 658         uint8_t protocol 
= 0; 
 660         //Validate params H or empty 
 661         if (strlen(Cmd
) < 1 || param1 
== 'h' || param1 
== 'H') return usage_hf_list(); 
 663         //Validate params  F,C 
 665                 (param1 
!= 0 && param1 
!= 'f' && param1 
!= 'c') ||  
 666                 (param2 
!= 0 && param2 
!= 'f' && param2 
!= 'c') 
 668                 return usage_hf_list(); 
 671         param_getstr(Cmd
,0,type
); 
 673         // validate type of output 
 674         if(strcmp(type
, "iclass") == 0)         protocol 
= ICLASS
; 
 675         else if(strcmp(type
, "14a") == 0)       protocol 
= ISO_14443A
; 
 676         else if(strcmp(type
, "14b") == 0)       protocol 
= ISO_14443B
; 
 677         else if(strcmp(type
, "topaz")== 0)      protocol 
= TOPAZ
; 
 678         else if(strcmp(type
, "7816")== 0)       protocol 
= ISO_7816_4
;                   
 679         else if(strcmp(type
, "raw")== 0)        protocol 
= -1;//No crc, no annotations 
 682         if (errors
) return usage_hf_list(); 
 684         if (param1 
== 'f' || param2 
== 'f') showWaitCycles 
= true; 
 685         if (param1 
== 'c' || param2 
== 'c') markCRCBytes 
= true; 
 688         uint16_t tracepos 
= 0; 
 689         trace 
= malloc(USB_CMD_DATA_SIZE
); 
 691         // Query for the size of the trace 
 693         GetFromBigBuf(trace
, USB_CMD_DATA_SIZE
, 0); 
 694         WaitForResponse(CMD_ACK
, &response
); 
 695         uint16_t traceLen 
= response
.arg
[2]; 
 696         if (traceLen 
> USB_CMD_DATA_SIZE
) { 
 697                 uint8_t *p 
= realloc(trace
, traceLen
); 
 699                         PrintAndLog("Cannot allocate memory for trace"); 
 704                 GetFromBigBuf(trace
, traceLen
, 0); 
 705                 WaitForResponse(CMD_ACK
, NULL
); 
 708         PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen
); 
 710         PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); 
 711         PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)"); 
 712         PrintAndLog("iClass    - Timings are not as accurate"); 
 714     PrintAndLog("      Start |        End | Src | Data (! denotes parity error)                                   | CRC | Annotation         |"); 
 715         PrintAndLog("------------|------------|-----|-----------------------------------------------------------------|-----|--------------------|"); 
 717         while(tracepos 
< traceLen
) 
 719                 tracepos 
= printTraceLine(tracepos
, traceLen
, trace
, protocol
, showWaitCycles
, markCRCBytes
); 
 726 int CmdHFSearch(const char *Cmd
){ 
 728         char cmdp 
= param_getchar(Cmd
, 0);       
 729         if (cmdp 
== 'h' || cmdp 
== 'H') return usage_hf_search(); 
 732         int ans 
= CmdHF14AReader("s"); 
 735                 PrintAndLog("\nValid ISO14443A Tag Found - Quiting Search\n"); 
 738         ans 
= HF14BInfo(false); 
 740                 PrintAndLog("\nValid ISO14443B Tag Found - Quiting Search\n"); 
 743         ans 
= HFiClassReader("", false, false); 
 745                 PrintAndLog("\nValid iClass Tag (or PicoPass Tag) Found - Quiting Search\n"); 
 748         ans 
= HF15Reader("", false); 
 750                 PrintAndLog("\nValid ISO15693 Tag Found - Quiting Search\n"); 
 753         ans 
= CmdHFTopazReader(""); 
 755                 PrintAndLog("\nValid Topaz Tag Found - Quiting Search\n"); 
 758         PrintAndLog("\nno known/supported 13.56 MHz tags found\n"); 
 762 int CmdHFSnoop(const char *Cmd
) 
 764         char cmdp 
= param_getchar(Cmd
, 0);       
 765         if (cmdp 
== 'h' || cmdp 
== 'H') return usage_hf_snoop(); 
 767         int skippairs 
=  param_get32ex(Cmd
, 0, 0, 10); 
 768         int skiptriggers 
=  param_get32ex(Cmd
, 1, 0, 10); 
 770         UsbCommand c 
= {CMD_HF_SNIFFER
, {skippairs
,skiptriggers
,0}}; 
 771         clearCommandBuffer(); 
 776 static command_t CommandTable
[] = { 
 777         {"help",        CmdHelp
,          1, "This help"}, 
 778         {"14a",         CmdHF14A
,         1, "{ ISO14443A RFIDs... }"}, 
 779         {"14b",         CmdHF14B
,         1, "{ ISO14443B RFIDs... }"}, 
 780         {"15",          CmdHF15
,          1, "{ ISO15693 RFIDs... }"}, 
 781         {"epa",         CmdHFEPA
,         1, "{ German Identification Card... }"}, 
 782         {"legic",       CmdHFLegic
,       0, "{ LEGIC RFIDs... }"}, 
 783         {"iclass",      CmdHFiClass
,      1, "{ ICLASS RFIDs... }"}, 
 784         {"mf",          CmdHFMF
,                  1, "{ MIFARE RFIDs... }"}, 
 785         {"mfu",         CmdHFMFUltra
,     1, "{ MIFARE Ultralight RFIDs... }"}, 
 786         {"mfdes",               CmdHFMFDes
,               1, "{ MIFARE Desfire RFIDs... }"}, 
 787         {"topaz",               CmdHFTopaz
,               1, "{ TOPAZ (NFC Type 1) RFIDs... }"}, 
 788         {"tune",                CmdHFTune
,            0, "Continuously measure HF antenna tuning"}, 
 789         {"list",        CmdHFList
,        1, "List protocol data in trace buffer"}, 
 790         {"search",      CmdHFSearch
,      1, "Search for known HF tags [preliminary]"}, 
 791         {"snoop",       CmdHFSnoop
,       0, "<samples to skip (10000)> <triggers to skip (1)> Generic LF/HF Snoop in Testing stage"}, 
 792         {NULL
, NULL
, 0, NULL
} 
 795 int CmdHF(const char *Cmd
) { 
 796         clearCommandBuffer(); 
 797         CmdsParse(CommandTable
, Cmd
); 
 801 int CmdHelp(const char *Cmd
) { 
 802         CmdsHelp(CommandTable
);