Commit fccdbc8b99c for nodejs
commit fccdbc8b99c4579636f4b7e980731f79cbc64231
Author: Lazizbek Ergashev <lazerg2@gmail.com>
Date: Mon Oct 19 09:04:58 2026 +0500
crypto: do not leak scrypt param check errors
Signed-off-by: lazerg <lazerg2@gmail.com>
Assisted-by: Claude Code
PR-URL: https://github.com/nodejs/node/pull/66671
Fixes: https://github.com/nodejs/node/issues/66668
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
diff --git a/src/crypto/crypto_scrypt.cc b/src/crypto/crypto_scrypt.cc
index 24ba2f3e3c5..8e1cd2e43a4 100644
--- a/src/crypto/crypto_scrypt.cc
+++ b/src/crypto/crypto_scrypt.cc
@@ -85,6 +85,7 @@ Maybe<void> ScryptTraits::AdditionalConfig(
params->length = args[offset + 6].As<Int32>()->Value();
CHECK_GE(params->length, 0);
+ ncrypto::MarkPopErrorOnReturn mark_pop_error_on_return;
if (!ncrypto::checkScryptParams(
params->N, params->r, params->p, params->maxmem)) {
// Do not use CryptoErrorStore or ThrowCryptoError here in order to maintain
diff --git a/test/parallel/test-crypto-scrypt.js b/test/parallel/test-crypto-scrypt.js
index e4a4a071558..03198a9a42b 100644
--- a/test/parallel/test-crypto-scrypt.js
+++ b/test/parallel/test-crypto-scrypt.js
@@ -5,6 +5,7 @@ if (!common.hasCrypto)
const assert = require('assert');
const crypto = require('crypto');
+const fixtures = require('../common/fixtures');
const { hasFIPS, isBoringSSL } = require('../common/crypto');
const isFips = hasFIPS(3);
@@ -196,6 +197,19 @@ for (const options of toobig) {
expected);
}
+// A failed parameter check must not leave an error on the OpenSSL error queue
+// for the next unrelated crypto operation to pick up.
+{
+ const key = fixtures.readKey('ec_p256_private.pem');
+ const options = { N: 2 ** 10, p: 1, r: 8, maxmem: 2 ** 20 };
+ const expected = { code: 'ERR_CRYPTO_INVALID_SCRYPT_PARAMS' };
+ assert.throws(() => crypto.scryptSync('pass', 'salt', 1, options), expected);
+ crypto.createPrivateKey(key);
+ assert.throws(() => crypto.scrypt('pass', 'salt', 1, options, () => {}),
+ expected);
+ crypto.createPrivateKey(key);
+}
+
if (!isFips) {
const expected = '4cac4540';
const actual = crypto.scryptSync('pass', 'salt', 4);