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