/**
* Initialize an initial random state based off of whatever we can find
+ * @return string
*/
protected function initialRandomState() {
// $_SERVER contains a variety of unstable user and system specific information
* @see self::generate()
*/
public function realGenerate( $bytes, $forceStrong = false ) {
- wfProfileIn( __METHOD__ );
wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " .
wfGetAllCallers( 5 ) . "\n" );
// entropy so this is also preferable to just trying to read urandom because it may work
// on Windows systems as well.
if ( function_exists( 'mcrypt_create_iv' ) ) {
- wfProfileIn( __METHOD__ . '-mcrypt' );
$rem = $bytes - strlen( $buffer );
$iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
if ( $iv === false ) {
wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) .
" bytes of randomness.\n" );
}
- wfProfileOut( __METHOD__ . '-mcrypt' );
}
}
if ( function_exists( 'openssl_random_pseudo_bytes' )
&& ( !wfIsWindows() || version_compare( PHP_VERSION, '5.3.4', '>=' ) )
) {
- wfProfileIn( __METHOD__ . '-openssl' );
$rem = $bytes - strlen( $buffer );
$openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
if ( $openssl_bytes === false ) {
// using it use it's say on whether the randomness is strong
$this->strong = !!$openssl_strong;
}
- wfProfileOut( __METHOD__ . '-openssl' );
}
}
if ( strlen( $buffer ) < $bytes &&
( function_exists( 'stream_set_read_buffer' ) || $forceStrong )
) {
- wfProfileIn( __METHOD__ . '-fopen-urandom' );
$rem = $bytes - strlen( $buffer );
if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom " .
} else {
wfDebug( __METHOD__ . ": /dev/urandom could not be opened.\n" );
}
- wfProfileOut( __METHOD__ . '-fopen-urandom' );
}
// If we cannot use or generate enough data from a secure source
": Falling back to using a pseudo random state to generate randomness.\n" );
}
while ( strlen( $buffer ) < $bytes ) {
- wfProfileIn( __METHOD__ . '-fallback' );
$buffer .= $this->hmac( $this->randomState(), mt_rand() );
// This code is never really cryptographically strong, if we use it
// at all, then set strong to false.
$this->strong = false;
- wfProfileOut( __METHOD__ . '-fallback' );
}
// Once the buffer has been filled up with enough random data to fulfill
wfDebug( __METHOD__ . ": " . strlen( $buffer ) .
" bytes of randomness leftover in the buffer.\n" );
- wfProfileOut( __METHOD__ );
-
return $generated;
}