]>
 
 
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"  
  30  #include  "cliparser/cliparser.h"  
  34  #define NESTED_SECTOR_RETRY     10                       // how often we try mfested() until we give up  
  36  static int  CmdHelp ( const char  * Cmd
);  
  38  int  CmdHF14AMifare ( const char  * Cmd
)  
  42          isOK 
=  mfDarkside (& key
);  
  44                  case  - 1  :  PrintAndLog ( "Button pressed. Aborted." );  return  1 ;  
  45                  case  - 2  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)." );  return  1 ;  
  46                  case  - 3  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator is not predictable)." );  return  1 ;  
  47                  case  - 4  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown" );  
  48                                    PrintAndLog ( "generating polynomial with 16 effective bits only, but shows unexpected behaviour." );  return  1 ;  
  49                  case  - 5  :  PrintAndLog ( "Aborted via keyboard." );   return  1 ;  
  50                  default  :  PrintAndLog ( "Found valid key: %0 12"  PRIx64 
" \n " ,  key
);  
  58  int  CmdHF14AMfWrBl ( const char  * Cmd
)  
  62          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
  63          uint8_t  bldata
[ 16 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
  68                  PrintAndLog ( "Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>" );  
  69                  PrintAndLog ( "        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F" );  
  73          blockNo 
=  param_get8 ( Cmd
,  0 );  
  74          cmdp 
=  param_getchar ( Cmd
,  1 );  
  76                  PrintAndLog ( "Key type must be A or B" );  
  79          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  
  80          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  
  81                  PrintAndLog ( "Key must include 12 HEX symbols" );  
  84          if  ( param_gethex ( Cmd
,  3 ,  bldata
,  32 )) {  
  85                  PrintAndLog ( "Block data must include 32 HEX symbols" );  
  88          PrintAndLog ( "--block no: %d , key type: %c , key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  
  89          PrintAndLog ( "--data:  %s " ,  sprint_hex ( bldata
,  16 ));  
  91    UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { blockNo
,  keyType
,  0 }};  
  92          memcpy ( c
. d
. asBytes
,  key
,  6 );  
  93          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );  
  97          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
  98                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
  99                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  
 101                  PrintAndLog ( "Command execute timeout" );  
 107  int  CmdHF14AMfRdBl ( const char  * Cmd
)  
 111          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
 117                  PrintAndLog ( "Usage:  hf mf rdbl    <block number> <key A/B> <key (12 hex symbols)>" );  
 118                  PrintAndLog ( "        sample: hf mf rdbl 0 A FFFFFFFFFFFF " );  
 122          blockNo 
=  param_get8 ( Cmd
,  0 );  
 123          cmdp 
=  param_getchar ( Cmd
,  1 );  
 125                  PrintAndLog ( "Key type must be A or B" );  
 128          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  
 129          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  
 130                  PrintAndLog ( "Key must include 12 HEX symbols" );  
 133          PrintAndLog ( "--block no: %d , key type: %c , key: %s  " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  
 135    UsbCommand c 
= { CMD_MIFARE_READBL
, { blockNo
,  keyType
,  0 }};  
 136          memcpy ( c
. d
. asBytes
,  key
,  6 );  
 140          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
 141                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 142                  uint8_t  * data 
=  resp
. d
. asBytes
;  
 145                          PrintAndLog ( "isOk: %0 2x data: %s " ,  isOK
,  sprint_hex ( data
,  16 ));  
 147                          PrintAndLog ( "isOk: %0 2x" ,  isOK
);  
 151                  if  ( mfIsSectorTrailer ( blockNo
) && ( data
[ 6 ] ||  data
[ 7 ] ||  data
[ 8 ])) {  
 152                          PrintAndLogEx ( NORMAL
,  "Trailer decoded:" );  
 153                          int  bln 
=  mfFirstBlockOfSector ( mfSectorNum ( blockNo
));  
 154                          int  blinc 
= ( mfNumBlocksPerSector ( mfSectorNum ( blockNo
)) >  4 ) ?  5  :  1 ;  
 155                          for  ( int  i 
=  0 ;  i 
<  4 ;  i
++) {  
 156                                  PrintAndLogEx ( NORMAL
,  "Access block  %d%s :  %s " ,  bln
, (( blinc 
>  1 ) && ( i 
<  3 ) ?  "+"  :  "" ) ,  mfGetAccessConditionsDesc ( i
, & data
[ 6 ]));  
 159                          PrintAndLogEx ( NORMAL
,  "UserData:  %s " ,  sprint_hex_inrow (& data
[ 9 ],  1 ));  
 162                  PrintAndLog ( "Command execute timeout" );  
 169  int  CmdHF14AMfRdSc ( const char  * Cmd
)  
 172          uint8_t  sectorNo 
=  0 ;  
 174          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
 176          uint8_t  * data  
=  NULL
;  
 180                  PrintAndLog ( "Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>" );  
 181                  PrintAndLog ( "        sample: hf mf rdsc 0 A FFFFFFFFFFFF " );  
 185          sectorNo 
=  param_get8 ( Cmd
,  0 );  
 187                  PrintAndLog ( "Sector number must be less than 40" );  
 190          cmdp 
=  param_getchar ( Cmd
,  1 );  
 191          if  ( cmdp 
!=  'a'  &&  cmdp 
!=  'A'  &&  cmdp 
!=  'b'  &&  cmdp 
!=  'B' ) {  
 192                  PrintAndLog ( "Key type must be A or B" );  
 195          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  
 196          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  
 197                  PrintAndLog ( "Key must include 12 HEX symbols" );  
 200          PrintAndLog ( "--sector no: %d  key type: %c  key: %s  " ,  sectorNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  
 202          UsbCommand c 
= { CMD_MIFARE_READSC
, { sectorNo
,  keyType
,  0 }};  
 203          memcpy ( c
. d
. asBytes
,  key
,  6 );  
 208          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
 209                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 210                  data  
=  resp
. d
. asBytes
;  
 212                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  
 214                          for  ( i 
=  0 ;  i 
< ( sectorNo
< 32 ? 3 : 15 );  i
++) {  
 215                                  PrintAndLog ( "data   :  %s " ,  sprint_hex ( data 
+  i 
*  16 ,  16 ));  
 217                          PrintAndLog ( "trailer:  %s " ,  sprint_hex ( data 
+ ( sectorNo
< 32 ? 3 : 15 ) *  16 ,  16 ));  
 219                          PrintAndLogEx ( NORMAL
,  "Trailer decoded:" );  
 220                          int  bln 
=  mfFirstBlockOfSector ( sectorNo
);  
 221                          int  blinc 
= ( mfNumBlocksPerSector ( sectorNo
) >  4 ) ?  5  :  1 ;  
 222                          for  ( i 
=  0 ;  i 
<  4 ;  i
++) {  
 223                                  PrintAndLogEx ( NORMAL
,  "Access block  %d%s :  %s " ,  bln
, (( blinc 
>  1 ) && ( i 
<  3 ) ?  "+"  :  "" ) ,  mfGetAccessConditionsDesc ( i
, &( data 
+ ( sectorNo
< 32 ? 3 : 15 ) *  16 )[ 6 ]));  
 226                          PrintAndLogEx ( NORMAL
,  "UserData:  %s " ,  sprint_hex_inrow (&( data 
+ ( sectorNo
< 32 ? 3 : 15 ) *  16 )[ 9 ],  1 ));  
 229                  PrintAndLog ( "Command execute timeout" );  
 235  uint8_t  FirstBlockOfSector ( uint8_t  sectorNo
)  
 240                  return  32  *  4  + ( sectorNo 
-  32 ) *  16 ;  
 244  uint8_t  NumBlocksPerSector ( uint8_t  sectorNo
)  
 253  static int  ParamCardSizeSectors ( const char  c
) {  
 256                  case  '0'  :  numBlocks 
=  5 ;  break ;  
 257                  case  '2'  :  numBlocks 
=  32 ;  break ;  
 258                  case  '4'  :  numBlocks 
=  40 ;  break ;  
 259                  default :    numBlocks 
=  16 ;  
 264  static int  ParamCardSizeBlocks ( const char  c
) {  
 265          int  numBlocks 
=  16  *  4 ;  
 267                  case  '0'  :  numBlocks 
=  5  *  4 ;  break ;  
 268                  case  '2'  :  numBlocks 
=  32  *  4 ;  break ;  
 269                  case  '4'  :  numBlocks 
=  32  *  4  +  8  *  16 ;  break ;  
 270                  default :    numBlocks 
=  16  *  4 ;  
 275  int  CmdHF14AMfDump ( const char  * Cmd
)  
 277          uint8_t  sectorNo
,  blockNo
;  
 281          uint8_t  rights
[ 40 ][ 4 ];  
 282          uint8_t  carddata
[ 256 ][ 16 ];  
 283          uint8_t  numSectors 
=  16 ;  
 290          char  cmdp 
=  param_getchar ( Cmd
,  0 );  
 291          numSectors 
=  ParamCardSizeSectors ( cmdp
);  
 293          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  
 294                  PrintAndLog ( "Usage:   hf mf dump [card memory]" );  
 295                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  
 297                  PrintAndLog ( "Samples: hf mf dump" );  
 298                  PrintAndLog ( "         hf mf dump 4" );  
 302          if  (( fin 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  
 303                  PrintAndLog ( "Could not find file dumpkeys.bin" );  
 307          // Read keys A from file  
 308          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  
 309                  size_t  bytes_read 
=  fread ( keyA
[ sectorNo
],  1 ,  6 ,  fin
);  
 310                  if  ( bytes_read 
!=  6 ) {  
 311                          PrintAndLog ( "File reading error." );  
 317          // Read keys B from file  
 318          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  
 319                  size_t  bytes_read 
=  fread ( keyB
[ sectorNo
],  1 ,  6 ,  fin
);  
 320                  if  ( bytes_read 
!=  6 ) {  
 321                          PrintAndLog ( "File reading error." );  
 329          PrintAndLog ( "|-----------------------------------------|" );  
 330          PrintAndLog ( "|------ Reading sector access bits...-----|" );  
 331          PrintAndLog ( "|-----------------------------------------|" );  
 333          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  
 334                  for  ( tries 
=  0 ;  tries 
<  3 ;  tries
++) {  
 335                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  0 ,  0 }};  
 336                          memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  
 339                          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
 340                                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 341                                  uint8_t  * data  
=  resp
. d
. asBytes
;  
 343                                          rights
[ sectorNo
][ 0 ] = (( data
[ 7 ] &  0x10 )>> 2 ) | (( data
[ 8 ] &  0x1 )<< 1 ) | (( data
[ 8 ] &  0x10 )>> 4 );  // C1C2C3 for data area 0  
 344                                          rights
[ sectorNo
][ 1 ] = (( data
[ 7 ] &  0x20 )>> 3 ) | (( data
[ 8 ] &  0x2 )<< 0 ) | (( data
[ 8 ] &  0x20 )>> 5 );  // C1C2C3 for data area 1  
 345                                          rights
[ sectorNo
][ 2 ] = (( data
[ 7 ] &  0x40 )>> 4 ) | (( data
[ 8 ] &  0x4 )>> 1 ) | (( data
[ 8 ] &  0x40 )>> 6 );  // C1C2C3 for data area 2  
 346                                          rights
[ sectorNo
][ 3 ] = (( data
[ 7 ] &  0x80 )>> 5 ) | (( data
[ 8 ] &  0x8 )>> 2 ) | (( data
[ 8 ] &  0x80 )>> 7 );  // C1C2C3 for sector trailer  
 348                                  }  else if  ( tries 
==  2 ) {  // on last try set defaults  
 349                                          PrintAndLog ( "Could not get access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  
 350                                          rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  
 351                                          rights
[ sectorNo
][ 3 ] =  0x01 ;  
 354                                  PrintAndLog ( "Command execute timeout when trying to read access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  
 355                                  rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  
 356                                  rights
[ sectorNo
][ 3 ] =  0x01 ;  
 361          PrintAndLog ( "|-----------------------------------------|" );  
 362          PrintAndLog ( "|----- Dumping all blocks to file... -----|" );  
 363          PrintAndLog ( "|-----------------------------------------|" );  
 366          for  ( sectorNo 
=  0 ;  isOK 
&&  sectorNo 
<  numSectors
;  sectorNo
++) {  
 367                  for  ( blockNo 
=  0 ;  isOK 
&&  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  
 368                          bool  received 
=  false ;  
 369                          for  ( tries 
=  0 ;  tries 
<  3 ;  tries
++) {  
 370                                  if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. At least the Access Conditions can always be read with key A.  
 371                                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  
 372                                          memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  
 374                                          received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  
 375                                  }  else  {                                                                                                 // data block. Check if it can be read with key A or key B  
 376                                          uint8_t  data_area 
=  sectorNo
< 32 ? blockNo
: blockNo
/ 5 ;  
 377                                          if  (( rights
[ sectorNo
][ data_area
] ==  0x03 ) || ( rights
[ sectorNo
][ data_area
] ==  0x05 )) {    // only key B would work  
 378                                                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  1 ,  0 }};  
 379                                                  memcpy ( c
. d
. asBytes
,  keyB
[ sectorNo
],  6 );  
 381                                                  received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  
 382                                          }  else if  ( rights
[ sectorNo
][ data_area
] ==  0x07 ) {                                                                                // no key would work  
 384                                                  PrintAndLog ( "Access rights do not allow reading of sector  %2 d block  %3 d" ,  sectorNo
,  blockNo
);  
 386                                          }  else  {                                                                                                                                                                 // key A would work  
 387                                                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  
 388                                                  memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  
 390                                                  received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  
 394                                          isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 400                                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 401                                  uint8_t  * data  
=  resp
. d
. asBytes
;  
 402                                  if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. Fill in the keys.  
 403                                          data
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  
 404                                          data
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  
 405                                          data
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  
 406                                          data
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  
 407                                          data
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  
 408                                          data
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  
 409                                          data
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  
 410                                          data
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  
 411                                          data
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  
 412                                          data
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  
 413                                          data
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  
 414                                          data
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  
 417                                          memcpy ( carddata
[ FirstBlockOfSector ( sectorNo
) +  blockNo
],  data
,  16 );  
 418                      PrintAndLog ( "Successfully read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  
 420                                          PrintAndLog ( "Could not read block  %2 d of sector  %2 d" ,  blockNo
,  sectorNo
);  
 426                                  PrintAndLog ( "Command execute timeout when trying to read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  
 433                  if  (( fout 
=  fopen ( "dumpdata.bin" , "wb" )) ==  NULL
) {  
 434                          PrintAndLog ( "Could not create file name dumpdata.bin" );  
 437                  uint16_t  numblocks 
=  FirstBlockOfSector ( numSectors 
-  1 ) +  NumBlocksPerSector ( numSectors 
-  1 );  
 438                  fwrite ( carddata
,  1 ,  16 * numblocks
,  fout
);  
 440                  PrintAndLog ( "Dumped  %d  blocks ( %d  bytes) to file dumpdata.bin" ,  numblocks
,  16 * numblocks
);  
 446  int  CmdHF14AMfRestore ( const char  * Cmd
)  
 448          uint8_t  sectorNo
, blockNo
;  
 450          uint8_t  key
[ 6 ] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };  
 451          uint8_t  bldata
[ 16 ] = { 0x00 };  
 459          char  cmdp 
=  param_getchar ( Cmd
,  0 );  
 461                  case  '0'  :  numSectors 
=  5 ;  break ;  
 463                  case  '\0' :  numSectors 
=  16 ;  break ;  
 464                  case  '2'  :  numSectors 
=  32 ;  break ;  
 465                  case  '4'  :  numSectors 
=  40 ;  break ;  
 466                  default :    numSectors 
=  16 ;  
 469          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  
 470                  PrintAndLog ( "Usage:   hf mf restore [card memory]" );  
 471                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  
 473                  PrintAndLog ( "Samples: hf mf restore" );  
 474                  PrintAndLog ( "         hf mf restore 4" );  
 478          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  
 479                  PrintAndLog ( "Could not find file dumpkeys.bin" );  
 483          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  
 484                  size_t  bytes_read 
=  fread ( keyA
[ sectorNo
],  1 ,  6 ,  fkeys
);  
 485                  if  ( bytes_read 
!=  6 ) {  
 486                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  
 492          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  
 493                  size_t  bytes_read 
=  fread ( keyB
[ sectorNo
],  1 ,  6 ,  fkeys
);  
 494                  if  ( bytes_read 
!=  6 ) {  
 495                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  
 503          if  (( fdump 
=  fopen ( "dumpdata.bin" , "rb" )) ==  NULL
) {  
 504                  PrintAndLog ( "Could not find file dumpdata.bin" );  
 507          PrintAndLog ( "Restoring dumpdata.bin to card" );  
 509          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  
 510                  for ( blockNo 
=  0 ;  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  
 511                          UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  keyType
,  0 }};  
 512                          memcpy ( c
. d
. asBytes
,  key
,  6 );  
 514                          size_t  bytes_read 
=  fread ( bldata
,  1 ,  16 ,  fdump
);  
 515                          if  ( bytes_read 
!=  16 ) {  
 516                                  PrintAndLog ( "File reading error (dumpdata.bin)." );  
 521                          if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {       // sector trailer  
 522                                  bldata
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  
 523                                  bldata
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  
 524                                  bldata
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  
 525                                  bldata
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  
 526                                  bldata
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  
 527                                  bldata
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  
 528                                  bldata
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  
 529                                  bldata
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  
 530                                  bldata
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  
 531                                  bldata
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  
 532                                  bldata
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  
 533                                  bldata
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  
 536                          PrintAndLog ( "Writing to block  %3 d:  %s " ,  FirstBlockOfSector ( sectorNo
) +  blockNo
,  sprint_hex ( bldata
,  16 ));  
 538                          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );  
 542                          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
 543                                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 544                                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  
 546                                  PrintAndLog ( "Command execute timeout" );  
 555  //----------------------------------------------  
 557  //----------------------------------------------  
 559  static void  parseParamTDS ( const char  * Cmd
,  const uint8_t  indx
,  bool  * paramT
,  bool  * paramD
,  uint8_t  * timeout
) {  
 561          int  len 
=  param_getlength ( Cmd
,  indx
);  
 562          if  ( len 
>  0  &&  len 
<  4 ){  
 563                  param_getstr ( Cmd
,  indx
,  ctmp3
,  sizeof ( ctmp3
));  
 565                  * paramT 
|= ( ctmp3
[ 0 ] ==  't'  ||  ctmp3
[ 0 ] ==  'T' );  
 566                  * paramD 
|= ( ctmp3
[ 0 ] ==  'd'  ||  ctmp3
[ 0 ] ==  'D' );  
 567                  bool  paramS1 
= * paramT 
|| * paramD
;  
 569                  // slow and very slow  
 570                  if  ( ctmp3
[ 0 ] ==  's'  ||  ctmp3
[ 0 ] ==  'S'  ||  ctmp3
[ 1 ] ==  's'  ||  ctmp3
[ 1 ] ==  'S' ) {  
 571                          * timeout 
=  11 ;  // slow  
 573                          if  (! paramS1 
&& ( ctmp3
[ 1 ] ==  's'  ||  ctmp3
[ 1 ] ==  'S' )) {  
 574                                  * timeout 
=  53 ;  // very slow  
 576                          if  ( paramS1 
&& ( ctmp3
[ 2 ] ==  's'  ||  ctmp3
[ 2 ] ==  'S' )) {  
 577                                  * timeout 
=  53 ;  // very slow  
 583  int  CmdHF14AMfNested ( const char  * Cmd
)  
 585          int  i
,  j
,  res
,  iterations
;  
 586          sector_t 
* e_sector 
=  NULL
;  
 589          uint8_t  trgBlockNo 
=  0 ;  
 590          uint8_t  trgKeyType 
=  0 ;  
 591          uint8_t  SectorsCnt 
=  0 ;  
 592          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
 593          uint8_t  keyBlock
[ MifareDefaultKeysSize 
*  6 ];  
 595          // timeout in units. (ms * 106)/10 or us*0.0106  
 596          uint8_t  btimeout14a 
=  MF_CHKKEYS_DEFTIMEOUT
;  // fast by default  
 598          bool  autosearchKey 
=  false ;  
 600          bool  transferToEml 
=  false ;  
 601          bool  createDumpFile 
=  false ;  
 603          uint8_t  standart
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  
 604          uint8_t  tempkey
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  
 609                  PrintAndLog ( "Usage:" );  
 610                  PrintAndLog ( " all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)> [t|d|s|ss]" );  
 611                  PrintAndLog ( " all sectors autosearch key:  hf mf nested  <card memory> * [t|d|s|ss]" );  
 612                  PrintAndLog ( " one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)>" );  
 613                  PrintAndLog ( "               <target block number> <target key A/B> [t]" );  
 615                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" );  
 616                  PrintAndLog ( "t - transfer keys to emulator memory" );  
 617                  PrintAndLog ( "d - write keys to binary file dumpkeys.bin" );  
 618                  PrintAndLog ( "s - Slow (1ms) check keys (required by some non standard cards)" );  
 619                  PrintAndLog ( "ss - Very slow (5ms) check keys" );  
 621                  PrintAndLog ( "      sample1: hf mf nested 1 0 A FFFFFFFFFFFF " );  
 622                  PrintAndLog ( "      sample2: hf mf nested 1 0 A FFFFFFFFFFFF t " );  
 623                  PrintAndLog ( "      sample3: hf mf nested 1 0 A FFFFFFFFFFFF d " );  
 624                  PrintAndLog ( "      sample4: hf mf nested o 0 A FFFFFFFFFFFF 4 A" );  
 625                  PrintAndLog ( "      sample5: hf mf nested 1 * t" );  
 626                  PrintAndLog ( "      sample6: hf mf nested 1 * ss" );  
 631          cmdp 
=  param_getchar ( Cmd
,  0 );  
 632          if  ( cmdp 
==  'o'  ||  cmdp 
==  'O' ) {  
 636                  SectorsCnt 
=  ParamCardSizeSectors ( cmdp
);  
 639          // <block number>. number or autosearch key (*)  
 640          if  ( param_getchar ( Cmd
,  1 ) ==  '*' ) {  
 641                  autosearchKey 
=  true ;  
 643                  parseParamTDS ( Cmd
,  2 , & transferToEml
, & createDumpFile
, & btimeout14a
);  
 645                  PrintAndLog ( "--nested. sectors: %2 d, block no:*, eml: %c , dmp= %c  checktimeout= %d  us" ,   
 646                          SectorsCnt
,  transferToEml
? 'y' : 'n' ,  createDumpFile
? 'y' : 'n' , (( int ) btimeout14a 
*  10000 ) /  106 );  
 648                  blockNo 
=  param_get8 ( Cmd
,  1 );  
 650                  ctmp 
=  param_getchar ( Cmd
,  2 );  
 651                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  
 652                          PrintAndLog ( "Key type must be A or B" );  
 656                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  
 659                  if  ( param_gethex ( Cmd
,  3 ,  key
,  12 )) {  
 660                          PrintAndLog ( "Key must include 12 HEX symbols" );  
 664                  // check if we can authenticate to sector  
 665                  res 
=  mfCheckKeys ( blockNo
,  keyType
,  true ,  1 ,  key
, & key64
);  
 667                          PrintAndLog ( "Can't authenticate to block: %3 d key type: %c  key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  
 673                          trgBlockNo 
=  param_get8 ( Cmd
,  4 );  
 675                          ctmp 
=  param_getchar ( Cmd
,  5 );  
 676                          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  
 677                                  PrintAndLog ( "Target key type must be A or B" );  
 680                          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  
 683                          parseParamTDS ( Cmd
,  6 , & transferToEml
, & createDumpFile
, & btimeout14a
);  
 685                          parseParamTDS ( Cmd
,  4 , & transferToEml
, & createDumpFile
, & btimeout14a
);  
 688                  PrintAndLog ( "--nested. sectors: %2 d, block no: %3 d, key type: %c , eml: %c , dmp= %c  checktimeout= %d  us" ,   
 689                          SectorsCnt
,  blockNo
,  keyType
? 'B' : 'A' ,  transferToEml
? 'y' : 'n' ,  createDumpFile
? 'y' : 'n' , (( int ) btimeout14a 
*  10000 ) /  106 );  
 693          if  ( cmdp 
==  'o' ) {  // ------------------------------------  one sector working  
 694                  PrintAndLog ( "--target block no: %3 d, target key type: %c  " ,  trgBlockNo
,  trgKeyType
? 'B' : 'A' );  
 695                  int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  trgBlockNo
,  trgKeyType
,  keyBlock
,  true );  
 698                                  case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  
 699                                  case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  
 700                                  case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  
 701                                  default  :  PrintAndLog ( "Unknown Error. \n " );  
 705                  key64 
=  bytes_to_num ( keyBlock
,  6 );  
 707                          PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  
 709                          // transfer key to the emulator  
 711                                  uint8_t  sectortrailer
;  
 712                                  if  ( trgBlockNo 
<  32 * 4 ) {         // 4 block sector  
 713                                          sectortrailer 
=  trgBlockNo 
|  0x03 ;  
 714                                  }  else  {                                         // 16 block sector  
 715                                          sectortrailer 
=  trgBlockNo 
|  0x0f ;  
 717                                  mfEmlGetMem ( keyBlock
,  sectortrailer
,  1 );  
 720                                          num_to_bytes ( key64
,  6 ,  keyBlock
);  
 722                                          num_to_bytes ( key64
,  6 , & keyBlock
[ 10 ]);  
 723                                  mfEmlSetMem ( keyBlock
,  sectortrailer
,  1 );  
 724                                  PrintAndLog ( "Key transferred to emulator memory." );  
 727                          PrintAndLog ( "No valid key found" );  
 730          else  {  // ------------------------------------  multiple sectors working  
 732                  msclock1 
=  msclock ();  
 734                  e_sector 
=  calloc ( SectorsCnt
,  sizeof ( sector_t
));  
 735                  if  ( e_sector 
==  NULL
)  return  1 ;  
 737                  //test current key and additional standard keys first  
 738                  for  ( int  defaultKeyCounter 
=  0 ;  defaultKeyCounter 
<  MifareDefaultKeysSize
;  defaultKeyCounter
++){  
 739                          num_to_bytes ( MifareDefaultKeys
[ defaultKeyCounter
],  6 , ( uint8_t *)( keyBlock 
+  defaultKeyCounter 
*  6 ));  
 742                  PrintAndLog ( "Testing known keys. Sector count= %d " ,  SectorsCnt
);  
 743                  mfCheckKeysSec ( SectorsCnt
,  2 ,  btimeout14a
,  true ,  MifareDefaultKeysSize
,  keyBlock
,  e_sector
);  
 745                  // get known key from array  
 746                  bool  keyFound 
=  false ;  
 748                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  
 749                                  for  ( j 
=  0 ;  j 
<  2 ;  j
++) {  
 750                                          if  ( e_sector
[ i
]. foundKey
[ j
]) {  
 754                                                  num_to_bytes ( e_sector
[ i
]. Key
[ j
],  6 ,  key
);  
 762                          // Can't found a key....  
 764                                  PrintAndLog ( "Can't found any of the known keys." );  
 768                          PrintAndLog ( "--auto key. block no: %3 d, key type: %c  key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  
 773                  PrintAndLog ( "nested..." );  
 774                  bool  calibrate 
=  true ;  
 775                  for  ( i 
=  0 ;  i 
<  NESTED_SECTOR_RETRY
;  i
++) {  
 776                          for  ( uint8_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  
 777                                  for  ( trgKeyType 
=  0 ;  trgKeyType 
<  2 ;  trgKeyType
++) {  
 778                                          if  ( e_sector
[ sectorNo
]. foundKey
[ trgKeyType
])  continue ;  
 779                                          PrintAndLog ( "-----------------------------------------------" );  
 780                                          int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  FirstBlockOfSector ( sectorNo
),  trgKeyType
,  keyBlock
,  calibrate
);  
 783                                                          case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  
 784                                                          case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  
 785                                                          case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  
 786                                                          default  :  PrintAndLog ( "Unknown Error. \n " );  
 796                                          key64 
=  bytes_to_num ( keyBlock
,  6 );  
 798                                                  PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  
 799                                                  e_sector
[ sectorNo
]. foundKey
[ trgKeyType
] =  1 ;  
 800                                                  e_sector
[ sectorNo
]. Key
[ trgKeyType
] =  key64
;  
 802                                                  // try to check this key as a key to the other sectors  
 803                                                  mfCheckKeysSec ( SectorsCnt
,  2 ,  btimeout14a
,  true ,  1 ,  keyBlock
,  e_sector
);  
 809                  // print nested statistic  
 810                  PrintAndLog ( " \n\n ----------------------------------------------- \n Nested statistic: \n Iterations count:  %d " ,  iterations
);  
 811                  PrintAndLog ( "Time in nested:  %1 .3f ( %1 .3f sec per key)" , (( float )( msclock () -  msclock1
))/ 1000.0 , (( float )( msclock () -  msclock1
))/ iterations
/ 1000.0 );  
 814                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  
 815                  PrintAndLog ( "|sec|key A           |res|key B           |res|" );  
 816                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  
 817                  for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  
 818                          PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |  %d  |   %0 12"  PRIx64 
"  |  %d  |" ,  i
,  
 819                                  e_sector
[ i
]. Key
[ 0 ],  e_sector
[ i
]. foundKey
[ 0 ],  e_sector
[ i
]. Key
[ 1 ],  e_sector
[ i
]. foundKey
[ 1 ]);  
 821                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  
 823                  // transfer keys to the emulator memory  
 825                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  
 826                                  mfEmlGetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  
 827                                  if  ( e_sector
[ i
]. foundKey
[ 0 ])  
 828                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  keyBlock
);  
 829                                  if  ( e_sector
[ i
]. foundKey
[ 1 ])  
 830                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 , & keyBlock
[ 10 ]);  
 831                                  mfEmlSetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  
 833                          PrintAndLog ( "Keys transferred to emulator memory." );  
 837                  if  ( createDumpFile
) {  
 838                          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "wb" )) ==  NULL
) {  
 839                                  PrintAndLog ( "Could not create file dumpkeys.bin" );  
 843                          PrintAndLog ( "Printing keys to binary file dumpkeys.bin..." );  
 844                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  
 845                                  if  ( e_sector
[ i
]. foundKey
[ 0 ]){  
 846                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  tempkey
);  
 847                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  
 850                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  
 853                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  
 854                                  if  ( e_sector
[ i
]. foundKey
[ 1 ]){  
 855                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 ,  tempkey
);  
 856                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  
 859                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  
 871  int  CmdHF14AMfNestedHard ( const char  * Cmd
)  
 875          uint8_t  trgBlockNo 
=  0 ;  
 876          uint8_t  trgKeyType 
=  0 ;  
 877          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
 878          uint8_t  trgkey
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
 881          ctmp 
=  param_getchar ( Cmd
,  0 );  
 883          if  ( ctmp 
!=  'R'  &&  ctmp 
!=  'r'  &&  ctmp 
!=  'T'  &&  ctmp 
!=  't'  &&  strlen ( Cmd
) <  20 ) {  
 884                  PrintAndLog ( "Usage:" );  
 885                  PrintAndLog ( "      hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>" );  
 886                  PrintAndLog ( "                       <target block number> <target key A|B> [known target key (12 hex symbols)] [w] [s]" );  
 887                  PrintAndLog ( "  or  hf mf hardnested r [known target key]" );  
 889                  PrintAndLog ( "Options: " );  
 890                  PrintAndLog ( "      w: Acquire nonces and write them to binary file nonces.bin" );  
 891                  PrintAndLog ( "      s: Slower acquisition (required by some non standard cards)" );  
 892                  PrintAndLog ( "      r: Read nonces.bin and start attack" );  
 893                  PrintAndLog ( "      iX: set type of SIMD instructions. Without this flag programs autodetect it." );  
 894                  PrintAndLog ( "        i5: AVX512" );  
 895                  PrintAndLog ( "        i2: AVX2" );  
 896                  PrintAndLog ( "        ia: AVX" );  
 897                  PrintAndLog ( "        is: SSE2" );  
 898                  PrintAndLog ( "        im: MMX" );  
 899                  PrintAndLog ( "        in: none (use CPU regular instruction set)" );  
 901                  PrintAndLog ( "      sample1: hf mf hardnested 0 A FFFFFFFFFFFF 4 A" );  
 902                  PrintAndLog ( "      sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w" );  
 903                  PrintAndLog ( "      sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s" );  
 904                  PrintAndLog ( "      sample4: hf mf hardnested r" );  
 906                  PrintAndLog ( "Add the known target key to check if it is present in the remaining key space:" );  
 907                  PrintAndLog ( "      sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF" );  
 911          bool  know_target_key 
=  false ;  
 912          bool  nonce_file_read 
=  false ;  
 913          bool  nonce_file_write 
=  false ;  
 919          if  ( ctmp 
==  'R'  ||  ctmp 
==  'r' ) {  
 920                  nonce_file_read 
=  true ;  
 922                  if  (! param_gethex ( Cmd
,  1 ,  trgkey
,  12 )) {  
 923                          know_target_key 
=  true ;  
 926          }  else if  ( ctmp 
==  'T'  ||  ctmp 
==  't' ) {  
 927                  tests 
=  param_get32ex ( Cmd
,  1 ,  100 ,  10 );  
 929                  if  (! param_gethex ( Cmd
,  2 ,  trgkey
,  12 )) {  
 930                          know_target_key 
=  true ;  
 934                  blockNo 
=  param_get8 ( Cmd
,  0 );  
 935                  ctmp 
=  param_getchar ( Cmd
,  1 );  
 936                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  
 937                          PrintAndLog ( "Key type must be A or B" );  
 940                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' ) {  
 944                  if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  
 945                          PrintAndLog ( "Key must include 12 HEX symbols" );  
 949                  trgBlockNo 
=  param_get8 ( Cmd
,  3 );  
 950                  ctmp 
=  param_getchar ( Cmd
,  4 );  
 951                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  
 952                          PrintAndLog ( "Target key type must be A or B" );  
 955                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' ) {  
 961                  if  (! param_gethex ( Cmd
,  5 ,  trgkey
,  12 )) {  
 962                          know_target_key 
=  true ;  
 967                  while  (( ctmp 
=  param_getchar ( Cmd
,  i
))) {  
 968                          if  ( ctmp 
==  's'  ||  ctmp 
==  'S' ) {  
 970                          }  else if  ( ctmp 
==  'w'  ||  ctmp 
==  'W' ) {  
 971                                  nonce_file_write 
=  true ;  
 972                          }  else if  ( param_getlength ( Cmd
,  i
) ==  2  &&  ctmp 
==  'i' ) {  
 975                                  PrintAndLog ( "Possible options are w , s and/or iX" );  
 982          SetSIMDInstr ( SIMD_AUTO
);  
 984                  while  (( ctmp 
=  param_getchar ( Cmd
,  iindx
))) {  
 985                          if  ( param_getlength ( Cmd
,  iindx
) ==  2  &&  ctmp 
==  'i' ) {  
 986                                  switch ( param_getchar_indx ( Cmd
,  1 ,  iindx
)) {  
 988                                                  SetSIMDInstr ( SIMD_AVX512
);  
 991                                                  SetSIMDInstr ( SIMD_AVX2
);  
 994                                                  SetSIMDInstr ( SIMD_AVX
);  
 997                                                  SetSIMDInstr ( SIMD_SSE2
);  
1000                                                  SetSIMDInstr ( SIMD_MMX
);  
1003                                                  SetSIMDInstr ( SIMD_NONE
);  
1006                                                  PrintAndLog ( "Unknown SIMD type.  %c " ,  param_getchar_indx ( Cmd
,  1 ,  iindx
));  
1014          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  " ,  
1017                          trgkey
[ 0 ],  trgkey
[ 1 ],  trgkey
[ 2 ],  trgkey
[ 3 ],  trgkey
[ 4 ],  trgkey
[ 5 ],  
1018                          know_target_key
? "" : " (not set)" ,  
1019                          nonce_file_write
? "write" : nonce_file_read
? "read" : "none" ,  
1023          int16_t  isOK 
=  mfnestedhard ( blockNo
,  keyType
,  key
,  trgBlockNo
,  trgKeyType
,  know_target_key
? trgkey
: NULL
,  nonce_file_read
,  nonce_file_write
,  slow
,  tests
);  
1027                          case  1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  
1028                          case  2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  
1038  int  CmdHF14AMfChk ( const char  * Cmd
)  
1040          if  ( strlen ( Cmd
)< 3 ) {  
1041                  PrintAndLog ( "Usage:  hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d|s|ss] [<key (12 hex symbols)>] [<dic (*.dic)>]" );  
1042                  PrintAndLog ( "          * - all sectors" );  
1043                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" );  
1044                  PrintAndLog ( "d  - write keys to binary file \n " );  
1045                  PrintAndLog ( "t  - write keys to emulator memory" );  
1046                  PrintAndLog ( "s  - slow execute. timeout 1ms" );  
1047                  PrintAndLog ( "ss - very slow execute. timeout 5ms" );  
1048                  PrintAndLog ( "      sample: hf mf chk 0 A 1234567890ab keys.dic" );  
1049                  PrintAndLog ( "              hf mf chk *1 ? t" );  
1050                  PrintAndLog ( "              hf mf chk *1 ? d" );  
1051                  PrintAndLog ( "              hf mf chk *1 ? s" );  
1052                  PrintAndLog ( "              hf mf chk *1 ? dss" );  
1057          char  filename
[ FILE_PATH_SIZE
]={ 0 };  
1059          uint8_t  * keyBlock 
=  NULL
, * p
;  
1060          uint16_t  stKeyBlock 
=  20 ;  
1066          uint8_t  blockNo 
=  0 ;  
1067          uint8_t  SectorsCnt 
=  0 ;  
1068          uint8_t  keyType 
=  0 ;  
1070          // timeout in units. (ms * 106)/10 or us*0.0106  
1071          uint8_t  btimeout14a 
=  MF_CHKKEYS_DEFTIMEOUT
;  // fast by default  
1072          bool  param3InUse 
=  false ;  
1074          bool  transferToEml 
=  0 ;  
1075          bool  createDumpFile 
=  0 ;  
1077          sector_t 
* e_sector 
=  NULL
;  
1079          keyBlock 
=  calloc ( stKeyBlock
,  6 );  
1080          if  ( keyBlock 
==  NULL
)  return  1 ;  
1082          int  defaultKeysSize 
=  MifareDefaultKeysSize
;  
1083          for  ( int  defaultKeyCounter 
=  0 ;  defaultKeyCounter 
<  defaultKeysSize
;  defaultKeyCounter
++){  
1084                  num_to_bytes ( MifareDefaultKeys
[ defaultKeyCounter
],  6 , ( uint8_t *)( keyBlock 
+  defaultKeyCounter 
*  6 ));  
1087          if  ( param_getchar ( Cmd
,  0 )== '*' ) {  
1088                  SectorsCnt 
=  ParamCardSizeSectors ( param_getchar ( Cmd 
+  1 ,  0 ));  
1091                  blockNo 
=  param_get8 ( Cmd
,  0 );  
1093          ctmp 
=  param_getchar ( Cmd
,  1 );  
1094          clen 
=  param_getlength ( Cmd
,  1 );  
1107                          PrintAndLog ( "Key type must be A , B or ?" );  
1113          parseParamTDS ( Cmd
,  2 , & transferToEml
, & createDumpFile
, & btimeout14a
);  
1115          param3InUse 
=  transferToEml 
|  createDumpFile 
| ( btimeout14a 
!=  MF_CHKKEYS_DEFTIMEOUT
);  
1117          PrintAndLog ( "--chk keys. sectors: %2 d, block no: %3 d, key type: %c , eml: %c , dmp= %c  checktimeout= %d  us" ,   
1118                          SectorsCnt
,  blockNo
,  keyType
? 'B' : 'A' ,  transferToEml
? 'y' : 'n' ,  createDumpFile
? 'y' : 'n' , (( int ) btimeout14a 
*  10000 ) /  106 );  
1120          for  ( i 
=  param3InUse
;  param_getchar ( Cmd
,  2  +  i
);  i
++) {  
1121                  if  (! param_gethex ( Cmd
,  2  +  i
,  keyBlock 
+  6  *  keycnt
,  12 )) {  
1122                          if  (  stKeyBlock 
-  keycnt 
<  2 ) {  
1123                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 ));  
1125                                          PrintAndLog ( "Cannot allocate memory for Keys" );  
1131                          PrintAndLog ( "chk key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
,  
1132                          ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ],  
1133                          ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 );  
1136                          // May be a dic file  
1137                          if  (  param_getstr ( Cmd
,  2  +  i
,  filename
,  sizeof ( filename
)) >=  FILE_PATH_SIZE 
) {  
1138                                  PrintAndLog ( "File name too long" );  
1143                          if  ( ( f 
=  fopen (  filename 
,  "r" )) ) {  
1144                                  while (  fgets ( buf
,  sizeof ( buf
),  f
) ){  
1145                                          if  ( strlen ( buf
) <  12  ||  buf
[ 11 ] ==  ' \n ' )  
1148                                          while  ( fgetc ( f
) !=  ' \n '  && ! feof ( f
)) ;   //goto next line  
1150                                          if (  buf
[ 0 ]== '#'  )  continue ;      //The line start with # is comment, skip  
1152                                          if  (! isxdigit (( unsigned char ) buf
[ 0 ])){  
1153                                                  PrintAndLog ( "File content error. ' %s ' must include 12 HEX symbols" , buf
);  
1159                                          if  (  stKeyBlock 
-  keycnt 
<  2 ) {  
1160                                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 ));  
1162                                                          PrintAndLog ( "Cannot allocate memory for defKeys" );  
1169                                          memset ( keyBlock 
+  6  *  keycnt
,  0 ,  6 );  
1170                                          num_to_bytes ( strtoll ( buf
,  NULL
,  16 ),  6 ,  keyBlock 
+  6 * keycnt
);  
1171                                          PrintAndLog ( "chk custom key[ %2 d]  %0 12"  PRIx64 
,  keycnt
,  bytes_to_num ( keyBlock 
+  6 * keycnt
,  6 ));  
1173                                          memset ( buf
,  0 ,  sizeof ( buf
));  
1177                                  PrintAndLog ( "File:  %s : not found or locked." ,  filename
);  
1185          // fill with default keys  
1187                  PrintAndLog ( "No key specified, trying default keys" );  
1188                  for  (; keycnt 
<  defaultKeysSize
;  keycnt
++)  
1189                          PrintAndLog ( "chk default key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
,  
1190                                  ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ],  
1191                                  ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 );  
1194          // initialize storage for found keys  
1195          e_sector 
=  calloc ( SectorsCnt
,  sizeof ( sector_t
));  
1196          if  ( e_sector 
==  NULL
) {  
1200          for  ( uint8_t  keyAB 
=  0 ;  keyAB 
<  2 ;  keyAB
++) {  
1201                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  
1202                          e_sector
[ sectorNo
]. Key
[ keyAB
] =  0xffffffffffff ;  
1203                          e_sector
[ sectorNo
]. foundKey
[ keyAB
] =  0 ;  
1208          bool  foundAKey 
=  false ;  
1209          uint32_t  max_keys 
=  keycnt 
>  USB_CMD_DATA_SIZE 
/  6  ?  USB_CMD_DATA_SIZE 
/  6  :  keycnt
;  
1211                  PrintAndLog ( "To cancel this operation press the button on the proxmark..." );  
1213                  for  ( uint32_t  c 
=  0 ;  c 
<  keycnt
;  c 
+=  max_keys
) {  
1215                          uint32_t  size 
=  keycnt
- c 
>  max_keys 
?  max_keys 
:  keycnt
- c
;  
1216                          res 
=  mfCheckKeysSec ( SectorsCnt
,  keyType
,  btimeout14a
,  true ,  size
, & keyBlock
[ 6  *  c
],  e_sector
);  // timeout is (ms * 106)/10 or us*0.0106  
1227                                  PrintAndLog ( "Command execute timeout" );  
1231                  int  keyAB 
=  keyType
;  
1233                          for  ( uint32_t  c 
=  0 ;  c 
<  keycnt
;  c
+= max_keys
) {  
1235                                  uint32_t  size 
=  keycnt
- c 
>  max_keys 
?  max_keys 
:  keycnt
- c
;  
1236                                  res 
=  mfCheckKeys ( blockNo
,  keyAB 
&  0x01 ,  true ,  size
, & keyBlock
[ 6  *  c
], & key64
);   
1240                                                  PrintAndLog ( "Found valid key:[ %d : %c ] %0 12"  PRIx64
,  blockNo
, ( keyAB 
&  0x01 )? 'B' : 'A' ,  key64
);  
1244                                          PrintAndLog ( "Command execute timeout" );  
1247                  }  while (-- keyAB 
>  0 );  
1254                          PrintAndLog ( "|---|----------------|---|----------------|---|" );  
1255                          PrintAndLog ( "|sec|key A           |res|key B           |res|" );  
1256                          PrintAndLog ( "|---|----------------|---|----------------|---|" );  
1257                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  
1258                                  PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |  %d  |   %0 12"  PRIx64 
"  |  %d  |" ,  i
,  
1259                                          e_sector
[ i
]. Key
[ 0 ],  e_sector
[ i
]. foundKey
[ 0 ],  e_sector
[ i
]. Key
[ 1 ],  e_sector
[ i
]. foundKey
[ 1 ]);  
1261                          PrintAndLog ( "|---|----------------|---|----------------|---|" );  
1265                  PrintAndLog ( "No valid keys found." );  
1268          if  ( transferToEml
) {  
1270                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  
1271                          if  ( e_sector
[ sectorNo
]. foundKey
[ 0 ] ||  e_sector
[ sectorNo
]. foundKey
[ 1 ]) {  
1272                                  mfEmlGetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 );  
1273                                  for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) {  
1274                                          if  ( e_sector
[ sectorNo
]. foundKey
[ t
]) {  
1275                                                  num_to_bytes ( e_sector
[ sectorNo
]. Key
[ t
],  6 ,  block 
+  t 
*  10 );  
1278                                  mfEmlSetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 );  
1281                  PrintAndLog ( "Found keys have been transferred to the emulator memory" );  
1284          if  ( createDumpFile
) {  
1285                  FILE  * fkeys 
=  fopen ( "dumpkeys.bin" , "wb" );  
1286                  if  ( fkeys 
==  NULL
) {  
1287                          PrintAndLog ( "Could not create file dumpkeys.bin" );  
1293                  for  ( uint8_t  t 
=  0 ;  t 
<  2 ;  t
++) {  
1294                          for  ( uint8_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  
1295                                  num_to_bytes ( e_sector
[ sectorNo
]. Key
[ t
],  6 ,  mkey
);  
1296                                  fwrite ( mkey
,  1 ,  6 ,  fkeys
);  
1300                  PrintAndLog ( "Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys." );  
1309  void  readerAttack ( nonces_t ar_resp
[],  bool  setEmulatorMem
,  bool  doStandardAttack
) {  
1310          #define ATTACK_KEY_COUNT 7  // keep same as define in iso14443a.c -> Mifare1ksim()  
1311                                      // cannot be more than 7 or it will overrun c.d.asBytes(512)  
1317          st_t sector_trailer
[ ATTACK_KEY_COUNT
];  
1318          memset ( sector_trailer
,  0x00 ,  sizeof ( sector_trailer
));  
1320          uint8_t  stSector
[ ATTACK_KEY_COUNT
];  
1321          memset ( stSector
,  0x00 ,  sizeof ( stSector
));  
1322          uint8_t  key_cnt
[ ATTACK_KEY_COUNT
];  
1323          memset ( key_cnt
,  0x00 ,  sizeof ( key_cnt
));  
1325          for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) {  
1326                  if  ( ar_resp
[ i
]. ar2 
>  0 ) {  
1327                          //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);  
1328                          if  ( doStandardAttack 
&&  mfkey32 ( ar_resp
[ i
], & key
)) {  
1329                                  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 ));  
1331                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) {  
1332                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== ar_resp
[ i
]. sector
) {  
1333                                                  if  ( ar_resp
[ i
]. keytype
== 0 ) {  
1335                                                          sector_trailer
[ ii
]. keyA 
=  key
;  
1336                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
;  
1341                                                          sector_trailer
[ ii
]. keyB 
=  key
;  
1342                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
;  
1348                          }  else if  ( mfkey32_moebius ( ar_resp
[ i
+ ATTACK_KEY_COUNT
], & key
)) {  
1349                                  uint8_t  sectorNum 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. sector
;  
1350                                  uint8_t  keyType 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. keytype
;  
1352                                  PrintAndLog ( "M-Found Key %s  for sector  %0 2d: [ %0 12"  PRIx64 
"]"  
1353                                          ,  keyType 
?  "B"  :  "A"  
1358                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) {  
1359                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== sectorNum
) {  
1362                                                          sector_trailer
[ ii
]. keyA 
=  key
;  
1363                                                          stSector
[ ii
] =  sectorNum
;  
1368                                                          sector_trailer
[ ii
]. keyB 
=  key
;  
1369                                                          stSector
[ ii
] =  sectorNum
;  
1379          //set emulator memory for keys  
1380          if  ( setEmulatorMem
) {  
1381                  for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) {  
1383                                  uint8_t  memBlock
[ 16 ];  
1384                                  memset ( memBlock
,  0x00 ,  sizeof ( memBlock
));  
1386                                  memset ( cmd1
, 0x00 , sizeof ( cmd1
));  
1387                                  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 ));  
1388                                  PrintAndLog ( "Setting Emulator Memory Block  %0 2d: [ %s ]" , stSector
[ i
]* 4 + 3 ,  cmd1
);  
1389                                  if  ( param_gethex ( cmd1
,  0 ,  memBlock
,  32 )) {  
1390                                          PrintAndLog ( "block data must include 32 HEX symbols" );  
1394                                  UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, {( stSector
[ i
]* 4 + 3 ),  1 ,  0 }};  
1395                                  memcpy ( c
. d
. asBytes
,  memBlock
,  16 );  
1396                                  clearCommandBuffer ();  
1402          //un-comment to use as well moebius attack  
1403          for (uint8_t i = ATTACK_KEY_COUNT; i<ATTACK_KEY_COUNT*2; i++) {  
1404                  if (ar_resp[i].ar2 > 0) {  
1405                          if (tryMfk32_moebius(ar_resp[i], &key)) {  
1406                                  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));  
1412  int  usage_hf14_mf1ksim ( void ) {  
1413          PrintAndLog ( "Usage:  hf mf sim h u <uid (8, 14, or 20 hex symbols)> n <numreads> i x" );  
1414          PrintAndLog ( "options:" );  
1415          PrintAndLog ( "      h    this help" );  
1416          PrintAndLog ( "      u    (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used" );  
1417          PrintAndLog ( "      n    (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite" );  
1418          PrintAndLog ( "      i    (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted" );  
1419          PrintAndLog ( "      x    (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)" );  
1420          PrintAndLog ( "      e    (Optional) set keys found from 'reader attack' to emulator memory (implies x and i)" );  
1421          PrintAndLog ( "      f    (Optional) get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)" );  
1422          PrintAndLog ( "      r    (Optional) Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works." );  
1423          PrintAndLog ( "samples:" );  
1424          PrintAndLog ( "           hf mf sim u 0a0a0a0a" );  
1425          PrintAndLog ( "           hf mf sim u 11223344556677" );  
1426          PrintAndLog ( "           hf mf sim u 112233445566778899AA" );  
1427          PrintAndLog ( "           hf mf sim f uids.txt" );  
1428          PrintAndLog ( "           hf mf sim u 0a0a0a0a e" );  
1433  int  CmdHF14AMf1kSim ( const char  * Cmd
) {  
1435          uint8_t  uid
[ 10 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 };  
1436          uint8_t  exitAfterNReads 
=  0 ;  
1440          bool  setEmulatorMem 
=  false ;  
1441          bool  attackFromFile 
=  false ;  
1443          char  filename
[ FILE_PATH_SIZE
];  
1444          memset ( filename
,  0x00 ,  sizeof ( filename
));  
1449          bool  errors 
=  false ;  
1451          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ) {  
1452                  switch ( param_getchar ( Cmd
,  cmdp
)) {  
1455                          setEmulatorMem 
=  true ;  
1457                          flags 
|=  FLAG_INTERACTIVE
;  
1458                          flags 
|=  FLAG_NR_AR_ATTACK
;  
1463                          len 
=  param_getstr ( Cmd
,  cmdp
+ 1 ,  filename
,  sizeof ( filename
));  
1465                                  PrintAndLog ( "error no filename found" );  
1468                          attackFromFile 
=  true ;  
1470                          flags 
|=  FLAG_INTERACTIVE
;  
1471                          flags 
|=  FLAG_NR_AR_ATTACK
;  
1476                          return  usage_hf14_mf1ksim ();  
1479                          flags 
|=  FLAG_INTERACTIVE
;  
1484                          exitAfterNReads 
=  param_get8 ( Cmd
,  pnr
+ 1 );  
1489                          flags 
|=  FLAG_RANDOM_NONCE
;  
1494                          param_gethex_ex ( Cmd
,  cmdp
+ 1 ,  uid
, & uidlen
);  
1496                                  case  20 :  flags 
=  FLAG_10B_UID_IN_DATA
;   break ;  //not complete  
1497                                  case  14 :  flags 
=  FLAG_7B_UID_IN_DATA
;  break ;  
1498                                  case   8 :  flags 
=  FLAG_4B_UID_IN_DATA
;  break ;  
1499                                  default :  return  usage_hf14_mf1ksim ();  
1505                          flags 
|=  FLAG_NR_AR_ATTACK
;  
1509                          PrintAndLog ( "Unknown parameter ' %c '" ,  param_getchar ( Cmd
,  cmdp
));  
1516          if ( errors
)  return  usage_hf14_mf1ksim ();  
1519          if  ( attackFromFile
) {  
1522                  f 
=  fopen ( filename
,  "r" );  
1524                          PrintAndLog ( "File  %s  not found or locked" ,  filename
);  
1527                  PrintAndLog ( "Loading file and simulating. Press keyboard to abort" );  
1528                  while (! feof ( f
) && ! ukbhit ()){  
1529                          memset ( buf
,  0 ,  sizeof ( buf
));  
1530                          memset ( uid
,  0 ,  sizeof ( uid
));  
1532                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) {  
1533                                  if  ( count 
>  0 )  break ;  
1535                                  PrintAndLog ( "File reading error." );  
1539                          if (! strlen ( buf
) &&  feof ( f
))  break ;  
1541                          uidlen 
=  strlen ( buf
)- 1 ;  
1543                                  case  20 :  flags 
|=  FLAG_10B_UID_IN_DATA
;  break ;  //not complete  
1544                                  case  14 :  flags 
|=  FLAG_7B_UID_IN_DATA
;  break ;  
1545                                  case   8 :  flags 
|=  FLAG_4B_UID_IN_DATA
;  break ;  
1547                                          PrintAndLog ( "uid in file wrong length at  %d  (length:  %d ) [ %s ]" , count
,  uidlen
,  buf
);  
1552                          for  ( uint8_t  i 
=  0 ;  i 
<  uidlen
;  i 
+=  2 ) {  
1553                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& uid
[ i 
/  2 ]);  
1556                          PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) - press button to abort" ,  
1557                                          flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ):  
1558                                                  flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ):  
1559                                                          flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A"  
1560                                          ,  exitAfterNReads
,  flags
,  flags
);  
1562                          UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }};  
1563                          memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
));  
1564                          clearCommandBuffer ();  
1567                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
1568                                  //We're waiting only 1.5 s at a time, otherwise we get the  
1569                                  // annoying message about "Waiting for a response... "  
1572                          nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ];  
1573                          memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
));  
1574                          // We can skip the standard attack if we have RANDOM_NONCE set.  
1575                          readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
));  
1576                          if  (( bool ) resp
. arg
[ 1 ]) {  
1577                                  PrintAndLog ( "Device button pressed - quitting" );  
1584          }  else  {  //not from file  
1586                  PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) " ,  
1587                                  flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ):  
1588                                          flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ):  
1589                                                  flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A"  
1590                                  ,  exitAfterNReads
,  flags
,  flags
);  
1592                  UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }};  
1593                  memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
));  
1594                  clearCommandBuffer ();  
1597                  if ( flags 
&  FLAG_INTERACTIVE
) {  
1598                          PrintAndLog ( "Press pm3-button to abort simulation" );  
1599                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
1600                                  //We're waiting only 1.5 s at a time, otherwise we get the  
1601                                  // annoying message about "Waiting for a response... "  
1604                          if  ( flags 
&  FLAG_NR_AR_ATTACK
) {  
1605                                  nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ];  
1606                                  memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
));  
1607                                  // We can skip the standard attack if we have RANDOM_NONCE set.  
1608                                  readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
));  
1616  int  CmdHF14AMfDbg ( const char  * Cmd
)  
1618          int  dbgMode 
=  param_get32ex ( Cmd
,  0 ,  0 ,  10 );  
1620                  PrintAndLog ( "Max debug mode parameter is 4  \n " );  
1623          if  ( strlen ( Cmd
) <  1  || ! param_getchar ( Cmd
,  0 ) ||  dbgMode 
>  4 ) {  
1624                  PrintAndLog ( "Usage:  hf mf dbg  <debug level>" );  
1625                  PrintAndLog ( " 0 - no debug messages" );  
1626                  PrintAndLog ( " 1 - error messages" );  
1627                  PrintAndLog ( " 2 - plus information messages" );  
1628                  PrintAndLog ( " 3 - plus debug messages" );  
1629                  PrintAndLog ( " 4 - print even debug messages in timing critical functions" );  
1630                  PrintAndLog ( "     Note: this option therefore may cause malfunction itself" );  
1634    UsbCommand c 
= { CMD_MIFARE_SET_DBGMODE
, { dbgMode
,  0 ,  0 }};  
1640  int  CmdHF14AMfEGet ( const char  * Cmd
)  
1642          uint8_t  blockNo 
=  0 ;  
1643          uint8_t  data
[ 16 ] = { 0x00 };  
1645          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) {  
1646                  PrintAndLog ( "Usage:  hf mf eget <block number>" );  
1647                  PrintAndLog ( " sample: hf mf eget 0 " );  
1651          blockNo 
=  param_get8 ( Cmd
,  0 );  
1654          if  (! mfEmlGetMem ( data
,  blockNo
,  1 )) {  
1655                  PrintAndLog ( "data[ %3 d]: %s " ,  blockNo
,  sprint_hex ( data
,  16 ));  
1657                  PrintAndLog ( "Command execute timeout" );  
1663  int  CmdHF14AMfEClear ( const char  * Cmd
)  
1665          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) {  
1666                  PrintAndLog ( "Usage:  hf mf eclr" );  
1667                  PrintAndLog ( "It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF  \n " );  
1671    UsbCommand c 
= { CMD_MIFARE_EML_MEMCLR
, { 0 ,  0 ,  0 }};  
1677  int  CmdHF14AMfESet ( const char  * Cmd
)  
1679          uint8_t  memBlock
[ 16 ];  
1680          uint8_t  blockNo 
=  0 ;  
1682          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
));  
1684          if  ( strlen ( Cmd
) <  3  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) {  
1685                  PrintAndLog ( "Usage:  hf mf eset <block number> <block data (32 hex symbols)>" );  
1686                  PrintAndLog ( " sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f " );  
1690          blockNo 
=  param_get8 ( Cmd
,  0 );  
1692          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) {  
1693                  PrintAndLog ( "block data must include 32 HEX symbols" );  
1698          return  mfEmlSetMem ( memBlock
,  blockNo
,  1 );  
1702  int  CmdHF14AMfELoad ( const char  * Cmd
)  
1705          char  filename
[ FILE_PATH_SIZE
];  
1706          char  * fnameptr 
=  filename
;  
1707          char  buf
[ 64 ] = { 0x00 };  
1708          uint8_t  buf8
[ 64 ] = { 0x00 };  
1709          int  i
,  len
,  blockNum
,  numBlocks
;  
1710          int  nameParamNo 
=  1 ;  
1712          char  ctmp 
=  param_getchar ( Cmd
,  0 );  
1714          if  (  ctmp 
==  'h'  ||  ctmp 
==  0x00 ) {  
1715                  PrintAndLog ( "It loads emul dump from the file `filename.eml`" );  
1716                  PrintAndLog ( "Usage:  hf mf eload [card memory] <file name w/o `.eml`>" );  
1717                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  
1719                  PrintAndLog ( " sample: hf mf eload filename" );  
1720                  PrintAndLog ( "         hf mf eload 4 filename" );  
1725                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ;  
1727                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ;  
1728                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ;  
1729                  case  '4'  :  numBlocks 
=  256 ;  break ;  
1736          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
, sizeof ( filename
));  
1738          if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ;  
1742          sprintf ( fnameptr
,  ".eml" );  
1745          f 
=  fopen ( filename
,  "r" );  
1747                  PrintAndLog ( "File  %s  not found or locked" ,  filename
);  
1753                  memset ( buf
,  0 ,  sizeof ( buf
));  
1755                  if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) {  
1757                          if  ( blockNum 
>=  numBlocks
)  break ;  
1759                          PrintAndLog ( "File reading error." );  
1764                  if  ( strlen ( buf
) <  32 ){  
1765                          if ( strlen ( buf
) &&  feof ( f
))  
1767                          PrintAndLog ( "File content error. Block data must include 32 HEX symbols" );  
1772                  for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 ) {  
1773                          sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]);  
1776                  if  ( mfEmlSetMem ( buf8
,  blockNum
,  1 )) {  
1777                          PrintAndLog ( "Cant set emul block:  %3 d" ,  blockNum
);  
1784                  if  ( blockNum 
>=  numBlocks
)  break ;  
1789          if  (( blockNum 
!=  numBlocks
)) {  
1790                  PrintAndLog ( "File content error. Got  %d  must be  %d  blocks." , blockNum
,  numBlocks
);  
1793          PrintAndLog ( "Loaded  %d  blocks from file:  %s " ,  blockNum
,  filename
);  
1798  int  CmdHF14AMfESave ( const char  * Cmd
)  
1801          char  filename
[ FILE_PATH_SIZE
];  
1802          char  *  fnameptr 
=  filename
;  
1804          int  i
,  j
,  len
,  numBlocks
;  
1805          int  nameParamNo 
=  1 ;  
1807          memset ( filename
,  0 ,  sizeof ( filename
));  
1808          memset ( buf
,  0 ,  sizeof ( buf
));  
1810          char  ctmp 
=  param_getchar ( Cmd
,  0 );  
1812          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H' ) {  
1813                  PrintAndLog ( "It saves emul dump into the file `filename.eml` or `cardID.eml`" );  
1814                  PrintAndLog ( " Usage:  hf mf esave [card memory] [file name w/o `.eml`]" );  
1815                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  
1817                  PrintAndLog ( " sample: hf mf esave " );  
1818                  PrintAndLog ( "         hf mf esave 4" );  
1819                  PrintAndLog ( "         hf mf esave 4 filename" );  
1824                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ;  
1826                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ;  
1827                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ;  
1828                  case  '4'  :  numBlocks 
=  256 ;  break ;  
1835          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
, sizeof ( filename
));  
1837          if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ;  
1839          // user supplied filename?  
1841                  // get filename (UID from memory)  
1842                  if  ( mfEmlGetMem ( buf
,  0 ,  1 )) {  
1843                          PrintAndLog ( "Can \' t get UID from block:  %d " ,  0 );  
1844                          len 
=  sprintf ( fnameptr
,  "dump" );  
1848                          for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 )  
1849                                  sprintf ( fnameptr
,  " %0 2X" ,  buf
[ j
]);  
1855          // add file extension  
1856          sprintf ( fnameptr
,  ".eml" );  
1859          f 
=  fopen ( filename
,  "w+" );  
1862                  PrintAndLog ( "Can't open file  %s  " ,  filename
);  
1867          for  ( i 
=  0 ;  i 
<  numBlocks
;  i
++) {  
1868                  if  ( mfEmlGetMem ( buf
,  i
,  1 )) {  
1869                          PrintAndLog ( "Cant get block:  %d " ,  i
);  
1872                  for  ( j 
=  0 ;  j 
<  16 ;  j
++)  
1873                          fprintf ( f
,  " %0 2X" ,  buf
[ j
]);  
1878          PrintAndLog ( "Saved  %d  blocks to file:  %s " ,  numBlocks
,  filename
);  
1884  int  CmdHF14AMfECFill ( const char  * Cmd
)  
1886          uint8_t  keyType 
=  0 ;  
1887          uint8_t  numSectors 
=  16 ;  
1889          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) {  
1890                  PrintAndLog ( "Usage:  hf mf ecfill <key A/B> [card memory]" );  
1891                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  
1893                  PrintAndLog ( "samples:  hf mf ecfill A" );  
1894                  PrintAndLog ( "          hf mf ecfill A 4" );  
1895                  PrintAndLog ( "Read card and transfer its data to emulator memory." );  
1896                  PrintAndLog ( "Keys must be laid in the emulator memory.  \n " );  
1900          char  ctmp 
=  param_getchar ( Cmd
,  0 );  
1901          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  
1902                  PrintAndLog ( "Key type must be A or B" );  
1905          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  keyType 
=  1 ;  
1907          ctmp 
=  param_getchar ( Cmd
,  1 );  
1909                  case  '0'  :  numSectors 
=  5 ;  break ;  
1911                  case  '\0' :  numSectors 
=  16 ;  break ;  
1912                  case  '2'  :  numSectors 
=  32 ;  break ;  
1913                  case  '4'  :  numSectors 
=  40 ;  break ;  
1914                  default :    numSectors 
=  16 ;  
1917          printf ( "--params: numSectors:  %d , keyType: %d \n " ,  numSectors
,  keyType
);  
1918          UsbCommand c 
= { CMD_MIFARE_EML_CARDLOAD
, { numSectors
,  keyType
,  0 }};  
1923  int  CmdHF14AMfEKeyPrn ( const char  * Cmd
)  
1928          uint64_t  keyA
,  keyB
;  
1930          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) {  
1931                  PrintAndLog ( "It prints the keys loaded in the emulator memory" );  
1932                  PrintAndLog ( "Usage:  hf mf ekeyprn [card memory]" );  
1933                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  
1935                  PrintAndLog ( " sample: hf mf ekeyprn 1" );  
1939          char  cmdp 
=  param_getchar ( Cmd
,  0 );  
1942                  case  '0'  :  numSectors 
=  5 ;  break ;  
1944                  case  '\0' :  numSectors 
=  16 ;  break ;  
1945                  case  '2'  :  numSectors 
=  32 ;  break ;  
1946                  case  '4'  :  numSectors 
=  40 ;  break ;  
1947                  default :    numSectors 
=  16 ;  
1950          PrintAndLog ( "|---|----------------|----------------|" );  
1951          PrintAndLog ( "|sec|key A           |key B           |" );  
1952          PrintAndLog ( "|---|----------------|----------------|" );  
1953          for  ( i 
=  0 ;  i 
<  numSectors
;  i
++) {  
1954                  if  ( mfEmlGetMem ( data
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 )) {  
1955                          PrintAndLog ( "error get block  %d " ,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 );  
1958                  keyA 
=  bytes_to_num ( data
,  6 );  
1959                  keyB 
=  bytes_to_num ( data 
+  10 ,  6 );  
1960                  PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |   %0 12"  PRIx64 
"  |" ,  i
,  keyA
,  keyB
);  
1962          PrintAndLog ( "|---|----------------|----------------|" );  
1967  int  CmdHF14AMfCSetUID ( const char  * Cmd
)  
1969          uint8_t  uid
[ 8 ] = { 0x00 };  
1970          uint8_t  oldUid
[ 8 ] = { 0x00 };  
1971          uint8_t  atqa
[ 2 ] = { 0x00 };  
1972          uint8_t  sak
[ 1 ] = { 0x00 };  
1973          uint8_t  atqaPresent 
=  0 ;  
1976          uint8_t  needHelp 
=  0 ;  
1979          if  ( param_getchar ( Cmd
,  0 ) &&  param_gethex ( Cmd
,  0 ,  uid
,  8 )) {  
1980                  PrintAndLog ( "UID must include 8 HEX symbols" );  
1984          if  ( param_getlength ( Cmd
,  1 ) >  1  &&  param_getlength ( Cmd
,  2 ) >   1 ) {  
1988                  if  ( param_gethex ( Cmd
,  1 ,  atqa
,  4 )) {  
1989                          PrintAndLog ( "ATQA must include 4 HEX symbols" );  
1993                  if  ( param_gethex ( Cmd
,  2 ,  sak
,  2 )) {  
1994                          PrintAndLog ( "SAK must include 2 HEX symbols" );  
1999          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 )  
2001                  switch ( param_getchar ( Cmd
,  cmdp
))  
2008                          PrintAndLog ( "ERROR: Unknown parameter ' %c '" ,  param_getchar ( Cmd
,  cmdp
));  
2015          if  ( strlen ( Cmd
) <  1  ||  needHelp
) {  
2017                  PrintAndLog ( "Usage:  hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols]" );  
2018                  PrintAndLog ( "sample:  hf mf csetuid 01020304" );  
2019                  PrintAndLog ( "sample:  hf mf csetuid 01020304 0004 08" );  
2020                  PrintAndLog ( "Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)" );  
2024          PrintAndLog ( "uid: %s " ,  sprint_hex ( uid
,  4 ));  
2026                  PrintAndLog ( "--atqa: %s  sak: %0 2x" ,  sprint_hex ( atqa
,  2 ),  sak
[ 0 ]);  
2029          res 
=  mfCSetUID ( uid
, ( atqaPresent
)? atqa
: NULL
, ( atqaPresent
)? sak
: NULL
,  oldUid
);  
2031                          PrintAndLog ( "Can't set UID. Error= %d " ,  res
);  
2035          PrintAndLog ( "old UID: %s " ,  sprint_hex ( oldUid
,  4 ));  
2036          PrintAndLog ( "new UID: %s " ,  sprint_hex ( uid
,  4 ));  
2040  int  CmdHF14AMfCWipe ( const char  * Cmd
)  
2043          int  numBlocks 
=  16  *  4 ;  
2044          bool  wipeCard 
=  false ;  
2045          bool  fillCard 
=  false ;  
2047          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) {  
2048                  PrintAndLog ( "Usage:  hf mf cwipe [card size] [w] [f]" );  
2049                  PrintAndLog ( "sample:  hf mf cwipe 1 w f" );  
2050                  PrintAndLog ( "[card size]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  
2051                  PrintAndLog ( "w - Wipe magic Chinese card (only works with gen:1a cards)" );  
2052                  PrintAndLog ( "f - Fill the card with default data and keys (works with gen:1a and gen:1b cards only)" );  
2056          gen 
=  mfCIdentify ();  
2057          if  (( gen 
!=  1 ) && ( gen 
!=  2 ))   
2060          numBlocks 
=  ParamCardSizeBlocks ( param_getchar ( Cmd
,  0 ));  
2063          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ){  
2064                  switch ( param_getchar ( Cmd
,  cmdp
)) {  
2079          if  (! wipeCard 
&& ! fillCard
)   
2082          PrintAndLog ( "--blocks count: %2 d wipe: %c  fill: %c " ,  numBlocks
, ( wipeCard
)? 'y' : 'n' , ( fillCard
)? 'y' : 'n' );  
2085                  /* generation 1b magic card */  
2087                          PrintAndLog ( "WARNING: can't wipe magic card 1b generation" );  
2089                  res 
=  mfCWipe ( numBlocks
,  true ,  false ,  fillCard
);   
2091                  /* generation 1a magic card by default */  
2092                  res 
=  mfCWipe ( numBlocks
,  false ,  wipeCard
,  fillCard
);   
2096                  PrintAndLog ( "Can't wipe. error= %d " ,  res
);  
2103  int  CmdHF14AMfCSetBlk ( const char  * Cmd
)  
2105          uint8_t  memBlock
[ 16 ] = { 0x00 };  
2106          uint8_t  blockNo 
=  0 ;  
2107          bool  wipeCard 
=  false ;  
2110          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) {  
2111                  PrintAndLog ( "Usage:  hf mf csetblk <block number> <block data (32 hex symbols)> [w]" );  
2112                  PrintAndLog ( "sample:  hf mf csetblk 1 01020304050607080910111213141516" );  
2113                  PrintAndLog ( "Set block data for magic Chinese card (only works with such cards)" );  
2114                  PrintAndLog ( "If you also want wipe the card then add 'w' at the end of the command line" );  
2118          gen 
=  mfCIdentify ();  
2119          if  (( gen 
!=  1 ) && ( gen 
!=  2 ))   
2122          blockNo 
=  param_get8 ( Cmd
,  0 );  
2124          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) {  
2125                  PrintAndLog ( "block data must include 32 HEX symbols" );  
2129          char  ctmp 
=  param_getchar ( Cmd
,  2 );  
2130          wipeCard 
= ( ctmp 
==  'w'  ||  ctmp 
==  'W' );  
2131          PrintAndLog ( "--block number: %2 d data: %s " ,  blockNo
,  sprint_hex ( memBlock
,  16 ));  
2134                  /* generation 1b magic card */  
2135                  res 
=  mfCSetBlock ( blockNo
,  memBlock
,  NULL
,  wipeCard
,  CSETBLOCK_SINGLE_OPER 
|  CSETBLOCK_MAGIC_1B
);  
2137                  /* generation 1a magic card by default */  
2138                  res 
=  mfCSetBlock ( blockNo
,  memBlock
,  NULL
,  wipeCard
,  CSETBLOCK_SINGLE_OPER
);  
2142                  PrintAndLog ( "Can't write block. error= %d " ,  res
);  
2149  int  CmdHF14AMfCLoad ( const char  * Cmd
)  
2152          char  filename
[ FILE_PATH_SIZE
] = { 0x00 };  
2153          char  *  fnameptr 
=  filename
;  
2154          char  buf
[ 256 ] = { 0x00 };  
2155          uint8_t  buf8
[ 256 ] = { 0x00 };  
2156          uint8_t  fillFromEmulator 
=  0 ;  
2157          int  i
,  len
,  blockNum
,  flags 
=  0 ,  gen 
=  0 ,  numblock 
=  64 ;  
2159          if  ( param_getchar ( Cmd
,  0 ) ==  'h'  ||  param_getchar ( Cmd
,  0 )==  0x00 ) {  
2160                  PrintAndLog ( "It loads magic Chinese card from the file `filename.eml`" );  
2161                  PrintAndLog ( "or from emulator memory (option `e`). 4K card: (option `4`)" );  
2162                  PrintAndLog ( "Usage:  hf mf cload [file name w/o `.eml`][e][4]" );  
2163                  PrintAndLog ( "   or:  hf mf cload e [4]" );  
2164                  PrintAndLog ( "Sample: hf mf cload filename" );  
2165                  PrintAndLog ( "        hf mf cload filname 4" );  
2166                  PrintAndLog ( "        hf mf cload e" );  
2167                  PrintAndLog ( "        hf mf cload e 4" );  
2171          char  ctmp 
=  param_getchar ( Cmd
,  0 );  
2172          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ;  
2173          ctmp 
=  param_getchar ( Cmd
,  1 );  
2174          if  ( ctmp 
==  '4' )  numblock 
=  256 ;  
2176          gen 
=  mfCIdentify ();  
2177          PrintAndLog ( "Loading magic mifare  %d K" ,  numblock 
==  256  ?  4 : 1 );  
2179          if  ( fillFromEmulator
) {  
2180                  for  ( blockNum 
=  0 ;  blockNum 
<  numblock
;  blockNum 
+=  1 ) {  
2181                          if  ( mfEmlGetMem ( buf8
,  blockNum
,  1 )) {  
2182                                  PrintAndLog ( "Cant get block:  %d " ,  blockNum
);  
2185                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence  
2186                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write  
2187                          if  ( blockNum 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;            // Done. Magic Halt and switch off field.  
2190                                  /* generation 1b magic card */  
2191                                  flags 
|=  CSETBLOCK_MAGIC_1B
;  
2192                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) {  
2193                                  PrintAndLog ( "Cant set magic card block:  %d " ,  blockNum
);  
2199                  param_getstr ( Cmd
,  0 ,  filename
,  sizeof ( filename
));  
2201                  len 
=  strlen ( filename
);  
2202                  if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ;  
2204                  //memcpy(filename, Cmd, len);  
2207                  sprintf ( fnameptr
,  ".eml" );  
2210                  f 
=  fopen ( filename
,  "r" );  
2212                          PrintAndLog ( "File not found or locked." );  
2219                          memset ( buf
,  0 ,  sizeof ( buf
));  
2221                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) {  
2223                                  PrintAndLog ( "File reading error." );  
2227                          if  ( strlen ( buf
) <  32 ) {  
2228                                  if ( strlen ( buf
) &&  feof ( f
))  
2230                                  PrintAndLog ( "File content error. Block data must include 32 HEX symbols" );  
2234                          for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 )  
2235                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]);  
2237                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence  
2238                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write  
2239                          if  ( blockNum 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;            // Done. Switch off field.  
2242                                  /* generation 1b magic card */  
2243                                  flags 
|=  CSETBLOCK_MAGIC_1B
;  
2244                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) {  
2245                                  PrintAndLog ( "Can't set magic card block:  %d " ,  blockNum
);  
2251                          if  ( blockNum 
>=  numblock
)  break ;   // magic card type - mifare 1K 64 blocks, mifare 4k 256 blocks  
2255                  //if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){  
2256                  if  ( blockNum 
!=  numblock
){  
2257                          PrintAndLog ( "File content error. There must be  %d  blocks" ,  numblock
);  
2260                  PrintAndLog ( "Loaded from file:  %s " ,  filename
);  
2266  int  CmdHF14AMfCGetBlk ( const char  * Cmd
) {  
2267          uint8_t  memBlock
[ 16 ];  
2268          uint8_t  blockNo 
=  0 ;  
2270          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
));  
2272          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) {  
2273                  PrintAndLog ( "Usage:  hf mf cgetblk <block number>" );  
2274                  PrintAndLog ( "sample:  hf mf cgetblk 1" );  
2275                  PrintAndLog ( "Get block data from magic Chinese card (only works with such cards) \n " );  
2279          gen 
=  mfCIdentify ();  
2281          blockNo 
=  param_get8 ( Cmd
,  0 );  
2283          PrintAndLog ( "--block number: %2 d " ,  blockNo
);  
2286                  /* generation 1b magic card */  
2287                  res 
=  mfCGetBlock ( blockNo
,  memBlock
,  CSETBLOCK_SINGLE_OPER 
|  CSETBLOCK_MAGIC_1B
);  
2289                  /* generation 1a magic card by default */  
2290                  res 
=  mfCGetBlock ( blockNo
,  memBlock
,  CSETBLOCK_SINGLE_OPER
);  
2293                          PrintAndLog ( "Can't read block. error= %d " ,  res
);  
2297          PrintAndLog ( "block data: %s " ,  sprint_hex ( memBlock
,  16 ));  
2299          if  ( mfIsSectorTrailer ( blockNo
)) {  
2300                  PrintAndLogEx ( NORMAL
,  "Trailer decoded:" );  
2301                  PrintAndLogEx ( NORMAL
,  "Key A:  %s " ,  sprint_hex_inrow ( memBlock
,  6 ));  
2302                  PrintAndLogEx ( NORMAL
,  "Key B:  %s " ,  sprint_hex_inrow (& memBlock
[ 10 ],  6 ));  
2303                  int  bln 
=  mfFirstBlockOfSector ( mfSectorNum ( blockNo
));  
2304                  int  blinc 
= ( mfNumBlocksPerSector ( mfSectorNum ( blockNo
)) >  4 ) ?  5  :  1 ;  
2305                  for  ( int  i 
=  0 ;  i 
<  4 ;  i
++) {  
2306                          PrintAndLogEx ( NORMAL
,  "Access block  %d%s :  %s " ,  bln
, (( blinc 
>  1 ) && ( i 
<  3 ) ?  "+"  :  "" ) ,  mfGetAccessConditionsDesc ( i
, & memBlock
[ 6 ]));  
2309                  PrintAndLogEx ( NORMAL
,  "UserData:  %s " ,  sprint_hex_inrow (& memBlock
[ 9 ],  1 ));  
2315  int  CmdHF14AMfCGetSc ( const char  * Cmd
) {  
2316          uint8_t  memBlock
[ 16 ] = { 0x00 };  
2317          uint8_t  sectorNo 
=  0 ;  
2318          int  i
,  res
,  flags
,  gen 
=  0 ,  baseblock 
=  0 ,  sect_size 
=  4 ;  
2320          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) {  
2321                  PrintAndLog ( "Usage:  hf mf cgetsc <sector number>" );  
2322                  PrintAndLog ( "sample:  hf mf cgetsc 0" );  
2323                  PrintAndLog ( "Get sector data from magic Chinese card (only works with such cards) \n " );  
2327          sectorNo 
=  param_get8 ( Cmd
,  0 );  
2329          if  ( sectorNo 
>  39 ) {  
2330                  PrintAndLog ( "Sector number must be in [0..15] in MIFARE classic 1k and [0..39] in MIFARE classic 4k." );  
2334          PrintAndLog ( "--sector number: %d  " ,  sectorNo
);  
2336          gen 
=  mfCIdentify ();  
2338          flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;  
2339          if  ( sectorNo 
<  32  ) {  
2340                  baseblock 
=  sectorNo 
*  4 ;  
2342                  baseblock 
=  128  +  16  * ( sectorNo 
-  32 );  
2345          if  ( sectorNo 
>  31 )  sect_size 
=  16 ;  
2347          for  ( i 
=  0 ;  i 
<  sect_size
;  i
++) {  
2348                  if  ( i 
==  1 )  flags 
=  0 ;  
2349                  if  ( i 
==  sect_size 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;  
2352                          /* generation 1b magic card */  
2353                          flags 
|=  CSETBLOCK_MAGIC_1B
;  
2355                  res 
=  mfCGetBlock ( baseblock 
+  i
,  memBlock
,  flags
);  
2357                          PrintAndLog ( "Can't read block.  %d  error= %d " ,  baseblock 
+  i
,  res
);  
2361                  PrintAndLog ( "block  %3 d data: %s " ,  baseblock 
+  i
,  sprint_hex ( memBlock
,  16 ));  
2363                  if  ( mfIsSectorTrailer ( baseblock 
+  i
)) {  
2364                  PrintAndLogEx ( NORMAL
,  "Trailer decoded:" );  
2365                  PrintAndLogEx ( NORMAL
,  "Key A:  %s " ,  sprint_hex_inrow ( memBlock
,  6 ));  
2366                  PrintAndLogEx ( NORMAL
,  "Key B:  %s " ,  sprint_hex_inrow (& memBlock
[ 10 ],  6 ));  
2367                  int  bln 
=  baseblock
;  
2368                  int  blinc 
= ( mfNumBlocksPerSector ( sectorNo
) >  4 ) ?  5  :  1 ;  
2369                  for  ( int  i 
=  0 ;  i 
<  4 ;  i
++) {  
2370                          PrintAndLogEx ( NORMAL
,  "Access block  %d%s :  %s " ,  bln
, (( blinc 
>  1 ) && ( i 
<  3 ) ?  "+"  :  "" ) ,  mfGetAccessConditionsDesc ( i
, & memBlock
[ 6 ]));  
2373                  PrintAndLogEx ( NORMAL
,  "UserData:  %s " ,  sprint_hex_inrow (& memBlock
[ 9 ],  1 ));  
2380  int  CmdHF14AMfCSave ( const char  * Cmd
) {  
2383          char  filename
[ FILE_PATH_SIZE
] = { 0x00 };  
2384          char  *  fnameptr 
=  filename
;  
2385          uint8_t  fillFromEmulator 
=  0 ;  
2386          uint8_t  buf
[ 256 ] = { 0x00 };  
2387          int  i
,  j
,  len
,  flags
,  gen 
=  0 ,  numblock 
=  64 ;  
2389          // memset(filename, 0, sizeof(filename));  
2390          // memset(buf, 0, sizeof(buf));  
2392          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) {  
2393                  PrintAndLog ( "It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`" );  
2394                  PrintAndLog ( "or into emulator memory (option `e`). 4K card: (option `4`)" );  
2395                  PrintAndLog ( "Usage:  hf mf csave [file name w/o `.eml`][e][4]" );  
2396                  PrintAndLog ( "Sample: hf mf csave " );  
2397                  PrintAndLog ( "        hf mf csave filename" );  
2398                  PrintAndLog ( "        hf mf csave e" );  
2399                  PrintAndLog ( "        hf mf csave 4" );  
2400                  PrintAndLog ( "        hf mf csave filename 4" );  
2401                  PrintAndLog ( "        hf mf csave e 4" );  
2405          char  ctmp 
=  param_getchar ( Cmd
,  0 );  
2406          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ;  
2407          if  ( ctmp 
==  '4' )  numblock 
=  256 ;  
2408          ctmp 
=  param_getchar ( Cmd
,  1 );  
2409          if  ( ctmp 
==  '4' )  numblock 
=  256 ;  
2411          gen 
=  mfCIdentify ();  
2412          PrintAndLog ( "Saving magic mifare  %d K" ,  numblock 
==  256  ?  4 : 1 );  
2414          if  ( fillFromEmulator
) {  
2415                  // put into emulator  
2416                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;  
2417                  for  ( i 
=  0 ;  i 
<  numblock
;  i
++) {  
2418                          if  ( i 
==  1 )  flags 
=  0 ;  
2419                          if  ( i 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;  
2422                                  /* generation 1b magic card */  
2423                                  flags 
|=  CSETBLOCK_MAGIC_1B
;  
2425                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) {  
2426                                  PrintAndLog ( "Cant get block:  %d " ,  i
);  
2430                          if  ( mfEmlSetMem ( buf
,  i
,  1 )) {  
2431                                  PrintAndLog ( "Cant set emul block:  %d " ,  i
);  
2437                  param_getstr ( Cmd
,  0 ,  filename
,  sizeof ( filename
));  
2439                  len 
=  strlen ( filename
);  
2440                  if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ;  
2442                  ctmp 
=  param_getchar ( Cmd
,  0 );  
2443                  if  ( len 
<  1  || ( ctmp 
==  '4' )) {  
2446                          flags 
=  CSETBLOCK_SINGLE_OPER
;  
2448                                  /* generation 1b magic card */  
2449                                  flags 
|=  CSETBLOCK_MAGIC_1B
;  
2450                          if  ( mfCGetBlock ( 0 ,  buf
,  flags
)) {  
2451                                  PrintAndLog ( "Cant get block:  %d " ,  0 );  
2452                                  len 
=  sprintf ( fnameptr
,  "dump" );  
2456                                  for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 )  
2457                                          sprintf ( fnameptr
,  " %0 2x" ,  buf
[ j
]);  
2460                          //memcpy(filename, Cmd, len);  
2464                  sprintf ( fnameptr
,  ".eml" );  
2467                  f 
=  fopen ( filename
,  "w+" );  
2470                          PrintAndLog ( "File not found or locked." );  
2475                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;  
2476                  for  ( i 
=  0 ;  i 
<  numblock
;  i
++) {  
2477                          if  ( i 
==  1 )  flags 
=  0 ;  
2478                          if  ( i 
==  numblock 
-  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;  
2481                                  /* generation 1b magic card */  
2482                                  flags 
|=  CSETBLOCK_MAGIC_1B
;  
2483                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) {  
2484                                  PrintAndLog ( "Cant get block:  %d " ,  i
);  
2487                          for  ( j 
=  0 ;  j 
<  16 ;  j
++)  
2488                                  fprintf ( f
,  " %0 2x" ,  buf
[ j
]);  
2493                  PrintAndLog ( "Saved to file:  %s " ,  filename
);  
2500  int  CmdHF14AMfSniff ( const char  * Cmd
){  
2502          bool  wantLogToFile 
=  0 ;  
2503          bool  wantDecrypt 
=  0 ;  
2504          //bool wantSaveToEml = 0; TODO  
2505          bool  wantSaveToEmlFile 
=  0 ;  
2516          uint8_t  atqa
[ 2 ] = { 0x00 };  
2519          uint8_t  * buf 
=  NULL
;  
2520          uint16_t  bufsize 
=  0 ;  
2521          uint8_t  * bufPtr 
=  NULL
;  
2524          char  ctmp 
=  param_getchar ( Cmd
,  0 );  
2525          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H'  ) {  
2526                  PrintAndLog ( "It continuously gets data from the field and saves it to: log, emulator, emulator file." );  
2527                  PrintAndLog ( "You can specify:" );  
2528                  PrintAndLog ( "    l - save encrypted sequence to logfile `uid.log`" );  
2529                  PrintAndLog ( "    d - decrypt sequence and put it to log file `uid.log`" );  
2530                  PrintAndLog ( " n/a   e - decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory" );  
2531                  PrintAndLog ( "    f - decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`" );  
2532                  PrintAndLog ( "Usage:  hf mf sniff [l][d][e][f]" );  
2533                  PrintAndLog ( "  sample: hf mf sniff l d e" );  
2537          for  ( int  i 
=  0 ;  i 
<  4 ;  i
++) {  
2538                  ctmp 
=  param_getchar ( Cmd
,  i
);  
2539                  if  ( ctmp 
==  'l'  ||  ctmp 
==  'L' )  wantLogToFile 
=  true ;  
2540                  if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  wantDecrypt 
=  true ;  
2541                  //if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO  
2542                  if  ( ctmp 
==  'f'  ||  ctmp 
==  'F' )  wantSaveToEmlFile 
=  true ;  
2545          printf ( "------------------------------------------------------------------------- \n " );  
2546          printf ( "Executing command.  \n " );  
2547          printf ( "Press the key on the proxmark3 device to abort both proxmark3 and client. \n " );  
2548          printf ( "Press the key on pc keyboard to abort the client. \n " );  
2549          printf ( "------------------------------------------------------------------------- \n " );  
2551          UsbCommand c 
= { CMD_MIFARE_SNIFFER
, { 0 ,  0 ,  0 }};  
2552          clearCommandBuffer ();  
2561                          printf ( " \n aborted via keyboard! \n " );  
2566                  if  ( WaitForResponseTimeoutW ( CMD_ACK
, & resp
,  2000 ,  false )) {  
2567                          res 
=  resp
. arg
[ 0 ] &  0xff ;  
2568                          uint16_t  traceLen 
=  resp
. arg
[ 1 ];  
2571                          if  ( res 
==  0 ) {                                                          // we are done  
2575                          if  ( res 
==  1 ) {                                                          // there is (more) data to be transferred  
2576                                  if  ( pckNum 
==  0 ) {                                               // first packet, (re)allocate necessary buffer  
2577                                          if  ( traceLen 
>  bufsize 
||  buf 
==  NULL
) {  
2579                                                  if  ( buf 
==  NULL
) {                               // not yet allocated  
2580                                                          p 
=  malloc ( traceLen
);  
2581                                                  }  else  {                                                 // need more memory  
2582                                                          p 
=  realloc ( buf
,  traceLen
);  
2585                                                          PrintAndLog ( "Cannot allocate memory for trace" );  
2593                                          memset ( buf
,  0x00 ,  traceLen
);  
2595                                  memcpy ( bufPtr
,  resp
. d
. asBytes
,  len
);  
2600                          if  ( res 
==  2 ) {                                                          // received all data, start displaying  
2601                                  blockLen 
=  bufPtr 
-  buf
;  
2604                                  PrintAndLog ( "received trace len:  %d  packages:  %d " ,  blockLen
,  pckNum
);  
2605                                  while  ( bufPtr 
-  buf 
<  blockLen
) {  
2606                                          bufPtr 
+=  6 ;                                             // skip (void) timing information  
2607                                          len 
= *(( uint16_t  *) bufPtr
);  
2614                                          parlen 
= ( len 
-  1 ) /  8  +  1 ;  
2616                                          if  (( len 
==  14 ) && ( bufPtr
[ 0 ] ==  0xff ) && ( bufPtr
[ 1 ] ==  0xff ) && ( bufPtr
[ 12 ] ==  0xff ) && ( bufPtr
[ 13 ] ==  0xff )) {  
2617                                                  memcpy ( uid
,  bufPtr 
+  2 ,  7 );  
2618                                                  memcpy ( atqa
,  bufPtr 
+  2  +  7 ,  2 );  
2619                                                  uid_len 
= ( atqa
[ 0 ] &  0xC0 ) ==  0x40  ?  7  :  4 ;  
2621                                                  PrintAndLog ( "tag select uid: %s  atqa:0x %0 2x %0 2x sak:0x %0 2x" ,  
2622                                                          sprint_hex ( uid 
+ ( 7  -  uid_len
),  uid_len
),  
2626                                                  if  ( wantLogToFile 
||  wantDecrypt
) {  
2627                                                          FillFileNameByUID ( logHexFileName
,  uid 
+ ( 7  -  uid_len
),  ".log" ,  uid_len
);  
2628                                                          AddLogCurrentDT ( logHexFileName
);  
2631                                                          mfTraceInit ( uid
,  atqa
,  sak
,  wantSaveToEmlFile
);  
2633                                                  oddparitybuf ( bufPtr
,  len
,  parity
);  
2634                                                  PrintAndLog ( " %s ( %d ): %s  [ %s ] c[ %s ] %c " ,   
2635                                                          isTag 
?  "TAG" : "RDR" ,   
2637                                                          sprint_hex ( bufPtr
,  len
),   
2638                                                          printBitsPar ( bufPtr 
+  len
,  len
),   
2639                                                          printBitsPar ( parity
,  len
),  
2640                                                          memcmp ( bufPtr 
+  len
,  parity
,  len 
/  8  +  1 ) ?  '!'  :  ' ' );  
2642                                                          AddLogHex ( logHexFileName
,  isTag 
?  "TAG: " : "RDR: " ,  bufPtr
,  len
);  
2644                                                          mfTraceDecode ( bufPtr
,  len
,  bufPtr
[ len
],  wantSaveToEmlFile
);  
2648                                          bufPtr 
+=  parlen
;        // ignore parity  
2657          msleep ( 300 );  // wait for exiting arm side.  
2658          PrintAndLog ( "Done." );  
2662  //needs nt, ar, at, Data to decrypt  
2663  int  CmdDecryptTraceCmds ( const char  * Cmd
){  
2666          param_gethex_ex ( Cmd
, 3 , data
,& len
);  
2667          return  tryDecryptWord ( param_get32ex ( Cmd
, 0 , 0 , 16 ), param_get32ex ( Cmd
, 1 , 0 , 16 ), param_get32ex ( Cmd
, 2 , 0 , 16 ), data
, len
/ 2 );  
2670  int  CmdHF14AMfAuth4 ( const char  * cmd
) {  
2671          uint8_t  keyn
[ 20 ] = { 0 };  
2673          uint8_t  key
[ 16 ] = { 0 };  
2676          CLIParserInit ( "hf mf auth4" ,   
2677                  "Executes AES authentication command in ISO14443-4" ,   
2678                  "Usage: \n\t hf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication \n "  
2679                          " \t hf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication \n " );  
2681          void *  argtable
[] = {  
2683                  arg_str1 ( NULL
,   NULL
,      "<Key Num (HEX 2 bytes)>" ,  NULL
),  
2684                  arg_str1 ( NULL
,   NULL
,      "<Key Value (HEX 16 bytes)>" ,  NULL
),  
2687          CLIExecWithReturn ( cmd
,  argtable
,  true );  
2689          CLIGetHexWithReturn ( 1 ,  keyn
, & keynlen
);  
2690          CLIGetHexWithReturn ( 2 ,  key
, & keylen
);  
2694                  PrintAndLog ( "ERROR: <Key Num> must be 2 bytes long instead of:  %d " ,  keynlen
);  
2699                  PrintAndLog ( "ERROR: <Key Value> must be 16 bytes long instead of:  %d " ,  keylen
);  
2703          return  MifareAuth4 ( NULL
,  keyn
,  key
,  true ,  false ,  true );  
2706  static  command_t CommandTable
[] =  
2708    { "help" ,              CmdHelp
,                  1 ,  "This help" },  
2709    { "dbg" ,               CmdHF14AMfDbg
,            0 ,  "Set default debug mode" },  
2710    { "rdbl" ,              CmdHF14AMfRdBl
,           0 ,  "Read MIFARE classic block" },  
2711    { "rdsc" ,              CmdHF14AMfRdSc
,           0 ,  "Read MIFARE classic sector" },  
2712    { "dump" ,              CmdHF14AMfDump
,           0 ,  "Dump MIFARE classic tag to binary file" },  
2713    { "restore" ,           CmdHF14AMfRestore
,        0 ,  "Restore MIFARE classic binary file to BLANK tag" },  
2714    { "wrbl" ,              CmdHF14AMfWrBl
,           0 ,  "Write MIFARE classic block" },  
2715    { "auth4" ,             CmdHF14AMfAuth4
,          0 ,  "ISO14443-4 AES authentication" },  
2716    { "chk" ,               CmdHF14AMfChk
,            0 ,  "Test block keys" },  
2717    { "mifare" ,            CmdHF14AMifare
,           0 ,  "Read parity error messages." },  
2718    { "hardnested" ,        CmdHF14AMfNestedHard
,     0 ,  "Nested attack for hardened Mifare cards" },  
2719    { "nested" ,            CmdHF14AMfNested
,         0 ,  "Test nested authentication" },  
2720    { "sniff" ,             CmdHF14AMfSniff
,          0 ,  "Sniff card-reader communication" },  
2721    { "sim" ,               CmdHF14AMf1kSim
,          0 ,  "Simulate MIFARE card" },  
2722    { "eclr" ,              CmdHF14AMfEClear
,         0 ,  "Clear simulator memory block" },  
2723    { "eget" ,              CmdHF14AMfEGet
,           0 ,  "Get simulator memory block" },  
2724    { "eset" ,              CmdHF14AMfESet
,           0 ,  "Set simulator memory block" },  
2725    { "eload" ,             CmdHF14AMfELoad
,          0 ,  "Load from file emul dump" },  
2726    { "esave" ,             CmdHF14AMfESave
,          0 ,  "Save to file emul dump" },  
2727    { "ecfill" ,            CmdHF14AMfECFill
,         0 ,  "Fill simulator memory with help of keys from simulator" },  
2728    { "ekeyprn" ,           CmdHF14AMfEKeyPrn
,        0 ,  "Print keys from simulator memory" },  
2729    { "cwipe" ,             CmdHF14AMfCWipe
,          0 ,  "Wipe magic Chinese card" },  
2730    { "csetuid" ,           CmdHF14AMfCSetUID
,        0 ,  "Set UID for magic Chinese card" },  
2731    { "csetblk" ,           CmdHF14AMfCSetBlk
,        0 ,  "Write block - Magic Chinese card" },  
2732    { "cgetblk" ,           CmdHF14AMfCGetBlk
,        0 ,  "Read block - Magic Chinese card" },  
2733    { "cgetsc" ,            CmdHF14AMfCGetSc
,         0 ,  "Read sector - Magic Chinese card" },  
2734    { "cload" ,             CmdHF14AMfCLoad
,          0 ,  "Load dump into magic Chinese card" },  
2735    { "csave" ,             CmdHF14AMfCSave
,          0 ,  "Save dump from magic Chinese card into file or emulator" },  
2736    { "decrypt" ,           CmdDecryptTraceCmds
,      1 ,  "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace" },  
2737    { NULL
,                NULL
,                     0 ,  NULL
}  
2740  int  CmdHFMF ( const char  * Cmd
)  
2742          ( void ) WaitForResponseTimeout ( CMD_ACK
, NULL
, 100 );  
2743          CmdsParse ( CommandTable
,  Cmd
);  
2747  int  CmdHelp ( const char  * Cmd
)  
2749    CmdsHelp ( CommandTable
);