1 //----------------------------------------------------------------------------- 
   3 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   4 // at your option, any later version. See the LICENSE.txt file for the text of 
   6 //----------------------------------------------------------------------------- 
   7 // Low frequency T55xx commands 
   8 //----------------------------------------------------------------------------- 
  14 #include "proxmark3.h" 
  18 #include "cmdparser.h" 
  21 #include "cmdlft55xx.h" 
  25 #include "../common/crc.h" 
  26 #include "../common/iso14443crc.h" 
  29 #define T55x7_CONFIGURATION_BLOCK 0x00 
  30 #define T55x7_PAGE0 0x00 
  31 #define T55x7_PAGE1 0x01 
  32 #define T55x7_PWD       0x00000010 
  33 #define REGULAR_READ_MODE_BLOCK 0xFF 
  35 // Default configuration 
  36 t55xx_conf_block_t config 
= { .modulation 
= DEMOD_ASK
, .inverted 
= FALSE
, .offset 
= 0x00, .block0 
= 0x00, .Q5 
= FALSE 
}; 
  38 t55xx_conf_block_t 
Get_t55xx_Config(){ 
  41 void Set_t55xx_Config(t55xx_conf_block_t conf
){ 
  45 int usage_t55xx_config(){ 
  46         PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>] [Q5]"); 
  47         PrintAndLog("Options:"); 
  48         PrintAndLog("       h                        This help"); 
  49         PrintAndLog("       b <8|16|32|40|50|64|100|128>     Set bitrate"); 
  50         PrintAndLog("       d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa>  Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A"); 
  51         PrintAndLog("       i [1]                            Invert data signal, defaults to normal"); 
  52         PrintAndLog("       o [offset]                       Set offset, where data should start decode in bitstream"); 
  53         PrintAndLog("       Q5                            Set as Q5(T5555) chip instead of T55x7"); 
  55         PrintAndLog("Examples:"); 
  56         PrintAndLog("      lf t55xx config d FSK          - FSK demodulation"); 
  57         PrintAndLog("      lf t55xx config d FSK i 1      - FSK demodulation, inverse data"); 
  58         PrintAndLog("      lf t55xx config d FSK i 1 o 3  - FSK demodulation, inverse data, offset=3,start from position 3 to decode data"); 
  62 int usage_t55xx_read(){ 
  63         PrintAndLog("Usage:  lf t55xx read [b <block>] [p <password>] <override_safety> <page1>"); 
  64         PrintAndLog("Options:"); 
  65         PrintAndLog("     b <block>    - block number to read. Between 0-7"); 
  66         PrintAndLog("     p <password> - OPTIONAL password (8 hex characters)"); 
  67         PrintAndLog("     o            - OPTIONAL override safety check"); 
  68         PrintAndLog("     1            - OPTIONAL read Page 1 instead of Page 0"); 
  69         PrintAndLog("     ****WARNING****"); 
  70         PrintAndLog("     Use of read with password on a tag not configured for a pwd"); 
  71         PrintAndLog("     can damage the tag"); 
  73         PrintAndLog("Examples:"); 
  74     PrintAndLog("      lf t55xx read b 0                                - read data from block 0"); 
  75         PrintAndLog("      lf t55xx read b 0 p feedbeef         - read data from block 0 password feedbeef"); 
  76         PrintAndLog("      lf t55xx read b 0 p feedbeef o       - read data from block 0 password feedbeef safety check"); 
  80 int usage_t55xx_write(){ 
  81         PrintAndLog("Usage:  lf t55xx wr [b <block>] [d <data>] [p <password>] [1]"); 
  82         PrintAndLog("Options:"); 
  83         PrintAndLog("     b <block>    - block number to write. Between 0-7"); 
  84         PrintAndLog("     d <data>     - 4 bytes of data to write (8 hex characters)"); 
  85         PrintAndLog("     p <password> - OPTIONAL password 4bytes (8 hex characters)"); 
  86         PrintAndLog("     1            - OPTIONAL write Page 1 instead of Page 0"); 
  88         PrintAndLog("Examples:"); 
  89         PrintAndLog("      lf t55xx write b 3 d 11223344            - write 11223344 to block 3"); 
  90         PrintAndLog("      lf t55xx write b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef"); 
  94 int usage_t55xx_trace() { 
  95         PrintAndLog("Usage:  lf t55xx trace [1]"); 
  96         PrintAndLog("Options:"); 
  97         PrintAndLog("     [graph buffer data]  - if set, use Graphbuffer otherwise read data from tag."); 
  99         PrintAndLog("Examples:"); 
 100         PrintAndLog("      lf t55xx trace"); 
 101         PrintAndLog("      lf t55xx trace 1"); 
 105 int usage_t55xx_info() { 
 106         PrintAndLog("Usage:  lf t55xx info [1]"); 
 107         PrintAndLog("Options:"); 
 108         PrintAndLog("     [graph buffer data]  - if set, use Graphbuffer otherwise read data from tag."); 
 110         PrintAndLog("Examples:"); 
 111         PrintAndLog("      lf t55xx info"); 
 112         PrintAndLog("      lf t55xx info 1"); 
 116 int usage_t55xx_dump(){ 
 117         PrintAndLog("Usage:  lf t55xx dump <password> [o]"); 
 118         PrintAndLog("Options:"); 
 119         PrintAndLog("     <password>  - OPTIONAL password 4bytes (8 hex symbols)"); 
 120         PrintAndLog("     o           - OPTIONAL override, force pwd read despite danger to card"); 
 122         PrintAndLog("Examples:"); 
 123         PrintAndLog("      lf t55xx dump"); 
 124         PrintAndLog("      lf t55xx dump feedbeef o"); 
 128 int usage_t55xx_detect(){ 
 129         PrintAndLog("Usage:  lf t55xx detect [1] [p <password>]"); 
 130         PrintAndLog("Options:"); 
 131         PrintAndLog("     1             - if set, use Graphbuffer otherwise read data from tag."); 
 132         PrintAndLog("     p <password>  - OPTIONAL password (8 hex characters)"); 
 134         PrintAndLog("Examples:"); 
 135         PrintAndLog("      lf t55xx detect"); 
 136         PrintAndLog("      lf t55xx detect 1"); 
 137         PrintAndLog("      lf t55xx detect p 11223344"); 
 141 int usage_t55xx_wakup(){ 
 142         PrintAndLog("Usage:  lf t55xx wakeup [h] p <password>"); 
 143         PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards."); 
 144         PrintAndLog("Options:"); 
 145         PrintAndLog("     h                     - this help"); 
 146     PrintAndLog("     p <password>      - password 4bytes (8 hex symbols)"); 
 148         PrintAndLog("Examples:"); 
 149     PrintAndLog("      lf t55xx wakeup p 11223344  - send wakeup password"); 
 152 int usage_t55xx_bruteforce(){ 
 153     PrintAndLog("Usage: lf t55xx bruteforce <start password> <end password> [i <*.dic>]"); 
 154     PrintAndLog("       password must be 4 bytes (8 hex symbols)"); 
 155         PrintAndLog("Options:"); 
 156         PrintAndLog("     h                     - this help"); 
 157     PrintAndLog("     i <*.dic> - loads a default keys dictionary file <*.dic>"); 
 159     PrintAndLog("Examples:"); 
 160     PrintAndLog("       lf t55xx bruteforce aaaaaaaa bbbbbbbb"); 
 161         PrintAndLog("       lf t55xx bruteforce i mykeys.dic"); 
 166 static int CmdHelp(const char *Cmd
); 
 168 void printT5xxHeader(uint8_t page
){ 
 169         PrintAndLog("Reading Page %d:", page
);   
 170         PrintAndLog("blk | hex data | binary"); 
 171         PrintAndLog("----+----------+---------------------------------");        
 174 int CmdT55xxSetConfig(const char *Cmd
) { 
 177         char modulation
[5] = {0x00}; 
 180         uint8_t rates
[9] = {8,16,32,40,50,64,100,128,0}; 
 184         while(param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) 
 186                 tmp 
= param_getchar(Cmd
, cmdp
); 
 191                         return usage_t55xx_config(); 
 193                         errors 
|= param_getdec(Cmd
, cmdp
+1, &bitRate
); 
 197                                         if (rates
[i
]==bitRate
) { 
 202                                 if (i
==9) errors 
= TRUE
; 
 207                         param_getstr(Cmd
, cmdp
+1, modulation
); 
 210                         if ( strcmp(modulation
, "FSK" ) == 0) { 
 211                                 config
.modulation 
= DEMOD_FSK
; 
 212                         } else if ( strcmp(modulation
, "FSK1" ) == 0) { 
 213                                 config
.modulation 
= DEMOD_FSK1
; 
 215                         } else if ( strcmp(modulation
, "FSK1a" ) == 0) { 
 216                                 config
.modulation 
= DEMOD_FSK1a
; 
 218                         } else if ( strcmp(modulation
, "FSK2" ) == 0) { 
 219                                 config
.modulation 
= DEMOD_FSK2
; 
 221                         } else if ( strcmp(modulation
, "FSK2a" ) == 0) { 
 222                                 config
.modulation 
= DEMOD_FSK2a
; 
 224                         } else if ( strcmp(modulation
, "ASK" ) == 0) { 
 225                                 config
.modulation 
= DEMOD_ASK
; 
 226                         } else if ( strcmp(modulation
, "NRZ" ) == 0) { 
 227                                 config
.modulation 
= DEMOD_NRZ
; 
 228                         } else if ( strcmp(modulation
, "PSK1" ) == 0) { 
 229                                 config
.modulation 
= DEMOD_PSK1
; 
 230                         } else if ( strcmp(modulation
, "PSK2" ) == 0) { 
 231                                 config
.modulation 
= DEMOD_PSK2
; 
 232                         } else if ( strcmp(modulation
, "PSK3" ) == 0) { 
 233                                 config
.modulation 
= DEMOD_PSK3
; 
 234                         } else if ( strcmp(modulation
, "BIa" ) == 0) { 
 235                                 config
.modulation 
= DEMOD_BIa
; 
 237                         } else if ( strcmp(modulation
, "BI" ) == 0) { 
 238                                 config
.modulation 
= DEMOD_BI
; 
 241                                 PrintAndLog("Unknown modulation '%s'", modulation
); 
 246                         config
.inverted 
= param_getchar(Cmd
,cmdp
+1) == '1'; 
 250                         errors 
|= param_getdec(Cmd
, cmdp
+1, &offset
); 
 252                                 config
.offset 
= offset
; 
 261                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 268         if (cmdp 
== 0) return printConfiguration( config 
); 
 271         if (errors
) return usage_t55xx_config(); 
 274         return printConfiguration ( config 
); 
 277 int T55xxReadBlock(uint8_t block
, bool page1
, bool usepwd
, bool override
, uint32_t password
){ 
 280                 // try reading the config block and verify that PWD bit is set before doing this! 
 283                         if ( !AquireData(T55x7_PAGE0
, T55x7_CONFIGURATION_BLOCK
, false, 0 ) ) return 0; 
 285                         if ( !tryDetectModulation() ) { 
 286                                 PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits."); 
 289                                 PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password...");    
 294                         PrintAndLog("Safety Check Overriden - proceeding despite risk"); 
 298         if (!AquireData(page1
, block
, usepwd
, password
) ) return 0; 
 299         if (!DecodeT55xxBlock()) return 0; 
 302         sprintf(blk
,"%02d", block
); 
 303         printT55xxBlock(blk
);    
 307 int CmdT55xxReadBlock(const char *Cmd
) { 
 308         uint8_t block 
= REGULAR_READ_MODE_BLOCK
; 
 309         uint32_t password 
= 0; //default to blank Block 7 
 311         bool override 
= false; 
 315         while(param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) { 
 316                 switch(param_getchar(Cmd
, cmdp
)) { 
 319                         return usage_t55xx_read(); 
 322                         errors 
|= param_getdec(Cmd
, cmdp
+1, &block
); 
 332                         password 
= param_get32ex(Cmd
, cmdp
+1, 0, 16); 
 341                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 346         if (errors
) return usage_t55xx_read(); 
 348         if (block 
> 7 && block 
!= REGULAR_READ_MODE_BLOCK       
) { 
 349                 PrintAndLog("Block must be between 0 and 7"); 
 353         printT5xxHeader(page1
); 
 354         return T55xxReadBlock(block
, page1
, usepwd
, override
, password
); 
 357 bool DecodeT55xxBlock(){ 
 359         char buf
[30] = {0x00}; 
 362         uint8_t bitRate
[8] = {8,16,32,40,50,64,100,128}; 
 363         DemodBufferLen 
= 0x00; 
 365         switch( config
.modulation 
){ 
 367                         snprintf(cmdStr
, sizeof(buf
),"%d %d", bitRate
[config
.bitrate
], config
.inverted 
); 
 368                         ans 
= FSKrawDemod(cmdStr
, FALSE
); 
 372                         snprintf(cmdStr
, sizeof(buf
),"%d %d 8 5", bitRate
[config
.bitrate
], config
.inverted 
); 
 373                         ans 
= FSKrawDemod(cmdStr
, FALSE
); 
 377                         snprintf(cmdStr
, sizeof(buf
),"%d %d 10 8", bitRate
[config
.bitrate
], config
.inverted 
); 
 378                         ans 
= FSKrawDemod(cmdStr
, FALSE
); 
 381                         snprintf(cmdStr
, sizeof(buf
),"%d %d 1", bitRate
[config
.bitrate
], config
.inverted 
); 
 382                         ans 
= ASKDemod(cmdStr
, FALSE
, FALSE
, 1); 
 385                         // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) 
 387                         snprintf(cmdStr
, sizeof(buf
),"%d %d 6", bitRate
[config
.bitrate
], config
.inverted 
); 
 388                         ans 
= PSKDemod(cmdStr
, FALSE
); 
 390                 case DEMOD_PSK2
: //inverted won't affect this 
 391                 case DEMOD_PSK3
: //not fully implemented 
 392                         // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) 
 394                         snprintf(cmdStr
, sizeof(buf
),"%d 0 6", bitRate
[config
.bitrate
] ); 
 395                         ans 
= PSKDemod(cmdStr
, FALSE
); 
 396                         psk1TOpsk2(DemodBuffer
, DemodBufferLen
); 
 399                         snprintf(cmdStr
, sizeof(buf
),"%d %d 1", bitRate
[config
.bitrate
], config
.inverted 
); 
 400                         ans 
= NRZrawDemod(cmdStr
, FALSE
); 
 404                         snprintf(cmdStr
, sizeof(buf
),"0 %d %d 1", bitRate
[config
.bitrate
], config
.inverted 
); 
 405                         ans 
= ASKbiphaseDemod(cmdStr
, FALSE
); 
 413 int CmdT55xxDetect(const char *Cmd
){ 
 418         uint32_t password 
= 0; 
 421         while(param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) { 
 422                 switch(param_getchar(Cmd
, cmdp
)) { 
 425                         return usage_t55xx_detect(); 
 428                         password 
= param_get32ex(Cmd
, cmdp
+1, 0, 16); 
 433                         // use Graphbuffer data 
 438                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 443         if (errors
) return usage_t55xx_detect(); 
 446                 if ( !AquireData(T55x7_PAGE0
, T55x7_CONFIGURATION_BLOCK
, usepwd
, password
) ) 
 450         if ( !tryDetectModulation() ) 
 451                 PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); 
 456 // detect configuration? 
 457 bool tryDetectModulation(){ 
 459         t55xx_conf_block_t tests
[15]; 
 461         uint8_t fc1 
= 0, fc2 
= 0, clk
=0; 
 464         if (GetFskClock("", FALSE
, FALSE
)){  
 465                 fskClocks(&fc1
, &fc2
, &clk
, FALSE
); 
 466                 if ( FSKrawDemod("0 0", FALSE
) && test(DEMOD_FSK
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)){ 
 467                         tests
[hits
].modulation 
= DEMOD_FSK
; 
 468                         if (fc1
==8 && fc2 
== 5) 
 469                                 tests
[hits
].modulation 
= DEMOD_FSK1a
; 
 470                         else if (fc1
==10 && fc2 
== 8) 
 471                                 tests
[hits
].modulation 
= DEMOD_FSK2
; 
 472                         tests
[hits
].bitrate 
= bitRate
; 
 473                         tests
[hits
].inverted 
= FALSE
; 
 474                         tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 477                 if ( FSKrawDemod("0 1", FALSE
) && test(DEMOD_FSK
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)) { 
 478                         tests
[hits
].modulation 
= DEMOD_FSK
; 
 479                         if (fc1 
== 8 && fc2 
== 5) 
 480                                 tests
[hits
].modulation 
= DEMOD_FSK1
; 
 481                         else if (fc1 
== 10 && fc2 
== 8) 
 482                                 tests
[hits
].modulation 
= DEMOD_FSK2a
; 
 484                         tests
[hits
].bitrate 
= bitRate
; 
 485                         tests
[hits
].inverted 
= TRUE
; 
 486                         tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 490                 clk 
= GetAskClock("", FALSE
, FALSE
); 
 492                         if ( ASKDemod("0 0 1", FALSE
, FALSE
, 1) && test(DEMOD_ASK
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)) { 
 493                                 tests
[hits
].modulation 
= DEMOD_ASK
; 
 494                                 tests
[hits
].bitrate 
= bitRate
; 
 495                                 tests
[hits
].inverted 
= FALSE
; 
 496                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 499                         if ( ASKDemod("0 1 1", FALSE
, FALSE
, 1)  && test(DEMOD_ASK
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)) { 
 500                                 tests
[hits
].modulation 
= DEMOD_ASK
; 
 501                                 tests
[hits
].bitrate 
= bitRate
; 
 502                                 tests
[hits
].inverted 
= TRUE
; 
 503                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 506                         if ( ASKbiphaseDemod("0 0 0 2", FALSE
) && test(DEMOD_BI
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
) ) { 
 507                                 tests
[hits
].modulation 
= DEMOD_BI
; 
 508                                 tests
[hits
].bitrate 
= bitRate
; 
 509                                 tests
[hits
].inverted 
= FALSE
; 
 510                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 513                         if ( ASKbiphaseDemod("0 0 1 2", FALSE
) && test(DEMOD_BIa
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
) ) { 
 514                                 tests
[hits
].modulation 
= DEMOD_BIa
; 
 515                                 tests
[hits
].bitrate 
= bitRate
; 
 516                                 tests
[hits
].inverted 
= TRUE
; 
 517                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 523                 clk 
= GetNrzClock("", FALSE
, FALSE
); 
 525                         if ( NRZrawDemod("0 0 1", FALSE
)  && test(DEMOD_NRZ
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)) { 
 526                                 tests
[hits
].modulation 
= DEMOD_NRZ
; 
 527                                 tests
[hits
].bitrate 
= bitRate
; 
 528                                 tests
[hits
].inverted 
= FALSE
; 
 529                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 533                         if ( NRZrawDemod("0 1 1", FALSE
)  && test(DEMOD_NRZ
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)) { 
 534                                 tests
[hits
].modulation 
= DEMOD_NRZ
; 
 535                                 tests
[hits
].bitrate 
= bitRate
; 
 536                                 tests
[hits
].inverted 
= TRUE
; 
 537                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 544                 // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise) 
 546                 clk 
= GetPskClock("", FALSE
, FALSE
); 
 548                         if ( PSKDemod("0 0 6", FALSE
) && test(DEMOD_PSK1
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)) { 
 549                                 tests
[hits
].modulation 
= DEMOD_PSK1
; 
 550                                 tests
[hits
].bitrate 
= bitRate
; 
 551                                 tests
[hits
].inverted 
= FALSE
; 
 552                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 555                         if ( PSKDemod("0 1 6", FALSE
) && test(DEMOD_PSK1
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)) { 
 556                                 tests
[hits
].modulation 
= DEMOD_PSK1
; 
 557                                 tests
[hits
].bitrate 
= bitRate
; 
 558                                 tests
[hits
].inverted 
= TRUE
; 
 559                                 tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 562                         // PSK2 - needs a call to psk1TOpsk2. 
 563                         if ( PSKDemod("0 0 6", FALSE
)) { 
 564                                 psk1TOpsk2(DemodBuffer
, DemodBufferLen
); 
 565                                 if (test(DEMOD_PSK2
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)){ 
 566                                         tests
[hits
].modulation 
= DEMOD_PSK2
; 
 567                                         tests
[hits
].bitrate 
= bitRate
; 
 568                                         tests
[hits
].inverted 
= FALSE
; 
 569                                         tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 572                         } // inverse waves does not affect this demod 
 573                         // PSK3 - needs a call to psk1TOpsk2. 
 574                         if ( PSKDemod("0 0 6", FALSE
)) { 
 575                                 psk1TOpsk2(DemodBuffer
, DemodBufferLen
); 
 576                                 if (test(DEMOD_PSK3
, &tests
[hits
].offset
, &bitRate
, clk
, &tests
[hits
].Q5
)){ 
 577                                         tests
[hits
].modulation 
= DEMOD_PSK3
; 
 578                                         tests
[hits
].bitrate 
= bitRate
; 
 579                                         tests
[hits
].inverted 
= FALSE
; 
 580                                         tests
[hits
].block0 
= PackBits(tests
[hits
].offset
, 32, DemodBuffer
); 
 583                         } // inverse waves does not affect this demod 
 588                 config
.modulation 
= tests
[0].modulation
; 
 589                 config
.bitrate 
= tests
[0].bitrate
; 
 590                 config
.inverted 
= tests
[0].inverted
; 
 591                 config
.offset 
= tests
[0].offset
; 
 592                 config
.block0 
= tests
[0].block0
; 
 593                 printConfiguration( config 
); 
 598                 PrintAndLog("Found [%d] possible matches for modulation.",hits
); 
 599                 for(int i
=0; i
<hits
; ++i
){ 
 600                         PrintAndLog("--[%d]---------------", i
+1); 
 601                         printConfiguration( tests
[i
] ); 
 607 bool testModulation(uint8_t mode
, uint8_t modread
){ 
 610                         if (modread 
>= DEMOD_FSK1 
&& modread 
<= DEMOD_FSK2a
) return TRUE
; 
 613                         if (modread 
== DEMOD_ASK
) return TRUE
; 
 616                         if (modread 
== DEMOD_PSK1
) return TRUE
; 
 619                         if (modread 
== DEMOD_PSK2
) return TRUE
; 
 622                         if (modread 
== DEMOD_PSK3
) return TRUE
; 
 625                         if (modread 
== DEMOD_NRZ
) return TRUE
; 
 628                         if (modread 
== DEMOD_BI
) return TRUE
; 
 631                         if (modread 
== DEMOD_BIa
) return TRUE
; 
 639 bool testQ5Modulation(uint8_t   mode
, uint8_t   modread
){ 
 642                         if (modread 
>= 4 && modread 
<= 5) return TRUE
; 
 645                         if (modread 
== 0) return TRUE
; 
 648                         if (modread 
== 1) return TRUE
; 
 651                         if (modread 
== 2) return TRUE
; 
 654                         if (modread 
== 3) return TRUE
; 
 657                         if (modread 
== 7) return TRUE
; 
 660                         if (modread 
== 6) return TRUE
; 
 668 bool testQ5(uint8_t mode
, uint8_t *offset
, int *fndBitRate
, uint8_t     clk
){ 
 670         if ( DemodBufferLen 
< 64 ) return FALSE
; 
 672         for (uint8_t idx 
= 28; idx 
< 64; idx
++){ 
 674                 if ( PackBits(si
, 28, DemodBuffer
) == 0x00 ) continue; 
 676                 uint8_t safer     
= PackBits(si
, 4, DemodBuffer
); si 
+= 4;     //master key 
 677                 uint8_t resv      
= PackBits(si
, 8, DemodBuffer
); si 
+= 8; 
 678                 // 2nibble must be zeroed. 
 679                 if (safer 
!= 0x6) continue; 
 680                 if ( resv 
> 0x00) continue; 
 681                 //uint8_t       pageSel   = PackBits(si, 1, DemodBuffer); si += 1; 
 682                 //uint8_t fastWrite = PackBits(si, 1, DemodBuffer); si += 1; 
 684                 int bitRate       
= PackBits(si
, 5, DemodBuffer
)*2 + 2; si 
+= 5;     //bit rate 
 685                 if (bitRate 
> 128 || bitRate 
< 8) continue; 
 687                 //uint8_t AOR       = PackBits(si, 1, DemodBuffer); si += 1;    
 688                 //uint8_t PWD       = PackBits(si, 1, DemodBuffer); si += 1;  
 689                 //uint8_t pskcr     = PackBits(si, 2, DemodBuffer); si += 2;  //could check psk cr 
 690                 //uint8_t inverse   = PackBits(si, 1, DemodBuffer); si += 1; 
 692                 uint8_t modread   
= PackBits(si
, 3, DemodBuffer
); si 
+= 3; 
 693                 uint8_t maxBlk    
= PackBits(si
, 3, DemodBuffer
); si 
+= 3; 
 694                 //uint8_t ST        = PackBits(si, 1, DemodBuffer); si += 1; 
 695                 if (maxBlk 
== 0) continue; 
 697                 if (!testQ5Modulation(mode
, modread
)) continue; 
 698                 if (bitRate 
!= clk
) continue; 
 699                 *fndBitRate 
= bitRate
; 
 707 bool testBitRate(uint8_t readRate
, uint8_t clk
){ 
 708         uint8_t expected
[] = {8, 16, 32, 40, 50, 64, 100, 128}; 
 709         if (expected
[readRate
] == clk
) 
 715 bool test(uint8_t mode
, uint8_t *offset
, int *fndBitRate
, uint8_t clk
, bool *Q5
){ 
 717         if ( DemodBufferLen 
< 64 ) return FALSE
; 
 719         for (uint8_t idx 
= 28; idx 
< 64; idx
++){ 
 721                 if ( PackBits(si
, 28, DemodBuffer
) == 0x00 ) continue; 
 723                 uint8_t safer    
= PackBits(si
, 4, DemodBuffer
); si 
+= 4;     //master key 
 724                 uint8_t resv     
= PackBits(si
, 4, DemodBuffer
); si 
+= 4;     //was 7 & +=7+3 //should be only 4 bits if extended mode 
 725                 // 2nibble must be zeroed. 
 726                 // moved test to here, since this gets most faults first. 
 727                 if ( resv 
> 0x00) continue; 
 729                 uint8_t xtRate   
= PackBits(si
, 3, DemodBuffer
); si 
+= 3;     //extended mode part of rate 
 730                 int bitRate  
= PackBits(si
, 3, DemodBuffer
); si 
+= 3;     //bit rate 
 731                 if (bitRate 
> 7) continue; 
 732                 uint8_t extend   
= PackBits(si
, 1, DemodBuffer
); si 
+= 1;     //bit 15 extended mode 
 733                 uint8_t modread  
= PackBits(si
, 5, DemodBuffer
); si 
+= 5+2+1;  
 734                 //uint8_t pskcr   = PackBits(si, 2, DemodBuffer); si += 2+1;  //could check psk cr 
 735                 uint8_t nml01    
= PackBits(si
, 1, DemodBuffer
); si 
+= 1+5;   //bit 24, 30, 31 could be tested for 0 if not extended mode 
 736                 uint8_t nml02    
= PackBits(si
, 2, DemodBuffer
); si 
+= 2; 
 739                 bool extMode 
=( (safer 
== 0x6 || safer 
== 0x9) && extend
) ? TRUE 
: FALSE
; 
 742                         if (nml01 
|| nml02 
|| xtRate
) continue; 
 745                 if (!testModulation(mode
, modread
)) continue; 
 746                 if (!testBitRate(bitRate
, clk
)) continue; 
 747                 *fndBitRate 
= bitRate
; 
 752         if (testQ5(mode
, offset
, fndBitRate
, clk
)) { 
 759 void printT55xxBlock(const char *blockNum
){ 
 761         uint8_t i 
= config
.offset
; 
 762         uint8_t endpos 
= 32 + i
; 
 763         uint32_t blockData 
= 0; 
 764         uint8_t bits
[64] = {0x00}; 
 766         if ( !DemodBufferLen
) return; 
 768         if ( endpos 
> DemodBufferLen
){ 
 769                 PrintAndLog("The configured offset %d is too big. Possible offset: %d)", i
, DemodBufferLen
-32); 
 773         for (; i 
< endpos
; ++i
) 
 774                 bits
[i 
- config
.offset
] = DemodBuffer
[i
]; 
 776         blockData 
= PackBits(0, 32, bits
); 
 778         PrintAndLog(" %s | %08X | %s", blockNum
, blockData
, sprint_bin(bits
,32)); 
 781 int special(const char *Cmd
) { 
 782         uint32_t blockData 
= 0; 
 783         uint8_t bits
[32] = {0x00}; 
 785         PrintAndLog("OFFSET | DATA  | BINARY"); 
 786         PrintAndLog("----------------------------------------------------"); 
 790                 for (i 
= 0; i 
< 32; ++i
) 
 791                         bits
[i
]=DemodBuffer
[j
+i
]; 
 793                 blockData 
= PackBits(0, 32, bits
); 
 795                 PrintAndLog("%02d | 0x%08X | %s",j 
, blockData
, sprint_bin(bits
,32));    
 800 int printConfiguration( t55xx_conf_block_t b
){ 
 801         PrintAndLog("Chip Type  : %s", (b
.Q5
) ? "T5555(Q5)" : "T55x7"); 
 802         PrintAndLog("Modulation : %s", GetSelectedModulationStr(b
.modulation
) ); 
 803         PrintAndLog("Bit Rate   : %s", GetBitRateStr(b
.bitrate
) ); 
 804         PrintAndLog("Inverted   : %s", (b
.inverted
) ? "Yes" : "No" ); 
 805         PrintAndLog("Offset     : %d", b
.offset
); 
 806         PrintAndLog("Block0     : 0x%08X", b
.block0
); 
 811 int CmdT55xxWakeUp(const char *Cmd
) { 
 812         uint32_t password 
= 0; 
 815         while(param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) { 
 816                 switch(param_getchar(Cmd
, cmdp
)) { 
 819                         return usage_t55xx_wakup(); 
 822                         password 
= param_get32ex(Cmd
, cmdp
+1, 0, 16); 
 827                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 832         if (errors
) return usage_t55xx_wakup(); 
 834         UsbCommand c 
= {CMD_T55XX_WAKEUP
, {password
, 0, 0}}; 
 835         clearCommandBuffer(); 
 837         PrintAndLog("Wake up command sent. Try read now"); 
 841 int CmdT55xxWriteBlock(const char *Cmd
) { 
 842         uint8_t block 
= 0xFF; //default to invalid block 
 843         uint32_t data 
= 0; //default to blank Block  
 844         uint32_t password 
= 0; //default to blank Block 7 
 847         bool gotdata 
= false; 
 850         while(param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) { 
 851                 switch(param_getchar(Cmd
, cmdp
)) { 
 854                         return usage_t55xx_write(); 
 857                         errors 
|= param_getdec(Cmd
, cmdp
+1, &block
); 
 862                         data 
= param_get32ex(Cmd
, cmdp
+1, 0, 16); 
 868                         password 
= param_get32ex(Cmd
, cmdp
+1, 0, 16); 
 877                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
 882         if (errors 
|| !gotdata
) return usage_t55xx_write(); 
 885                 PrintAndLog("Block number must be between 0 and 7"); 
 889         UsbCommand c 
= {CMD_T55XX_WRITE_BLOCK
, {data
, block
, 0}}; 
 891         c
.d
.asBytes
[0] = (page1
) ? 0x2 : 0;  
 893         char pwdStr
[16] = {0}; 
 894         snprintf(pwdStr
, sizeof(pwdStr
), "pwd: 0x%08X", password
); 
 896         PrintAndLog("Writing page %d  block: %02d  data: 0x%08X %s", page1
, block
, data
,  (usepwd
) ? pwdStr 
: "" ); 
 901                 c
.d
.asBytes
[0] |= 0x1;  
 903         clearCommandBuffer(); 
 905         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1000)){ 
 906                 PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)"); 
 912 int CmdT55xxReadTrace(const char *Cmd
) { 
 913         char cmdp 
= param_getchar(Cmd
, 0); 
 914         bool pwdmode 
= false; 
 915         uint32_t password 
= 0;   
 916         if (strlen(Cmd
) > 1 || cmdp 
== 'h' || cmdp 
== 'H') return usage_t55xx_trace(); 
 919                 if ( !AquireData( T55x7_PAGE1
, REGULAR_READ_MODE_BLOCK
, pwdmode
, password 
) ) 
 922         if (!DecodeT55xxBlock()) return 0; 
 924         if ( !DemodBufferLen
) return 0; 
 926         RepaintGraphWindow(); 
 928         if (config
.offset 
> 5)  
 930         uint8_t si 
= config
.offset
+repeat
; 
 931         uint32_t bl1     
= PackBits(si
, 32, DemodBuffer
); 
 932         uint32_t bl2     
= PackBits(si
+32, 32, DemodBuffer
); 
 934         uint32_t acl     
= PackBits(si
, 8,  DemodBuffer
); si 
+= 8; 
 935         uint32_t mfc     
= PackBits(si
, 8,  DemodBuffer
); si 
+= 8; 
 936         uint32_t cid     
= PackBits(si
, 5,  DemodBuffer
); si 
+= 5; 
 937         uint32_t icr     
= PackBits(si
, 3,  DemodBuffer
); si 
+= 3; 
 938         uint32_t year    
= PackBits(si
, 4,  DemodBuffer
); si 
+= 4; 
 939         uint32_t quarter 
= PackBits(si
, 2,  DemodBuffer
); si 
+= 2; 
 940         uint32_t lotid   
= PackBits(si
, 14, DemodBuffer
); si 
+= 14; 
 941         uint32_t wafer   
= PackBits(si
, 5,  DemodBuffer
); si 
+= 5; 
 942         uint32_t dw      
= PackBits(si
, 15, DemodBuffer
);  
 944         time_t t 
= time(NULL
); 
 945         struct tm tm 
= *localtime(&t
); 
 946         if ( year 
> tm
.tm_year
-110) 
 951         if (config
.Q5
) PrintAndLog("*** Warning *** Info read off a Q5 will not work as expected"); 
 953                 PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. "); 
 957         PrintAndLog("-- T55xx Trace Information ----------------------------------"); 
 958         PrintAndLog("-------------------------------------------------------------"); 
 959         PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1)  : 0x%02X (%d)", acl
, acl
); 
 960         PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6)    : 0x%02X (%d) - %s", mfc
, mfc
, getTagInfo(mfc
)); 
 961         PrintAndLog(" CID                                     : 0x%02X (%d) - %s", cid
, cid
, GetModelStrFromCID(cid
)); 
 962         PrintAndLog(" ICR IC Revision                         : %d",icr 
); 
 963         PrintAndLog(" Manufactured"); 
 964         PrintAndLog("     Year/Quarter : %d/%d",year
, quarter
); 
 965         PrintAndLog("     Lot ID       : %d", lotid 
); 
 966         PrintAndLog("     Wafer number : %d", wafer
); 
 967         PrintAndLog("     Die Number   : %d", dw
); 
 968         PrintAndLog("-------------------------------------------------------------"); 
 969         PrintAndLog(" Raw Data - Page 1"); 
 970         PrintAndLog("     Block 1  : 0x%08X  %s", bl1
, sprint_bin(DemodBuffer
+config
.offset
+repeat
,32) ); 
 971         PrintAndLog("     Block 2  : 0x%08X  %s", bl2
, sprint_bin(DemodBuffer
+config
.offset
+repeat
+32,32) ); 
 972         PrintAndLog("-------------------------------------------------------------"); 
 977                 1-8             ACL Allocation class (ISO/IEC 15963-1)  0xE0  
 978                 9-16    MFC Manufacturer ID (ISO/IEC 7816-6)    0x15 Atmel Corporation 
 979                 17-21   CID                                                                             0x1 = Atmel ATA5577M1  0x2 = Atmel ATA5577M2  
 980                 22-24   ICR IC revision 
 981                 25-28   YEAR (BCD encoded)                                              9 (= 2009) 
 982                 29-30   QUARTER                                                                 1,2,3,4  
 988                 18-32   DW,  die number sequential 
 994 int CmdT55xxInfo(const char *Cmd
){ 
 996                 Page 0 Block 0 Configuration data. 
1000         bool pwdmode 
= false; 
1001         uint32_t password 
= 0; 
1002         char cmdp 
= param_getchar(Cmd
, 0); 
1004         if (strlen(Cmd
) > 1 || cmdp 
== 'h' || cmdp 
== 'H') return usage_t55xx_info(); 
1007                 if ( !AquireData( T55x7_PAGE0
, T55x7_CONFIGURATION_BLOCK
, pwdmode
, password 
) ) 
1010         if (!DecodeT55xxBlock()) return 1; 
1012         if ( DemodBufferLen 
< 32) return 1; 
1014         uint8_t si 
= config
.offset
; 
1015         uint32_t bl0      
= PackBits(si
, 32, DemodBuffer
); 
1017         uint32_t safer    
= PackBits(si
, 4, DemodBuffer
); si 
+= 4;       
1018         uint32_t resv     
= PackBits(si
, 7, DemodBuffer
); si 
+= 7; 
1019         uint32_t dbr      
= PackBits(si
, 3, DemodBuffer
); si 
+= 3; 
1020         uint32_t extend   
= PackBits(si
, 1, DemodBuffer
); si 
+= 1; 
1021         uint32_t datamod  
= PackBits(si
, 5, DemodBuffer
); si 
+= 5; 
1022         uint32_t pskcf    
= PackBits(si
, 2, DemodBuffer
); si 
+= 2; 
1023         uint32_t aor      
= PackBits(si
, 1, DemodBuffer
); si 
+= 1;       
1024         uint32_t otp      
= PackBits(si
, 1, DemodBuffer
); si 
+= 1;       
1025         uint32_t maxblk   
= PackBits(si
, 3, DemodBuffer
); si 
+= 3; 
1026         uint32_t pwd      
= PackBits(si
, 1, DemodBuffer
); si 
+= 1;       
1027         uint32_t sst      
= PackBits(si
, 1, DemodBuffer
); si 
+= 1;       
1028         uint32_t fw       
= PackBits(si
, 1, DemodBuffer
); si 
+= 1; 
1029         uint32_t inv      
= PackBits(si
, 1, DemodBuffer
); si 
+= 1;       
1030         uint32_t por      
= PackBits(si
, 1, DemodBuffer
); si 
+= 1; 
1031         if (config
.Q5
) PrintAndLog("*** Warning *** Config Info read off a Q5 will not display as expected"); 
1033         PrintAndLog("-- T55xx Configuration & Tag Information --------------------"); 
1034         PrintAndLog("-------------------------------------------------------------"); 
1035         PrintAndLog(" Safer key                 : %s", GetSaferStr(safer
)); 
1036         PrintAndLog(" reserved                  : %d", resv
); 
1037         PrintAndLog(" Data bit rate             : %s", GetBitRateStr(dbr
)); 
1038         PrintAndLog(" eXtended mode             : %s", (extend
) ? "Yes - Warning":"No"); 
1039         PrintAndLog(" Modulation                : %s", GetModulationStr(datamod
)); 
1040         PrintAndLog(" PSK clock frequency       : %d", pskcf
); 
1041         PrintAndLog(" AOR - Answer on Request   : %s", (aor
) ? "Yes":"No"); 
1042         PrintAndLog(" OTP - One Time Pad        : %s", (otp
) ? "Yes - Warning":"No" ); 
1043         PrintAndLog(" Max block                 : %d", maxblk
); 
1044         PrintAndLog(" Password mode             : %s", (pwd
) ? "Yes":"No"); 
1045         PrintAndLog(" Sequence Start Terminator : %s", (sst
) ? "Yes":"No"); 
1046         PrintAndLog(" Fast Write                : %s", (fw
)  ? "Yes":"No"); 
1047         PrintAndLog(" Inverse data              : %s", (inv
) ? "Yes":"No"); 
1048         PrintAndLog(" POR-Delay                 : %s", (por
) ? "Yes":"No"); 
1049         PrintAndLog("-------------------------------------------------------------"); 
1050         PrintAndLog(" Raw Data - Page 0"); 
1051         PrintAndLog("     Block 0  : 0x%08X  %s", bl0
, sprint_bin(DemodBuffer
+config
.offset
,32) ); 
1052         PrintAndLog("-------------------------------------------------------------"); 
1057 int CmdT55xxDump(const char *Cmd
){ 
1059         uint32_t password 
= 0; 
1060         bool override 
= false; 
1061         char cmdp 
= param_getchar(Cmd
, 0);       
1062         if ( cmdp 
== 'h' || cmdp 
== 'H') return usage_t55xx_dump(); 
1064         bool usepwd 
= ( strlen(Cmd
) > 0);        
1066                 password 
= param_get32ex(Cmd
, 0, 0, 16); 
1067                 if (param_getchar(Cmd
, 1) =='o' ) 
1072         for ( uint8_t i 
= 0; i 
< 8; ++i
) 
1073                 T55xxReadBlock(i
, 0, usepwd
, override
, password
); 
1076         for ( uint8_t   i 
= 0; i 
< 4; i
++) 
1077                 T55xxReadBlock(i
, 1, usepwd
, override
, password
);                
1082 int AquireData( uint8_t page
, uint8_t block
, bool pwdmode
, uint32_t password 
){ 
1085         // bit1 = page to read from 
1086         uint8_t arg0 
= (page
<<1) | pwdmode
; 
1087         UsbCommand c 
= {CMD_T55XX_READ_BLOCK
, {arg0
, block
, password
}}; 
1089         clearCommandBuffer(); 
1091         if ( !WaitForResponseTimeout(CMD_ACK
,NULL
,2500) ) { 
1092                 PrintAndLog("command execution time out"); 
1097         GetFromBigBuf(got
,sizeof(got
),0); 
1098         WaitForResponse(CMD_ACK
,NULL
); 
1099         setGraphBuf(got
, sizeof(got
)); 
1103 char * GetBitRateStr(uint32_t id
){ 
1104         static char buf
[25]; 
1109                         snprintf(retStr
,sizeof(buf
),"%d - RF/8",id
); 
1112                         snprintf(retStr
,sizeof(buf
),"%d - RF/16",id
); 
1115                         snprintf(retStr
,sizeof(buf
),"%d - RF/32",id
); 
1118                         snprintf(retStr
,sizeof(buf
),"%d - RF/40",id
); 
1121                         snprintf(retStr
,sizeof(buf
),"%d - RF/50",id
); 
1124                         snprintf(retStr
,sizeof(buf
),"%d - RF/64",id
); 
1127                         snprintf(retStr
,sizeof(buf
),"%d - RF/100",id
); 
1130                         snprintf(retStr
,sizeof(buf
),"%d - RF/128",id
); 
1133                         snprintf(retStr
,sizeof(buf
),"%d - (Unknown)",id
); 
1140 char * GetSaferStr(uint32_t id
){ 
1141         static char buf
[40]; 
1144         snprintf(retStr
,sizeof(buf
),"%d",id
); 
1146                 snprintf(retStr
,sizeof(buf
),"%d - passwd",id
); 
1149                 snprintf(retStr
,sizeof(buf
),"%d - testmode",id
); 
1155 char * GetModulationStr( uint32_t id
){ 
1156         static char buf
[60]; 
1161                         snprintf(retStr
,sizeof(buf
),"%d - DIRECT (ASK/NRZ)",id
); 
1164                         snprintf(retStr
,sizeof(buf
),"%d - PSK 1 phase change when input changes",id
); 
1167                         snprintf(retStr
,sizeof(buf
),"%d - PSK 2 phase change on bitclk if input high",id
); 
1170                         snprintf(retStr
,sizeof(buf
),"%d - PSK 3 phase change on rising edge of input",id
); 
1173                         snprintf(retStr
,sizeof(buf
),"%d - FSK 1 RF/8  RF/5",id
); 
1176                         snprintf(retStr
,sizeof(buf
),"%d - FSK 2 RF/8  RF/10",id
); 
1179                         snprintf(retStr
,sizeof(buf
),"%d - FSK 1a RF/5  RF/8",id
); 
1182                         snprintf(retStr
,sizeof(buf
),"%d - FSK 2a RF/10  RF/8",id
); 
1185                         snprintf(retStr
,sizeof(buf
),"%d - Manchester",id
); 
1188                         snprintf(retStr
,sizeof(buf
),"%d - Biphase",id
); 
1191                         snprintf(retStr
,sizeof(buf
),"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id
); 
1194                         snprintf(retStr
,sizeof(buf
),"%d - Reserved",id
); 
1197                         snprintf(retStr
,sizeof(buf
),"0x%02X (Unknown)",id
); 
1203 char * GetModelStrFromCID(uint32_t cid
){ 
1205         static char buf
[10]; 
1208         if (cid 
== 1) snprintf(retStr
, sizeof(buf
),"ATA5577M1"); 
1209         if (cid 
== 2) snprintf(retStr
, sizeof(buf
),"ATA5577M2");         
1213 char * GetSelectedModulationStr( uint8_t id
){ 
1215         static char buf
[20]; 
1220                         snprintf(retStr
,sizeof(buf
),"FSK"); 
1223                         snprintf(retStr
,sizeof(buf
),"FSK1"); 
1226                         snprintf(retStr
,sizeof(buf
),"FSK1a"); 
1229                         snprintf(retStr
,sizeof(buf
),"FSK2"); 
1232                         snprintf(retStr
,sizeof(buf
),"FSK2a"); 
1235                         snprintf(retStr
,sizeof(buf
),"ASK"); 
1238                         snprintf(retStr
,sizeof(buf
),"DIRECT/NRZ"); 
1241                         snprintf(retStr
,sizeof(buf
),"PSK1"); 
1244                         snprintf(retStr
,sizeof(buf
),"PSK2"); 
1247                         snprintf(retStr
,sizeof(buf
),"PSK3"); 
1250                         snprintf(retStr
,sizeof(buf
),"BIPHASE"); 
1253                         snprintf(retStr
,sizeof(buf
),"BIPHASEa - (CDP)"); 
1256                         snprintf(retStr
,sizeof(buf
),"(Unknown)"); 
1262 void t55x7_create_config_block( int tagtype 
){ 
1265      T55X7_DEFAULT_CONFIG_BLOCK, T55X7_RAW_CONFIG_BLOCK 
1266      T55X7_EM_UNIQUE_CONFIG_BLOCK, T55X7_FDXB_CONFIG_BLOCK, 
1267          T55X7_FDXB_CONFIG_BLOCK, T55X7_HID_26_CONFIG_BLOCK, T55X7_INDALA_64_CONFIG_BLOCK, T55X7_INDALA_224_CONFIG_BLOCK  
1268          T55X7_GUARDPROXII_CONFIG_BLOCK, T55X7_VIKING_CONFIG_BLOCK,     T55X7_NORALYS_CONFIG_BLOCK, T55X7_IOPROX_CONFIG_BLOCK    
1270         static char buf
[60]; 
1274                 case 0: snprintf(retStr
, sizeof(buf
),"%08X - T55X7 Default", T55X7_DEFAULT_CONFIG_BLOCK
); break; 
1275                 case 1: snprintf(retStr
, sizeof(buf
),"%08X - T55X7 Raw", T55X7_RAW_CONFIG_BLOCK
); break; 
1282 int CmdResetRead(const char *Cmd
) { 
1283         UsbCommand c 
= {CMD_T55XX_RESET_READ
, {0,0,0}}; 
1285         clearCommandBuffer(); 
1287         if ( !WaitForResponseTimeout(CMD_ACK
,NULL
,2500) ) { 
1288                 PrintAndLog("command execution time out"); 
1292         uint8_t got
[BIGBUF_SIZE
-1]; 
1293         GetFromBigBuf(got
,sizeof(got
),0); 
1294         WaitForResponse(CMD_ACK
,NULL
); 
1295         setGraphBuf(got
, sizeof(got
)); 
1299 int CmdT55xxWipe(const char *Cmd
) { 
1300         char writeData
[20] = {0}; 
1301         char *ptrData 
= writeData
; 
1303         PrintAndLog("\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n"); 
1305         //try with the default password to reset block 0  (with a pwd should work even if pwd bit not set) 
1306         snprintf(ptrData
,sizeof(writeData
),"b 0 d 000880E0 p 0"); 
1308         if (!CmdT55xxWriteBlock(ptrData
)) 
1309                 PrintAndLog("Error writing blk 0"); 
1311         for (uint8_t blk 
= 1; blk
<8; blk
++) { 
1313                 snprintf(ptrData
,sizeof(writeData
),"b %d d 0", blk
); 
1315                 if (!CmdT55xxWriteBlock(ptrData
))  
1316                         PrintAndLog("Error writing blk %d", blk
); 
1318                 memset(writeData
, sizeof(writeData
), 0x00); 
1323 int CmdT55xxBruteForce(const char *Cmd
) { 
1325         // load a default pwd file. 
1327         char filename
[FILE_PATH_SIZE
]={0}; 
1329         uint8_t stKeyBlock 
= 20; 
1330         uint8_t *keyBlock 
= NULL
, *p
; 
1331         keyBlock 
= calloc(stKeyBlock
, 6); 
1332         if (keyBlock 
== NULL
) return 1; 
1334     uint32_t start_password 
= 0x00000000; //start password 
1335     uint32_t end_password   
= 0xFFFFFFFF; //end   password 
1338     char cmdp 
= param_getchar(Cmd
, 0); 
1339     if (cmdp 
== 'h' || cmdp 
== 'H') return usage_t55xx_bruteforce(); 
1341         if (cmdp 
== 'i' || cmdp 
== 'I') { 
1343                 int len 
= strlen(Cmd
+2); 
1344                 if (len 
> FILE_PATH_SIZE
) len 
= FILE_PATH_SIZE
; 
1345                 memcpy(filename
, Cmd
+2, len
); 
1347                 FILE * f 
= fopen( filename 
, "r"); 
1350                         PrintAndLog("File: %s: not found or locked.", filename
); 
1355                 while( fgets(buf
, sizeof(buf
), f
) ){ 
1356                         if (strlen(buf
) < 8 || buf
[7] == '\n') continue; 
1358                         while (fgetc(f
) != '\n' && !feof(f
)) ;  //goto next line 
1360                         //The line start with # is comment, skip 
1361                         if( buf
[0]=='#' ) continue; 
1363                         if (!isxdigit(buf
[0])){ 
1364                                 PrintAndLog("File content error. '%s' must include 8 HEX symbols", buf
); 
1370                         if ( stKeyBlock 
- keycnt 
< 2) { 
1371                                 p 
= realloc(keyBlock
, 6*(stKeyBlock
+=10)); 
1373                                         PrintAndLog("Cannot allocate memory for defaultKeys"); 
1379                         memset(keyBlock 
+ 4 * keycnt
, 0, 4); 
1380                         num_to_bytes(strtoll(buf
, NULL
, 16), 4, keyBlock 
+ 4*keycnt
); 
1381                         PrintAndLog("chk custom pwd[%2d] %08X", keycnt
, bytes_to_num(keyBlock 
+ 4*keycnt
, 4)); 
1383                         memset(buf
, 0, sizeof(buf
)); 
1388                         PrintAndLog("No keys found in file"); 
1391                 PrintAndLog("Loaded %d keys", keycnt
); 
1394                 uint64_t testpwd 
= 0x00; 
1395                 for (uint16_t c 
= 0; c 
< keycnt
; ++c 
) { 
1397                         testpwd 
= bytes_to_num(keyBlock 
+ 4*c
, 4); 
1399                         PrintAndLog("Testing %08X", testpwd
); 
1402                         if ( !AquireData(T55x7_PAGE0
, T55x7_CONFIGURATION_BLOCK
, TRUE
, testpwd
)) { 
1403                                 PrintAndLog("Aquireing data from device failed. Quitting"); 
1407                         found 
= tryDetectModulation(); 
1410                                 PrintAndLog("Found valid password: [%08X]", testpwd
); 
1414                 PrintAndLog("Password NOT found."); 
1418         // Try to read Block 7, first :) 
1420         // incremental pwd range search 
1421     start_password 
= param_get32ex(Cmd
, 0, 0, 16); 
1422         end_password 
= param_get32ex(Cmd
, 1, 0, 16); 
1424         if ( start_password 
>= end_password 
) return usage_t55xx_bruteforce(); 
1426     PrintAndLog("Search password  range [%08X -> %08X]", start_password
, end_password
); 
1428     uint32_t i 
= start_password
; 
1430     while ((!found
) && (i 
<= end_password
)){ 
1432                 if (!AquireData(T55x7_PAGE0
, T55x7_CONFIGURATION_BLOCK
, TRUE
, i
)) { 
1433                         PrintAndLog("Aquireing data from device failed. Quitting"); 
1436                 found 
= tryDetectModulation(); 
1441         if ((i 
% 0x100) == 0) printf("[%08x], ",i
); 
1449                 PrintAndLog("Found valid password: [%08x]", i
); 
1451                 PrintAndLog("Password NOT found. Last tried: [%08x]", i
); 
1455 static command_t CommandTable
[] = { 
1456         {"help",                CmdHelp
,           1, "This help"}, 
1457         {"bruteforce",  CmdT55xxBruteForce
,0, "Simple bruteforce attack to find password"}, 
1458         {"config",              CmdT55xxSetConfig
, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, 
1459         {"detect",              CmdT55xxDetect
,    1, "[1] Try detecting the tag modulation from reading the configuration block."}, 
1460         {"dump",                CmdT55xxDump
,      0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"}, 
1461         {"info",                CmdT55xxInfo
,      1, "[1] Show T55x7 configuration data (page 0/ blk 0)"}, 
1462         {"read",                CmdT55xxReadBlock
, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"}, 
1463         {"resetread",   CmdResetRead
,      0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"}, 
1464         {"special",             special
,           0, "Show block changes with 64 different offsets"},   
1465         {"trace",               CmdT55xxReadTrace
, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"}, 
1466         {"wakeup",              CmdT55xxWakeUp
,    0, "Send AOR wakeup command"}, 
1467         {"wipe",                CmdT55xxWipe
,      0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"}, 
1468         {"write",               CmdT55xxWriteBlock
,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"}, 
1469         {NULL
, NULL
, 0, NULL
} 
1472 int CmdLFT55XX(const char *Cmd
) { 
1473   CmdsParse(CommandTable
, Cmd
); 
1477 int CmdHelp(const char *Cmd
) { 
1478   CmdsHelp(CommandTable
);