]>
 
 
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdanalyse.c 
 
 
 
 
 
 
 
fb084f433083545b428ff348ae687c91880a685f
   1  //-----------------------------------------------------------------------------  
   2  // Copyright (C) 2016 iceman  
   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  // Analyse bytes commands  
   9  //-----------------------------------------------------------------------------  
  10  #include  "cmdanalyse.h"  
  11  #include  "nonce2key/nonce2key.h"  
  13  static int  CmdHelp ( const char  * Cmd
);  
  15  int  usage_analyse_lcr ( void ) {  
  16          PrintAndLog ( "Specifying the bytes of a UID with a known LRC will find the last byte value" );  
  17          PrintAndLog ( "needed to generate that LRC with a rolling XOR. All bytes should be specified in HEX." );  
  19          PrintAndLog ( "Usage:  analyse lcr [h] <bytes>" );  
  20          PrintAndLog ( "Options:" );  
  21          PrintAndLog ( "           h          This help" );  
  22          PrintAndLog ( "           <bytes>    bytes to calc missing XOR in a LCR" );  
  24          PrintAndLog ( "Samples:" );  
  25          PrintAndLog ( "           analyse lcr 04008064BA" );  
  26          PrintAndLog ( "expected output: Target (BA) requires final LRC XOR byte value: 5A" );  
  30  int  usage_analyse_checksum ( void ) {  
  31          PrintAndLog ( "The bytes will be added with eachother and than limited with the applied mask" );  
  32          PrintAndLog ( "Finally compute ones' complement of the least significant bytes" );  
  34          PrintAndLog ( "Usage:  analyse chksum [h] b <bytes> m <mask>" );  
  35          PrintAndLog ( "Options:" );  
  36          PrintAndLog ( "           h          This help" );  
  37          PrintAndLog ( "           b <bytes>  bytes to calc missing XOR in a LCR" );  
  38          PrintAndLog ( "           m <mask>   bit mask to limit the outpuyt" );  
  40          PrintAndLog ( "Samples:" );  
  41          PrintAndLog ( "           analyse chksum b 137AF00A0A0D m FF" );  
  42          PrintAndLog ( "expected output: 0x61" );  
  46  int  usage_analyse_crc ( void ){  
  47          PrintAndLog ( "A stub method to test different crc implementations inside the PM3 sourcecode. Just because you figured out the poly, doesn't mean you get the desired output" );  
  49          PrintAndLog ( "Usage:  analyse crc [h] <bytes>" );  
  50          PrintAndLog ( "Options:" );  
  51          PrintAndLog ( "           h          This help" );  
  52          PrintAndLog ( "           <bytes>    bytes to calc crc" );  
  54          PrintAndLog ( "Samples:" );  
  55          PrintAndLog ( "           analyse crc 137AF00A0A0D" );  
  59  static uint8_t  calculateLRC (  uint8_t *  bytes
,  uint8_t  len
) {  
  61      for  ( uint8_t  i 
=  0 ;  i 
<  len
;  i
++)  
  66  static uint8_t  calcSumCrumbAdd (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
  68      for  ( uint8_t  i 
=  0 ;  i 
<  len
;  i
++) {  
  69          sum 
+=  CRUMB ( bytes
[ i
],  0 );  
  70                  sum 
+=  CRUMB ( bytes
[ i
],  2 );  
  71                  sum 
+=  CRUMB ( bytes
[ i
],  4 );  
  72                  sum 
+=  CRUMB ( bytes
[ i
],  6 );  
  77  static uint8_t  calcSumCrumbAddOnes (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
  78          return  ~ calcSumCrumbAdd ( bytes
,  len
,  mask
);  
  80  static uint8_t  calcSumNibbleAdd (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
  82      for  ( uint8_t  i 
=  0 ;  i 
<  len
;  i
++) {  
  83          sum 
+=  NIBBLE_LOW ( bytes
[ i
]);  
  84                  sum 
+=  NIBBLE_HIGH ( bytes
[ i
]);  
  89  static uint8_t  calcSumNibbleAddOnes (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
){  
  90          return  ~ calcSumNibbleAdd ( bytes
,  len
,  mask
);  
  93  static uint8_t  calcSumByteAdd (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
  95      for  ( uint8_t  i 
=  0 ;  i 
<  len
;  i
++)  
 101  static uint8_t  calcSumByteAddOnes (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
 102          return  ~ calcSumByteAdd ( bytes
,  len
,  mask
);  
 105  static uint8_t  calcSumByteSub (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
 107      for  ( uint8_t  i 
=  0 ;  i 
<  len
;  i
++)  
 112  static uint8_t  calcSumByteSubOnes (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
){  
 113          return  ~ calcSumByteSub ( bytes
,  len
,  mask
);  
 115  static uint8_t  calcSumNibbleSub (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
 117      for  ( uint8_t  i 
=  0 ;  i 
<  len
;  i
++) {  
 118          sum 
-=  NIBBLE_LOW ( bytes
[ i
]);  
 119                  sum 
-=  NIBBLE_HIGH ( bytes
[ i
]);  
 124  static uint8_t  calcSumNibbleSubOnes (  uint8_t *  bytes
,  uint8_t  len
,  uint32_t  mask
) {  
 125          return  ~ calcSumNibbleSub ( bytes
,  len
,  mask
);  
 128  // measuring LFSR maximum length  
 129  int  CmdAnalyseLfsr ( const char  * Cmd
){  
 131      uint16_t  start_state 
=  0 ;   /* Any nonzero start state will work. */  
 132      uint16_t  lfsr 
=  start_state
;  
 133      //uint32_t period = 0;  
 135          uint8_t  iv 
=  param_get8ex ( Cmd
,  0 ,  0 ,  16 );  
 136          uint8_t  find 
=  param_get8ex ( Cmd
,  1 ,  0 ,  16 );  
 138          printf ( "LEGIC LFSR IV 0x %0 2X:  \n " ,  iv
);  
 139          printf ( " bit# | lfsr | ^0x40 |  0x %0 2X ^ lfsr  \n " , find
);  
 141          for  ( uint8_t  i 
=  0x01 ;  i 
<  0x30 ;  i 
+=  1 ) {  
 144                  legic_prng_forward ( i
);  
 145                  lfsr 
=  legic_prng_get_bits ( 12 );  
 147                  printf ( "  %0 2X |  %0 3X |  %0 3X |  %0 3X  \n " , i
,  lfsr
,  0x40  ^  lfsr
,  find 
^  lfsr
);  
 151  int  CmdAnalyseLCR ( const char  * Cmd
) {  
 153          char  cmdp 
=  param_getchar ( Cmd
,  0 );  
 154          if  ( strlen ( Cmd
) ==  0 ||  cmdp 
==  'h'  ||  cmdp 
==  'H' )  return  usage_analyse_lcr ();  
 157          param_gethex_ex ( Cmd
,  0 ,  data
, & len
);  
 158          if  (  len%2 
)  return  usage_analyse_lcr ();  
 160          uint8_t  finalXor 
=  calculateLRC ( data
,  len
);  
 161          PrintAndLog ( "Target [ %0 2X] requires final LRC XOR byte value: 0x %0 2X" , data
[ len
- 1 ] , finalXor
);  
 164  int  CmdAnalyseCRC ( const char  * Cmd
) {  
 166          char  cmdp 
=  param_getchar ( Cmd
,  0 );  
 167          if  ( strlen ( Cmd
) ==  0  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' )  return  usage_analyse_crc ();  
 169          int  len 
=  strlen ( Cmd
);  
 170          if  (  len 
&  1  )  return  usage_analyse_crc ();  
 172          // add 1 for null terminator.  
 173          uint8_t  * data 
=  malloc ( len
+ 1 );  
 174          if  (  data 
==  NULL 
)  return  1 ;  
 176          if  (  param_gethex ( Cmd
,  0 ,  data
,  len
)) {  
 178                  return  usage_analyse_crc ();  
 182          //PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len));  
 184          PrintAndLog ( " \n Tests of reflection. Two current methods in source code" );         
 185          PrintAndLog ( "   reflect(0x3e23L,3) is  %0 4X == 0x3e26" ,  reflect ( 0x3e23 L
, 3 ) );  
 186          PrintAndLog ( "  SwapBits(0x3e23L,3) is  %0 4X == 0x3e26" ,  SwapBits ( 0x3e23 L
, 3 ) );  
 187          PrintAndLog ( "  0xB400 ==  %0 4X" ,  reflect ( ( 1  <<  16  |  0xb400 ), 16 ) );  
 190          // Test of CRC16,  '123456789' string.  
 192          PrintAndLog ( " \n Tests with '123456789' string" );  
 193          uint8_t  dataStr
[] = {  0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 , 0x38 , 0x39  };  
 194          uint8_t  legic8 
=  CRC8Legic ( dataStr
,  sizeof ( dataStr
));  
 196          PrintAndLog ( "LEGIC: CRC16:  %X " ,  CRC16Legic ( dataStr
,  sizeof ( dataStr
),  legic8
));  
 198          //these below has been tested OK.  
 199          PrintAndLog ( "Confirmed CRC Implementations" );  
 200          PrintAndLog ( "LEGIC: CRC8 :  %X  (0xC6 expected)" ,  legic8
);  
 201          PrintAndLog ( "MAXIM: CRC8 :  %X  (0xA1 expected)" ,  CRC8Maxim ( dataStr
,  sizeof ( dataStr
)));  
 202          PrintAndLog ( "DNP  : CRC16:  %X  (0x82EA expected)" ,  CRC16_DNP ( dataStr
,  sizeof ( dataStr
)));   
 203          PrintAndLog ( "CCITT: CRC16:  %X  (0xE5CC expected)" ,  CRC16_CCITT ( dataStr
,  sizeof ( dataStr
)));  
 205          PrintAndLog ( "ICLASS org: CRC16:  %X  (0x expected)" , iclass_crc16 ( ( char *) dataStr
,  sizeof ( dataStr
)));  
 206          PrintAndLog ( "ICLASS ice: CRC16:  %X  (0x expected)" , CRC16_ICLASS ( dataStr
,  sizeof ( dataStr
)));  
 210          uint8_t  dataStr1234
[] = {  0x1 , 0x2 , 0x3 , 0x4 };  
 211          PrintAndLog ( "ISO15693 org:  : CRC16:  %X  (0xF0B8 expected)" ,  Iso15693Crc ( dataStr1234
,  sizeof ( dataStr1234
)));  
 212          PrintAndLog ( "ISO15693 ice:  : CRC16:  %X  (0xF0B8 expected)" ,  CRC16_Iso15693 ( dataStr1234
,  sizeof ( dataStr1234
)));  
 217  int  CmdAnalyseCHKSUM ( const char  * Cmd
){  
 221          uint32_t  mask 
=  0xFF ;  
 224          memset ( data
,  0x0 ,  sizeof ( data
));  
 226          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ) {  
 227                  switch ( param_getchar ( Cmd
,  cmdp
)) {  
 230                          param_gethex_ex ( Cmd
,  cmdp
+ 1 ,  data
, & len
);  
 231                          if  (  len%2 
)  errors 
=  true ;  
 237                          mask 
=  param_get32ex ( Cmd
,  cmdp
+ 1 ,  0 ,  16 );  
 242                          return  usage_analyse_checksum ();  
 244                          PrintAndLog ( "Unknown parameter ' %c '" ,  param_getchar ( Cmd
,  cmdp
));  
 251          if ( errors
)  return  usage_analyse_checksum ();  
 253          PrintAndLog ( " \n Byte Add        | 0x %X " ,  calcSumByteAdd ( data
,  len
,  mask
));  
 254          PrintAndLog ( "Nibble Add      | 0x %X " ,  calcSumNibbleAdd ( data
,  len
,  mask
));  
 255          PrintAndLog ( "Crumb Add       | 0x %X " ,  calcSumCrumbAdd ( data
,  len
,  mask
));  
 257          PrintAndLog ( " \n Byte Subtract   | 0x %X " ,  calcSumByteSub ( data
,  len
,  mask
));  
 258          PrintAndLog ( "Nibble Subtract | 0x %X " ,  calcSumNibbleSub ( data
,  len
,  mask
));  
 260          PrintAndLog ( " \n CHECKSUM - One's complement" );  
 261          PrintAndLog ( "Byte Add        | 0x %X " ,  calcSumByteAddOnes ( data
,  len
,  mask
));  
 262          PrintAndLog ( "Nibble Add      | 0x %X " ,  calcSumNibbleAddOnes ( data
,  len
,  mask
));  
 263          PrintAndLog ( "Crumb Add       | 0x %X " ,  calcSumCrumbAddOnes ( data
,  len
,  mask
));  
 265          PrintAndLog ( "Byte Subtract   | 0x %X " ,  calcSumByteSubOnes ( data
,  len
,  mask
));  
 266          PrintAndLog ( "Nibble Subtract | 0x %X " ,  calcSumNibbleSubOnes ( data
,  len
,  mask
));  
 271  int  CmdAnalyseDates ( const char  * Cmd
){  
 272          // look for datestamps in a given array of bytes  
 273          PrintAndLog ( "To be implemented. Feel free to contribute!" );  
 276  int  CmdAnalyseTEASelfTest ( const char  * Cmd
){  
 278          uint8_t  v
[ 8 ],  v_le
[ 8 ];  
 279          memset ( v
,  0x00 ,  sizeof ( v
));  
 280          memset ( v_le
,  0x00 ,  sizeof ( v_le
));  
 281          uint8_t *  v_ptr 
=  v_le
;  
 283          uint8_t  cmdlen 
=  strlen ( Cmd
);  
 284          cmdlen 
= (  sizeof ( v
)<< 2  <  cmdlen 
) ?  sizeof ( v
)<< 2  :  cmdlen
;  
 286          if  (  param_gethex ( Cmd
,  0 ,  v
,  cmdlen
) >  0  ){  
 287                  PrintAndLog ( "can't read hex chars, uneven? ::  %u " ,  cmdlen
);  
 291          SwapEndian64ex ( v 
,  8 ,  4 ,  v_ptr
);  
 294          uint8_t  key
[ 16 ] = { 0x55 , 0xFE , 0xF6 , 0x30 , 0x62 , 0xBF , 0x0B , 0xC1 , 0xC9 , 0xB3 , 0x7C , 0x34 , 0x97 , 0x3E , 0x29 , 0xFB  };  
 296          uint8_t *  key_ptr 
=  keyle
;  
 297          SwapEndian64ex ( key 
,  sizeof ( key
),  4 ,  key_ptr
);  
 299          PrintAndLog ( "TEST LE enc|  %s " ,  sprint_hex ( v_ptr
,  8 ));  
 301          tea_decrypt ( v_ptr
,  key_ptr
);      
 302          PrintAndLog ( "TEST LE dec |  %s " ,  sprint_hex_ascii ( v_ptr
,  8 ));  
 304          tea_encrypt ( v_ptr
,  key_ptr
);      
 305          tea_encrypt ( v_ptr
,  key_ptr
);  
 306          PrintAndLog ( "TEST enc2 |  %s " ,  sprint_hex_ascii ( v_ptr
,  8 ));  
 311  int  CmdAnalyseA ( const char  * Cmd
){  
 313  // uid(2e086b1a) nt(230736f6) par(0000000000000000) ks(0b0008000804000e) nr(000000000)  
 314  // uid(2e086b1a) nt(230736f6) par(0000000000000000) ks(0e0b0e0b090c0d02) nr(000000001)  
 315  // uid(2e086b1a) nt(230736f6) par(0000000000000000) ks(0e05060e01080b08) nr(000000002)  
 316          uint32_t  uid 
=  0x2e086b1a ,  nt 
=  0x230736f6 ,  nr 
=  0x000000001 ;  
 317          uint64_t  ks_list 
=  0x0e0b0e0b090c0d02 ,  r_key 
=  0 ;  
 319          nonce2key_ex ( 0 ,  0  ,  uid
,  nt
,  nr
,  ks_list
, & r_key
);  
 322          ks_list 
=  0x0e05060e01080b08 ;  
 323          nonce2key_ex ( 0 ,  0  ,  uid
,  nt
,  nr
,  ks_list
, & r_key
);  
 325          printf ( "Found valid key:  %0 12" llx
"  \n " ,  r_key
);   
 330  static  command_t CommandTable
[] = {  
 331          { "help" ,         CmdHelp
,             1 ,  "This help" },  
 332          { "lcr" ,          CmdAnalyseLCR
,           1 ,  "Generate final byte for XOR LRC" },  
 333          { "crc" ,          CmdAnalyseCRC
,           1 ,  "Stub method for CRC evaluations" },  
 334          { "chksum" ,       CmdAnalyseCHKSUM
,        1 ,  "Checksum with adding, masking and one's complement" },  
 335          { "dates" ,        CmdAnalyseDates
,         1 ,  "Look for datestamps in a given array of bytes" },  
 336          { "tea" ,          CmdAnalyseTEASelfTest
,   1 ,  "Crypto TEA test" },  
 337          { "lfsr" ,         CmdAnalyseLfsr
,          1 ,       "LFSR tests" },  
 338          { "a" ,            CmdAnalyseA
,             1 ,       "num bits test" },  
 339          { NULL
,  NULL
,  0 ,  NULL
}  
 342  int  CmdAnalyse ( const char  * Cmd
) {  
 343          clearCommandBuffer ();  
 344          CmdsParse ( CommandTable
,  Cmd
);  
 348  int  CmdHelp ( const char  * Cmd
) {  
 349          CmdsHelp ( CommandTable
);