summaryrefslogtreecommitdiffstats
path: root/lib/random_bytes_dev_urandom.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/random_bytes_dev_urandom.php')
-rw-r--r--lib/random_bytes_dev_urandom.php190
1 files changed, 96 insertions, 94 deletions
diff --git a/lib/random_bytes_dev_urandom.php b/lib/random_bytes_dev_urandom.php
index a0d9b42..aaccd5a 100644
--- a/lib/random_bytes_dev_urandom.php
+++ b/lib/random_bytes_dev_urandom.php
@@ -30,119 +30,121 @@ if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
-/**
- * Unless open_basedir is enabled, use /dev/urandom for
- * random numbers in accordance with best practices
- *
- * Why we use /dev/urandom and not /dev/random
- * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
- *
- * @param int $bytes
- *
- * @throws Exception
- *
- * @return string
- */
-function random_bytes($bytes)
-{
- static $fp = null;
+if (!is_callable('random_bytes')) {
/**
- * This block should only be run once
+ * Unless open_basedir is enabled, use /dev/urandom for
+ * random numbers in accordance with best practices
+ *
+ * Why we use /dev/urandom and not /dev/random
+ * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
*/
- if (empty($fp)) {
+ function random_bytes($bytes)
+ {
+ static $fp = null;
/**
- * We use /dev/urandom if it is a char device.
- * We never fall back to /dev/random
+ * This block should only be run once
*/
- $fp = fopen('/dev/urandom', 'rb');
- if (!empty($fp)) {
- $st = fstat($fp);
- if (($st['mode'] & 0170000) !== 020000) {
- fclose($fp);
- $fp = false;
- }
- }
-
- if (!empty($fp)) {
+ if (empty($fp)) {
/**
- * stream_set_read_buffer() does not exist in HHVM
- *
- * If we don't set the stream's read buffer to 0, PHP will
- * internally buffer 8192 bytes, which can waste entropy
- *
- * stream_set_read_buffer returns 0 on success
+ * We use /dev/urandom if it is a char device.
+ * We never fall back to /dev/random
*/
- if (is_callable('stream_set_read_buffer')) {
- stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
+ $fp = fopen('/dev/urandom', 'rb');
+ if (!empty($fp)) {
+ $st = fstat($fp);
+ if (($st['mode'] & 0170000) !== 020000) {
+ fclose($fp);
+ $fp = false;
+ }
}
- if (is_callable('stream_set_chunk_size')) {
- stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
+
+ if (!empty($fp)) {
+ /**
+ * stream_set_read_buffer() does not exist in HHVM
+ *
+ * If we don't set the stream's read buffer to 0, PHP will
+ * internally buffer 8192 bytes, which can waste entropy
+ *
+ * stream_set_read_buffer returns 0 on success
+ */
+ if (is_callable('stream_set_read_buffer')) {
+ stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
+ }
+ if (is_callable('stream_set_chunk_size')) {
+ stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
+ }
}
}
- }
-
- try {
- $bytes = RandomCompat_intval($bytes);
- } catch (TypeError $ex) {
- throw new TypeError(
- 'random_bytes(): $bytes must be an integer'
- );
- }
- if ($bytes < 1) {
- throw new Error(
- 'Length must be greater than 0'
- );
- }
+ try {
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
- /**
- * This if() block only runs if we managed to open a file handle
- *
- * It does not belong in an else {} block, because the above
- * if (empty($fp)) line is logic that should only be run once per
- * page load.
- */
- if (!empty($fp)) {
- $remaining = $bytes;
- $buf = '';
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
/**
- * We use fread() in a loop to protect against partial reads
+ * This if() block only runs if we managed to open a file handle
+ *
+ * It does not belong in an else {} block, because the above
+ * if (empty($fp)) line is logic that should only be run once per
+ * page load.
*/
- do {
- $read = fread($fp, $remaining);
- if ($read === false) {
- /**
- * We cannot safely read from the file. Exit the
- * do-while loop and trigger the exception condition
- */
- $buf = false;
- break;
- }
+ if (!empty($fp)) {
+ $remaining = $bytes;
+ $buf = '';
+
/**
- * Decrease the number of bytes returned from remaining
+ * We use fread() in a loop to protect against partial reads
*/
- $remaining -= RandomCompat_strlen($read);
- $buf .= $read;
- } while ($remaining > 0);
-
- /**
- * Is our result valid?
- */
- if ($buf !== false) {
- if (RandomCompat_strlen($buf) === $bytes) {
+ do {
+ $read = fread($fp, $remaining);
+ if ($read === false) {
+ /**
+ * We cannot safely read from the file. Exit the
+ * do-while loop and trigger the exception condition
+ */
+ $buf = false;
+ break;
+ }
/**
- * Return our random entropy buffer here:
+ * Decrease the number of bytes returned from remaining
*/
- return $buf;
+ $remaining -= RandomCompat_strlen($read);
+ $buf .= $read;
+ } while ($remaining > 0);
+
+ /**
+ * Is our result valid?
+ */
+ if ($buf !== false) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return $buf;
+ }
}
}
- }
- /**
- * If we reach here, PHP has failed us.
- */
- throw new Exception(
- 'Error reading from source device'
- );
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Error reading from source device'
+ );
+ }
}