|
49 | 49 |
|
50 | 50 | #if HAVE_OPENSSL |
51 | 51 | #include "ncrypto.h" |
| 52 | +#if OPENSSL_VERSION_MAJOR >= 3 |
| 53 | +#include <openssl/provider.h> |
| 54 | +#endif |
52 | 55 | #include "node_crypto.h" |
53 | 56 | #if OPENSSL_VERSION_MAJOR >= 3 && !defined(CONF_MFLAGS_IGNORE_MISSING_FILE) |
54 | 57 | // OpenSSL hides this deprecated macro under OPENSSL_NO_DEPRECATED, but the |
@@ -1264,15 +1267,36 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args, |
1264 | 1267 | } |
1265 | 1268 | crypto::InstallFipsIndicatorCallback(); |
1266 | 1269 |
|
1267 | | - // Ensure CSPRNG is properly seeded. |
1268 | | - CHECK(ncrypto::CSPRNG(nullptr, 0)); |
| 1270 | + // Activating the default provider here keeps --openssl-legacy-provider |
| 1271 | + // working. Its explicit load disables OpenSSL's fallback, and the eager |
| 1272 | + // CSPRNG check used to activate the provider as a side effect. Only |
| 1273 | + // check the seeding when that provider is missing or FIPS is on, so a |
| 1274 | + // configuration without a DRBG still aborts at startup instead of |
| 1275 | + // hanging at the first crypto call. Otherwise the DRBG is instantiated |
| 1276 | + // on first use. |
| 1277 | +#if OPENSSL_VERSION_MAJOR >= 3 |
| 1278 | + const bool check_csprng = ncrypto::isFipsEnabled() || |
| 1279 | + !OSSL_PROVIDER_available(nullptr, "default"); |
| 1280 | +#else |
| 1281 | + const bool check_csprng = true; |
| 1282 | +#endif |
| 1283 | + if (check_csprng) { |
| 1284 | + CHECK(ncrypto::CSPRNG(nullptr, 0)); |
| 1285 | + } |
1269 | 1286 |
|
| 1287 | + // V8 uses the entropy for hash seeds, ASLR and Math.random(), none of |
| 1288 | + // it cryptographic. Going through OpenSSL would instantiate the DRBG |
| 1289 | + // and build the default provider's algorithm tables on every startup. |
| 1290 | + // V8 falls back to very weak entropy when the source fails, so abort |
| 1291 | + // instead. |
1270 | 1292 | V8::SetEntropySource([](unsigned char* buffer, size_t length) { |
1271 | | - // V8 falls back to very weak entropy when this function fails |
1272 | | - // and /dev/urandom isn't available. That wouldn't be so bad if |
1273 | | - // the entropy was only used for Math.random() but it's also used for |
1274 | | - // hash table and address space layout randomization. Better to abort. |
| 1293 | +#ifdef _AIX |
| 1294 | + // uv_random() reads /dev/random on AIX, which blocks. OpenSSL seeds |
| 1295 | + // from /dev/urandom there. |
1275 | 1296 | CHECK(ncrypto::CSPRNG(buffer, length)); |
| 1297 | +#else |
| 1298 | + CHECK_EQ(uv_random(nullptr, nullptr, buffer, length, 0, nullptr), 0); |
| 1299 | +#endif |
1276 | 1300 | return true; |
1277 | 1301 | }); |
1278 | 1302 | #endif // !defined(OPENSSL_IS_BORINGSSL) |
|
0 commit comments