Skip to content

Commit 7371d33

Browse files
authored
src: use V8 entropy source if RAND_bytes() != 1
RAND_bytes() may return 0 to indicate an error, in which case the buffer might not have been filled with random data at all. Instead of ignoring this case, let V8 use its own entropy source. Historically, this used to be a weak source of entropy, but V8 now implements a proper source even on Windows. And even if V8's own entropy source turns out to be weak, it does not matter much: V8's PRNG itself is not cryptographically secure, so even if it is seeded from a cryptographically secure entropy source, it does not produce cryptographically secure random numbers. PR-URL: nodejs#44493 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
1 parent 4236ef9 commit 7371d33

File tree

3 files changed

+15
-7
lines changed

3 files changed

+15
-7
lines changed

src/crypto/crypto_util.cc

+10-4
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,16 @@ void CheckEntropy() {
7676
bool EntropySource(unsigned char* buffer, size_t length) {
7777
// Ensure that OpenSSL's PRNG is properly seeded.
7878
CheckEntropy();
79-
// RAND_bytes() can return 0 to indicate that the entropy data is not truly
80-
// random. That's okay, it's still better than V8's stock source of entropy,
81-
// which is /dev/urandom on UNIX platforms and the current time on Windows.
82-
return RAND_bytes(buffer, length) != -1;
79+
// If RAND_bytes() returns 0 or -1, the data might not be random at all. In
80+
// that case, return false, which causes V8 to use its own entropy source. The
81+
// quality of V8's entropy source depends on multiple factors and we should
82+
// not assume that it is cryptographically secure (even though it often is).
83+
// However, even if RAND_bytes() fails and V8 resorts to its potentially weak
84+
// entropy source, it really does not matter much: V8 only uses the entropy
85+
// source to seed its own PRNG, which itself is not cryptographically secure.
86+
// In other words, even a cryptographically secure entropy source would not
87+
// guarantee cryptographically secure random numbers in V8.
88+
return RAND_bytes(buffer, length) == 1;
8389
}
8490

8591
int PasswordCallback(char* buf, int size, int rwflag, void* u) {

src/crypto/crypto_util.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ struct MarkPopErrorOnReturn {
134134
void CheckEntropy();
135135

136136
// Generate length bytes of random data. If this returns false, the data
137-
// may not be truly random but it's still generally good enough.
137+
// might not be random at all and should not be used.
138138
bool EntropySource(unsigned char* buffer, size_t length);
139139

140140
int PasswordCallback(char* buf, int size, int rwflag, void* u);

src/node.cc

+4-2
Original file line numberDiff line numberDiff line change
@@ -980,8 +980,10 @@ std::unique_ptr<InitializationResult> InitializeOncePerProcess(
980980
return result;
981981
}
982982

983-
// V8 on Windows doesn't have a good source of entropy. Seed it from
984-
// OpenSSL's pool.
983+
// Seed V8's PRNG from OpenSSL's pool. This is recommended by V8 and a
984+
// potentially better source of randomness than what V8 uses by default, but
985+
// it does not guarantee that pseudo-random values produced by V8 will be
986+
// cryptograhically secure.
985987
V8::SetEntropySource(crypto::EntropySource);
986988
#endif // HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
987989
}

0 commit comments

Comments
 (0)