]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlft55xx.c
b060bdee83b94aaa829b06b43a31ccff51b1d3e1
   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 //----------------------------------------------------------------------------- 
  13 #include "proxmark3.h" 
  17 #include "cmdparser.h" 
  20 #include "cmdlft55xx.h" 
  25 #define LF_TRACE_BUFF_SIZE 20000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..) 
  26 #define LF_BITSSTREAM_LEN 1000 // more then 1000 bits shouldn't happend..  8block * 4 bytes * 8bits =  
  29         PrintAndLog("Usage:  lf t55xx rd <block> <password>"); 
  30     PrintAndLog("     <block>, block number to read. Between 0-7"); 
  31     PrintAndLog("     <password>, OPTIONAL password (8 hex characters)"); 
  33     PrintAndLog("    sample: lf t55xx rd 0           = try reading data from block 0"); 
  34         PrintAndLog("          : lf t55xx rd 0 feedbeef  = try reading data from block 0 using password"); 
  39         PrintAndLog("Usage:  lf t55xx wr <block> <data> [password]"); 
  40     PrintAndLog("     <block>, block number to read. Between 0-7"); 
  41         PrintAndLog("     <data>,  4 bytes of data to write (8 hex characters)"); 
  42     PrintAndLog("     [password], OPTIONAL password 4bytes (8 hex characters)"); 
  44     PrintAndLog("    sample: lf t55xx wd 3 11223344  = try writing data 11223344 to block 3"); 
  45         PrintAndLog("          : lf t55xx wd 3 11223344 feedbeef  = try writing data 11223344 to block 3 using password feedbeef"); 
  49 int usage_t55xx_trace() { 
  50         PrintAndLog("Usage:  lf t55xx trace  [graph buffer data]"); 
  51         PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); 
  53         PrintAndLog("     sample: lf t55xx trace"); 
  54         PrintAndLog("           : lf t55xx trace 1"); 
  58 int usage_t55xx_info() { 
  59         PrintAndLog("Usage:  lf t55xx info [graph buffer data]"); 
  60         PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag."); 
  62         PrintAndLog("    sample: lf t55xx info"); 
  63         PrintAndLog("          : lf t55xx info 1"); 
  67 int usage_t55xx_dump(){ 
  68         PrintAndLog("Usage:  lf t55xx dump <password>"); 
  69     PrintAndLog("     <password>, OPTIONAL password 4bytes (8 hex characters)"); 
  71         PrintAndLog("        sample: lf t55xx dump"); 
  72         PrintAndLog("              : lf t55xx dump feedbeef"); 
  77 static int CmdHelp(const char *Cmd
); 
  81 size = fskdemod(dest, size, 32, 0, 8, 10);  // fsk1 RF/32  
  82 size = fskdemod(dest, size, 32, 1, 8, 10);  // fsk1a RF/32  
  85 size = fskdemod(dest, size, 32, 0, 10, 8);  // fsk2 RF/32  
  86 size = fskdemod(dest, size, 32, 1, 10, 8);  // fsk2a RF/32  
  87 size = fskdemod(dest, size, 50, 1, 10, 8);  // fsk2a RF/50  
  88 size = fskdemod(dest, size, 64, 1, 10, 8);  // FSK2a RF/64  
  92 int CmdReadBlk(const char *Cmd
) 
  97         int password 
= 0xFFFFFFFF; //default to blank Block 7 
 101     //uint8_t askAmp = 0; 
 103         uint8_t bits
[MAX_GRAPH_TRACE_LEN
] = {0x00}; 
 106         char cmdp 
= param_getchar(Cmd
, 0); 
 107         if (cmdp 
== 'h' || cmdp 
== 'H') { 
 112         int res 
= sscanf(Cmd
, "%d %x", &block
, &password
); 
 114         if ( res 
< 1 || res 
> 2 ){ 
 119         if ((block 
< 0) | (block 
> 7)) { 
 120                 PrintAndLog("Block must be between 0 and 7"); 
 124         UsbCommand c 
= {CMD_T55XX_READ_BLOCK
, {0, block
, 0}}; 
 125         c
.d
.asBytes
[0] = 0x0;  
 130                 c
.d
.asBytes
[0] = 0x1;  
 134         if ( !WaitForResponseTimeout(CMD_ACK
,NULL
,1500) ) { 
 135                 PrintAndLog("command execution time out"); 
 141         bitlen 
= getFromGraphBuf(bits
); 
 143         //errCnt = askrawdemod(bits, &bitlen, &clk, &invert, maxErr, askAmp); 
 144         errCnt 
= askmandemod(bits
, &bitlen
, &clk
, &invert
, maxErr
); 
 146         //throw away static - allow 1 and -1 (in case of threshold command first) 
 147         if ( errCnt 
== -1 || bitlen 
< 16 ){   
 148                 PrintAndLog("no data found"); 
 150                         PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt
, bitlen
, clk
, invert
); 
 154                 PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk
, invert
, bitlen
); 
 156         //move bits back to DemodBuffer 
 157         setDemodBuf(bits
, bitlen
, 0); 
 158         printBitStream(bits
,bitlen
); 
 160         // bits has the manchester encoded data. 
 161         errCnt 
= manrawdecode(bits
, &bitlen
);    
 162         if ( errCnt 
== -1 || bitlen 
< 16 ){   
 163                 PrintAndLog("no data found"); 
 165                         PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt
, bitlen
, clk
, invert
); 
 169         blockData 
= PackBits(1, 32, bits
); 
 172                 PrintAndLog(" Decoded     : 0x%08X  %s", blockData
, sprint_bin(bits
+1,32) ); 
 174                 PrintAndLog(" Block %d    : 0x%08X  %s", block
, blockData
, sprint_bin(bits
+1,32) ); 
 179 int CmdWriteBlk(const char *Cmd
) 
 181         int block 
= 8; //default to invalid block 
 182         int data 
= 0xFFFFFFFF; //default to blank Block  
 183         int password 
= 0xFFFFFFFF; //default to blank Block 7 
 185         char cmdp 
= param_getchar(Cmd
, 0); 
 186         if (cmdp 
== 'h' || cmdp 
== 'H') { 
 191         int res 
= sscanf(Cmd
, "%d %x %x",&block
, &data
, &password
); 
 193         if ( res 
< 2 || res 
> 3) { 
 199                 PrintAndLog("Block must be between 0 and 7"); 
 203         UsbCommand c 
= {CMD_T55XX_WRITE_BLOCK
, {data
, block
, 0}}; 
 204         c
.d
.asBytes
[0] = 0x0;  
 207                 PrintAndLog("Writing block %d  data %08X", block
, data
); 
 211                 c
.d
.asBytes
[0] = 0x1;  
 212                 PrintAndLog("Writing block %d  data %08X  password %08X", block
, data
, password
); 
 219 int CmdReadTrace(const char *Cmd
) 
 226         uint8_t bits
[MAX_GRAPH_TRACE_LEN
] = {0x00}; 
 228         char cmdp 
= param_getchar(Cmd
, 0); 
 230         if (strlen(Cmd
) > 1 || cmdp 
== 'h' || cmdp 
== 'H') { 
 235         if ( strlen(Cmd
)==0){ 
 237                 UsbCommand c 
= {CMD_T55XX_READ_TRACE
, {0, 0, 0}}; 
 239                 WaitForResponse(CMD_ACK
, NULL
); 
 244         bitlen 
= getFromGraphBuf(bits
); 
 246         //errCnt = askrawdemod(bits, &bitlen, &clk, &invert, maxErr, askAmp); 
 247         errCnt 
= askmandemod(bits
, &bitlen
, &clk
, &invert
, maxErr
); 
 249         //throw away static - allow 1 and -1 (in case of threshold command first) 
 250         if ( errCnt 
== -1 || bitlen 
< 16 ){   
 251                 PrintAndLog("no data found"); 
 253                         PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt
, bitlen
, clk
, invert
); 
 257                 PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk
, invert
, bitlen
); 
 259         //move bits back to DemodBuffer 
 260         setDemodBuf(bits
, bitlen
, 0); 
 262         // bits has the manchester encoded data. 
 263         errCnt 
= manrawdecode(bits
, &bitlen
);    
 264         if ( errCnt 
== -1 || bitlen 
< 16 ){   
 265                 PrintAndLog("no data found"); 
 267                         PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt
, bitlen
, clk
, invert
); 
 271         RepaintGraphWindow(); 
 274         uint32_t bl0     
= PackBits(si
, 32, bits
); 
 275         uint32_t bl1     
= PackBits(si
+32, 32, bits
); 
 277         uint32_t acl     
= PackBits(si
,  8, bits
); si 
+= 8; 
 278         uint32_t mfc     
= PackBits(si
, 8, bits
); si 
+= 8; 
 279         uint32_t cid     
= PackBits(si
, 5, bits
); si 
+= 5; 
 280         uint32_t icr     
= PackBits(si
, 3, bits
); si 
+= 3; 
 281         uint32_t year    
= PackBits(si
, 4, bits
); si 
+= 4; 
 282         uint32_t quarter 
= PackBits(si
, 2, bits
); si 
+= 2; 
 283         uint32_t lotid    
= PackBits(si
, 12, bits
); si 
+= 12; 
 284         uint32_t wafer   
= PackBits(si
, 5, bits
); si 
+= 5; 
 285         uint32_t dw      
= PackBits(si
, 15, bits
);  
 288         PrintAndLog("-- T55xx Trace Information ----------------------------------"); 
 289         PrintAndLog("-------------------------------------------------------------"); 
 290         PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1)  : 0x%02X (%d)", acl
, acl
); 
 291         PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6)    : 0x%02X (%d)", mfc
, mfc
); 
 292         PrintAndLog(" CID                                     : 0x%02X (%d)", cid
, cid
); 
 293         PrintAndLog(" ICR IC Revision                         : %d",icr 
); 
 294         PrintAndLog(" Manufactured"); 
 295         PrintAndLog("     Year/Quarter : %d/%d",2000+year
, quarter 
); 
 296         PrintAndLog("     Lot ID       : %d", lotid 
); 
 297         PrintAndLog("     Wafer number : %d", wafer
); 
 298         PrintAndLog("     Die Number   : %d", dw
); 
 299         PrintAndLog("-------------------------------------------------------------"); 
 300         PrintAndLog(" Raw Data - Page 1"); 
 301         PrintAndLog("     Block 0  : 0x%08X  %s", bl0
, sprint_bin(bits
+5,32) ); 
 302         PrintAndLog("     Block 0  : 0x%08X  %s", bl1
, sprint_bin(bits
+37,32) ); 
 303         PrintAndLog("-------------------------------------------------------------"); 
 307                 1-8             ACL Allocation class (ISO/IEC 15963-1)  0xE0  
 308                 9-16    MFC Manufacturer ID (ISO/IEC 7816-6)    0x15 Atmel Corporation 
 309                 17-21   CID                                                                             0x1 = Atmel ATA5577M1  0x2 = Atmel ATA5577M2  
 310                 22-24   ICR IC revision 
 311                 25-28   YEAR (BCD encoded)                                              9 (= 2009) 
 312                 29-30   QUARTER                                                                 1,2,3,4  
 318                 18-32   DW,  die number sequential 
 324 int CmdInfo(const char *Cmd
){ 
 326                 Page 0 Block 0 Configuration data. 
 330         char cmdp 
= param_getchar(Cmd
, 0); 
 332         if (strlen(Cmd
) > 1 || cmdp 
== 'h' || cmdp 
== 'H') { 
 339         uint8_t bits
[LF_BITSSTREAM_LEN
] = {0x00}; 
 341         manchester_decode(GraphBuffer
, LF_TRACE_BUFF_SIZE
, bits
, LF_BITSSTREAM_LEN
); 
 344         uint32_t bl0      
= PackBits(si
, 32, bits
); 
 346         uint32_t safer    
= PackBits(si
, 4, bits
); si 
+= 4;      
 347         uint32_t resv     
= PackBits(si
, 7, bits
); si 
+= 7; 
 348         uint32_t dbr      
= PackBits(si
, 3, bits
); si 
+= 3; 
 349         uint32_t extend   
= PackBits(si
, 1, bits
); si 
+= 1; 
 350         uint32_t datamodulation   
= PackBits(si
, 5, bits
); si 
+= 5; 
 351         uint32_t pskcf    
= PackBits(si
, 2, bits
); si 
+= 2; 
 352         uint32_t aor      
= PackBits(si
, 1, bits
); si 
+= 1;      
 353         uint32_t otp      
= PackBits(si
, 1, bits
); si 
+= 1;      
 354         uint32_t maxblk   
= PackBits(si
, 3, bits
); si 
+= 3; 
 355         uint32_t pwd      
= PackBits(si
, 1, bits
); si 
+= 1;      
 356         uint32_t sst      
= PackBits(si
, 1, bits
); si 
+= 1;      
 357         uint32_t fw       
= PackBits(si
, 1, bits
); si 
+= 1; 
 358         uint32_t inv      
= PackBits(si
, 1, bits
); si 
+= 1;      
 359         uint32_t por      
= PackBits(si
, 1, bits
); si 
+= 1; 
 362         PrintAndLog("-- T55xx Configuration & Tag Information --------------------"); 
 363         PrintAndLog("-------------------------------------------------------------"); 
 364         PrintAndLog(" Safer key                 : %s", GetSaferStr(safer
)); 
 365         PrintAndLog(" reserved                  : %d", resv
); 
 366         PrintAndLog(" Data bit rate             : %s", GetBitRateStr(dbr
)); 
 367         PrintAndLog(" eXtended mode             : %s", (extend
) ? "Yes - Warning":"No"); 
 368         PrintAndLog(" Modulation                : %s", GetModulationStr(datamodulation
) ); 
 369         PrintAndLog(" PSK clock freq            : %d", pskcf
); 
 370         PrintAndLog(" AOR - Answer on Request   : %s", (aor
) ? "Yes":"No"); 
 371         PrintAndLog(" OTP - One Time Pad        : %s", (otp
) ? "Yes - Warning":"No" ); 
 372         PrintAndLog(" Max block                 : %d", maxblk
); 
 373         PrintAndLog(" Password mode             : %s", (pwd
) ? "Yes":"No"); 
 374         PrintAndLog(" Sequence Start Terminator : %s", (sst
) ? "Yes":"No"); 
 375         PrintAndLog(" Fast Write                : %s", (fw
) ? "Yes":"No"); 
 376         PrintAndLog(" Inverse data              : %s", (inv
) ? "Yes":"No"); 
 377         PrintAndLog(" POR-Delay                 : %s", (por
) ? "Yes":"No"); 
 378         PrintAndLog("-------------------------------------------------------------"); 
 379         PrintAndLog(" Raw Data - Page 0"); 
 380         PrintAndLog("     Block 0  : 0x%08X  %s", bl0
, sprint_bin(bits
+5,32) ); 
 381         PrintAndLog("-------------------------------------------------------------"); 
 386 int CmdDump(const char *Cmd
){ 
 389         uint8_t pwd
[4] = {0x00}; 
 391         char cmdp 
= param_getchar(Cmd
, 0); 
 392         if ( cmdp 
== 'h' || cmdp 
== 'H') { 
 397         bool hasPwd 
= ( strlen(Cmd
) > 0);        
 399                 if (param_gethex(Cmd
, 0, pwd
, 8)) { 
 400                         PrintAndLog("password must include 8 HEX symbols"); 
 405         for ( int i 
= 0; i 
<8; ++i
){ 
 406                 memset(s
,0,sizeof(s
)); 
 408                         sprintf(s
,"%d %02x%02x%02x%02x", i
, pwd
[0],pwd
[1],pwd
[2],pwd
[3]); 
 417 int CmdIceFsk(const char *Cmd
){ 
 419         if (!HasGraphData()) return 0; 
 421         iceFsk3(GraphBuffer
, LF_TRACE_BUFF_SIZE
); 
 422         RepaintGraphWindow(); 
 425 int CmdIceManchester(const char *Cmd
){ 
 426         ManchesterDemod( -1); 
 429 int ManchesterDemod(int blockNum
){ 
 431         if (!HasGraphData()) return 0; 
 433         uint8_t sizebyte 
= 32; 
 434         // the value 5 was selected during empirical studies of the decoded data. Some signal noise to skip. 
 437         uint8_t  bits
[LF_BITSSTREAM_LEN
] = {0x00}; 
 438         uint8_t * bitstream 
= bits
; 
 440         manchester_decode(GraphBuffer
, LF_TRACE_BUFF_SIZE
, bits
, LF_BITSSTREAM_LEN
);     
 441         blockData 
= PackBits(offset
, sizebyte
, bits
); 
 444                 PrintAndLog(" Decoded     : 0x%08X  %s", blockData
, sprint_bin(bitstream
+offset
,sizebyte
) ); 
 446                 PrintAndLog(" Block %d    : 0x%08X  %s", blockNum
, blockData
, sprint_bin(bitstream
+offset
,sizebyte
) ); 
 451 char * GetBitRateStr(uint32_t id
){ 
 456                         sprintf(retStr
,"%d - RF/8",id
); 
 459                         sprintf(retStr
,"%d - RF/16",id
); 
 462                         sprintf(retStr
,"%d - RF/32",id
); 
 465                         sprintf(retStr
,"%d - RF/40",id
); 
 468                         sprintf(retStr
,"%d - RF/50",id
); 
 471                         sprintf(retStr
,"%d - RF/64",id
); 
 474                         sprintf(retStr
,"%d - RF/100",id
); 
 477                         sprintf(retStr
,"%d - RF/128",id
); 
 480                         sprintf(retStr
,"%d - (Unknown)",id
); 
 487 char * GetSaferStr(uint32_t id
){ 
 491         sprintf(retStr
,"%d",id
); 
 493                 sprintf(retStr
,"%d - pasdwd",id
); 
 496                 sprintf(retStr
,"%d - testmode ",id
); 
 501 char * GetModulationStr( uint32_t id
){ 
 507                         sprintf(retStr
,"%d - DIRECT (ASK/NRZ)",id
); 
 510                         sprintf(retStr
,"%d - PSK 1 phase change when input changes",id
); 
 513                         sprintf(retStr
,"%d - PSK 2 phase change on bitclk if input high",id
); 
 516                         sprintf(retStr
,"%d - PSK 3 phase change on rising edge of input",id
); 
 519                         sprintf(retStr
,"%d - FSK 1 RF/8  RF/5",id
); 
 522                         sprintf(retStr
,"%d - FSK 2 RF/8  RF/10",id
); 
 525                         sprintf(retStr
,"%d - FSK 1a RF/5  RF/8",id
); 
 528                         sprintf(retStr
,"%d - FSK 2a RF/10  RF/8",id
); 
 531                         sprintf(retStr
,"%d - Manschester",id
); 
 534                         sprintf(retStr
,"%d - Biphase",id
); 
 537                         sprintf(retStr
,"%d - Reserved",id
); 
 540                         sprintf(retStr
,"0x%02X (Unknown)",id
); 
 547 uint32_t PackBits(uint8_t start
, uint8_t len
, uint8_t* bits
){ 
 555         for (; j 
>= 0; --j
, ++i
){ 
 561 static command_t CommandTable
[] = 
 563   {"help",   CmdHelp
,        1, "This help"}, 
 564   {"rd",     CmdReadBlk
,     0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"}, 
 565   {"wr",     CmdWriteBlk
,    0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"}, 
 566   {"trace",  CmdReadTrace
,   0, "[1] Read T55xx traceability data (page 1/ blk 0-1)"}, 
 567   {"info",   CmdInfo
,        0, "[1] Read T55xx configuration data (page 0/ blk 0)"}, 
 568   {"dump",   CmdDump
,        0, "[password] Dump T55xx card block 0-7. [optional password]"}, 
 569   {"man",    CmdIceManchester
,      0, "Manchester demod (with SST)"}, 
 570   {NULL
, NULL
, 0, NULL
} 
 573 int CmdLFT55XX(const char *Cmd
) 
 575   CmdsParse(CommandTable
, Cmd
); 
 579 int CmdHelp(const char *Cmd
) 
 581   CmdsHelp(CommandTable
);