Commit 6511fb8e340 for nodejs

commit 6511fb8e34010ad6ea0f73003542373111660fe7
Author: Filip Skokan <panva.ip@gmail.com>
Date:   Wed Oct 21 18:24:04 2026 +0200

    Revert "src: seed V8 from the OS CSPRNG instead of OpenSSL's DRBG"

    This reverts commit 43d3fe95581cb599611dc8e1aae9a79a900998b8.

    PR-URL: https://github.com/nodejs/node/pull/66903
    Reviewed-By: Richard Lau <richard.lau@ibm.com>
    Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
    Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>

diff --git a/src/node.cc b/src/node.cc
index e2efaad8a20..f7a19747bed 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -50,9 +50,6 @@

 #if HAVE_OPENSSL
 #include "ncrypto.h"
-#if OPENSSL_VERSION_MAJOR >= 3
-#include <openssl/provider.h>
-#endif
 #include "node_crypto.h"
 #if OPENSSL_VERSION_MAJOR >= 3 && !defined(CONF_MFLAGS_IGNORE_MISSING_FILE)
 // OpenSSL hides this deprecated macro under OPENSSL_NO_DEPRECATED, but the
@@ -1393,36 +1390,15 @@ InitializeOncePerProcessInternal(
     }
     crypto::InstallFipsIndicatorCallback();

-    // Activating the default provider here keeps --openssl-legacy-provider
-    // working. Its explicit load disables OpenSSL's fallback, and the eager
-    // CSPRNG check used to activate the provider as a side effect. Only
-    // check the seeding when that provider is missing or FIPS is on, so a
-    // configuration without a DRBG still aborts at startup instead of
-    // hanging at the first crypto call. Otherwise the DRBG is instantiated
-    // on first use.
-#if OPENSSL_VERSION_MAJOR >= 3
-    const bool check_csprng = ncrypto::isFipsEnabled() ||
-                              !OSSL_PROVIDER_available(nullptr, "default");
-#else
-    const bool check_csprng = true;
-#endif
-    if (check_csprng) {
-      CHECK(ncrypto::CSPRNG(nullptr, 0));
-    }
+    // Ensure CSPRNG is properly seeded.
+    CHECK(ncrypto::CSPRNG(nullptr, 0));

-    // V8 uses the entropy for hash seeds, ASLR and Math.random(), none of
-    // it cryptographic. Going through OpenSSL would instantiate the DRBG
-    // and build the default provider's algorithm tables on every startup.
-    // V8 falls back to very weak entropy when the source fails, so abort
-    // instead.
     V8::SetEntropySource([](unsigned char* buffer, size_t length) {
-#ifdef _AIX
-      // uv_random() reads /dev/random on AIX, which blocks. OpenSSL seeds
-      // from /dev/urandom there.
+      // V8 falls back to very weak entropy when this function fails
+      // and /dev/urandom isn't available. That wouldn't be so bad if
+      // the entropy was only used for Math.random() but it's also used for
+      // hash table and address space layout randomization. Better to abort.
       CHECK(ncrypto::CSPRNG(buffer, length));
-#else
-      CHECK_EQ(uv_random(nullptr, nullptr, buffer, length, 0, nullptr), 0);
-#endif
       return true;
     });
 #endif  // !defined(OPENSSL_IS_BORINGSSL)
diff --git a/test/addons/openssl-providers/test-legacy-provider-option.js b/test/addons/openssl-providers/test-legacy-provider-option.js
index 1f01ce55a8f..5ad60dac9b8 100644
--- a/test/addons/openssl-providers/test-legacy-provider-option.js
+++ b/test/addons/openssl-providers/test-legacy-provider-option.js
@@ -22,6 +22,3 @@ if (getFips()) {
   common.skip('this test cannot be run in FIPS mode');
 }
 providers.testProviderPresent('legacy');
-// The explicit legacy load disables OpenSSL's provider fallback, so the
-// default provider has to be active before it runs.
-providers.testProviderPresent('default');
diff --git a/test/fixtures/openssl3-conf/random_unavailable.cnf b/test/fixtures/openssl3-conf/random_unavailable.cnf
deleted file mode 100644
index a2dc8d2c9ff..00000000000
--- a/test/fixtures/openssl3-conf/random_unavailable.cnf
+++ /dev/null
@@ -1,7 +0,0 @@
-nodejs_conf = nodejs_init
-
-[nodejs_init]
-random = random_sect
-
-[random_sect]
-random = NO-SUCH-DRBG
diff --git a/test/parallel/test-crypto-no-algorithm.js b/test/parallel/test-crypto-no-algorithm.js
index 0354aad8b0b..06aab7614ff 100644
--- a/test/parallel/test-crypto-no-algorithm.js
+++ b/test/parallel/test-crypto-no-algorithm.js
@@ -57,21 +57,3 @@ if (isMainThread) {
   assert(common.nodeProcessAborted(cp.status, cp.signal),
          `process did not abort, code:${cp.status} signal:${cp.signal}`);
 }
-
-// AIX keeps OpenSSL as V8's entropy source, so a DRBG that cannot be
-// fetched still aborts at startup there.
-if (!common.isAIX) {
-  // A configuration whose random section names a DRBG that cannot be
-  // fetched starts normally; the first crypto call fails, without a hang.
-  const fixtures = require('../common/fixtures');
-  const { spawnSync } = require('node:child_process');
-  const randomConf = fixtures.path('openssl3-conf', 'random_unavailable.cnf');
-  const cp = spawnSync(process.execPath,
-                       [ `--openssl-config=${randomConf}`, '-e',
-                         'require("node:crypto").randomBytes(8)' ],
-                       { encoding: 'utf8' });
-  assert(!common.nodeProcessAborted(cp.status, cp.signal),
-         `process aborted, code:${cp.status} signal:${cp.signal}`);
-  assert.strictEqual(cp.status, 1);
-  assert.match(cp.stderr, /unable to fetch drbg/);
-}
diff --git a/test/parallel/test-crypto-secure-heap.js b/test/parallel/test-crypto-secure-heap.js
index 3c79d1bb8a6..22f90b6be99 100644
--- a/test/parallel/test-crypto-secure-heap.js
+++ b/test/parallel/test-crypto-secure-heap.js
@@ -70,28 +70,6 @@ if (process.argv[2] === 'child') {
   return;
 }

-if (process.argv[2] === 'workers') {
-  // Eight Workers held alive at once. A 1 KiB secure heap has room for a
-  // few DRBGs only, so an isolate setup that drew its entropy through
-  // OpenSSL would fail for the later Workers and abort the process.
-  const { Worker } = require('worker_threads');
-  const i32 = new Int32Array(new SharedArrayBuffer(4));
-  let online = 0;
-  for (let i = 0; i < 8; i++) {
-    const worker = new Worker(
-      'const { workerData } = require("worker_threads");' +
-      'Atomics.wait(workerData.i32, 0, 0);',
-      { eval: true, workerData: { i32 } });
-    worker.on('online', () => {
-      if (++online === 8) {
-        Atomics.store(i32, 0, 1);
-        Atomics.notify(i32, 0);
-      }
-    });
-  }
-  return;
-}
-
 const child = fork(
   process.argv[1],
   ['child'],
@@ -101,19 +79,6 @@ child.on('exit', common.mustCall((code) => {
   assert.strictEqual(code, 0);
 }));

-// AIX keeps OpenSSL as V8's entropy source, so a Worker's isolate setup
-// still draws on the secure heap there.
-if (!common.isAIX) {
-  const child = fork(
-    process.argv[1],
-    ['workers'],
-    { execArgv: ['--secure-heap=1024', '--secure-heap-min=4'] });
-  child.on('exit', common.mustCall((code, signal) => {
-    assert.strictEqual(signal, null);
-    assert.strictEqual(code, 0);
-  }));
-}
-
 {
   const child = fork(fixtures.path('a.js'), {
     execArgv: ['--secure-heap=3', '--secure-heap-min=3'],