Skip to content

Commit 7735824

Browse files
tniessenBethGriggs
authored andcommitted
crypto: increase maxmem range from 32 to 53 bits
Fixes: #28755 Backport-PR-URL: #29316 PR-URL: #28799 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent a3eda28 commit 7735824

File tree

4 files changed

+32
-8
lines changed

4 files changed

+32
-8
lines changed

doc/api/crypto.md

+6
Original file line numberDiff line numberDiff line change
@@ -2352,6 +2352,9 @@ request.
23522352
<!-- YAML
23532353
added: v10.5.0
23542354
changes:
2355+
- version: REPLACEME
2356+
pr-url: https://github.com/nodejs/node/pull/28799
2357+
description: The `maxmem` value can now be any safe integer.
23552358
- version: v10.9.0
23562359
pr-url: https://github.com/nodejs/node/pull/21525
23572360
description: The `cost`, `blockSize` and `parallelization` option names
@@ -2407,6 +2410,9 @@ crypto.scrypt('secret', 'salt', 64, { N: 1024 }, (err, derivedKey) => {
24072410
<!-- YAML
24082411
added: v10.5.0
24092412
changes:
2413+
- version: REPLACEME
2414+
pr-url: https://github.com/nodejs/node/pull/28799
2415+
description: The `maxmem` value can now be any safe integer.
24102416
- version: v10.9.0
24112417
pr-url: https://github.com/nodejs/node/pull/21525
24122418
description: The `cost`, `blockSize` and `parallelization` option names

lib/internal/crypto/scrypt.js

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
const { AsyncWrap, Providers } = internalBinding('async_wrap');
44
const { Buffer } = require('buffer');
5-
const { scrypt: _scrypt } = process.binding('crypto');
6-
const { validateUint32 } = require('internal/validators');
5+
const { scrypt: _scrypt } = internalBinding('crypto');
6+
const { validateInteger, validateUint32 } = require('internal/validators');
77
const {
88
ERR_CRYPTO_SCRYPT_INVALID_PARAMETER,
99
ERR_CRYPTO_SCRYPT_NOT_SUPPORTED,
10-
ERR_INVALID_CALLBACK,
10+
ERR_INVALID_CALLBACK
1111
} = require('internal/errors').codes;
1212
const {
1313
getDefaultEncoding,
@@ -99,8 +99,10 @@ function check(password, salt, keylen, options) {
9999
if (has_p) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER();
100100
p = validateUint32(options.parallelization, 'parallelization');
101101
}
102-
if (options.maxmem !== undefined)
103-
maxmem = validateUint32(options.maxmem, 'maxmem');
102+
if (options.maxmem !== undefined) {
103+
maxmem = options.maxmem;
104+
validateInteger(maxmem, 'maxmem', 0);
105+
}
104106
if (N === 0) N = defaults.N;
105107
if (r === 0) r = defaults.r;
106108
if (p === 0) p = defaults.p;

src/node_crypto.cc

+4-3
Original file line numberDiff line numberDiff line change
@@ -4754,7 +4754,7 @@ struct ScryptJob : public CryptoJob {
47544754
uint32_t N;
47554755
uint32_t r;
47564756
uint32_t p;
4757-
uint32_t maxmem;
4757+
uint64_t maxmem;
47584758
CryptoErrorVector errors;
47594759

47604760
inline explicit ScryptJob(Environment* env) : CryptoJob(env) {}
@@ -4809,7 +4809,7 @@ void Scrypt(const FunctionCallbackInfo<Value>& args) {
48094809
CHECK(args[3]->IsUint32()); // N
48104810
CHECK(args[4]->IsUint32()); // r
48114811
CHECK(args[5]->IsUint32()); // p
4812-
CHECK(args[6]->IsUint32()); // maxmem
4812+
CHECK(args[6]->IsNumber()); // maxmem
48134813
CHECK(args[7]->IsObject() || args[7]->IsUndefined()); // wrap object
48144814
std::unique_ptr<ScryptJob> job(new ScryptJob(env));
48154815
job->keybuf_data = reinterpret_cast<unsigned char*>(Buffer::Data(args[0]));
@@ -4819,7 +4819,8 @@ void Scrypt(const FunctionCallbackInfo<Value>& args) {
48194819
job->N = args[3].As<Uint32>()->Value();
48204820
job->r = args[4].As<Uint32>()->Value();
48214821
job->p = args[5].As<Uint32>()->Value();
4822-
job->maxmem = args[6].As<Uint32>()->Value();
4822+
Local<Context> ctx = env->isolate()->GetCurrentContext();
4823+
job->maxmem = static_cast<uint64_t>(args[6]->IntegerValue(ctx).ToChecked());
48234824
if (!job->Validate()) {
48244825
// EVP_PBE_scrypt() does not always put errors on the error stack
48254826
// and therefore ToResult() may or may not return an exception

test/parallel/test-crypto-scrypt.js

+15
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,18 @@ for (const { args, expected } of badargs) {
217217
common.expectsError(() => crypto.scrypt('', '', 42, {}), expected);
218218
common.expectsError(() => crypto.scrypt('', '', 42, {}, {}), expected);
219219
}
220+
221+
{
222+
// Values for maxmem that do not fit in 32 bits but that are still safe
223+
// integers should be allowed.
224+
crypto.scrypt('', '', 4, { maxmem: 2 ** 52 },
225+
common.mustCall((err, actual) => {
226+
assert.ifError(err);
227+
assert.strictEqual(actual.toString('hex'), 'd72c87d0');
228+
}));
229+
230+
// Values that exceed Number.isSafeInteger should not be allowed.
231+
common.expectsError(() => crypto.scryptSync('', '', 0, { maxmem: 2 ** 53 }), {
232+
code: 'ERR_OUT_OF_RANGE'
233+
});
234+
}

0 commit comments

Comments
 (0)