rfc:easy_userland_csprng

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
rfc:easy_userland_csprng [2015/02/20 22:09] – created sammykrfc:easy_userland_csprng [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== PHP RFC: Easy User-land CSPRNG ====== ====== PHP RFC: Easy User-land CSPRNG ======
-  * Version: 0.0+  * Version: 0.5
   * Date: 2015-02-20   * Date: 2015-02-20
-  * Author: Sammy Kaye Powersme@sammyk.me +  * Author: Sammy Kaye Powers <me@sammyk.me> & Leigh <leigh@php.net> 
-  * Status: Draft+  * Status: Implemented (in PHP 7.0)
   * First Published at: http://wiki.php.net/rfc/easy_userland_csprng   * First Published at: http://wiki.php.net/rfc/easy_userland_csprng
  
  
 ===== Introduction ===== ===== Introduction =====
-This RFC proposes adding an easy user-land API for reliable [[http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator|CSPRNG]] in PHP.+This RFC proposes adding user-land API for an easy to use and reliable [[http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator|CSPRNG]] in PHP.
  
 ==== The Problem ==== ==== The Problem ====
-PHP is particularly bad at providing CSPRNG'in user-land. Users have a few options like ''openssl_random_pseudo_bytes()'' and ''mcrypt_create_iv()'' to generate pseudo-random bytes, but unfortunately system support for these functions varies.+By default PHP does not provide an easy mechanism for accessing cryptographically strong random numbers in user-land. Users have a few options like ''openssl_random_pseudo_bytes()''''mcrypt_create_iv()'' or directly opening ''/dev/*random'' devices to obtain high quality pseudo-random bytes, but unfortunately system support for these functions and extensions varies between platforms and each come with their own set of problems
  
-The ''mcrypt_create_iv()'' function is provided by the [[http://mcrypt.sourceforge.net/|MCrypt lib]] which is solid, but unmaintained. Since it is built into PHP as an extensionit might not be enabled in certain environments (like most versions of PHP on Mac OS X)The longer this lib goes unmaintained, the more likely it is to have a security hole discovered that goes unfixedAnd on top of all that, [[https://twitter.com/ircmaxell/status/564919926700658689|there is a bounty on MCrypt's head]]!+  * The ''mcrypt_create_iv()'' function has no dependency on [[http://mcrypt.sourceforge.net/|MCrypt lib]] yet it requires the MCrypt extension to be installed before it can be usedUsers are forced to include an entire library for no reason. 
 +  * ''openssl_random_pseudo_bytes()'' is provided by the [[https://www.openssl.org/|OpenSSL lib]]. This function comes with a ''$crypto_strong'' the meaning of which may just confuse users. 
 +  * Falling back to ''/dev/urandom'' is OS-specific.
  
-The ''openssl_random_pseudo_bytes()'' function is provided by the [[https://www.openssl.org/|OpenSSL lib]] which is being actively maintained but is hugely bloated and we've seen several major security issues pop up requiring the most-up-to-date version of the lib to stay secure. Moreover, in certain configurations, ''openssl_random_pseudo_bytes()'' will return bytes that are not cryptographically secure adding more required knowledge in user-land to ensure secure bytes. +In addition users may attempt to generate their own streams of random bytes relying on ''rand()'' or ''mt_rand()''and this is something we absolutely want to avoid.
- +
-Currently the most reliable way to grab pseudo-random bytes across systems is by using either of the libs mentioned above or falling back to a stream of bytes from ''/dev/urandom'' which is OS-specific and can fail when the ''open_basedir'' ini setting is set. This requires user-land apps to write potentially 100's of lines of code to simply generate pseudo-random bytes and there are several caveats that will not generate cryptographically secure bytes. And in some cases no reliable method can be found at all. +
- +
-See the [[https://github.com/facebook/facebook-php-sdk-v4/tree/master/src/Facebook/PseudoRandomString|Facebook PHP SDK's implementation of a CSPRNG]] in PHP to understand how much code is needed in user-land to simply generate cryptographically secure pseudo-random bytes.+
  
 ===== Proposal ===== ===== Proposal =====
-There should be a user-land API to easily return an arbitrary length of cryptographically secure pseudo-random bytes directly from ''arc4random'', ''getrandom'' or ''/dev/urandom'' and work on any supported server configuration or OS.+There should be a user-land API to easily return an arbitrary length of cryptographically secure pseudo-random bytes directly and work on any supported platform.
  
-The initial proposal is to add **two** user-land functions that return the bytes as binary and integer.+The initial proposal is to add **two** user-land functions that return the bytes as binary and integer. Arbitrary length strings of random bytes are important for salts, keys and initialisation vectors. Integers based on CS random are important for applications where unbiased results are critical (i.e. shuffling a Poker deck).
  
 +Signatures:
 +<code>
 +random_bytes(int length);
 +random_int(int min, int max);
 +</code>
 +
 +Examples:
 <code php> <code php>
-$randBinary = random_bytes($bytes 10);+$randomStr = random_bytes($length 16);
  
-$randomInt = random_int($maxInt 900);+$randomInt = random_int($min 0, $max = 127);
 </code> </code>
 +
 +The sources of random used are as follows:
 +  * On windows ''CryptGenRandom'' is used exclusively
 +  * ''arc4random_buf()'' is used if it is available (generally BSD specific)
 +  * ''/dev/arandom'' is used where available
 +  * ''/dev/urandom'' is used where none of the above is available
 +  * An error is thrown in the event that a sufficient source of randomness is unavailable.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
-There would be no BC breaks.+Any user-land code that defines a ''random_bytes()'' or ''random_int()'' function would generate a fatal error, however it is likely that these functions provide the same or similar functionality as desired.
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
Line 43: Line 55:
  
 ==== To Existing Extensions ==== ==== To Existing Extensions ====
-No existing extensions be affected.+No existing extensions are affected.
  
 ==== To Opcache ==== ==== To Opcache ====
-__TODO Leigh - this one is all yours :)__ +Opcache is unaffected.
-Please explain how you have verified your RFC's compatibility with opcache.+
  
 ==== New Constants ==== ==== New Constants ====
Line 56: Line 67:
  
 ===== Open Issues ===== ===== Open Issues =====
-  * Verify Windows support (@auroraeosrose?+  * Nothing yet
-  * Implement support for ''arc4random'' / ''getrandom'' (Leigh)+
  
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
-This change should not affect any of the existing ''rand()'' or ''mt_rand()'' functionality.+This change does not affect any of the existing ''rand()'' or ''mt_rand()'' functionality.
  
 ===== Future Scope ===== ===== Future Scope =====
Line 67: Line 77:
    * Deprecate ''mcrypt_create_iv()''    * Deprecate ''mcrypt_create_iv()''
    * Improve ''session_id'' randomness generation    * Improve ''session_id'' randomness generation
 +   * Detect LibreSSL-portable for arc4random() on Linux
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
-The current WIP patch can be found here: https://github.com/SammyK/php-src/compare/rand-bytes#diff-f1067207e863d8fa568e63446920e7fcR182+The current patch can be found here: https://github.com/php/php-src/pull/1119 
 + 
 +===== Proposed Voting Choices ===== 
 + 
 +The voting choices are yes (in favor for accepting this RFC for PHP 7) or no (against it). 
 + 
 +===== Vote ===== 
 + 
 +Vote starts on March 14th, and will end two weeks later, on March 28th. 
 + 
 +This RFC requires a 2/3 majority.
  
-===== References ===== +<doodle title="Reliable user-land CSPRNG" auth="SammyK" voteType="single" closed="true"> 
-None so far.+   * Yes 
 +   * No 
 +</doodle>
  
-===== Rejected Features ===== 
-None so far. 
  
 ===== Changelog ===== ===== Changelog =====
-   * 0.0: Initial draft - need Leigh's input+   * 0.5: Updated the function header for random_int() to reflect all args as required. - SammyK  
 +   * 0.4: Added BC info. Updated patch link to point to PR. - SammyK 
 +   * 0.3: Changed ''-PHP_INT_MAX'' to ''~PHP_INT_MAX'' (thanks [[https://twitter.com/trevorsuarez/status/570308776185733122|@trevorsuarez]]) - SammyK 
 +   * 0.2: Condensed the problem domain into something more focused. Added function sigs. - Leigh. 
 +   * 0.1: Mmmm drafty  - Leigh 
 +   * 0.0: Initial draft - need Leigh's input - SammyK
  
 ===== Acknowledgements ===== ===== Acknowledgements =====
-Big thanks to Anthony Ferrara, Daniel Lowrey, Leigh, E. Smith and [[http://chat.stackoverflow.com/rooms/11/php|all the kids in the PHP room]] for all the help with this one!+Big thanks to Anthony Ferrara, Daniel Lowrey, E. Smith and [[http://chat.stackoverflow.com/rooms/11/php|all the kids in the PHP room]] for all the help with this one!
  
rfc/easy_userland_csprng.1424470175.txt.gz · Last modified: 2017/09/22 13:28 (external edit)