Index: src/wp-includes/pluggable.php
===================================================================
--- src/wp-includes/pluggable.php	(revision 31466)
+++ src/wp-includes/pluggable.php	(working copy)
@@ -2005,43 +2005,205 @@
 	for ( $i = 0; $i < $length; $i++ ) {
 		$password .= substr($chars, wp_rand(0, strlen($chars) - 1), 1);
 	}
 
 	/**
 	 * Filter the randomly-generated password.
 	 *
 	 * @since 3.0.0
 	 *
 	 * @param string $password The generated password.
 	 */
 	return apply_filters( 'random_password', $password );
 }
 endif;
 
+/**
+ * Generate a cryptographically secure random string
+ * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
+ *
+ * @since x.x.x
+ * @internal
+ *
+ * @param int $bytes Number of random bytes.
+ * @return string|WP_Error A string of random charcters of $bytes length, WP_Error if external random sources unavailable
+ */
+function wp_external_random_bytes( $bytes = 32 ) {
+
+	// Uses system native Crypto API in most OS's
+	// Uses native Windows Crypto API in PHP 5.3+ (MCRYPT_DEV_URANDOM)
+	// Prior to 5.3.7 this may also fatal on Windows - https://bugs.php.net/bug.php?id=55169
+	$use_mcrypt = function_exists('mcrypt_create_iv');
+	$use_mcrypt = $use_mcrypt && ! ( 'WIN' == substr( PHP_OS, 0, 3 ) && version_compare( phpversion(), '5.3.7', '<') );
+	if ( $use_mcrypt ) {
+		$buf = mcrypt_create_iv( $bytes, MCRYPT_DEV_URANDOM );
+		if ( $buf !== false ) {
+			return $buf;
+		}
+	}
+
+	// Use /dev/urandom if available
+	// Will cause issues with open_basedir denying access
+	if ( @is_readable( '/dev/urandom' ) ) {
+		$fp = @fopen( '/dev/urandom', 'rb' );
+
+		// Use unbuffered reads if available in PHP 5.3.3+ to avoid read-ahead buffering eating entropy
+		if ( $fp && function_exists( 'stream_set_read_buffer' ) ) {
+			if ( false === stream_set_read_buffer( $fp, 0 ) ) {
+				// We'll skip using /dev/urandom if we can't use an unbuffered file
+				fclose( $fp );
+				unset( $fp );
+			}
+		}
+
+		if ( $fp ) {
+			$buf = '';
+
+			mbstring_binary_safe_encoding();
+
+			// How many bytes do we need?
+			$bytes_remaining = $bytes;
+			do {
+				$buf .= $read = fread( $fp, $bytes_remaining );
+				if ( $read === false ) {
+					// We cannot safely read from /dev/urandom.
+					$buf = false;
+					break;
+				}
+				$bytes_remaining -= strlen( $read );
+			} while( $bytes_remaining > 0 );
+
+			reset_mbstring_encoding();
+
+			fclose( $fp );
+
+			if ( $buf ) {
+				return $buf;
+			}
+		}
+	}
+
+	// Available since PHP 5.3.0
+	// Uses native Windows Cyrpto API's in PHP 5.4+
+	// can be exceedingly slow before PHP 5.3.4 on windows - https://bugs.php.net/bug.php?id=51636
+	$use_openssl = function_exists('openssl_random_pseudo_bytes');
+	$use_openssl = $use_openssl && ! ( 'WIN' == substr( PHP_OS, 0, 3 ) && version_compare( phpversion(), '5.3.4', '<') );
+	if ( $use_openssl ) {
+		$buf = openssl_random_pseudo_bytes( $bytes );
+		if ( $buf !== false ) {
+			return $buf;
+		}
+	}
+
+	return new WP_Error( 'external_rand_source_unavailable', 'External Random Sources unavailable' );
+}
+
+/**
+ * Generate a random positive integer between 0 and PHP_INT_MAX.
+ *
+ * @since x.x.x
+ * @internal
+ *
+ * @return int|WP_Error A random positive integer, WP_Error upon no external random sources being available
+ */
+function wp_external_random_positive_int() {
+	$buf = wp_external_random_bytes( PHP_INT_SIZE );
+	if ( is_wp_error( $buf ) ) {
+		return $buf;
+	}
+
+	$val = 0;
+	$i = strlen( $buf );
+
+	// TODO: Test on a 32bit machine with PHP_INT_SIZE = 4
+	do {
+		$i--;
+		$val <<= 8;
+		$val |= ord( $buf[ $i ] );
+	} while( $i != 0 );
+
+	// effectively absint()
+	return $val & PHP_INT_MAX;
+}
+
+/**
+ * Generates an unbiased, unpredictably random number.
+ *
+ * @since x.x.x
+ * @internal
+ *
+ * @param int $min Lower limit for the generated number.
+ * @param int $max Upper limit for the generated number.
+ * @return int|WP_Error A random number between min and max inclusively, WP_Error on external rand-source failure
+ */
+function wp_external_rand( $min = 0, $max = PHP_INT_MAX ) {
+	// Compat for `wp_rand()`
+	if ( 0 === $max ) {
+		$max = PHP_INT_MAX;
+	}
+	if ( $min == $max ) {
+		return $min;
+	}
+
+	// Calculate from 0..($max-$min), resulting in $min+$rand..$max
+	$max -= $min;
+
+	// 7776 -> 13
+	$bits = ceil( log( $max + 1 ) / log( 2 ) );
+
+	// 2^13 - 1 == 8191 or 0x00001111 11111111
+	// Calculate a mask of how much of the PHP int we're interested in
+	$mask = ceil( pow( 2, $bits ) ) - 1;
+
+	do {
+		$val = wp_external_random_positive_int();
+		if ( is_wp_error( $val ) ) {
+			return $val;
+		}
+
+		// Apply the mask to our val
+		$val &= $mask;
+	} while ( $val > $max );
+
+	// $min..($min+$max)
+	return (int) ( $min + $val );
+}
+
+
 if ( !function_exists('wp_rand') ) :
 /**
  * Generates a random number
  *
  * @since 2.6.2
  *
  * @param int $min Lower limit for the generated number
  * @param int $max Upper limit for the generated number
  * @return int A random number between min and max
  */
 function wp_rand( $min = 0, $max = 0 ) {
 	global $rnd_value;
 
+	// Use an external-
+	static $external_rand_source_available = true;
+	if ( $external_rand_source_available ) {
+		$val = wp_external_rand( $min, $max );
+		if ( ! is_wp_error( $val ) ) {
+			return $val;
+		}
+		$external_rand_source_available = false;
+	}
+
 	// Reset $rnd_value after 14 uses
 	// 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value
 	if ( strlen($rnd_value) < 8 ) {
 		if ( defined( 'WP_SETUP_CONFIG' ) )
 			static $seed = '';
 		else
 			$seed = get_transient('random_seed');
 		$rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed );
 		$rnd_value .= sha1($rnd_value);
 		$rnd_value .= sha1($rnd_value . $seed);
 		$seed = md5($seed . $rnd_value);
 		if ( ! defined( 'WP_SETUP_CONFIG' ) )
 			set_transient('random_seed', $seed);
 	}
 
