]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmf.c 
   1  //-----------------------------------------------------------------------------    2  // Copyright (C) 2011,2012 Merlok    4  // This code is licensed to you under the terms of the GNU GPL, version 2 or,    5  // at your option, any later version. See the LICENSE.txt file for the text of    7  //-----------------------------------------------------------------------------    8  // High frequency MIFARE commands    9  //-----------------------------------------------------------------------------   20  #include  "cmdhfmfhard.h"   23  #include  "util_posix.h"   26  #include  "mifarehost.h"   29  #include  "hardnested/hardnested_bf_core.h"   31  #define NESTED_SECTOR_RETRY     10                       // how often we try mfested() until we give up   33  static int  CmdHelp ( const char  * Cmd
);   35  int  CmdHF14AMifare ( const char  * Cmd
)   39          isOK 
=  mfDarkside (& key
);   41                  case  - 1  :  PrintAndLog ( "Button pressed. Aborted." );  return  1 ;   42                  case  - 2  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)." );  return  1 ;   43                  case  - 3  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator is not predictable)." );  return  1 ;   44                  case  - 4  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown" );   45                                    PrintAndLog ( "generating polynomial with 16 effective bits only, but shows unexpected behaviour." );  return  1 ;   46                  case  - 5  :  PrintAndLog ( "Aborted via keyboard." );   return  1 ;   47                  default  :  PrintAndLog ( "Found valid key: %0 12"  PRIx64 
" \n " ,  key
);   55  int  CmdHF14AMfWrBl ( const char  * Cmd
)   59          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };   60          uint8_t  bldata
[ 16 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 };   65                  PrintAndLog ( "Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>" );   66                  PrintAndLog ( "        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F" );   70          blockNo 
=  param_get8 ( Cmd
,  0 );   71          cmdp 
=  param_getchar ( Cmd
,  1 );   73                  PrintAndLog ( "Key type must be A or B" );   76          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;   77          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {   78                  PrintAndLog ( "Key must include 12 HEX symbols" );   81          if  ( param_gethex ( Cmd
,  3 ,  bldata
,  32 )) {   82                  PrintAndLog ( "Block data must include 32 HEX symbols" );   85          PrintAndLog ( "--block no: %d , key type: %c , key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));   86          PrintAndLog ( "--data:  %s " ,  sprint_hex ( bldata
,  16 ));   88    UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { blockNo
,  keyType
,  0 }};   89          memcpy ( c
. d
. asBytes
,  key
,  6 );   90          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );   94          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {   95                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;   96                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);   98                  PrintAndLog ( "Command execute timeout" );  104  int  CmdHF14AMfRdBl ( const char  * Cmd
)  108          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  114                  PrintAndLog ( "Usage:  hf mf rdbl    <block number> <key A/B> <key (12 hex symbols)>" );  115                  PrintAndLog ( "        sample: hf mf rdbl 0 A FFFFFFFFFFFF " );  119          blockNo 
=  param_get8 ( Cmd
,  0 );  120          cmdp 
=  param_getchar ( Cmd
,  1 );  122                  PrintAndLog ( "Key type must be A or B" );  125          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  126          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  127                  PrintAndLog ( "Key must include 12 HEX symbols" );  130          PrintAndLog ( "--block no: %d , key type: %c , key: %s  " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  132    UsbCommand c 
= { CMD_MIFARE_READBL
, { blockNo
,  keyType
,  0 }};  133          memcpy ( c
. d
. asBytes
,  key
,  6 );  137          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  138                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  139                  uint8_t  * data 
=  resp
. d
. asBytes
;  142                          PrintAndLog ( "isOk: %0 2x data: %s " ,  isOK
,  sprint_hex ( data
,  16 ));  144                          PrintAndLog ( "isOk: %0 2x" ,  isOK
);  146                  PrintAndLog ( "Command execute timeout" );  152  int  CmdHF14AMfRdSc ( const char  * Cmd
)  155          uint8_t  sectorNo 
=  0 ;  157          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  159          uint8_t  * data  
=  NULL
;  163                  PrintAndLog ( "Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>" );  164                  PrintAndLog ( "        sample: hf mf rdsc 0 A FFFFFFFFFFFF " );  168          sectorNo 
=  param_get8 ( Cmd
,  0 );  170                  PrintAndLog ( "Sector number must be less than 40" );  173          cmdp 
=  param_getchar ( Cmd
,  1 );  174          if  ( cmdp 
!=  'a'  &&  cmdp 
!=  'A'  &&  cmdp 
!=  'b'  &&  cmdp 
!=  'B' ) {  175                  PrintAndLog ( "Key type must be A or B" );  178          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  179          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  180                  PrintAndLog ( "Key must include 12 HEX symbols" );  183          PrintAndLog ( "--sector no: %d  key type: %c  key: %s  " ,  sectorNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  185          UsbCommand c 
= { CMD_MIFARE_READSC
, { sectorNo
,  keyType
,  0 }};  186          memcpy ( c
. d
. asBytes
,  key
,  6 );  191          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  192                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  193                  data  
=  resp
. d
. asBytes
;  195                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  197                          for  ( i 
=  0 ;  i 
< ( sectorNo
< 32 ? 3 : 15 );  i
++) {  198                                  PrintAndLog ( "data   :  %s " ,  sprint_hex ( data 
+  i 
*  16 ,  16 ));  200                          PrintAndLog ( "trailer:  %s " ,  sprint_hex ( data 
+ ( sectorNo
< 32 ? 3 : 15 ) *  16 ,  16 ));  203                  PrintAndLog ( "Command execute timeout" );  209  uint8_t  FirstBlockOfSector ( uint8_t  sectorNo
)  214                  return  32  *  4  + ( sectorNo 
-  32 ) *  16 ;  218  uint8_t  NumBlocksPerSector ( uint8_t  sectorNo
)  227  static int  ParamCardSizeSectors ( const char  c
) {  230                  case  '0'  :  numBlocks 
=  5 ;  break ;  231                  case  '2'  :  numBlocks 
=  32 ;  break ;  232                  case  '4'  :  numBlocks 
=  40 ;  break ;  233                  default :    numBlocks 
=  16 ;  238  static int  ParamCardSizeBlocks ( const char  c
) {  239          int  numBlocks 
=  16  *  4 ;  241                  case  '0'  :  numBlocks 
=  5  *  4 ;  break ;  242                  case  '2'  :  numBlocks 
=  32  *  4 ;  break ;  243                  case  '4'  :  numBlocks 
=  32  *  4  +  8  *  16 ;  break ;  244                  default :    numBlocks 
=  16  *  4 ;  249  int  CmdHF14AMfDump ( const char  * Cmd
)  251          uint8_t  sectorNo
,  blockNo
;  255          uint8_t  rights
[ 40 ][ 4 ];  256          uint8_t  carddata
[ 256 ][ 16 ];  257          uint8_t  numSectors 
=  16 ;  264          char  cmdp 
=  param_getchar ( Cmd
,  0 );  265          numSectors 
=  ParamCardSizeSectors ( cmdp
);  267          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  268                  PrintAndLog ( "Usage:   hf mf dump [card memory]" );  269                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  271                  PrintAndLog ( "Samples: hf mf dump" );  272                  PrintAndLog ( "         hf mf dump 4" );  276          if  (( fin 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  277                  PrintAndLog ( "Could not find file dumpkeys.bin" );  281          // Read keys A from file  282          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  283                  size_t  bytes_read 
=  fread ( keyA
[ sectorNo
],  1 ,  6 ,  fin
);  284                  if  ( bytes_read 
!=  6 ) {  285                          PrintAndLog ( "File reading error." );  291          // Read keys B from file  292          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  293                  size_t  bytes_read 
=  fread ( keyB
[ sectorNo
],  1 ,  6 ,  fin
);  294                  if  ( bytes_read 
!=  6 ) {  295                          PrintAndLog ( "File reading error." );  303          PrintAndLog ( "|-----------------------------------------|" );  304          PrintAndLog ( "|------ Reading sector access bits...-----|" );  305          PrintAndLog ( "|-----------------------------------------|" );  307          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  308                  for  ( tries 
=  0 ;  tries 
<  3 ;  tries
++) {  309                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  0 ,  0 }};  310                          memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  313                          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  314                                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  315                                  uint8_t  * data  
=  resp
. d
. asBytes
;  317                                          rights
[ sectorNo
][ 0 ] = (( data
[ 7 ] &  0x10 )>> 2 ) | (( data
[ 8 ] &  0x1 )<< 1 ) | (( data
[ 8 ] &  0x10 )>> 4 );  // C1C2C3 for data area 0  318                                          rights
[ sectorNo
][ 1 ] = (( data
[ 7 ] &  0x20 )>> 3 ) | (( data
[ 8 ] &  0x2 )<< 0 ) | (( data
[ 8 ] &  0x20 )>> 5 );  // C1C2C3 for data area 1  319                                          rights
[ sectorNo
][ 2 ] = (( data
[ 7 ] &  0x40 )>> 4 ) | (( data
[ 8 ] &  0x4 )>> 1 ) | (( data
[ 8 ] &  0x40 )>> 6 );  // C1C2C3 for data area 2  320                                          rights
[ sectorNo
][ 3 ] = (( data
[ 7 ] &  0x80 )>> 5 ) | (( data
[ 8 ] &  0x8 )>> 2 ) | (( data
[ 8 ] &  0x80 )>> 7 );  // C1C2C3 for sector trailer  322                                  }  else if  ( tries 
==  2 ) {  // on last try set defaults  323                                          PrintAndLog ( "Could not get access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  324                                          rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  325                                          rights
[ sectorNo
][ 3 ] =  0x01 ;  328                                  PrintAndLog ( "Command execute timeout when trying to read access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  329                                  rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  330                                  rights
[ sectorNo
][ 3 ] =  0x01 ;  335          PrintAndLog ( "|-----------------------------------------|" );  336          PrintAndLog ( "|----- Dumping all blocks to file... -----|" );  337          PrintAndLog ( "|-----------------------------------------|" );  340          for  ( sectorNo 
=  0 ;  isOK 
&&  sectorNo 
<  numSectors
;  sectorNo
++) {  341                  for  ( blockNo 
=  0 ;  isOK 
&&  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  342                          bool  received 
=  false ;  343                          for  ( tries 
=  0 ;  tries 
<  3 ;  tries
++) {  344                                  if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. At least the Access Conditions can always be read with key A.  345                                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  346                                          memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  348                                          received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  349                                  }  else  {                                                                                                 // data block. Check if it can be read with key A or key B  350                                          uint8_t  data_area 
=  sectorNo
< 32 ? blockNo
: blockNo
/ 5 ;  351                                          if  (( rights
[ sectorNo
][ data_area
] ==  0x03 ) || ( rights
[ sectorNo
][ data_area
] ==  0x05 )) {    // only key B would work  352                                                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  1 ,  0 }};  353                                                  memcpy ( c
. d
. asBytes
,  keyB
[ sectorNo
],  6 );  355                                                  received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  356                                          }  else if  ( rights
[ sectorNo
][ data_area
] ==  0x07 ) {                                                                                // no key would work  358                                                  PrintAndLog ( "Access rights do not allow reading of sector  %2 d block  %3 d" ,  sectorNo
,  blockNo
);  360                                          }  else  {                                                                                                                                                                 // key A would work  361                                                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  362                                                  memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  364                                                  received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  368                                          isOK  
=  resp
. arg
[ 0 ] &  0xff ;  374                                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  375                                  uint8_t  * data  
=  resp
. d
. asBytes
;  376                                  if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. Fill in the keys.  377                                          data
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  378                                          data
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  379                                          data
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  380                                          data
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  381                                          data
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  382                                          data
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  383                                          data
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  384                                          data
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  385                                          data
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  386                                          data
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  387                                          data
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  388                                          data
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  391                                          memcpy ( carddata
[ FirstBlockOfSector ( sectorNo
) +  blockNo
],  data
,  16 );  392                      PrintAndLog ( "Successfully read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  394                                          PrintAndLog ( "Could not read block  %2 d of sector  %2 d" ,  blockNo
,  sectorNo
);  400                                  PrintAndLog ( "Command execute timeout when trying to read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  407                  if  (( fout 
=  fopen ( "dumpdata.bin" , "wb" )) ==  NULL
) {  408                          PrintAndLog ( "Could not create file name dumpdata.bin" );  411                  uint16_t  numblocks 
=  FirstBlockOfSector ( numSectors 
-  1 ) +  NumBlocksPerSector ( numSectors 
-  1 );  412                  fwrite ( carddata
,  1 ,  16 * numblocks
,  fout
);  414                  PrintAndLog ( "Dumped  %d  blocks ( %d  bytes) to file dumpdata.bin" ,  numblocks
,  16 * numblocks
);  420  int  CmdHF14AMfRestore ( const char  * Cmd
)  422          uint8_t  sectorNo
, blockNo
;  424          uint8_t  key
[ 6 ] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };  425          uint8_t  bldata
[ 16 ] = { 0x00 };  433          char  cmdp 
=  param_getchar ( Cmd
,  0 );  435                  case  '0'  :  numSectors 
=  5 ;  break ;  437                  case  '\0' :  numSectors 
=  16 ;  break ;  438                  case  '2'  :  numSectors 
=  32 ;  break ;  439                  case  '4'  :  numSectors 
=  40 ;  break ;  440                  default :    numSectors 
=  16 ;  443          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  444                  PrintAndLog ( "Usage:   hf mf restore [card memory]" );  445                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  447                  PrintAndLog ( "Samples: hf mf restore" );  448                  PrintAndLog ( "         hf mf restore 4" );  452          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  453                  PrintAndLog ( "Could not find file dumpkeys.bin" );  457          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  458                  size_t  bytes_read 
=  fread ( keyA
[ sectorNo
],  1 ,  6 ,  fkeys
);  459                  if  ( bytes_read 
!=  6 ) {  460                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  466          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  467                  size_t  bytes_read 
=  fread ( keyB
[ sectorNo
],  1 ,  6 ,  fkeys
);  468                  if  ( bytes_read 
!=  6 ) {  469                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  477          if  (( fdump 
=  fopen ( "dumpdata.bin" , "rb" )) ==  NULL
) {  478                  PrintAndLog ( "Could not find file dumpdata.bin" );  481          PrintAndLog ( "Restoring dumpdata.bin to card" );  483          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  484                  for ( blockNo 
=  0 ;  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  485                          UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  keyType
,  0 }};  486                          memcpy ( c
. d
. asBytes
,  key
,  6 );  488                          size_t  bytes_read 
=  fread ( bldata
,  1 ,  16 ,  fdump
);  489                          if  ( bytes_read 
!=  16 ) {  490                                  PrintAndLog ( "File reading error (dumpdata.bin)." );  495                          if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {       // sector trailer  496                                  bldata
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  497                                  bldata
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  498                                  bldata
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  499                                  bldata
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  500                                  bldata
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  501                                  bldata
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  502                                  bldata
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  503                                  bldata
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  504                                  bldata
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  505                                  bldata
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  506                                  bldata
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  507                                  bldata
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  510                          PrintAndLog ( "Writing to block  %3 d:  %s " ,  FirstBlockOfSector ( sectorNo
) +  blockNo
,  sprint_hex ( bldata
,  16 ));  512                          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );  516                          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  517                                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  518                                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  520                                  PrintAndLog ( "Command execute timeout" );  529  //----------------------------------------------  531  //----------------------------------------------  533  static void  parseParamTDS ( const char  * Cmd
,  const uint8_t  indx
,  bool  * paramT
,  bool  * paramD
,  uint8_t  * timeout
) {  535          int  len 
=  param_getlength ( Cmd
,  indx
);  536          if  ( len 
>  0  &&  len 
<  4 ){  537                  param_getstr ( Cmd
,  indx
,  ctmp3
,  sizeof ( ctmp3
));  539                  * paramT 
|= ( ctmp3
[ 0 ] ==  't'  ||  ctmp3
[ 0 ] ==  'T' );  540                  * paramD 
|= ( ctmp3
[ 0 ] ==  'd'  ||  ctmp3
[ 0 ] ==  'D' );  541                  bool  paramS1 
= * paramT 
|| * paramD
;  543                  // slow and very slow  544                  if  ( ctmp3
[ 0 ] ==  's'  ||  ctmp3
[ 0 ] ==  'S'  ||  ctmp3
[ 1 ] ==  's'  ||  ctmp3
[ 1 ] ==  'S' ) {  545                          * timeout 
=  11 ;  // slow  547                          if  (! paramS1 
&& ( ctmp3
[ 1 ] ==  's'  ||  ctmp3
[ 1 ] ==  'S' )) {  548                                  * timeout 
=  53 ;  // very slow  550                          if  ( paramS1 
&& ( ctmp3
[ 2 ] ==  's'  ||  ctmp3
[ 2 ] ==  'S' )) {  551                                  * timeout 
=  53 ;  // very slow  557  int  CmdHF14AMfNested ( const char  * Cmd
)  559          int  i
,  j
,  res
,  iterations
;  560          sector_t 
* e_sector 
=  NULL
;  563          uint8_t  trgBlockNo 
=  0 ;  564          uint8_t  trgKeyType 
=  0 ;  565          uint8_t  SectorsCnt 
=  0 ;  566          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  567          uint8_t  keyBlock
[ MifareDefaultKeysSize 
*  6 ];  569          // timeout in units. (ms * 106)/10 or us*0.0106  570          uint8_t  btimeout14a 
=  MF_CHKKEYS_DEFTIMEOUT
;  // fast by default  572          bool  autosearchKey 
=  false ;  574          bool  transferToEml 
=  false ;  575          bool  createDumpFile 
=  false ;  577          uint8_t  standart
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  578          uint8_t  tempkey
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  583                  PrintAndLog ( "Usage:" );  584                  PrintAndLog ( " all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)> [t|d|s|ss]" );  585                  PrintAndLog ( " all sectors autosearch key:  hf mf nested  <card memory> * [t|d|s|ss]" );  586                  PrintAndLog ( " one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)>" );  587                  PrintAndLog ( "               <target block number> <target key A/B> [t]" );  589                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" );  590                  PrintAndLog ( "t - transfer keys to emulator memory" );  591                  PrintAndLog ( "d - write keys to binary file dumpkeys.bin" );  592                  PrintAndLog ( "s - Slow (1ms) check keys (required by some non standard cards)" );  593                  PrintAndLog ( "ss - Very slow (5ms) check keys" );  595                  PrintAndLog ( "      sample1: hf mf nested 1 0 A FFFFFFFFFFFF " );  596                  PrintAndLog ( "      sample2: hf mf nested 1 0 A FFFFFFFFFFFF t " );  597                  PrintAndLog ( "      sample3: hf mf nested 1 0 A FFFFFFFFFFFF d " );  598                  PrintAndLog ( "      sample4: hf mf nested o 0 A FFFFFFFFFFFF 4 A" );  599                  PrintAndLog ( "      sample5: hf mf nested 1 * t" );  600                  PrintAndLog ( "      sample6: hf mf nested 1 * ss" );  605          cmdp 
=  param_getchar ( Cmd
,  0 );  606          if  ( cmdp 
==  'o'  ||  cmdp 
==  'O' ) {  610                  SectorsCnt 
=  ParamCardSizeSectors ( cmdp
);  613          // <block number>. number or autosearch key (*)  614          if  ( param_getchar ( Cmd
,  1 ) ==  '*' ) {  615                  autosearchKey 
=  true ;  617                  parseParamTDS ( Cmd
,  2 , & transferToEml
, & createDumpFile
, & btimeout14a
);  619                  PrintAndLog ( "--nested. sectors: %2 d, block no:*, eml: %c , dmp= %c  checktimeout= %d  us" ,   620                          SectorsCnt
,  transferToEml
? 'y' : 'n' ,  createDumpFile
? 'y' : 'n' , (( int ) btimeout14a 
*  10000 ) /  106 );  622                  blockNo 
=  param_get8 ( Cmd
,  1 );  624                  ctmp 
=  param_getchar ( Cmd
,  2 );  625                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  626                          PrintAndLog ( "Key type must be A or B" );  630                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  633                  if  ( param_gethex ( Cmd
,  3 ,  key
,  12 )) {  634                          PrintAndLog ( "Key must include 12 HEX symbols" );  638                  // check if we can authenticate to sector  639                  res 
=  mfCheckKeys ( blockNo
,  keyType
,  true ,  1 ,  key
, & key64
);  641                          PrintAndLog ( "Can't authenticate to block: %3 d key type: %c  key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  647                          trgBlockNo 
=  param_get8 ( Cmd
,  4 );  649                          ctmp 
=  param_getchar ( Cmd
,  5 );  650                          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  651                                  PrintAndLog ( "Target key type must be A or B" );  654                          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  657                          parseParamTDS ( Cmd
,  6 , & transferToEml
, & createDumpFile
, & btimeout14a
);  659                          parseParamTDS ( Cmd
,  4 , & transferToEml
, & createDumpFile
, & btimeout14a
);  662                  PrintAndLog ( "--nested. sectors: %2 d, block no: %3 d, key type: %c , eml: %c , dmp= %c  checktimeout= %d  us" ,   663                          SectorsCnt
,  blockNo
,  keyType
? 'B' : 'A' ,  transferToEml
? 'y' : 'n' ,  createDumpFile
? 'y' : 'n' , (( int ) btimeout14a 
*  10000 ) /  106 );  667          if  ( cmdp 
==  'o' ) {  // ------------------------------------  one sector working  668                  PrintAndLog ( "--target block no: %3 d, target key type: %c  " ,  trgBlockNo
,  trgKeyType
? 'B' : 'A' );  669                  int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  trgBlockNo
,  trgKeyType
,  keyBlock
,  true );  672                                  case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  673                                  case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  674                                  case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  675                                  default  :  PrintAndLog ( "Unknown Error. \n " );  679                  key64 
=  bytes_to_num ( keyBlock
,  6 );  681                          PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  683                          // transfer key to the emulator  685                                  uint8_t  sectortrailer
;  686                                  if  ( trgBlockNo 
<  32 * 4 ) {         // 4 block sector  687                                          sectortrailer 
=  trgBlockNo 
|  0x03 ;  688                                  }  else  {                                         // 16 block sector  689                                          sectortrailer 
=  trgBlockNo 
|  0x0f ;  691                                  mfEmlGetMem ( keyBlock
,  sectortrailer
,  1 );  694                                          num_to_bytes ( key64
,  6 ,  keyBlock
);  696                                          num_to_bytes ( key64
,  6 , & keyBlock
[ 10 ]);  697                                  mfEmlSetMem ( keyBlock
,  sectortrailer
,  1 );  698                                  PrintAndLog ( "Key transferred to emulator memory." );  701                          PrintAndLog ( "No valid key found" );  704          else  {  // ------------------------------------  multiple sectors working  706                  msclock1 
=  msclock ();  708                  e_sector 
=  calloc ( SectorsCnt
,  sizeof ( sector_t
));  709                  if  ( e_sector 
==  NULL
)  return  1 ;  711                  //test current key and additional standard keys first  712                  for  ( int  defaultKeyCounter 
=  0 ;  defaultKeyCounter 
<  MifareDefaultKeysSize
;  defaultKeyCounter
++){  713                          num_to_bytes ( MifareDefaultKeys
[ defaultKeyCounter
],  6 , ( uint8_t *)( keyBlock 
+  defaultKeyCounter 
*  6 ));  716                  PrintAndLog ( "Testing known keys. Sector count= %d " ,  SectorsCnt
);  717                  mfCheckKeysSec ( SectorsCnt
,  2 ,  btimeout14a
,  true ,  MifareDefaultKeysSize
,  keyBlock
,  e_sector
);  719                  // get known key from array  720                  bool  keyFound 
=  false ;  722                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  723                                  for  ( j 
=  0 ;  j 
<  2 ;  j
++) {  724                                          if  ( e_sector
[ i
]. foundKey
[ j
]) {  728                                                  num_to_bytes ( e_sector
[ i
]. Key
[ j
],  6 ,  key
);  736                          // Can't found a key....  738                                  PrintAndLog ( "Can't found any of the known keys." );  742                          PrintAndLog ( "--auto key. block no: %3 d, key type: %c  key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  747                  PrintAndLog ( "nested..." );  748                  bool  calibrate 
=  true ;  749                  for  ( i 
=  0 ;  i 
<  NESTED_SECTOR_RETRY
;  i
++) {  750                          for  ( uint8_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  751                                  for  ( trgKeyType 
=  0 ;  trgKeyType 
<  2 ;  trgKeyType
++) {  752                                          if  ( e_sector
[ sectorNo
]. foundKey
[ trgKeyType
])  continue ;  753                                          PrintAndLog ( "-----------------------------------------------" );  754                                          int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  FirstBlockOfSector ( sectorNo
),  trgKeyType
,  keyBlock
,  calibrate
);  757                                                          case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  758                                                          case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  759                                                          case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  760                                                          default  :  PrintAndLog ( "Unknown Error. \n " );  770                                          key64 
=  bytes_to_num ( keyBlock
,  6 );  772                                                  PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  773                                                  e_sector
[ sectorNo
]. foundKey
[ trgKeyType
] =  1 ;  774                                                  e_sector
[ sectorNo
]. Key
[ trgKeyType
] =  key64
;  776                                                  // try to check this key as a key to the other sectors  777                                                  mfCheckKeysSec ( SectorsCnt
,  2 ,  btimeout14a
,  true ,  1 ,  keyBlock
,  e_sector
);  783                  // print nested statistic  784                  PrintAndLog ( " \n\n ----------------------------------------------- \n Nested statistic: \n Iterations count:  %d " ,  iterations
);  785                  PrintAndLog ( "Time in nested:  %1 .3f ( %1 .3f sec per key)" , (( float )( msclock () -  msclock1
))/ 1000.0 , (( float )( msclock () -  msclock1
))/ iterations
/ 1000.0 );  788                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  789                  PrintAndLog ( "|sec|key A           |res|key B           |res|" );  790                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  791                  for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  792                          PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |  %d  |   %0 12"  PRIx64 
"  |  %d  |" ,  i
,  793                                  e_sector
[ i
]. Key
[ 0 ],  e_sector
[ i
]. foundKey
[ 0 ],  e_sector
[ i
]. Key
[ 1 ],  e_sector
[ i
]. foundKey
[ 1 ]);  795                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  797                  // transfer keys to the emulator memory  799                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  800                                  mfEmlGetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  801                                  if  ( e_sector
[ i
]. foundKey
[ 0 ])  802                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  keyBlock
);  803                                  if  ( e_sector
[ i
]. foundKey
[ 1 ])  804                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 , & keyBlock
[ 10 ]);  805                                  mfEmlSetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  807                          PrintAndLog ( "Keys transferred to emulator memory." );  811                  if  ( createDumpFile
) {  812                          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "wb" )) ==  NULL
) {  813                                  PrintAndLog ( "Could not create file dumpkeys.bin" );  817                          PrintAndLog ( "Printing keys to binary file dumpkeys.bin..." );  818                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  819                                  if  ( e_sector
[ i
]. foundKey
[ 0 ]){  820                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  tempkey
);  821                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  824                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  827                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  828                                  if  ( e_sector
[ i
]. foundKey
[ 1 ]){  829                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 ,  tempkey
);  830                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  833                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  845  int  CmdHF14AMfNestedHard ( const char  * Cmd
)  849          uint8_t  trgBlockNo 
=  0 ;  850          uint8_t  trgKeyType 
=  0 ;  851          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  852          uint8_t  trgkey
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  855          ctmp 
=  param_getchar ( Cmd
,  0 );  857          if  ( ctmp 
!=  'R'  &&  ctmp 
!=  'r'  &&  ctmp 
!=  'T'  &&  ctmp 
!=  't'  &&  strlen ( Cmd
) <  20 ) {  858                  PrintAndLog ( "Usage:" );  859                  PrintAndLog ( "      hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>" );  860                  PrintAndLog ( "                       <target block number> <target key A|B> [known target key (12 hex symbols)] [w] [s]" );  861                  PrintAndLog ( "  or  hf mf hardnested r [known target key]" );  863                  PrintAndLog ( "Options: " );  864                  PrintAndLog ( "      w: Acquire nonces and write them to binary file nonces.bin" );  865                  PrintAndLog ( "      s: Slower acquisition (required by some non standard cards)" );  866                  PrintAndLog ( "      r: Read nonces.bin and start attack" );  867                  PrintAndLog ( "      iX: set type of SIMD instructions. Without this flag programs autodetect it." );  868                  PrintAndLog ( "        i5: AVX512" );  869                  PrintAndLog ( "        i2: AVX2" );  870                  PrintAndLog ( "        ia: AVX" );  871                  PrintAndLog ( "        is: SSE2" );  872                  PrintAndLog ( "        im: MMX" );  873                  PrintAndLog ( "        in: none (use CPU regular instruction set)" );  875                  PrintAndLog ( "      sample1: hf mf hardnested 0 A FFFFFFFFFFFF 4 A" );  876                  PrintAndLog ( "      sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w" );  877                  PrintAndLog ( "      sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s" );  878                  PrintAndLog ( "      sample4: hf mf hardnested r" );  880                  PrintAndLog ( "Add the known target key to check if it is present in the remaining key space:" );  881                  PrintAndLog ( "      sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF" );  885          bool  know_target_key 
=  false ;  886          bool  nonce_file_read 
=  false ;  887          bool  nonce_file_write 
=  false ;  893          if  ( ctmp 
==  'R'  ||  ctmp 
==  'r' ) {  894                  nonce_file_read 
=  true ;  896                  if  (! param_gethex ( Cmd
,  1 ,  trgkey
,  12 )) {  897                          know_target_key 
=  true ;  900          }  else if  ( ctmp 
==  'T'  ||  ctmp 
==  't' ) {  901                  tests 
=  param_get32ex ( Cmd
,  1 ,  100 ,  10 );  903                  if  (! param_gethex ( Cmd
,  2 ,  trgkey
,  12 )) {  904                          know_target_key 
=  true ;  908                  blockNo 
=  param_get8 ( Cmd
,  0 );  909                  ctmp 
=  param_getchar ( Cmd
,  1 );  910                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  911                          PrintAndLog ( "Key type must be A or B" );  914                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' ) {  918                  if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  919                          PrintAndLog ( "Key must include 12 HEX symbols" );  923                  trgBlockNo 
=  param_get8 ( Cmd
,  3 );  924                  ctmp 
=  param_getchar ( Cmd
,  4 );  925                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  926                          PrintAndLog ( "Target key type must be A or B" );  929                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' ) {  935                  if  (! param_gethex ( Cmd
,  5 ,  trgkey
,  12 )) {  936                          know_target_key 
=  true ;  941                  while  (( ctmp 
=  param_getchar ( Cmd
,  i
))) {  942                          if  ( ctmp 
==  's'  ||  ctmp 
==  'S' ) {  944                          }  else if  ( ctmp 
==  'w'  ||  ctmp 
==  'W' ) {  945                                  nonce_file_write 
=  true ;  946                          }  else if  ( param_getlength ( Cmd
,  i
) ==  2  &&  ctmp 
==  'i' ) {  949                                  PrintAndLog ( "Possible options are w , s and/or iX" );  956          SetSIMDInstr ( SIMD_AUTO
);  958                  while  (( ctmp 
=  param_getchar ( Cmd
,  iindx
))) {  959                          if  ( param_getlength ( Cmd
,  iindx
) ==  2  &&  ctmp 
==  'i' ) {  960                                  switch ( param_getchar_indx ( Cmd
,  1 ,  iindx
)) {  962                                                  SetSIMDInstr ( SIMD_AVX512
);  965                                                  SetSIMDInstr ( SIMD_AVX2
);  968                                                  SetSIMDInstr ( SIMD_AVX
);  971                                                  SetSIMDInstr ( SIMD_SSE2
);  974                                                  SetSIMDInstr ( SIMD_MMX
);  977                                                  SetSIMDInstr ( SIMD_NONE
);  980                                                  PrintAndLog ( "Unknown SIMD type.  %c " ,  param_getchar_indx ( Cmd
,  1 ,  iindx
));  988          PrintAndLog ( "--target block no: %3 d, target key type: %c , known target key: 0x %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x %s , file action:  %s , Slow:  %s , Tests:  %d  " ,  991                          trgkey
[ 0 ],  trgkey
[ 1 ],  trgkey
[ 2 ],  trgkey
[ 3 ],  trgkey
[ 4 ],  trgkey
[ 5 ],  992                          know_target_key
? "" : " (not set)" ,  993                          nonce_file_write
? "write" : nonce_file_read
? "read" : "none" ,  997          int16_t  isOK 
=  mfnestedhard ( blockNo
,  keyType
,  key
,  trgBlockNo
,  trgKeyType
,  know_target_key
? trgkey
: NULL
,  nonce_file_read
,  nonce_file_write
,  slow
,  tests
); 1001                          case  1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ; 1002                          case  2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ; 1012  int  CmdHF14AMfChk ( const char  * Cmd
) 1014          if  ( strlen ( Cmd
)< 3 ) { 1015                  PrintAndLog ( "Usage:  hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d|s|ss] [<key (12 hex symbols)>] [<dic (*.dic)>]" ); 1016                  PrintAndLog ( "          * - all sectors" ); 1017                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" ); 1018                  PrintAndLog ( "d - write keys to binary file \n " ); 1019                  PrintAndLog ( "t - write keys to emulator memory" ); 1020                  PrintAndLog ( "s - slow execute. timeout 1ms" ); 1021                  PrintAndLog ( "ss- very slow execute. timeout 5ms" ); 1022                  PrintAndLog ( "      sample: hf mf chk 0 A 1234567890ab keys.dic" ); 1023                  PrintAndLog ( "              hf mf chk *1 ? t" ); 1024                  PrintAndLog ( "              hf mf chk *1 ? d" ); 1025                  PrintAndLog ( "              hf mf chk *1 ? s" ); 1026                  PrintAndLog ( "              hf mf chk *1 ? dss" ); 1031          char  filename
[ FILE_PATH_SIZE
]={ 0 }; 1033          uint8_t  * keyBlock 
=  NULL
, * p
; 1034          uint16_t  stKeyBlock 
=  20 ; 1040          char  ctmp3
[ 3 ]   = { 0x00 }; 1041          uint8_t  blockNo 
=  0 ; 1042          uint8_t  SectorsCnt 
=  0 ; 1043          uint8_t  keyType 
=  0 ; 1045          uint32_t  timeout14a 
=  0 ;  // timeout in us 1046          bool  param3InUse 
=  false ; 1048          int  transferToEml 
=  0 ; 1049          int  createDumpFile 
=  0 ; 1051          sector_t 
* e_sector 
=  NULL
; 1053          keyBlock 
=  calloc ( stKeyBlock
,  6 ); 1054          if  ( keyBlock 
==  NULL
)  return  1 ; 1056          int  defaultKeysSize 
=  MifareDefaultKeysSize
; 1057          for  ( int  defaultKeyCounter 
=  0 ;  defaultKeyCounter 
<  defaultKeysSize
;  defaultKeyCounter
++){ 1058                  num_to_bytes ( MifareDefaultKeys
[ defaultKeyCounter
],  6 , ( uint8_t *)( keyBlock 
+  defaultKeyCounter 
*  6 )); 1061          if  ( param_getchar ( Cmd
,  0 )== '*' ) { 1062                  SectorsCnt 
=  ParamCardSizeSectors ( param_getchar ( Cmd 
+  1 ,  0 )); 1065                  blockNo 
=  param_get8 ( Cmd
,  0 ); 1067          ctmp 
=  param_getchar ( Cmd
,  1 ); 1068          clen 
=  param_getlength ( Cmd
,  1 ); 1081                          PrintAndLog ( "Key type must be A , B or ?" ); 1087          // transfer to emulator & create dump file 1088          ctmp 
=  param_getchar ( Cmd
,  2 ); 1089          clen 
=  param_getlength ( Cmd
,  2 ); 1090          if  ( clen 
==  1  && ( ctmp 
==  't'  ||  ctmp 
==  'T' ))  transferToEml 
=  1 ; 1091          if  ( clen 
==  1  && ( ctmp 
==  'd'  ||  ctmp 
==  'D' ))  createDumpFile 
=  1 ; 1093          param3InUse 
=  transferToEml 
|  createDumpFile
; 1095          timeout14a 
=  500 ;  // fast by default 1096          // double parameters - ts, ds 1097          clen 
=  param_getlength ( Cmd
,  2 ); 1098          if  ( clen 
==  2  ||  clen 
==  3 ){ 1099                  param_getstr ( Cmd
,  2 ,  ctmp3
,  sizeof ( ctmp3
)); 1103          if  ( ctmp 
==  's'  ||  ctmp 
==  'S' ) { 1104                  timeout14a 
=  1000 ;  // slow 1105                  if  (! param3InUse 
&&  clen 
==  2  && ( ctmp3
[ 1 ] ==  's'  ||  ctmp3
[ 1 ] ==  'S' )) { 1106                          timeout14a 
=  5000 ;  // very slow 1108                  if  ( param3InUse 
&&  clen 
==  3  && ( ctmp3
[ 2 ] ==  's'  ||  ctmp3
[ 2 ] ==  'S' )) { 1109                          timeout14a 
=  5000 ;  // very slow 1114          for  ( i 
=  param3InUse
;  param_getchar ( Cmd
,  2  +  i
);  i
++) { 1115                  if  (! param_gethex ( Cmd
,  2  +  i
,  keyBlock 
+  6  *  keycnt
,  12 )) { 1116                          if  (  stKeyBlock 
-  keycnt 
<  2 ) { 1117                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 )); 1119                                          PrintAndLog ( "Cannot allocate memory for Keys" ); 1125                          PrintAndLog ( "chk key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
, 1126                          ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ], 1127                          ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 ); 1130                          // May be a dic file 1131                          if  (  param_getstr ( Cmd
,  2  +  i
,  filename
,  sizeof ( filename
)) >=  FILE_PATH_SIZE 
) { 1132                                  PrintAndLog ( "File name too long" ); 1137                          if  ( ( f 
=  fopen (  filename 
,  "r" )) ) { 1138                                  while (  fgets ( buf
,  sizeof ( buf
),  f
) ){ 1139                                          if  ( strlen ( buf
) <  12  ||  buf
[ 11 ] ==  ' \n ' ) 1142                                          while  ( fgetc ( f
) !=  ' \n '  && ! feof ( f
)) ;   //goto next line 1144                                          if (  buf
[ 0 ]== '#'  )  continue ;      //The line start with # is comment, skip 1146                                          if  (! isxdigit (( unsigned char ) buf
[ 0 ])){ 1147                                                  PrintAndLog ( "File content error. ' %s ' must include 12 HEX symbols" , buf
); 1153                                          if  (  stKeyBlock 
-  keycnt 
<  2 ) { 1154                                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 )); 1156                                                          PrintAndLog ( "Cannot allocate memory for defKeys" ); 1163                                          memset ( keyBlock 
+  6  *  keycnt
,  0 ,  6 ); 1164                                          num_to_bytes ( strtoll ( buf
,  NULL
,  16 ),  6 ,  keyBlock 
+  6 * keycnt
); 1165                                          PrintAndLog ( "chk custom key[ %2 d]  %0 12"  PRIx64 
,  keycnt
,  bytes_to_num ( keyBlock 
+  6 * keycnt
,  6 )); 1167                                          memset ( buf
,  0 ,  sizeof ( buf
)); 1171                                  PrintAndLog ( "File:  %s : not found or locked." ,  filename
); 1179          // fill with default keys 1181                  PrintAndLog ( "No key specified, trying default keys" ); 1182                  for  (; keycnt 
<  defaultKeysSize
;  keycnt
++) 1183                          PrintAndLog ( "chk default key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
, 1184                                  ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ], 1185                                  ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 ); 1188          // initialize storage for found keys 1189          e_sector 
=  calloc ( SectorsCnt
,  sizeof ( sector_t
)); 1190          if  ( e_sector 
==  NULL
) { 1194          for  ( uint8_t  keyAB 
=  0 ;  keyAB 
<  2 ;  keyAB
++) { 1195                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) { 1196                          e_sector
[ sectorNo
]. Key
[ keyAB
] =  0xffffffffffff ; 1197                          e_sector
[ sectorNo
]. foundKey
[ keyAB
] =  0 ; 1202          bool  foundAKey 
=  false ; 1203          uint32_t  max_keys 
=  keycnt 
>  USB_CMD_DATA_SIZE 
/  6  ?  USB_CMD_DATA_SIZE 
/  6  :  keycnt
; 1205                  PrintAndLog ( "To cancel this operation press the button on the proxmark..." ); 1207                  for  ( uint32_t  c 
=  0 ;  c 
<  keycnt
;  c 
+=  max_keys
) { 1209                          uint32_t  size 
=  keycnt
- c 
>  max_keys 
?  max_keys 
:  keycnt
- c
; 1210                          res 
=  mfCheckKeysSec ( SectorsCnt
,  keyType
,  timeout14a 
*  1.06  /  100 ,  true ,  size
, & keyBlock
[ 6  *  c
],  e_sector
);  // timeout is (ms * 106)/10 or us*0.0106 1221                                  PrintAndLog ( "Command execute timeout" ); 1225                  int  keyAB 
=  keyType
; 1227                          for  ( uint32_t  c 
=  0 ;  c 
<  keycnt
;  c
+= max_keys
) { 1229                                  uint32_t  size 
=  keycnt
- c 
>  max_keys 
?  max_keys 
:  keycnt
- c
; 1230                                  res 
=  mfCheckKeys ( blockNo
,  keyAB 
&  0x01 ,  true ,  size
, & keyBlock
[ 6  *  c
], & key64
);  1234                                                  PrintAndLog ( "Found valid key:[ %d : %c ] %0 12"  PRIx64
,  blockNo
, ( keyAB 
&  0x01 )? 'B' : 'A' ,  key64
); 1238                                          PrintAndLog ( "Command execute timeout" ); 1241                  }  while (-- keyAB 
>  0 ); 1248                          PrintAndLog ( "|---|----------------|---|----------------|---|" ); 1249                          PrintAndLog ( "|sec|key A           |res|key B           |res|" ); 1250                          PrintAndLog ( "|---|----------------|---|----------------|---|" ); 1251                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) { 1252                                  PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |  %d  |   %0 12"  PRIx64 
"  |  %d  |" ,  i
, 1253                                          e_sector
[ i
]. Key
[ 0 ],  e_sector
[ i
]. foundKey
[ 0 ],  e_sector
[ i
]. Key
[ 1 ],  e_sector
[ i
]. foundKey
[ 1 ]); 1255                          PrintAndLog ( "|---|----------------|---|----------------|---|" ); 1259                  PrintAndLog ( "No valid keys found." ); 1262          if  ( transferToEml
) { 1264                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) { 1265                          if  ( e_sector
[ sectorNo
]. foundKey
[ 0 ] ||  e_sector
[ sectorNo
]. foundKey
[ 1 ]) { 1266                                  mfEmlGetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 ); 1267                                  for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) { 1268                                          if  ( e_sector
[ sectorNo
]. foundKey
[ t
]) { 1269                                                  num_to_bytes ( e_sector
[ sectorNo
]. Key
[ t
],  6 ,  block 
+  t 
*  10 ); 1272                                  mfEmlSetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 ); 1275                  PrintAndLog ( "Found keys have been transferred to the emulator memory" ); 1278          if  ( createDumpFile
) { 1279                  FILE  * fkeys 
=  fopen ( "dumpkeys.bin" , "wb" ); 1280                  if  ( fkeys 
==  NULL
) { 1281                          PrintAndLog ( "Could not create file dumpkeys.bin" ); 1287                  for  ( uint8_t  t 
=  0 ;  t 
<  2 ;  t
++) { 1288                          for  ( uint8_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) { 1289                                  num_to_bytes ( e_sector
[ sectorNo
]. Key
[ t
],  6 ,  mkey
); 1290                                  fwrite ( mkey
,  1 ,  6 ,  fkeys
); 1294                  PrintAndLog ( "Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys." ); 1303  void  readerAttack ( nonces_t ar_resp
[],  bool  setEmulatorMem
,  bool  doStandardAttack
) { 1304          #define ATTACK_KEY_COUNT 7  // keep same as define in iso14443a.c -> Mifare1ksim() 1305  // cannot be more than 7 or it will overrun c.d.asBytes(512) 1311          st_t sector_trailer
[ ATTACK_KEY_COUNT
]; 1312          memset ( sector_trailer
,  0x00 ,  sizeof ( sector_trailer
)); 1314          uint8_t  stSector
[ ATTACK_KEY_COUNT
]; 1315          memset ( stSector
,  0x00 ,  sizeof ( stSector
)); 1316          uint8_t  key_cnt
[ ATTACK_KEY_COUNT
]; 1317          memset ( key_cnt
,  0x00 ,  sizeof ( key_cnt
)); 1319          for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) { 1320                  if  ( ar_resp
[ i
]. ar2 
>  0 ) { 1321                          //PrintAndLog("DEBUG: Trying sector %d, cuid %08x, nt %08x, ar %08x, nr %08x, ar2 %08x, nr2 %08x",ar_resp[i].sector, ar_resp[i].cuid,ar_resp[i].nonce,ar_resp[i].ar,ar_resp[i].nr,ar_resp[i].ar2,ar_resp[i].nr2); 1322                          if  ( doStandardAttack 
&&  mfkey32 ( ar_resp
[ i
], & key
)) { 1323                                  PrintAndLog ( "  Found Key %s  for sector  %0 2d: [ %0 4x %0 8x]" , ( ar_resp
[ i
]. keytype
) ?  "B"  :  "A" ,  ar_resp
[ i
]. sector
, ( uint32_t ) ( key
>> 32 ), ( uint32_t ) ( key 
& 0xFFFFFFFF )); 1325                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) { 1326                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== ar_resp
[ i
]. sector
) { 1327                                                  if  ( ar_resp
[ i
]. keytype
== 0 ) { 1329                                                          sector_trailer
[ ii
]. keyA 
=  key
; 1330                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
; 1335                                                          sector_trailer
[ ii
]. keyB 
=  key
; 1336                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
; 1342                          }  else if  ( mfkey32_moebius ( ar_resp
[ i
+ ATTACK_KEY_COUNT
], & key
)) { 1343                                  uint8_t  sectorNum 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. sector
; 1344                                  uint8_t  keyType 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. keytype
; 1346                                  PrintAndLog ( "M-Found Key %s  for sector  %0 2d: [ %0 12"  PRIx64 
"]" 1347                                          ,  keyType 
?  "B"  :  "A" 1352                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) { 1353                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== sectorNum
) { 1356                                                          sector_trailer
[ ii
]. keyA 
=  key
; 1357                                                          stSector
[ ii
] =  sectorNum
; 1362                                                          sector_trailer
[ ii
]. keyB 
=  key
; 1363                                                          stSector
[ ii
] =  sectorNum
; 1373          //set emulator memory for keys 1374          if  ( setEmulatorMem
) { 1375                  for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) { 1377                                  uint8_t  memBlock
[ 16 ]; 1378                                  memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1380                                  memset ( cmd1
, 0x00 , sizeof ( cmd1
)); 1381                                  snprintf ( cmd1
, sizeof ( cmd1
), " %0 4x %0 8xFF078069 %0 4x %0 8x" ,( uint32_t ) ( sector_trailer
[ i
]. keyA
>> 32 ), ( uint32_t ) ( sector_trailer
[ i
]. keyA 
& 0xFFFFFFFF ),( uint32_t ) ( sector_trailer
[ i
]. keyB
>> 32 ), ( uint32_t ) ( sector_trailer
[ i
]. keyB 
& 0xFFFFFFFF )); 1382                                  PrintAndLog ( "Setting Emulator Memory Block  %0 2d: [ %s ]" , stSector
[ i
]* 4 + 3 ,  cmd1
); 1383                                  if  ( param_gethex ( cmd1
,  0 ,  memBlock
,  32 )) { 1384                                          PrintAndLog ( "block data must include 32 HEX symbols" ); 1388                                  UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, {( stSector
[ i
]* 4 + 3 ),  1 ,  0 }}; 1389                                  memcpy ( c
. d
. asBytes
,  memBlock
,  16 ); 1390                                  clearCommandBuffer (); 1396          //un-comment to use as well moebius attack 1397          for (uint8_t i = ATTACK_KEY_COUNT; i<ATTACK_KEY_COUNT*2; i++) { 1398                  if (ar_resp[i].ar2 > 0) { 1399                          if (tryMfk32_moebius(ar_resp[i], &key)) { 1400                                  PrintAndLog("M-Found Key%s for sector %02d: [%04x%08x]", (ar_resp[i].keytype) ? "B" : "A", ar_resp[i].sector, (uint32_t) (key>>32), (uint32_t) (key &0xFFFFFFFF)); 1406  int  usage_hf14_mf1ksim ( void ) { 1407          PrintAndLog ( "Usage:  hf mf sim h u <uid (8, 14, or 20 hex symbols)> n <numreads> i x" ); 1408          PrintAndLog ( "options:" ); 1409          PrintAndLog ( "      h    this help" ); 1410          PrintAndLog ( "      u    (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used" ); 1411          PrintAndLog ( "      n    (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite" ); 1412          PrintAndLog ( "      i    (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted" ); 1413          PrintAndLog ( "      x    (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)" ); 1414          PrintAndLog ( "      e    (Optional) set keys found from 'reader attack' to emulator memory (implies x and i)" ); 1415          PrintAndLog ( "      f    (Optional) get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)" ); 1416          PrintAndLog ( "      r    (Optional) Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works." ); 1417          PrintAndLog ( "samples:" ); 1418          PrintAndLog ( "           hf mf sim u 0a0a0a0a" ); 1419          PrintAndLog ( "           hf mf sim u 11223344556677" ); 1420          PrintAndLog ( "           hf mf sim u 112233445566778899AA" ); 1421          PrintAndLog ( "           hf mf sim f uids.txt" ); 1422          PrintAndLog ( "           hf mf sim u 0a0a0a0a e" ); 1427  int  CmdHF14AMf1kSim ( const char  * Cmd
) { 1429          uint8_t  uid
[ 10 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 }; 1430          uint8_t  exitAfterNReads 
=  0 ; 1434          bool  setEmulatorMem 
=  false ; 1435          bool  attackFromFile 
=  false ; 1437          char  filename
[ FILE_PATH_SIZE
]; 1438          memset ( filename
,  0x00 ,  sizeof ( filename
)); 1443          bool  errors 
=  false ; 1445          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ) { 1446                  switch ( param_getchar ( Cmd
,  cmdp
)) { 1449                          setEmulatorMem 
=  true ; 1451                          flags 
|=  FLAG_INTERACTIVE
; 1452                          flags 
|=  FLAG_NR_AR_ATTACK
; 1457                          len 
=  param_getstr ( Cmd
,  cmdp
+ 1 ,  filename
,  sizeof ( filename
)); 1459                                  PrintAndLog ( "error no filename found" ); 1462                          attackFromFile 
=  true ; 1464                          flags 
|=  FLAG_INTERACTIVE
; 1465                          flags 
|=  FLAG_NR_AR_ATTACK
; 1470                          return  usage_hf14_mf1ksim (); 1473                          flags 
|=  FLAG_INTERACTIVE
; 1478                          exitAfterNReads 
=  param_get8 ( Cmd
,  pnr
+ 1 ); 1483                          flags 
|=  FLAG_RANDOM_NONCE
; 1488                          param_gethex_ex ( Cmd
,  cmdp
+ 1 ,  uid
, & uidlen
); 1490                                  case  20 :  flags 
=  FLAG_10B_UID_IN_DATA
;   break ;  //not complete 1491                                  case  14 :  flags 
=  FLAG_7B_UID_IN_DATA
;  break ; 1492                                  case   8 :  flags 
=  FLAG_4B_UID_IN_DATA
;  break ; 1493                                  default :  return  usage_hf14_mf1ksim (); 1499                          flags 
|=  FLAG_NR_AR_ATTACK
; 1503                          PrintAndLog ( "Unknown parameter ' %c '" ,  param_getchar ( Cmd
,  cmdp
)); 1510          if ( errors
)  return  usage_hf14_mf1ksim (); 1513          if  ( attackFromFile
) { 1516                  f 
=  fopen ( filename
,  "r" ); 1518                          PrintAndLog ( "File  %s  not found or locked" ,  filename
); 1521                  PrintAndLog ( "Loading file and simulating. Press keyboard to abort" ); 1522                  while (! feof ( f
) && ! ukbhit ()){ 1523                          memset ( buf
,  0 ,  sizeof ( buf
)); 1524                          memset ( uid
,  0 ,  sizeof ( uid
)); 1526                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) { 1527                                  if  ( count 
>  0 )  break ; 1529                                  PrintAndLog ( "File reading error." ); 1533                          if (! strlen ( buf
) &&  feof ( f
))  break ; 1535                          uidlen 
=  strlen ( buf
)- 1 ; 1537                                  case  20 :  flags 
|=  FLAG_10B_UID_IN_DATA
;  break ;  //not complete 1538                                  case  14 :  flags 
|=  FLAG_7B_UID_IN_DATA
;  break ; 1539                                  case   8 :  flags 
|=  FLAG_4B_UID_IN_DATA
;  break ; 1541                                          PrintAndLog ( "uid in file wrong length at  %d  (length:  %d ) [ %s ]" , count
,  uidlen
,  buf
); 1546                          for  ( uint8_t  i 
=  0 ;  i 
<  uidlen
;  i 
+=  2 ) { 1547                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& uid
[ i 
/  2 ]); 1550                          PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) - press button to abort" , 1551                                          flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ): 1552                                                  flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ): 1553                                                          flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A" 1554                                          ,  exitAfterNReads
,  flags
,  flags
); 1556                          UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }}; 1557                          memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
)); 1558                          clearCommandBuffer (); 1561                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) { 1562                                  //We're waiting only 1.5 s at a time, otherwise we get the 1563                                  // annoying message about "Waiting for a response... " 1566                          nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ]; 1567                          memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
)); 1568                          // We can skip the standard attack if we have RANDOM_NONCE set. 1569                          readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
)); 1570                          if  (( bool ) resp
. arg
[ 1 ]) { 1571                                  PrintAndLog ( "Device button pressed - quitting" ); 1578          }  else  {  //not from file 1580                  PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) " , 1581                                  flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ): 1582                                          flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ): 1583                                                  flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A" 1584                                  ,  exitAfterNReads
,  flags
,  flags
); 1586                  UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }}; 1587                  memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
)); 1588                  clearCommandBuffer (); 1591                  if ( flags 
&  FLAG_INTERACTIVE
) { 1592                          PrintAndLog ( "Press pm3-button to abort simulation" ); 1593                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) { 1594                                  //We're waiting only 1.5 s at a time, otherwise we get the 1595                                  // annoying message about "Waiting for a response... " 1598                          if  ( flags 
&  FLAG_NR_AR_ATTACK
) { 1599                                  nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ]; 1600                                  memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
)); 1601                                  // We can skip the standard attack if we have RANDOM_NONCE set. 1602                                  readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
)); 1610  int  CmdHF14AMfDbg ( const char  * Cmd
) 1612          int  dbgMode 
=  param_get32ex ( Cmd
,  0 ,  0 ,  10 ); 1614                  PrintAndLog ( "Max debug mode parameter is 4  \n " ); 1617          if  ( strlen ( Cmd
) <  1  || ! param_getchar ( Cmd
,  0 ) ||  dbgMode 
>  4 ) { 1618                  PrintAndLog ( "Usage:  hf mf dbg  <debug level>" ); 1619                  PrintAndLog ( " 0 - no debug messages" ); 1620                  PrintAndLog ( " 1 - error messages" ); 1621                  PrintAndLog ( " 2 - plus information messages" ); 1622                  PrintAndLog ( " 3 - plus debug messages" ); 1623                  PrintAndLog ( " 4 - print even debug messages in timing critical functions" ); 1624                  PrintAndLog ( "     Note: this option therefore may cause malfunction itself" ); 1628    UsbCommand c 
= { CMD_MIFARE_SET_DBGMODE
, { dbgMode
,  0 ,  0 }}; 1634  int  CmdHF14AMfEGet ( const char  * Cmd
) 1636          uint8_t  blockNo 
=  0 ; 1637          uint8_t  data
[ 16 ] = { 0x00 }; 1639          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1640                  PrintAndLog ( "Usage:  hf mf eget <block number>" ); 1641                  PrintAndLog ( " sample: hf mf eget 0 " ); 1645          blockNo 
=  param_get8 ( Cmd
,  0 ); 1648          if  (! mfEmlGetMem ( data
,  blockNo
,  1 )) { 1649                  PrintAndLog ( "data[ %3 d]: %s " ,  blockNo
,  sprint_hex ( data
,  16 )); 1651                  PrintAndLog ( "Command execute timeout" ); 1657  int  CmdHF14AMfEClear ( const char  * Cmd
) 1659          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 1660                  PrintAndLog ( "Usage:  hf mf eclr" ); 1661                  PrintAndLog ( "It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF  \n " ); 1665    UsbCommand c 
= { CMD_MIFARE_EML_MEMCLR
, { 0 ,  0 ,  0 }}; 1671  int  CmdHF14AMfESet ( const char  * Cmd
) 1673          uint8_t  memBlock
[ 16 ]; 1674          uint8_t  blockNo 
=  0 ; 1676          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1678          if  ( strlen ( Cmd
) <  3  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1679                  PrintAndLog ( "Usage:  hf mf eset <block number> <block data (32 hex symbols)>" ); 1680                  PrintAndLog ( " sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f " ); 1684          blockNo 
=  param_get8 ( Cmd
,  0 ); 1686          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) { 1687                  PrintAndLog ( "block data must include 32 HEX symbols" ); 1692          return  mfEmlSetMem ( memBlock
,  blockNo
,  1 ); 1696  int  CmdHF14AMfELoad ( const char  * Cmd
) 1699          char  filename
[ FILE_PATH_SIZE
]; 1700          char  * fnameptr 
=  filename
; 1701          char  buf
[ 64 ] = { 0x00 }; 1702          uint8_t  buf8
[ 64 ] = { 0x00 }; 1703          int  i
,  len
,  blockNum
,  numBlocks
; 1704          int  nameParamNo 
=  1 ; 1706          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1708          if  (  ctmp 
==  'h'  ||  ctmp 
==  0x00 ) { 1709                  PrintAndLog ( "It loads emul dump from the file `filename.eml`" ); 1710                  PrintAndLog ( "Usage:  hf mf eload [card memory] <file name w/o `.eml`>" ); 1711                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1713                  PrintAndLog ( " sample: hf mf eload filename" ); 1714                  PrintAndLog ( "         hf mf eload 4 filename" ); 1719                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ; 1721                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ; 1722                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ; 1723                  case  '4'  :  numBlocks 
=  256 ;  break ; 1730          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
, sizeof ( filename
)); 1732          if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 1736          sprintf ( fnameptr
,  ".eml" ); 1739          f 
=  fopen ( filename
,  "r" ); 1741                  PrintAndLog ( "File  %s  not found or locked" ,  filename
); 1747                  memset ( buf
,  0 ,  sizeof ( buf
)); 1749                  if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) { 1751                          if  ( blockNum 
>=  numBlocks
)  break ; 1753                          PrintAndLog ( "File reading error." ); 1758                  if  ( strlen ( buf
) <  32 ){ 1759                          if ( strlen ( buf
) &&  feof ( f
)) 1761                          PrintAndLog ( "File content error. Block data must include 32 HEX symbols" ); 1766                  for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 ) { 1767                          sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]); 1770                  if  ( mfEmlSetMem ( buf8
,  blockNum
,  1 )) { 1771                          PrintAndLog ( "Cant set emul block:  %3 d" ,  blockNum
); 1778                  if  ( blockNum 
>=  numBlocks
)  break ; 1783          if  (( blockNum 
!=  numBlocks
)) { 1784                  PrintAndLog ( "File content error. Got  %d  must be  %d  blocks." , blockNum
,  numBlocks
); 1787          PrintAndLog ( "Loaded  %d  blocks from file:  %s " ,  blockNum
,  filename
); 1792  int  CmdHF14AMfESave ( const char  * Cmd
) 1795          char  filename
[ FILE_PATH_SIZE
]; 1796          char  *  fnameptr 
=  filename
; 1798          int  i
,  j
,  len
,  numBlocks
; 1799          int  nameParamNo 
=  1 ; 1801          memset ( filename
,  0 ,  sizeof ( filename
)); 1802          memset ( buf
,  0 ,  sizeof ( buf
)); 1804          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1806          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H' ) { 1807                  PrintAndLog ( "It saves emul dump into the file `filename.eml` or `cardID.eml`" ); 1808                  PrintAndLog ( " Usage:  hf mf esave [card memory] [file name w/o `.eml`]" ); 1809                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1811                  PrintAndLog ( " sample: hf mf esave " ); 1812                  PrintAndLog ( "         hf mf esave 4" ); 1813                  PrintAndLog ( "         hf mf esave 4 filename" ); 1818                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ; 1820                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ; 1821                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ; 1822                  case  '4'  :  numBlocks 
=  256 ;  break ; 1829          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
, sizeof ( filename
)); 1831          if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 1833          // user supplied filename? 1835                  // get filename (UID from memory) 1836                  if  ( mfEmlGetMem ( buf
,  0 ,  1 )) { 1837                          PrintAndLog ( "Can \' t get UID from block:  %d " ,  0 ); 1838                          len 
=  sprintf ( fnameptr
,  "dump" ); 1842                          for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 ) 1843                                  sprintf ( fnameptr
,  " %0 2X" ,  buf
[ j
]); 1849          // add file extension 1850          sprintf ( fnameptr
,  ".eml" ); 1853          f 
=  fopen ( filename
,  "w+" ); 1856                  PrintAndLog ( "Can't open file  %s  " ,  filename
); 1861          for  ( i 
=  0 ;  i 
<  numBlocks
;  i
++) { 1862                  if  ( mfEmlGetMem ( buf
,  i
,  1 )) { 1863                          PrintAndLog ( "Cant get block:  %d " ,  i
); 1866                  for  ( j 
=  0 ;  j 
<  16 ;  j
++) 1867                          fprintf ( f
,  " %0 2X" ,  buf
[ j
]); 1872          PrintAndLog ( "Saved  %d  blocks to file:  %s " ,  numBlocks
,  filename
); 1878  int  CmdHF14AMfECFill ( const char  * Cmd
) 1880          uint8_t  keyType 
=  0 ; 1881          uint8_t  numSectors 
=  16 ; 1883          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1884                  PrintAndLog ( "Usage:  hf mf ecfill <key A/B> [card memory]" ); 1885                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1887                  PrintAndLog ( "samples:  hf mf ecfill A" ); 1888                  PrintAndLog ( "          hf mf ecfill A 4" ); 1889                  PrintAndLog ( "Read card and transfer its data to emulator memory." ); 1890                  PrintAndLog ( "Keys must be laid in the emulator memory.  \n " ); 1894          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1895          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) { 1896                  PrintAndLog ( "Key type must be A or B" ); 1899          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  keyType 
=  1 ; 1901          ctmp 
=  param_getchar ( Cmd
,  1 ); 1903                  case  '0'  :  numSectors 
=  5 ;  break ; 1905                  case  '\0' :  numSectors 
=  16 ;  break ; 1906                  case  '2'  :  numSectors 
=  32 ;  break ; 1907                  case  '4'  :  numSectors 
=  40 ;  break ; 1908                  default :    numSectors 
=  16 ; 1911          printf ( "--params: numSectors:  %d , keyType: %d \n " ,  numSectors
,  keyType
); 1912          UsbCommand c 
= { CMD_MIFARE_EML_CARDLOAD
, { numSectors
,  keyType
,  0 }}; 1917  int  CmdHF14AMfEKeyPrn ( const char  * Cmd
) 1922          uint64_t  keyA
,  keyB
; 1924          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 1925                  PrintAndLog ( "It prints the keys loaded in the emulator memory" ); 1926                  PrintAndLog ( "Usage:  hf mf ekeyprn [card memory]" ); 1927                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1929                  PrintAndLog ( " sample: hf mf ekeyprn 1" ); 1933          char  cmdp 
=  param_getchar ( Cmd
,  0 ); 1936                  case  '0'  :  numSectors 
=  5 ;  break ; 1938                  case  '\0' :  numSectors 
=  16 ;  break ; 1939                  case  '2'  :  numSectors 
=  32 ;  break ; 1940                  case  '4'  :  numSectors 
=  40 ;  break ; 1941                  default :    numSectors 
=  16 ; 1944          PrintAndLog ( "|---|----------------|----------------|" ); 1945          PrintAndLog ( "|sec|key A           |key B           |" ); 1946          PrintAndLog ( "|---|----------------|----------------|" ); 1947          for  ( i 
=  0 ;  i 
<  numSectors
;  i
++) { 1948                  if  ( mfEmlGetMem ( data
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 )) { 1949                          PrintAndLog ( "error get block  %d " ,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ); 1952                  keyA 
=  bytes_to_num ( data
,  6 ); 1953                  keyB 
=  bytes_to_num ( data 
+  10 ,  6 ); 1954                  PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |   %0 12"  PRIx64 
"  |" ,  i
,  keyA
,  keyB
); 1956          PrintAndLog ( "|---|----------------|----------------|" ); 1961  int  CmdHF14AMfCSetUID ( const char  * Cmd
) 1963          uint8_t  uid
[ 8 ] = { 0x00 }; 1964          uint8_t  oldUid
[ 8 ] = { 0x00 }; 1965          uint8_t  atqa
[ 2 ] = { 0x00 }; 1966          uint8_t  sak
[ 1 ] = { 0x00 }; 1967          uint8_t  atqaPresent 
=  0 ; 1970          uint8_t  needHelp 
=  0 ; 1973          if  ( param_getchar ( Cmd
,  0 ) &&  param_gethex ( Cmd
,  0 ,  uid
,  8 )) { 1974                  PrintAndLog ( "UID must include 8 HEX symbols" ); 1978          if  ( param_getlength ( Cmd
,  1 ) >  1  &&  param_getlength ( Cmd
,  2 ) >   1 ) { 1982                  if  ( param_gethex ( Cmd
,  1 ,  atqa
,  4 )) { 1983                          PrintAndLog ( "ATQA must include 4 HEX symbols" ); 1987                  if  ( param_gethex ( Cmd
,  2 ,  sak
,  2 )) { 1988                          PrintAndLog ( "SAK must include 2 HEX symbols" ); 1993          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ) 1995                  switch ( param_getchar ( Cmd
,  cmdp
)) 2002                          PrintAndLog ( "ERROR: Unknown parameter ' %c '" ,  param_getchar ( Cmd
,  cmdp
)); 2009          if  ( strlen ( Cmd
) <  1  ||  needHelp
) { 2011                  PrintAndLog ( "Usage:  hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols]" ); 2012                  PrintAndLog ( "sample:  hf mf csetuid 01020304" ); 2013                  PrintAndLog ( "sample:  hf mf csetuid 01020304 0004 08" ); 2014                  PrintAndLog ( "Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)" ); 2018          PrintAndLog ( "uid: %s " ,  sprint_hex ( uid
,  4 )); 2020                  PrintAndLog ( "--atqa: %s  sak: %0 2x" ,  sprint_hex ( atqa
,  2 ),  sak
[ 0 ]); 2023          res 
=  mfCSetUID ( uid
, ( atqaPresent
)? atqa
: NULL
, ( atqaPresent
)? sak
: NULL
,  oldUid
); 2025                          PrintAndLog ( "Can't set UID. Error= %d " ,  res
); 2029          PrintAndLog ( "old UID: %s " ,  sprint_hex ( oldUid
,  4 )); 2030          PrintAndLog ( "new UID: %s " ,  sprint_hex ( uid
,  4 )); 2034  int  CmdHF14AMfCWipe ( const char  * Cmd
) 2037          int  numBlocks 
=  16  *  4 ; 2038          bool  wipeCard 
=  false ; 2039          bool  fillCard 
=  false ; 2041          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 2042                  PrintAndLog ( "Usage:  hf mf cwipe [card size] [w] [f]" ); 2043                  PrintAndLog ( "sample:  hf mf cwipe 1 w f" ); 2044                  PrintAndLog ( "[card size]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 2045                  PrintAndLog ( "w - Wipe magic Chinese card (only works with gen:1a cards)" ); 2046                  PrintAndLog ( "f - Fill the card with default data and keys (works with gen:1a and gen:1b cards only)" ); 2050          gen 
=  mfCIdentify (); 2051          if  (( gen 
!=  1 ) && ( gen 
!=  2 ))  2054          numBlocks 
=  ParamCardSizeBlocks ( param_getchar ( Cmd
,  0 )); 2057          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ){ 2058                  switch ( param_getchar ( Cmd
,  cmdp
)) { 2073          if  (! wipeCard 
&& ! fillCard
)  2076          PrintAndLog ( "--blocks count: %2 d wipe: %c  fill: %c " ,  numBlocks
, ( wipeCard
)? 'y' : 'n' , ( fillCard
)? 'y' : 'n' ); 2079                  /* generation 1b magic card */ 2081                          PrintAndLog ( "WARNING: can't wipe magic card 1b generation" ); 2083                  res 
=  mfCWipe ( numBlocks
,  true ,  false ,  fillCard
);  2085                  /* generation 1a magic card by default */ 2086                  res 
=  mfCWipe ( numBlocks
,  false ,  wipeCard
,  fillCard
);  2090                  PrintAndLog ( "Can't wipe. error= %d " ,  res
); 2097  int  CmdHF14AMfCSetBlk ( const char  * Cmd
) 2099          uint8_t  memBlock
[ 16 ] = { 0x00 }; 2100          uint8_t  blockNo 
=  0 ; 2101          bool  wipeCard 
=  false ; 2104          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 2105                  PrintAndLog ( "Usage:  hf mf csetblk <block number> <block data (32 hex symbols)> [w]" ); 2106                  PrintAndLog ( "sample:  hf mf csetblk 1 01020304050607080910111213141516" ); 2107                  PrintAndLog ( "Set block data for magic Chinese card (only works with such cards)" ); 2108                  PrintAndLog ( "If you also want wipe the card then add 'w' at the end of the command line" ); 2112          gen 
=  mfCIdentify (); 2113          if  (( gen 
!=  1 ) && ( gen 
!=  2 ))  2116          blockNo 
=  param_get8 ( Cmd
,  0 ); 2118          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) { 2119                  PrintAndLog ( "block data must include 32 HEX symbols" ); 2123          char  ctmp 
=  param_getchar ( Cmd
,  2 ); 2124          wipeCard 
= ( ctmp 
==  'w'  ||  ctmp 
==  'W' ); 2125          PrintAndLog ( "--block number: %2 d data: %s " ,  blockNo
,  sprint_hex ( memBlock
,  16 )); 2128                  /* generation 1b magic card */ 2129                  res 
=  mfCSetBlock ( blockNo
,  memBlock
,  NULL
,  wipeCard
,  CSETBLOCK_SINGLE_OPER 
|  CSETBLOCK_MAGIC_1B
); 2131                  /* generation 1a magic card by default */ 2132                  res 
=  mfCSetBlock ( blockNo
,  memBlock
,  NULL
,  wipeCard
,  CSETBLOCK_SINGLE_OPER
); 2136                  PrintAndLog ( "Can't write block. error= %d " ,  res
); 2143  int  CmdHF14AMfCLoad ( const char  * Cmd
) 2146          char  filename
[ FILE_PATH_SIZE
] = { 0x00 }; 2147          char  *  fnameptr 
=  filename
; 2148          char  buf
[ 256 ] = { 0x00 }; 2149          uint8_t  buf8
[ 256 ] = { 0x00 }; 2150          uint8_t  fillFromEmulator 
=  0 ; 2151          int  i
,  len
,  blockNum
,  flags 
=  0 ,  gen 
=  0 ,  numblock 
=  64 ; 2153          if  ( param_getchar ( Cmd
,  0 ) ==  'h'  ||  param_getchar ( Cmd
,  0 )==  0x00 ) { 2154                  PrintAndLog ( "It loads magic Chinese card from the file `filename.eml`" ); 2155                  PrintAndLog ( "or from emulator memory (option `e`). 4K card: (option `4`)" ); 2156                  PrintAndLog ( "Usage:  hf mf cload [file name w/o `.eml`][e][4]" ); 2157                  PrintAndLog ( "   or:  hf mf cload e [4]" ); 2158                  PrintAndLog ( "Sample: hf mf cload filename" ); 2159                  PrintAndLog ( "        hf mf cload filname 4" ); 2160                  PrintAndLog ( "        hf mf cload e" ); 2161                  PrintAndLog ( "        hf mf cload e 4" ); 2165          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 2166          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ; 2167          ctmp 
=  param_getchar ( Cmd
,  1 ); 2168          if  ( ctmp 
==  '4' )  numblock 
=  256 ; 2170          gen 
=  mfCIdentify (); 2171          PrintAndLog ( "Loading magic mifare  %d K" ,  numblock 
==  256  ?  4 : 1 ); 2173          if  ( fillFromEmulator
) { 2174                  for  ( blockNum 
=  0 ;  blockNum 
<  numblock
;  blockNum 
+=  1 ) { 2175                          if  ( mfEmlGetMem ( buf8
,  blockNum
,  1 )) { 2176                                  PrintAndLog ( "Cant get block:  %d " ,  blockNum
); 2179                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence 2180                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write 2181                          if  ( blockNum 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;            // Done. Magic Halt and switch off field. 2184                                  /* generation 1b magic card */ 2185                                  flags 
|=  CSETBLOCK_MAGIC_1B
; 2186                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) { 2187                                  PrintAndLog ( "Cant set magic card block:  %d " ,  blockNum
); 2193                  param_getstr ( Cmd
,  0 ,  filename
,  sizeof ( filename
)); 2195                  len 
=  strlen ( filename
); 2196                  if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 2198                  //memcpy(filename, Cmd, len); 2201                  sprintf ( fnameptr
,  ".eml" ); 2204                  f 
=  fopen ( filename
,  "r" ); 2206                          PrintAndLog ( "File not found or locked." ); 2213                          memset ( buf
,  0 ,  sizeof ( buf
)); 2215                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) { 2217                                  PrintAndLog ( "File reading error." ); 2221                          if  ( strlen ( buf
) <  32 ) { 2222                                  if ( strlen ( buf
) &&  feof ( f
)) 2224                                  PrintAndLog ( "File content error. Block data must include 32 HEX symbols" ); 2228                          for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 ) 2229                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]); 2231                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence 2232                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write 2233                          if  ( blockNum 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;            // Done. Switch off field. 2236                                  /* generation 1b magic card */ 2237                                  flags 
|=  CSETBLOCK_MAGIC_1B
; 2238                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) { 2239                                  PrintAndLog ( "Can't set magic card block:  %d " ,  blockNum
); 2245                          if  ( blockNum 
>=  numblock
)  break ;   // magic card type - mifare 1K 64 blocks, mifare 4k 256 blocks 2249                  //if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){ 2250                  if  ( blockNum 
!=  numblock
){ 2251                          PrintAndLog ( "File content error. There must be  %d  blocks" ,  numblock
); 2254                  PrintAndLog ( "Loaded from file:  %s " ,  filename
); 2260  int  CmdHF14AMfCGetBlk ( const char  * Cmd
) { 2261          uint8_t  memBlock
[ 16 ]; 2262          uint8_t  blockNo 
=  0 ; 2264          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 2266          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 2267                  PrintAndLog ( "Usage:  hf mf cgetblk <block number>" ); 2268                  PrintAndLog ( "sample:  hf mf cgetblk 1" ); 2269                  PrintAndLog ( "Get block data from magic Chinese card (only works with such cards) \n " ); 2273          gen 
=  mfCIdentify (); 2275          blockNo 
=  param_get8 ( Cmd
,  0 ); 2277          PrintAndLog ( "--block number: %2 d " ,  blockNo
); 2280                  /* generation 1b magic card */ 2281                  res 
=  mfCGetBlock ( blockNo
,  memBlock
,  CSETBLOCK_SINGLE_OPER 
|  CSETBLOCK_MAGIC_1B
); 2283                  /* generation 1a magic card by default */ 2284                  res 
=  mfCGetBlock ( blockNo
,  memBlock
,  CSETBLOCK_SINGLE_OPER
); 2287                          PrintAndLog ( "Can't read block. error= %d " ,  res
); 2291          PrintAndLog ( "block data: %s " ,  sprint_hex ( memBlock
,  16 )); 2295  int  CmdHF14AMfCGetSc ( const char  * Cmd
) { 2296          uint8_t  memBlock
[ 16 ] = { 0x00 }; 2297          uint8_t  sectorNo 
=  0 ; 2298          int  i
,  res
,  flags
,  gen 
=  0 ,  baseblock 
=  0 ,  sect_size 
=  4 ; 2300          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 2301                  PrintAndLog ( "Usage:  hf mf cgetsc <sector number>" ); 2302                  PrintAndLog ( "sample:  hf mf cgetsc 0" ); 2303                  PrintAndLog ( "Get sector data from magic Chinese card (only works with such cards) \n " ); 2307          sectorNo 
=  param_get8 ( Cmd
,  0 ); 2309          if  ( sectorNo 
>  39 ) { 2310                  PrintAndLog ( "Sector number must be in [0..15] in MIFARE classic 1k and [0..39] in MIFARE classic 4k." ); 2314          PrintAndLog ( "--sector number: %d  " ,  sectorNo
); 2316          gen 
=  mfCIdentify (); 2318          flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 2319          if  ( sectorNo 
<  32  ) { 2320                  baseblock 
=  sectorNo 
*  4 ; 2322                  baseblock 
=  128  +  16  * ( sectorNo 
-  32 ); 2325          if  ( sectorNo 
>  31 )  sect_size 
=  16 ; 2327          for  ( i 
=  0 ;  i 
<  sect_size
;  i
++) { 2328                  if  ( i 
==  1 )  flags 
=  0 ; 2329                  if  ( i 
==  sect_size 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 2332                          /* generation 1b magic card */ 2333                          flags 
|=  CSETBLOCK_MAGIC_1B
; 2335                  res 
=  mfCGetBlock ( baseblock 
+  i
,  memBlock
,  flags
); 2337                          PrintAndLog ( "Can't read block.  %d  error= %d " ,  baseblock 
+  i
,  res
); 2341                  PrintAndLog ( "block  %3 d data: %s " ,  baseblock 
+  i
,  sprint_hex ( memBlock
,  16 )); 2347  int  CmdHF14AMfCSave ( const char  * Cmd
) { 2350          char  filename
[ FILE_PATH_SIZE
] = { 0x00 }; 2351          char  *  fnameptr 
=  filename
; 2352          uint8_t  fillFromEmulator 
=  0 ; 2353          uint8_t  buf
[ 256 ] = { 0x00 }; 2354          int  i
,  j
,  len
,  flags
,  gen 
=  0 ,  numblock 
=  64 ; 2356          // memset(filename, 0, sizeof(filename)); 2357          // memset(buf, 0, sizeof(buf)); 2359          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 2360                  PrintAndLog ( "It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`" ); 2361                  PrintAndLog ( "or into emulator memory (option `e`). 4K card: (option `4`)" ); 2362                  PrintAndLog ( "Usage:  hf mf csave [file name w/o `.eml`][e][4]" ); 2363                  PrintAndLog ( "Sample: hf mf csave " ); 2364                  PrintAndLog ( "        hf mf csave filename" ); 2365                  PrintAndLog ( "        hf mf csave e" ); 2366                  PrintAndLog ( "        hf mf csave 4" ); 2367                  PrintAndLog ( "        hf mf csave filename 4" ); 2368                  PrintAndLog ( "        hf mf csave e 4" ); 2372          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 2373          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ; 2374          if  ( ctmp 
==  '4' )  numblock 
=  256 ; 2375          ctmp 
=  param_getchar ( Cmd
,  1 ); 2376          if  ( ctmp 
==  '4' )  numblock 
=  256 ; 2378          gen 
=  mfCIdentify (); 2379          PrintAndLog ( "Saving magic mifare  %d K" ,  numblock 
==  256  ?  4 : 1 ); 2381          if  ( fillFromEmulator
) { 2382                  // put into emulator 2383                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 2384                  for  ( i 
=  0 ;  i 
<  numblock
;  i
++) { 2385                          if  ( i 
==  1 )  flags 
=  0 ; 2386                          if  ( i 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 2389                                  /* generation 1b magic card */ 2390                                  flags 
|=  CSETBLOCK_MAGIC_1B
; 2392                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) { 2393                                  PrintAndLog ( "Cant get block:  %d " ,  i
); 2397                          if  ( mfEmlSetMem ( buf
,  i
,  1 )) { 2398                                  PrintAndLog ( "Cant set emul block:  %d " ,  i
); 2404                  param_getstr ( Cmd
,  0 ,  filename
,  sizeof ( filename
)); 2406                  len 
=  strlen ( filename
); 2407                  if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 2409                  ctmp 
=  param_getchar ( Cmd
,  0 ); 2410                  if  ( len 
<  1  || ( ctmp 
==  '4' )) { 2413                          flags 
=  CSETBLOCK_SINGLE_OPER
; 2415                                  /* generation 1b magic card */ 2416                                  flags 
|=  CSETBLOCK_MAGIC_1B
; 2417                          if  ( mfCGetBlock ( 0 ,  buf
,  flags
)) { 2418                                  PrintAndLog ( "Cant get block:  %d " ,  0 ); 2419                                  len 
=  sprintf ( fnameptr
,  "dump" ); 2423                                  for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 ) 2424                                          sprintf ( fnameptr
,  " %0 2x" ,  buf
[ j
]); 2427                          //memcpy(filename, Cmd, len); 2431                  sprintf ( fnameptr
,  ".eml" ); 2434                  f 
=  fopen ( filename
,  "w+" ); 2437                          PrintAndLog ( "File not found or locked." ); 2442                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 2443                  for  ( i 
=  0 ;  i 
<  numblock
;  i
++) { 2444                          if  ( i 
==  1 )  flags 
=  0 ; 2445                          if  ( i 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 2448                                  /* generation 1b magic card */ 2449                                  flags 
|=  CSETBLOCK_MAGIC_1B
; 2450                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) { 2451                                  PrintAndLog ( "Cant get block:  %d " ,  i
); 2454                          for  ( j 
=  0 ;  j 
<  16 ;  j
++) 2455                                  fprintf ( f
,  " %0 2x" ,  buf
[ j
]); 2460                  PrintAndLog ( "Saved to file:  %s " ,  filename
); 2467  int  CmdHF14AMfSniff ( const char  * Cmd
){ 2469          bool  wantLogToFile 
=  0 ; 2470          bool  wantDecrypt 
=  0 ; 2471          //bool wantSaveToEml = 0; TODO 2472          bool  wantSaveToEmlFile 
=  0 ; 2483          uint8_t  atqa
[ 2 ] = { 0x00 }; 2486          uint8_t  * buf 
=  NULL
; 2487          uint16_t  bufsize 
=  0 ; 2488          uint8_t  * bufPtr 
=  NULL
; 2491          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 2492          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H'  ) { 2493                  PrintAndLog ( "It continuously gets data from the field and saves it to: log, emulator, emulator file." ); 2494                  PrintAndLog ( "You can specify:" ); 2495                  PrintAndLog ( "    l - save encrypted sequence to logfile `uid.log`" ); 2496                  PrintAndLog ( "    d - decrypt sequence and put it to log file `uid.log`" ); 2497                  PrintAndLog ( " n/a   e - decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory" ); 2498                  PrintAndLog ( "    f - decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`" ); 2499                  PrintAndLog ( "Usage:  hf mf sniff [l][d][e][f]" ); 2500                  PrintAndLog ( "  sample: hf mf sniff l d e" ); 2504          for  ( int  i 
=  0 ;  i 
<  4 ;  i
++) { 2505                  ctmp 
=  param_getchar ( Cmd
,  i
); 2506                  if  ( ctmp 
==  'l'  ||  ctmp 
==  'L' )  wantLogToFile 
=  true ; 2507                  if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  wantDecrypt 
=  true ; 2508                  //if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO 2509                  if  ( ctmp 
==  'f'  ||  ctmp 
==  'F' )  wantSaveToEmlFile 
=  true ; 2512          printf ( "------------------------------------------------------------------------- \n " ); 2513          printf ( "Executing command.  \n " ); 2514          printf ( "Press the key on the proxmark3 device to abort both proxmark3 and client. \n " ); 2515          printf ( "Press the key on pc keyboard to abort the client. \n " ); 2516          printf ( "------------------------------------------------------------------------- \n " ); 2518          UsbCommand c 
= { CMD_MIFARE_SNIFFER
, { 0 ,  0 ,  0 }}; 2519          clearCommandBuffer (); 2528                          printf ( " \n aborted via keyboard! \n " ); 2533                  if  ( WaitForResponseTimeoutW ( CMD_ACK
, & resp
,  2000 ,  false )) { 2534                          res 
=  resp
. arg
[ 0 ] &  0xff ; 2535                          uint16_t  traceLen 
=  resp
. arg
[ 1 ]; 2538                          if  ( res 
==  0 ) {                                                          // we are done 2542                          if  ( res 
==  1 ) {                                                          // there is (more) data to be transferred 2543                                  if  ( pckNum 
==  0 ) {                                               // first packet, (re)allocate necessary buffer 2544                                          if  ( traceLen 
>  bufsize 
||  buf 
==  NULL
) { 2546                                                  if  ( buf 
==  NULL
) {                               // not yet allocated 2547                                                          p 
=  malloc ( traceLen
); 2548                                                  }  else  {                                                 // need more memory 2549                                                          p 
=  realloc ( buf
,  traceLen
); 2552                                                          PrintAndLog ( "Cannot allocate memory for trace" ); 2560                                          memset ( buf
,  0x00 ,  traceLen
); 2562                                  memcpy ( bufPtr
,  resp
. d
. asBytes
,  len
); 2567                          if  ( res 
==  2 ) {                                                          // received all data, start displaying 2568                                  blockLen 
=  bufPtr 
-  buf
; 2571                                  PrintAndLog ( "received trace len:  %d  packages:  %d " ,  blockLen
,  pckNum
); 2572                                  while  ( bufPtr 
-  buf 
<  blockLen
) { 2573                                          bufPtr 
+=  6 ;                                             // skip (void) timing information 2574                                          len 
= *(( uint16_t  *) bufPtr
); 2581                                          parlen 
= ( len 
-  1 ) /  8  +  1 ; 2583                                          if  (( len 
==  14 ) && ( bufPtr
[ 0 ] ==  0xff ) && ( bufPtr
[ 1 ] ==  0xff ) && ( bufPtr
[ 12 ] ==  0xff ) && ( bufPtr
[ 13 ] ==  0xff )) { 2584                                                  memcpy ( uid
,  bufPtr 
+  2 ,  7 ); 2585                                                  memcpy ( atqa
,  bufPtr 
+  2  +  7 ,  2 ); 2586                                                  uid_len 
= ( atqa
[ 0 ] &  0xC0 ) ==  0x40  ?  7  :  4 ; 2588                                                  PrintAndLog ( "tag select uid: %s  atqa:0x %0 2x %0 2x sak:0x %0 2x" , 2589                                                          sprint_hex ( uid 
+ ( 7  -  uid_len
),  uid_len
), 2593                                                  if  ( wantLogToFile 
||  wantDecrypt
) { 2594                                                          FillFileNameByUID ( logHexFileName
,  uid 
+ ( 7  -  uid_len
),  ".log" ,  uid_len
); 2595                                                          AddLogCurrentDT ( logHexFileName
); 2598                                                          mfTraceInit ( uid
,  atqa
,  sak
,  wantSaveToEmlFile
); 2600                                                  oddparitybuf ( bufPtr
,  len
,  parity
); 2601                                                  PrintAndLog ( " %s ( %d ): %s  [ %s ] c[ %s ] %c " ,  2602                                                          isTag 
?  "TAG" : "RDR" ,  2604                                                          sprint_hex ( bufPtr
,  len
),  2605                                                          printBitsPar ( bufPtr 
+  len
,  len
),  2606                                                          printBitsPar ( parity
,  len
), 2607                                                          memcmp ( bufPtr 
+  len
,  parity
,  len 
/  8  +  1 ) ?  '!'  :  ' ' ); 2609                                                          AddLogHex ( logHexFileName
,  isTag 
?  "TAG: " : "RDR: " ,  bufPtr
,  len
); 2611                                                          mfTraceDecode ( bufPtr
,  len
,  bufPtr
[ len
],  wantSaveToEmlFile
); 2615                                          bufPtr 
+=  parlen
;        // ignore parity 2624          msleep ( 300 );  // wait for exiting arm side. 2625          PrintAndLog ( "Done." ); 2629  //needs nt, ar, at, Data to decrypt 2630  int  CmdDecryptTraceCmds ( const char  * Cmd
){ 2633          param_gethex_ex ( Cmd
, 3 , data
,& len
); 2634          return  tryDecryptWord ( param_get32ex ( Cmd
, 0 , 0 , 16 ), param_get32ex ( Cmd
, 1 , 0 , 16 ), param_get32ex ( Cmd
, 2 , 0 , 16 ), data
, len
/ 2 ); 2637  static  command_t CommandTable
[] = 2639    { "help" ,              CmdHelp
,                  1 ,  "This help" }, 2640    { "dbg" ,               CmdHF14AMfDbg
,            0 ,  "Set default debug mode" }, 2641    { "rdbl" ,              CmdHF14AMfRdBl
,           0 ,  "Read MIFARE classic block" }, 2642    { "rdsc" ,              CmdHF14AMfRdSc
,           0 ,  "Read MIFARE classic sector" }, 2643    { "dump" ,              CmdHF14AMfDump
,           0 ,  "Dump MIFARE classic tag to binary file" }, 2644    { "restore" ,           CmdHF14AMfRestore
,        0 ,  "Restore MIFARE classic binary file to BLANK tag" }, 2645    { "wrbl" ,              CmdHF14AMfWrBl
,           0 ,  "Write MIFARE classic block" }, 2646    { "chk" ,               CmdHF14AMfChk
,            0 ,  "Test block keys" }, 2647    { "mifare" ,            CmdHF14AMifare
,           0 ,  "Read parity error messages." }, 2648    { "hardnested" ,        CmdHF14AMfNestedHard
,     0 ,  "Nested attack for hardened Mifare cards" }, 2649    { "nested" ,            CmdHF14AMfNested
,         0 ,  "Test nested authentication" }, 2650    { "sniff" ,             CmdHF14AMfSniff
,          0 ,  "Sniff card-reader communication" }, 2651    { "sim" ,               CmdHF14AMf1kSim
,          0 ,  "Simulate MIFARE card" }, 2652    { "eclr" ,              CmdHF14AMfEClear
,         0 ,  "Clear simulator memory block" }, 2653    { "eget" ,              CmdHF14AMfEGet
,           0 ,  "Get simulator memory block" }, 2654    { "eset" ,              CmdHF14AMfESet
,           0 ,  "Set simulator memory block" }, 2655    { "eload" ,             CmdHF14AMfELoad
,          0 ,  "Load from file emul dump" }, 2656    { "esave" ,             CmdHF14AMfESave
,          0 ,  "Save to file emul dump" }, 2657    { "ecfill" ,            CmdHF14AMfECFill
,         0 ,  "Fill simulator memory with help of keys from simulator" }, 2658    { "ekeyprn" ,           CmdHF14AMfEKeyPrn
,        0 ,  "Print keys from simulator memory" }, 2659    { "cwipe" ,             CmdHF14AMfCWipe
,          0 ,  "Wipe magic Chinese card" }, 2660    { "csetuid" ,           CmdHF14AMfCSetUID
,        0 ,  "Set UID for magic Chinese card" }, 2661    { "csetblk" ,           CmdHF14AMfCSetBlk
,        0 ,  "Write block - Magic Chinese card" }, 2662    { "cgetblk" ,           CmdHF14AMfCGetBlk
,        0 ,  "Read block - Magic Chinese card" }, 2663    { "cgetsc" ,            CmdHF14AMfCGetSc
,         0 ,  "Read sector - Magic Chinese card" }, 2664    { "cload" ,             CmdHF14AMfCLoad
,          0 ,  "Load dump into magic Chinese card" }, 2665    { "csave" ,             CmdHF14AMfCSave
,          0 ,  "Save dump from magic Chinese card into file or emulator" }, 2666    { "decrypt" ,           CmdDecryptTraceCmds
,      1 ,  "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace" }, 2667    { NULL
,                NULL
,                     0 ,  NULL
} 2670  int  CmdHFMF ( const char  * Cmd
) 2672          ( void ) WaitForResponseTimeout ( CMD_ACK
, NULL
, 100 ); 2673          CmdsParse ( CommandTable
,  Cmd
); 2677  int  CmdHelp ( const char  * Cmd
) 2679    CmdsHelp ( CommandTable
);