openssl_random_pseudo_bytes() is not cryptographically secure

Sec Bug #70014 openssl_random_pseudo_bytes() is not cryptographically secure
Submitted: 2015-07-08 00:50 UTC Modified: 2016-04-26 09:30 UTC
From: masonm at the-jci dot org Assigned: stas (profile)
Status: Closed Package: OpenSSL related
PHP Version: 5.6.10 OS:
Private report: No CVE-ID: 2015-8867

 [2015-07-08 00:50 UTC] masonm at the-jci dot org

Description:
------------
The docs claim that openssl_random_pseudo_bytes() returns a "cryptographically strong" result as long as the $crypto_strong parameter is true, but I checked the source and that does not appear to be the case. The openssl_random_pseudo_bytes() PHP function calls the RAND_psuedo_bytes() OpenSSL function (https://github.com/php/php-src/blob/php-5.6.10/ext/openssl/openssl.c#L5408), which the OpenSSL docs (https://www.openssl.org/docs/crypto/RAND_bytes.html) say should only be used for non-cryptographic purposes:

    RAND_pseudo_bytes() has been deprecated. Users should use RAND_bytes() instead. RAND_pseudo_bytes() puts num pseudo-random bytes into buf. Pseudo-random byte sequences generated by RAND_pseudo_bytes() will be unique if they are of sufficient length, but are not necessarily unpredictable. They can be used for non-cryptographic purposes and for certain purposes in cryptographic protocols, but usually not for key generation etc.


Test script:
---------------
N/A


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

 [2015-07-08 02:58 UTC] masonm at the-jci dot org

Here's a patch: https://gist.github.com/MasonM/05b4e425d55c6d6d1b23
(I couldn't attach the patch since this bug is private)

The patch changes openssl_random_pseudo_bytes() to call RAND_bytes() instead, as recommended in the OpenSSL docs. I made the patch against the "php-5.6.10" tag in the Git repo and ran all the tests. I got a few "EXPECTED FAIL" errors, but they appear unrelated.

 [2015-07-08 14:43 UTC] masonm at the-jci dot org

There's one additional issue with https://github.com/php/php-src/blob/php-5.6.10/ext/openssl/openssl.c#L5408 that I forgot to mention before: it only checks if the return value of RAND_pseudo_bytes() is less than zero. However, RAND_pseudo_bytes() can return 0 if the result is not "cryptographically strong" (which seems to contradict the earlier statement in the OpenSSL docs that I posted). This means the $crypto_strong isn't being set correctly. My patch fixes this issue.

 [2015-07-16 06:12 UTC] masonm at the-jci dot org

Sorry, disregard my previous comment. I misread the code there.

 [2015-08-04 22:22 UTC] stas@php.net

-Status: Open +Status: Closed

 [2016-04-22 21:33 UTC] stas@php.net

-Assigned To: +Assigned To: stas

 [2016-04-26 09:30 UTC] remi@php.net

-CVE-ID: +CVE-ID: 2015-8867

 [2016-06-20 08:40 UTC] samuel dot chemla at orange dot com

Hi guys,

is PHP5.4 affected?
If yes, will this path be backported?
If no, on which release was it backported?

Regards

 [2016-06-20 11:45 UTC] samuel dot chemla at orange dot com

Sorry, thanks for your reply.