]>
 
 
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/mifare/mifarehost.c 
 
 
 
 
 
 
 
7b7107105aa92b9ff000b1221b6cabc4d578ba1a
   2  // people from mifare@nethemba.com, 2010  
   4  // This code is licensed to you under the terms of the GNU GPL, version 2 or,  
   5  // at your option, any later version. See the LICENSE.txt file for the text of  
   7  //-----------------------------------------------------------------------------  
   9  //-----------------------------------------------------------------------------  
  11  #include  "mifarehost.h"  
  19  #include  "crapto1/crapto1.h"  
  26  #include  "iso14443crc.h"  
  27  #include  "util_posix.h"  
  32  // mifare tracer flags used in mfTraceDecode()  
  33  #define TRACE_IDLE                                              0x00  
  34  #define TRACE_AUTH1                                             0x01  
  35  #define TRACE_AUTH2                                             0x02  
  36  #define TRACE_AUTH_OK                                   0x03  
  37  #define TRACE_READ_DATA                                 0x04  
  38  #define TRACE_WRITE_OK                                  0x05  
  39  #define TRACE_WRITE_DATA                                0x06  
  40  #define TRACE_ERROR                                             0xFF  
  43  static int  compare_uint64 ( const void  * a
,  const void  * b
) {  
  44          // didn't work: (the result is truncated to 32 bits)  
  45          //return (*(int64_t*)b - *(int64_t*)a);  
  48          if  (*( uint64_t *) b 
== *( uint64_t *) a
)  return  0 ;  
  49          else if  (*( uint64_t *) b 
< *( uint64_t *) a
)  return  1 ;  
  54  // create the intersection (common members) of two sorted lists. Lists are terminated by -1. Result will be in list1. Number of elements is returned.  
  55  static uint32_t  intersection ( uint64_t  * list1
,  uint64_t  * list2
)  
  57          if  ( list1 
==  NULL 
||  list2 
==  NULL
) {  
  60          uint64_t  * p1
, * p2
, * p3
;  
  64          while  ( * p1 
!= - 1  && * p2 
!= - 1  ) {  
  65                  if  ( compare_uint64 ( p1
,  p2
) ==  0 ) {  
  70                          while  ( compare_uint64 ( p1
,  p2
) <  0 ) ++ p1
;  
  71                          while  ( compare_uint64 ( p1
,  p2
) >  0 ) ++ p2
;  
  79  // Darkside attack (hf mf mifare)  
  80  static uint32_t  nonce2key ( uint32_t  uid
,  uint32_t  nt
,  uint32_t  nr
,  uint32_t  ar
,  uint64_t  par_info
,  uint64_t  ks_info
,  uint64_t  ** keys
) {  
  81          struct  Crypto1State 
* states
;  
  83          uint8_t  bt
,  ks3x
[ 8 ],  par
[ 8 ][ 8 ];  
  84          uint64_t  key_recovered
;  
  87          // Reset the last three significant bits of the reader nonce  
  90          for  ( pos
= 0 ;  pos
< 8 ;  pos
++) {  
  91                  ks3x
[ 7 - pos
] = ( ks_info 
>> ( pos
* 8 )) &  0x0f ;  
  92                  bt 
= ( par_info 
>> ( pos
* 8 )) &  0xff ;  
  94                                  par
[ 7 - pos
][ i
] = ( bt 
>>  i
) &  0x01 ;  
  98          states 
=  lfsr_common_prefix ( nr
,  ar
,  ks3x
,  par
, ( par_info 
==  0 ));  
 100          if  ( states 
==  NULL
) {  
 105          keylist 
= ( uint64_t *) states
;  
 107          for  ( i 
=  0 ;  keylist
[ i
];  i
++) {  
 108                  lfsr_rollback_word ( states
+ i
,  uid
^ nt
,  0 );  
 109                  crypto1_get_lfsr ( states
+ i
, & key_recovered
);  
 110                  keylist
[ i
] =  key_recovered
;  
 119  int  mfDarkside ( uint64_t  * key
) {  
 121          uint32_t  nt 
=  0 ,  nr 
=  0 ,  ar 
=  0 ;  
 122          uint64_t  par_list 
=  0 ,  ks_list 
=  0 ;  
 123          uint64_t  * keylist 
=  NULL
, * last_keylist 
=  NULL
;  
 124          uint32_t  keycount 
=  0 ;  
 127          UsbCommand c 
= { CMD_READER_MIFARE
, { true ,  0 ,  0 }};  
 130          printf ( "------------------------------------------------------------------------- \n " );  
 131          printf ( "Executing command. Expected execution time: 25sec on average \n " );  
 132          printf ( "Press button on the proxmark3 device to abort both proxmark3 and client. \n " );  
 133          printf ( "------------------------------------------------------------------------- \n " );  
 137                  clearCommandBuffer ();  
 142                          int  c 
=  getchar (); ( void )  c
;  
 155                          if  ( WaitForResponseTimeout ( CMD_ACK
, & resp
,  1000 )) {  
 160                                  uid 
= ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+   0 ,  4 );  
 161                                  nt 
=  ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+   4 ,  4 );  
 162                                  par_list 
=  bytes_to_num ( resp
. d
. asBytes 
+   8 ,  8 );  
 163                                  ks_list 
=  bytes_to_num ( resp
. d
. asBytes 
+   16 ,  8 );  
 164                                  nr 
= ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+  24 ,  4 );  
 165                                  ar 
= ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+  28 ,  4 );  
 170                  if  ( par_list 
==  0  &&  c
. arg
[ 0 ] ==  true ) {  
 171                          PrintAndLog ( "Parity is all zero. Most likely this card sends NACK on every failed authentication." );  
 175                  keycount 
=  nonce2key ( uid
,  nt
,  nr
,  ar
,  par_list
,  ks_list
, & keylist
);  
 178                          PrintAndLog ( "Key not found (lfsr_common_prefix list is null). Nt= %0 8x" ,  nt
);  
 179                          PrintAndLog ( "This is expected to happen in 25%% of all cases. Trying again with a different reader nonce..." );  
 184                          qsort ( keylist
,  keycount
,  sizeof (* keylist
),  compare_uint64
);  
 185                          keycount 
=  intersection ( last_keylist
,  keylist
);  
 188                                  last_keylist 
=  keylist
;  
 194                          PrintAndLog ( "Found  %u  possible keys. Trying to authenticate with each of them ... \n " ,  keycount
);  
 196                          PrintAndLog ( "Found a possible key. Trying to authenticate... \n " );  
 199                  uint8_t  * keys_to_chk 
=  malloc ( keycount 
*  6 );  
 200                  for  ( int  i 
=  0 ;  i 
<  keycount
;  i
++) {  
 201                          num_to_bytes ( keylist
[ i
],  6 ,  keys_to_chk
+ i
);  
 205                  mfCheckKeys ( 0 ,  0 ,  0 ,  false ,  keycount
,  keys_to_chk
,  key
);  
 214                          PrintAndLog ( "Authentication failed. Trying again..." );  
 216                          last_keylist 
=  keylist
;  
 224  int  mfCheckKeys ( uint8_t  blockNo
,  uint8_t  keyType
,  uint16_t  timeout14a
,  bool  clear_trace
,  uint32_t  keycnt
,  uint8_t  * keys
,  uint64_t  * found_key
) {  
 226          bool  display_progress 
=  false ;  
 227          uint64_t  start_time 
=  msclock ();  
 228          uint64_t  next_print_time 
=  start_time 
+  5  *  1000 ;  
 231                  PrintAndLog ( "We have  %d  keys to check. This will take some time!" ,  keycnt
);  
 232                  PrintAndLog ( "Press button to abort." );  
 233                  display_progress 
=  true ;  
 236          uint32_t  max_keys  
= ( keycnt 
> ( USB_CMD_DATA_SIZE 
/  6 )) ? ( USB_CMD_DATA_SIZE 
/  6 ) :  keycnt
;  
 238          bool  multisectorCheck 
=  false ;  
 240          for  ( int  i 
=  0 ,  ii 
=  0 ;  i 
<  keycnt
;  i 
+=  max_keys
) {  
 242                  if  (( i 
+  max_keys
) >=  keycnt
) {  
 243                          max_keys 
=  keycnt 
-  i
;  
 246                  bool  init 
= ( i 
==  0 );  
 247                  bool  drop_field 
= ( max_keys 
==  keycnt
);  
 248                  uint8_t  flags 
=  clear_trace 
|  multisectorCheck 
<<  1  |  init 
<<  2  |  drop_field 
<<  3 ;  
 250                  UsbCommand c 
= { CMD_MIFARE_CHKKEYS
, {(( blockNo 
&  0xff ) | (( keyType 
&  0xff ) <<  8 )),  flags 
|  timeout14a 
<<  16 ,  max_keys
}};   
 251                  memcpy ( c
. d
. asBytes
,  keys 
+  i 
*  6 ,  max_keys 
*  6 );  
 255                  if  (! WaitForResponseTimeout ( CMD_ACK
, & resp
,  3000 ))  
 258                  if  (( resp
. arg
[ 0 ] &  0xff ) !=  0x01 ) {  
 259                          if  ((( int ) resp
. arg
[ 1 ]) <  0 ) {    // error  
 260                                  return  ( int ) resp
. arg
[ 1 ];  
 261                          }  else  {                         // nothing found yet  
 262                                  if  ( display_progress 
&&  msclock () >=  next_print_time
) {  
 263                                          float  brute_force_per_second 
= ( float )( i 
-  ii
) / ( float )( msclock () -  start_time
) *  1000.0 ;  
 265                                          start_time 
=  msclock ();  
 266                                          next_print_time 
=  start_time 
+  10  *  1000 ;  
 267                                          PrintAndLog ( "  %8 d keys left |  %5 .1f keys/sec | worst case  %6 .1f seconds remaining" ,  keycnt 
-  i
,  brute_force_per_second
, ( keycnt
- i
)/ brute_force_per_second
);  
 271                          * found_key 
=  bytes_to_num ( resp
. d
. asBytes
,  6 );  
 276          return  2 ;        // nothing found  
 280  int  mfCheckKeysSec ( uint8_t  sectorCnt
,  uint8_t  keyType
,  uint16_t  timeout14a
,  bool  clear_trace
,  bool  init
,  bool  drop_field
,  uint8_t  keycnt
,  uint8_t  *  keyBlock
,  sector_t 
*  e_sector
) {  
 284          if  ( e_sector 
==  NULL
)  
 287          bool  multisectorCheck 
=  true ;  
 288          uint8_t  flags 
=  clear_trace 
|  multisectorCheck 
<<  1  |  init 
<<  2  |  drop_field 
<<  3 ;  
 290          UsbCommand c 
= { CMD_MIFARE_CHKKEYS
, {(( sectorCnt 
&  0xff ) | (( keyType 
&  0xff ) <<  8 )),  flags 
|  timeout14a 
<<  16 ,  keycnt
}};   
 291          memcpy ( c
. d
. asBytes
,  keyBlock
,  6  *  keycnt
);  
 295          if  (! WaitForResponseTimeoutW ( CMD_ACK
, & resp
,  MAX ( 3000 ,  1000  +  13  *  sectorCnt 
*  keycnt 
* ( keyType 
==  2  ?  2  :  1 )),  false ))  return  1 ;  // timeout: 13 ms / fail auth  
 296          if  (( resp
. arg
[ 0 ] &  0xff ) !=  0x01 )  return  2 ;  
 298          bool  foundAKey 
=  false ;  
 299          for ( int  sec 
=  0 ;  sec 
<  sectorCnt
;  sec
++){  
 300                  for ( int  keyAB 
=  0 ;  keyAB 
<  2 ;  keyAB
++){  
 301                          keyPtr 
= *( resp
. d
. asBytes 
+  keyAB 
*  40  +  sec
);  
 303                                  e_sector
[ sec
]. foundKey
[ keyAB
] =  true ;  
 304                                  e_sector
[ sec
]. Key
[ keyAB
] =  bytes_to_num ( keyBlock 
+ ( keyPtr 
-  1 ) *  6 ,  6 );  
 309          return  foundAKey 
?  0  :  3 ;  
 312  // Compare 16 Bits out of cryptostate  
 313  int  Compare16Bits ( const void  *  a
,  const void  *  b
) {  
 314          if  ((*( uint64_t *) b 
&  0x00ff000000ff0000 ) == (*( uint64_t *) a 
&  0x00ff000000ff0000 ))  return  0 ;  
 315          else if  ((*( uint64_t *) b 
&  0x00ff000000ff0000 ) > (*( uint64_t *) a 
&  0x00ff000000ff0000 ))  return  1 ;  
 322                          struct  Crypto1State 
* slhead
;  
 326                          struct  Crypto1State 
* sltail
;  
 338  // wrapper function for multi-threaded lfsr_recovery32  
 340  #ifdef __has_attribute  
 341  #if __has_attribute(force_align_arg_pointer)  
 342  __attribute__ (( force_align_arg_pointer
))   
 345  * nested_worker_thread ( void  * arg
) {  
 346          struct  Crypto1State 
* p1
;  
 347          StateList_t 
* statelist 
=  arg
;  
 349          statelist
-> head
. slhead 
=  lfsr_recovery32 ( statelist
-> ks1
,  statelist
-> nt_enc 
^  statelist
-> uid
);  
 350          for  ( p1 
=  statelist
-> head
. slhead
; *( uint64_t  *) p1 
!=  0 ;  p1
++);  
 351          statelist
-> len 
=  p1 
-  statelist
-> head
. slhead
;  
 352          statelist
-> tail
. sltail 
= -- p1
;  
 353          qsort ( statelist
-> head
. slhead
,  statelist
-> len
,  sizeof ( uint64_t ),  Compare16Bits
);  
 355          return  statelist
-> head
. slhead
;  
 359  int  mfnested ( uint8_t  blockNo
,  uint8_t  keyType
,  uint16_t  timeout14a
,  uint8_t  * key
,  uint8_t  trgBlockNo
,  uint8_t  trgKeyType
,  uint8_t  * resultKey
,  bool  calibrate
) {  
 364          int  num_unique_nonces
;  
 366          StateList_t statelists
[ 2 ];  
 367          struct  Crypto1State 
* p1
, * p2
, * p3
, * p4
;  
 369          uint8_t  * keyBlock 
=  NULL
;  
 375          ( void ) WaitForResponseTimeout ( CMD_ACK
, NULL
, 100 );  
 377          UsbCommand c 
= { CMD_MIFARE_NESTED
, { blockNo 
+  keyType 
*  0x100 ,  trgBlockNo 
+  trgKeyType 
*  0x100 ,  calibrate
}};  
 378          memcpy ( c
. d
. asBytes
,  key
,  6 );  
 381          if  (! WaitForResponseTimeout ( CMD_ACK
, & resp
,  2500 )) {  
 382                  // some cards can cause it to get stuck in a loop, so break out of it  
 383                  UsbCommand c 
= { CMD_PING
};  
 385                  ( void ) WaitForResponseTimeout ( CMD_ACK
, NULL
, 500 );  
 390                  return  resp
. arg
[ 0 ];   // error during nested  
 393          memcpy (& uid
,  resp
. d
. asBytes
,  4 );  
 394          PrintAndLog ( "uid: %0 8x trgbl= %d  trgkey= %x " ,  uid
, ( uint16_t ) resp
. arg
[ 2 ] &  0xff , ( uint16_t ) resp
. arg
[ 2 ] >>  8 );  
 396          for  ( i 
=  0 ;  i 
<  2 ;  i
++) {  
 397                  statelists
[ i
]. blockNo 
=  resp
. arg
[ 2 ] &  0xff ;  
 398                  statelists
[ i
]. keyType 
= ( resp
. arg
[ 2 ] >>  8 ) &  0xff ;  
 399                  statelists
[ i
]. uid 
=  uid
;  
 400                  memcpy (& statelists
[ i
]. nt_enc
,  ( void  *)( resp
. d
. asBytes 
+  4  +  i 
*  8  +  0 ),  4 );  
 401                  memcpy (& statelists
[ i
]. ks1
, ( void  *)( resp
. d
. asBytes 
+  4  +  i 
*  8  +  4 ),  4 );  
 404          uint32_t  authentication_timeout
;  
 405          memcpy (& authentication_timeout
,  resp
. d
. asBytes 
+  20 ,  4 );  
 406          PrintAndLog ( "Setting authentication timeout to %"  PRIu32 
"us" ,  authentication_timeout 
*  1000  /  106 );  
 408          if  ( statelists
[ 0 ]. nt_enc 
==  statelists
[ 1 ]. nt_enc 
&&  statelists
[ 0 ]. ks1 
==  statelists
[ 1 ]. ks1
)  
 409                  num_unique_nonces 
=  1 ;  
 411                  num_unique_nonces 
=  2 ;  
 415          pthread_t thread_id
[ 2 ];  
 417          // create and run worker threads  
 418          for  ( i 
=  0 ;  i 
<  2 ;  i
++) {  
 419                  pthread_create ( thread_id 
+  i
,  NULL
,  nested_worker_thread
, & statelists
[ i
]);  
 422          // wait for threads to terminate:  
 423          for  ( i 
=  0 ;  i 
<  2 ;  i
++) {  
 424                  pthread_join ( thread_id
[ i
], ( void *)& statelists
[ i
]. head
. slhead
);  
 428          // the first 16 Bits of the cryptostate already contain part of our key.  
 429          // Create the intersection of the two lists based on these 16 Bits and  
 430          // roll back the cryptostate  
 431          p1 
=  p3 
=  statelists
[ 0 ]. head
. slhead
;  
 432          p2 
=  p4 
=  statelists
[ 1 ]. head
. slhead
;  
 433          while  ( p1 
<=  statelists
[ 0 ]. tail
. sltail 
&&  p2 
<=  statelists
[ 1 ]. tail
. sltail
) {  
 434                  if  ( Compare16Bits ( p1
,  p2
) ==  0 ) {  
 435                          struct  Crypto1State savestate
, * savep 
= & savestate
;  
 437                          while ( Compare16Bits ( p1
,  savep
) ==  0  &&  p1 
<=  statelists
[ 0 ]. tail
. sltail
) {  
 439                                  lfsr_rollback_word ( p3
,  statelists
[ 0 ]. nt_enc 
^  statelists
[ 0 ]. uid
,  0 );  
 444                          while ( Compare16Bits ( p2
,  savep
) ==  0  &&  p2 
<=  statelists
[ 1 ]. tail
. sltail
) {  
 446                                  lfsr_rollback_word ( p4
,  statelists
[ 1 ]. nt_enc 
^  statelists
[ 1 ]. uid
,  0 );  
 452                          while  ( Compare16Bits ( p1
,  p2
) == - 1 )  p1
++;  
 453                          while  ( Compare16Bits ( p1
,  p2
) ==  1 )  p2
++;  
 458          statelists
[ 0 ]. len 
=  p3 
-  statelists
[ 0 ]. head
. slhead
;  
 459          statelists
[ 1 ]. len 
=  p4 
-  statelists
[ 1 ]. head
. slhead
;  
 460          statelists
[ 0 ]. tail
. sltail
=-- p3
;  
 461          statelists
[ 1 ]. tail
. sltail
=-- p4
;  
 463          for  ( i 
=  0 ;  i 
<  2 ;  i
++) {  
 464                  PrintAndLog ( "statelist  %d : length: %d  block: %0 2d keytype: %d  nt_enc: %0 8X ks1: %0 8X" ,  i
,  statelists
[ i
]. len
,  statelists
[ i
]. blockNo
,  statelists
[ i
]. keyType
,  statelists
[ i
]. nt_enc
,  statelists
[ i
]. ks1
);  
 467          // the statelists now contain possible keys. The key we are searching for must be in the  
 468          // intersection of both lists. Create the intersection:  
 469          qsort ( statelists
[ 0 ]. head
. keyhead
,  statelists
[ 0 ]. len
,  sizeof ( uint64_t ),  compare_uint64
);  
 471          if  ( num_unique_nonces 
>  1 ) {  
 472                  qsort ( statelists
[ 1 ]. head
. keyhead
,  statelists
[ 1 ]. len
,  sizeof ( uint64_t ),  compare_uint64
);  
 473                  statelists
[ 0 ]. len 
=  intersection ( statelists
[ 0 ]. head
. keyhead
,  statelists
[ 1 ]. head
. keyhead
);  
 476                  PrintAndLog ( "Nonce 1 and 2 are the same!" );  
 479          uint32_t  num_keys 
=  statelists
[ 0 ]. len
;  
 480          keyBlock 
=  calloc ( num_keys
,  6 );  
 481          if  ( keyBlock 
==  NULL
) {  
 482                  free ( statelists
[ 0 ]. head
. slhead
);  
 483                  free ( statelists
[ 1 ]. head
. slhead
);  
 487          for  ( i 
=  0 ;  i 
<  num_keys
;  i
++) {  
 488                  crypto1_get_lfsr ( statelists
[ 0 ]. head
. slhead 
+  i
, & key64
);  
 489                  num_to_bytes ( key64
,  6 ,  keyBlock 
+  i
* 6 );  
 492          // The list may still contain several key candidates. Test each of them with mfCheckKeys  
 493          isOK 
=  mfCheckKeys ( statelists
[ 0 ]. blockNo
,  statelists
[ 0 ]. keyType
,  authentication_timeout
,  true ,  num_keys
,  keyBlock
, & key64
);  
 495          if  ( isOK 
==  0 ) {      // success, key found  
 496                  num_to_bytes ( key64
,  6 ,  resultKey
);  
 499          if  ( isOK 
==  1 ) {      // timeout  
 503          free ( statelists
[ 0 ]. head
. slhead
);  
 504          free ( statelists
[ 1 ]. head
. slhead
);  
 511  int  mfReadSector ( uint8_t  sectorNo
,  uint8_t  keyType
,  uint8_t  * key
,  uint8_t  * data
) {  
 513      UsbCommand c 
= { CMD_MIFARE_READSC
, { sectorNo
,  keyType
,  0 }};  
 514      memcpy ( c
. d
. asBytes
,  key
,  6 );  
 515      clearCommandBuffer ();  
 519      if  ( WaitForResponseTimeout ( CMD_ACK
, & resp
,  1500 )) {  
 520          uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 523              memcpy ( data
,  resp
. d
. asBytes
,  mfNumBlocksPerSector ( sectorNo
) *  16 );  
 529          PrintAndLogEx ( ERR
,  "Command execute timeout" );  
 538  int  mfEmlGetMem ( uint8_t  * data
,  int  blockNum
,  int  blocksCount
) {  
 539          UsbCommand c 
= { CMD_MIFARE_EML_MEMGET
, { blockNum
,  blocksCount
,  0 }};  
 543          if  (! WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 ))  return  1 ;  
 544          memcpy ( data
,  resp
. d
. asBytes
,  blocksCount 
*  16 );  
 548  int  mfEmlSetMem ( uint8_t  * data
,  int  blockNum
,  int  blocksCount
) {  
 549          UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, { blockNum
,  blocksCount
,  0 }};  
 550          memcpy ( c
. d
. asBytes
,  data
,  blocksCount 
*  16 );  
 557  int  mfCGetBlock ( uint8_t  blockNo
,  uint8_t  * data
,  uint8_t  params
) {  
 560          UsbCommand c 
= { CMD_MIFARE_CGETBLOCK
, { params
,  0 ,  blockNo
}};  
 564          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  
 565                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 566                  memcpy ( data
,  resp
. d
. asBytes
,  16 );  
 569                  PrintAndLog ( "Command execute timeout" );  
 575  int  mfCSetBlock ( uint8_t  blockNo
,  uint8_t  * data
,  uint8_t  * uid
,  bool  wantWipe
,  uint8_t  params
) {  
 578          UsbCommand c 
= { CMD_MIFARE_CSETBLOCK
, { wantWipe
,  params 
& ( 0xFE  | ( uid 
==  NULL 
?  0 : 1 )),  blockNo
}};  
 579          memcpy ( c
. d
. asBytes
,  data
,  16 );  
 583          if  ( WaitForResponseTimeout ( CMD_ACK
, & resp
,  1500 )) {  
 584                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 586                          memcpy ( uid
,  resp
. d
. asBytes
,  4 );  
 590                  PrintAndLog ( "Command execute timeout" );  
 597  int  mfCWipe ( uint32_t  numSectors
,  bool  gen1b
,  bool  wantWipe
,  bool  wantFill
) {  
 599          uint8_t  cmdParams 
=  wantWipe 
+  wantFill 
*  0x02  +  gen1b 
*  0x04 ;  
 600          UsbCommand c 
= { CMD_MIFARE_CWIPE
, { numSectors
,  cmdParams
,  0 }};  
 604          WaitForResponse ( CMD_ACK
,& resp
);  
 605          isOK  
=  resp
. arg
[ 0 ] &  0xff ;  
 610  int  mfCSetUID ( uint8_t  * uid
,  uint8_t  * atqa
,  uint8_t  * sak
,  uint8_t  * oldUID
) {  
 611          uint8_t  oldblock0
[ 16 ] = { 0x00 };  
 612          uint8_t  block0
[ 16 ] = { 0x00 };  
 617          /* generation 1a magic card by default */  
 618          uint8_t  cmdParams 
=  CSETBLOCK_SINGLE_OPER
;  
 620                  /* generation 1b magic card */  
 621                  cmdParams 
=  CSETBLOCK_SINGLE_OPER 
|  CSETBLOCK_MAGIC_1B
;  
 624          res 
=  mfCGetBlock ( 0 ,  oldblock0
,  cmdParams
);  
 627                  memcpy ( block0
,  oldblock0
,  16 );  
 628                  PrintAndLog ( "old block 0:   %s " ,  sprint_hex ( block0
, 16 ));  
 630                  PrintAndLog ( "Couldn't get old data. Will write over the last bytes of Block 0." );  
 633          // fill in the new values  
 635          memcpy ( block0
,  uid
,  4 );  
 637          block0
[ 4 ] =  block0
[ 0 ] ^  block0
[ 1 ] ^  block0
[ 2 ] ^  block0
[ 3 ];  
 638          // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)  
 645          PrintAndLog ( "new block 0:   %s " ,  sprint_hex ( block0
,  16 ));  
 647          res 
=  mfCSetBlock ( 0 ,  block0
,  oldUID
,  false ,  cmdParams
);  
 649                  PrintAndLog ( "Can't set block 0. Error:  %d " ,  res
);  
 657          UsbCommand c 
= { CMD_MIFARE_CIDENT
, { 0 ,  0 ,  0 }};  
 660          WaitForResponse ( CMD_ACK
,& resp
);  
 662          uint8_t  isGeneration 
=  resp
. arg
[ 0 ] &  0xff ;  
 663          switch (  isGeneration 
){  
 664                  case  1 :  PrintAndLog ( "Chinese magic backdoor commands (GEN 1a) detected" );  break ;  
 665                  case  2 :  PrintAndLog ( "Chinese magic backdoor command (GEN 1b) detected" );  break ;  
 666                  default :  PrintAndLog ( "No chinese magic backdoor command detected" );  break ;  
 669          return  ( int )  isGeneration
;  
 676  static uint8_t  trailerAccessBytes
[ 4 ] = { 0x08 ,  0x77 ,  0x8F ,  0x00 };  
 679  char  logHexFileName
[ FILE_PATH_SIZE
] = { 0x00 };  
 680  static uint8_t  traceCard
[ 4096 ] = { 0x00 };  
 681  static char  traceFileName
[ FILE_PATH_SIZE
] = { 0x00 };  
 682  static int  traceState 
=  TRACE_IDLE
;  
 683  static uint8_t  traceCurBlock 
=  0 ;  
 684  static uint8_t  traceCurKey 
=  0 ;  
 686  struct  Crypto1State 
* traceCrypto1 
=  NULL
;  
 688  struct  Crypto1State 
* revstate
;  
 694  uint32_t  uid
;        // serial number  
 695  uint32_t  nt
;         // tag challenge  
 696  uint32_t  nt_enc
;     // encrypted tag challenge  
 697  uint8_t  nt_enc_par
;  // encrypted tag challenge parity  
 698  uint32_t  nr_enc
;     // encrypted reader challenge  
 699  uint32_t  ar_enc
;     // encrypted reader response  
 700  uint8_t  ar_enc_par
;  // encrypted reader response parity  
 701  uint32_t  at_enc
;     // encrypted tag response  
 702  uint8_t  at_enc_par
;  // encrypted tag response parity  
 704  int  isTraceCardEmpty ( void ) {  
 705          return  (( traceCard
[ 0 ] ==  0 ) && ( traceCard
[ 1 ] ==  0 ) && ( traceCard
[ 2 ] ==  0 ) && ( traceCard
[ 3 ] ==  0 ));  
 708  int  isBlockEmpty ( int  blockN
) {  
 709          for  ( int  i 
=  0 ;  i 
<  16 ;  i
++)  
 710                  if  ( traceCard
[ blockN 
*  16  +  i
] !=  0 )  return  0 ;  
 715  int  isBlockTrailer ( int  blockN
) {  
 716   return  (( blockN 
&  0x03 ) ==  0x03 );  
 719  int  saveTraceCard ( void ) {  
 722          if  ((! strlen ( traceFileName
)) || ( isTraceCardEmpty ()))  return  0 ;  
 724          f 
=  fopen ( traceFileName
,  "w+" );  
 727          for  ( int  i 
=  0 ;  i 
<  64 ;  i
++) {   // blocks  
 728                  for  ( int  j 
=  0 ;  j 
<  16 ;  j
++)   // bytes  
 729                          fprintf ( f
,  " %0 2x" , *( traceCard 
+  i 
*  16  +  j
));  
 737  int  loadTraceCard ( uint8_t  * tuid
) {  
 739          char  buf
[ 64 ] = { 0x00 };  
 740          uint8_t  buf8
[ 64 ] = { 0x00 };  
 743          if  (! isTraceCardEmpty ())  
 746          memset ( traceCard
,  0x00 ,  4096 );  
 747          memcpy ( traceCard
,  tuid 
+  3 ,  4 );  
 749          FillFileNameByUID ( traceFileName
,  tuid
,  ".eml" ,  7 );  
 751          f 
=  fopen ( traceFileName
,  "r" );  
 758                  memset ( buf
,  0 ,  sizeof ( buf
));  
 759                  if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) {  
 760                          PrintAndLog ( "File reading error." );  
 765                  if  ( strlen ( buf
) <  32 ){  
 767                          PrintAndLog ( "File content error. Block data must include 32 HEX symbols" );  
 771                  for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 )  
 772                          sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]);  
 774                  memcpy ( traceCard 
+  blockNum 
*  16 ,  buf8
,  16 );  
 783  int  mfTraceInit ( uint8_t  * tuid
,  uint8_t  * atqa
,  uint8_t  sak
,  bool  wantSaveToEmlFile
) {  
 786                  crypto1_destroy ( traceCrypto1
);  
 790          if  ( wantSaveToEmlFile
)  
 793          traceCard
[ 4 ] =  traceCard
[ 0 ] ^  traceCard
[ 1 ] ^  traceCard
[ 2 ] ^  traceCard
[ 3 ];  
 795          memcpy (& traceCard
[ 6 ],  atqa
,  2 );  
 797          uid 
=  bytes_to_num ( tuid 
+  3 ,  4 );  
 799          traceState 
=  TRACE_IDLE
;  
 804  void  mf_crypto1_decrypt ( struct  Crypto1State 
* pcs
,  uint8_t  * data
,  int  len
,  bool  isEncrypted
){  
 809                  for  ( i 
=  0 ;  i 
<  len
;  i
++)  
 810                          data
[ i
] =  crypto1_byte ( pcs
,  0x00 ,  isEncrypted
) ^  data
[ i
];  
 813                  for  ( i 
=  0 ;  i 
<  4 ;  i
++)  
 814                          bt 
|= ( crypto1_bit ( pcs
,  0 ,  isEncrypted
) ^  BIT ( data
[ 0 ],  i
)) <<  i
;  
 821  bool  NTParityCheck ( uint32_t  ntx
) {  
 823                  ( oddparity8 ( ntx 
>>  8  &  0xff ) ^ ( ntx 
&  0x01 ) ^ (( nt_enc_par 
>>  5 ) &  0x01 ) ^ ( nt_enc 
&  0x01 )) ||  
 824                  ( oddparity8 ( ntx 
>>  16  &  0xff ) ^ ( ntx 
>>  8  &  0x01 ) ^ (( nt_enc_par 
>>  6 ) &  0x01 ) ^ ( nt_enc 
>>  8  &  0x01 )) ||  
 825                  ( oddparity8 ( ntx 
>>  24  &  0xff ) ^ ( ntx 
>>  16  &  0x01 ) ^ (( nt_enc_par 
>>  7 ) &  0x01 ) ^ ( nt_enc 
>>  16  &  0x01 ))  
 829          uint32_t  ar 
=  prng_successor ( ntx
,  64 );  
 831                  ( oddparity8 ( ar 
>>  8  &  0xff ) ^ ( ar 
&  0x01 ) ^ (( ar_enc_par 
>>  5 ) &  0x01 ) ^ ( ar_enc 
&  0x01 )) ||  
 832                  ( oddparity8 ( ar 
>>  16  &  0xff ) ^ ( ar 
>>  8  &  0x01 ) ^ (( ar_enc_par 
>>  6 ) &  0x01 ) ^ ( ar_enc 
>>  8  &  0x01 )) ||  
 833                  ( oddparity8 ( ar 
>>  24  &  0xff ) ^ ( ar 
>>  16  &  0x01 ) ^ (( ar_enc_par 
>>  7 ) &  0x01 ) ^ ( ar_enc 
>>  16  &  0x01 ))  
 837          uint32_t  at 
=  prng_successor ( ntx
,  96 );  
 839                  ( oddparity8 ( ar 
&  0xff ) ^ ( at 
>>  24  &  0x01 ) ^ (( ar_enc_par 
>>  4 ) &  0x01 ) ^ ( at_enc 
>>  24  &  0x01 )) ||  
 840                  ( oddparity8 ( at 
>>  8  &  0xff ) ^ ( at 
&  0x01 ) ^ (( at_enc_par 
>>  5 ) &  0x01 ) ^ ( at_enc 
&  0x01 )) ||  
 841                  ( oddparity8 ( at 
>>  16  &  0xff ) ^ ( at 
>>  8  &  0x01 ) ^ (( at_enc_par 
>>  6 ) &  0x01 ) ^ ( at_enc 
>>  8  &  0x01 )) ||  
 842                  ( oddparity8 ( at 
>>  24  &  0xff ) ^ ( at 
>>  16  &  0x01 ) ^ (( at_enc_par 
>>  7 ) &  0x01 ) ^ ( at_enc 
>>  16  &  0x01 ))  
 850  int  mfTraceDecode ( uint8_t  * data_src
,  int  len
,  uint8_t  parity
,  bool  wantSaveToEmlFile
) {  
 853          if  ( traceState 
==  TRACE_ERROR
)  return  1 ;  
 855                  traceState 
=  TRACE_ERROR
;  
 859          memcpy ( data
,  data_src
,  len
);  
 860          if  (( traceCrypto1
) && (( traceState 
==  TRACE_IDLE
) || ( traceState 
>  TRACE_AUTH_OK
))) {  
 861                  mf_crypto1_decrypt ( traceCrypto1
,  data
,  len
,  0 );  
 863                  oddparitybuf ( data
,  len
,  parity
);  
 864                  PrintAndLog ( "dec>  %s  [ %s ]" ,  sprint_hex ( data
,  len
),  printBitsPar ( parity
,  len
));  
 865                  AddLogHex ( logHexFileName
,  "dec> " ,  data
,  len
);  
 868          switch  ( traceState
) {  
 870                  // check packet crc16!  
 871                  if  (( len 
>=  4 ) && (! CheckCrc14443 ( CRC_14443_A
,  data
,  len
))) {  
 872                          PrintAndLog ( "dec> CRC ERROR!!!" );  
 873                          AddLogLine ( logHexFileName
,  "dec> " ,  "CRC ERROR!!!" );  
 874                          traceState 
=  TRACE_ERROR
;   // do not decrypt the next commands  
 879                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0x60 ) || ( data
[ 0 ] ==  0x61 ))) {  
 880                          traceState 
=  TRACE_AUTH1
;  
 881                          traceCurBlock 
=  data
[ 1 ];  
 882                          traceCurKey 
=  data
[ 0 ] ==  60  ?  1 : 0 ;  
 887                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0x30 ))) {  
 888                          traceState 
=  TRACE_READ_DATA
;  
 889                          traceCurBlock 
=  data
[ 1 ];  
 894                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0xA0 ))) {  
 895                          traceState 
=  TRACE_WRITE_OK
;  
 896                          traceCurBlock 
=  data
[ 1 ];  
 901                  if  (( len 
== 4 ) && (( data
[ 0 ] ==  0x50 ) && ( data
[ 1 ] ==  0x00 ))) {  
 902                          traceState 
=  TRACE_ERROR
;   // do not decrypt the next commands  
 909          case  TRACE_READ_DATA
:  
 911                          traceState 
=  TRACE_IDLE
;  
 913                          if  ( isBlockTrailer ( traceCurBlock
)) {  
 914                                  memcpy ( traceCard 
+  traceCurBlock 
*  16  +  6 ,  data 
+  6 ,  4 );  
 916                                  memcpy ( traceCard 
+  traceCurBlock 
*  16 ,  data
,  16 );  
 918                          if  ( wantSaveToEmlFile
)  saveTraceCard ();  
 921                          traceState 
=  TRACE_ERROR
;  
 927                  if  (( len 
==  1 ) && ( data
[ 0 ] ==  0x0a )) {  
 928                          traceState 
=  TRACE_WRITE_DATA
;  
 932                          traceState 
=  TRACE_ERROR
;  
 937          case  TRACE_WRITE_DATA
:  
 939                          traceState 
=  TRACE_IDLE
;  
 941                          memcpy ( traceCard 
+  traceCurBlock 
*  16 ,  data
,  16 );  
 942                          if  ( wantSaveToEmlFile
)  saveTraceCard ();  
 945                          traceState 
=  TRACE_ERROR
;  
 952                          traceState 
=  TRACE_AUTH2
;  
 954                                  nt 
=  bytes_to_num ( data
,  4 );  
 956                                  nt_enc 
=  bytes_to_num ( data
,  4 );  
 961                          traceState 
=  TRACE_ERROR
;  
 968                          traceState 
=  TRACE_AUTH_OK
;  
 970                          nr_enc 
=  bytes_to_num ( data
,  4 );  
 971                          ar_enc 
=  bytes_to_num ( data 
+  4 ,  4 );  
 972                          ar_enc_par 
=  parity 
<<  4 ;  
 975                          traceState 
=  TRACE_ERROR
;  
 982                          traceState 
=  TRACE_IDLE
;  
 984                          at_enc 
=  bytes_to_num ( data
,  4 );  
 989                                  ks2 
=  ar_enc 
^  prng_successor ( nt
,  64 );  
 990                                  ks3 
=  at_enc 
^  prng_successor ( nt
,  96 );  
 991                                  revstate 
=  lfsr_recovery64 ( ks2
,  ks3
);  
 992                                  lfsr_rollback_word ( revstate
,  0 ,  0 );  
 993                                  lfsr_rollback_word ( revstate
,  0 ,  0 );  
 994                                  lfsr_rollback_word ( revstate
,  nr_enc
,  1 );  
 995                                  lfsr_rollback_word ( revstate
,  uid 
^  nt
,  0 );  
 997                                  crypto1_get_lfsr ( revstate
, & lfsr
);  
 998                                  crypto1_destroy ( revstate
);  
1000                                  printf ( "key> probable key: %x%x  Prng: %s  ks2: %0 8x ks3: %0 8x \n " ,   
1001                                          ( unsigned int )(( lfsr 
&  0xFFFFFFFF00000000 ) >>  32 ), ( unsigned int )( lfsr 
&  0xFFFFFFFF ),   
1002                                          validate_prng_nonce ( nt
) ?  "WEAK" :  "HARDEND" ,  
1005                                  AddLogUint64 ( logHexFileName
,  "key> " ,  lfsr
);  
1007                                  if  ( validate_prng_nonce ( nt
)) {  
1008                                          struct  Crypto1State 
* pcs
;  
1009                                          pcs 
=  crypto1_create ( ui64Key
);  
1010                                          uint32_t  nt1 
=  crypto1_word ( pcs
,  nt_enc 
^  uid
,  1 ) ^  nt_enc
;  
1011                                          uint32_t  ar 
=  prng_successor ( nt1
,  64 );  
1012                                          uint32_t  at 
=  prng_successor ( nt1
,  96 );  
1013                                          printf ( "key> nested auth uid:  %0 8x nt:  %0 8x nt_parity:  %s  ar:  %0 8x at:  %0 8x \n " ,  uid
,  nt1
,  printBitsPar (& nt_enc_par
,  4 ),  ar
,  at
);  
1014                                          uint32_t  nr1 
=  crypto1_word ( pcs
,  nr_enc
,  1 ) ^  nr_enc
;  
1015                                          uint32_t  ar1 
=  crypto1_word ( pcs
,  0 ,  0 ) ^  ar_enc
;  
1016                                          uint32_t  at1 
=  crypto1_word ( pcs
,  0 ,  0 ) ^  at_enc
;  
1017                                          crypto1_destroy ( pcs
);  
1018                                          printf ( "key> the same key test. nr1:  %0 8x ar1:  %0 8x at1:  %0 8x  \n " ,  nr1
,  ar1
,  at1
);  
1020                                          if  ( NTParityCheck ( nt1
))  
1021                                                  printf ( "key> the same key test OK. key= %x%x \n " , ( unsigned int )(( ui64Key 
&  0xFFFFFFFF00000000 ) >>  32 ), ( unsigned int )( ui64Key 
&  0xFFFFFFFF ));  
1023                                                  printf ( "key> the same key test. check nt parity error. \n " );  
1025                                          uint32_t  ntc 
=  prng_successor ( nt
,  90 );  
1028                                          for  ( int  i 
=  0 ;  i 
<  16383 ;  i
++) {  
1029                                                  ntc 
=  prng_successor ( ntc
,  1 );  
1030                                                  if  ( NTParityCheck ( ntc
)){  
1037                                                  printf ( "key> nt candidate= %0 8x nonce distance= %d  candidates count= %d \n " ,  ntx
,  nonce_distance ( nt
,  ntx
),  ntcnt
);  
1039                                                  printf ( "key> don't have any nt candidate(  \n " );  
1042                                          ks2 
=  ar_enc 
^  prng_successor ( ntx
,  64 );  
1043                                          ks3 
=  at_enc 
^  prng_successor ( ntx
,  96 );  
1046                                          revstate 
=  lfsr_recovery64 ( ks2
,  ks3
);  
1047                                          lfsr_rollback_word ( revstate
,  0 ,  0 );  
1048                                          lfsr_rollback_word ( revstate
,  0 ,  0 );  
1049                                          lfsr_rollback_word ( revstate
,  nr_enc
,  1 );  
1050                                          lfsr_rollback_word ( revstate
,  uid 
^  nt
,  0 );  
1052                                          crypto1_get_lfsr ( revstate
, & lfsr
);  
1053                                          crypto1_destroy ( revstate
);  
1055                                          printf ( "key> probable key: %x%x   ks2: %0 8x ks3: %0 8x \n " ,   
1056                                                  ( unsigned int )(( lfsr 
&  0xFFFFFFFF00000000 ) >>  32 ), ( unsigned int )( lfsr 
&  0xFFFFFFFF ),  
1059                                          AddLogUint64 ( logHexFileName
,  "key> " ,  lfsr
);  
1061                                          printf ( "key> hardnested not implemented! \n " );  
1063                                          crypto1_destroy ( traceCrypto1
);  
1066                                          traceState 
=  TRACE_ERROR
;  
1070                          int  blockShift 
= (( traceCurBlock 
&  0xFC ) +  3 ) *  16 ;  
1071                          if  ( isBlockEmpty (( traceCurBlock 
&  0xFC ) +  3 ))  memcpy ( traceCard 
+  blockShift 
+  6 ,  trailerAccessBytes
,  4 );  
1074                                  num_to_bytes ( lfsr
,  6 ,  traceCard 
+  blockShift 
+  10 );  
1076                                  num_to_bytes ( lfsr
,  6 ,  traceCard 
+  blockShift
);  
1078                          if  ( wantSaveToEmlFile
)  saveTraceCard ();  
1081                                  crypto1_destroy ( traceCrypto1
);  
1084                          // set cryptosystem state  
1085                          traceCrypto1 
=  lfsr_recovery64 ( ks2
,  ks3
);  
1088                          traceState 
=  TRACE_ERROR
;  
1094                  traceState 
=  TRACE_ERROR
;  
1103  int  tryDecryptWord ( uint32_t  nt
,  uint32_t  ar_enc
,  uint32_t  at_enc
,  uint8_t  * data
,  int  len
){  
1105          uint32_t nt;      // tag challenge  
1106          uint32_t ar_enc;  // encrypted reader response  
1107          uint32_t at_enc;  // encrypted tag response  
1110                  crypto1_destroy ( traceCrypto1
);  
1112          ks2 
=  ar_enc 
^  prng_successor ( nt
,  64 );  
1113          ks3 
=  at_enc 
^  prng_successor ( nt
,  96 );  
1114          traceCrypto1 
=  lfsr_recovery64 ( ks2
,  ks3
);  
1116          mf_crypto1_decrypt ( traceCrypto1
,  data
,  len
,  0 );  
1118          PrintAndLog ( "Decrypted data: [ %s ]" ,  sprint_hex ( data
, len
) );  
1119          crypto1_destroy ( traceCrypto1
);  
1123  /** validate_prng_nonce  
1124   * Determine if nonce is deterministic. ie: Suspectable to Darkside attack.  
1127   *   false = hardend prng  
1129  bool  validate_prng_nonce ( uint32_t  nonce
) {  
1133          dist 
=  malloc ( 2  <<  16 );  
1138          for  ( x 
=  i 
=  1 ;  i
; ++ i
) {  
1139                  dist
[( x 
&  0xff ) <<  8  |  x 
>>  8 ] =  i
;  
1140                  x 
=  x 
>>  1  | ( x 
^  x 
>>  2  ^  x 
>>  3  ^  x 
>>  5 ) <<  15 ;  
1143          uint32_t  res 
= ( 65535  -  dist
[ nonce 
>>  16 ] +  dist
[ nonce 
&  0xffff ]) %  65535 ;  
1150  * function performs a partial AUTH,  where it tries to authenticate against block0, key A, but only collects tag nonce.  
1151  * the tag nonce is check to see if it has a predictable PRNG.  
1153  *       TRUE if tag uses WEAK prng (ie Now the NACK bug also needs to be present for Darkside attack)  
1154  *   FALSE is tag uses HARDEND prng (ie hardnested attack possible, with known key)  
1156  int  DetectClassicPrng ( void ){  
1158          UsbCommand resp
,  respA
;   
1159          uint8_t  cmd
[] = { 0x60 ,  0x00 };  // MIFARE_AUTH_KEYA  
1160          uint32_t  flags 
=  ISO14A_CONNECT 
|  ISO14A_RAW 
|  ISO14A_APPEND_CRC 
|  ISO14A_NO_RATS
;  
1162          UsbCommand c 
= { CMD_READER_ISO_14443a
, { flags
,  sizeof ( cmd
),  0 }};  
1163          memcpy ( c
. d
. asBytes
,  cmd
,  sizeof ( cmd
));  
1165          clearCommandBuffer ();  
1167          if  (! WaitForResponseTimeout ( CMD_ACK
, & resp
,  2000 )) {  
1168          PrintAndLog ( "PRNG UID: Reply timeout." );  
1172          // if select tag failed.  
1173          if  ( resp
. arg
[ 0 ] ==  0 ) {  
1174                  PrintAndLog ( "PRNG error: selecting tag failed, can't detect prng." );  
1178          if  (! WaitForResponseTimeout ( CMD_ACK
, & respA
,  5000 )) {  
1179          PrintAndLog ( "PRNG data: Reply timeout." );  
1184          if  ( respA
. arg
[ 0 ] !=  4 ) {  
1185                  PrintAndLog ( "PRNG data error: Wrong length:  %d " ,  respA
. arg
[ 0 ]);  
1189          uint32_t  nonce 
=  bytes_to_num ( respA
. d
. asBytes
,  respA
. arg
[ 0 ]);  
1190          return  validate_prng_nonce ( nonce
);