Skip to content

Commit f8af800

Browse files
authored
Merge pull request #43 from TotalTechGeek/master
Fix bug that occurs with data structures that don't support .push when password.length > 64
2 parents 37d8d6b + 99de2cb commit f8af800

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

scrypt-async.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,13 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin
154154

155155
function PBKDF2_HMAC_SHA256_OneIter(password, salt, dkLen) {
156156
// compress password if it's longer than hash block length
157-
password = password.length <= 64 ? password : SHA256(password);
157+
if(password.length > 64)
158+
{
159+
// coerces the structure into an array type if it lacks support for the .push operation
160+
// use [...password] when you instead of the "Array.prototype.slice.call" when you deprecate pre-ES6
161+
// it's supposed to be faster in most browsers.
162+
password = SHA256(password.push ? password : Array.prototype.slice.call(password, 0))
163+
}
158164

159165
var i, innerLen = 64 + salt.length + 4,
160166
inner = new Array(innerLen),
@@ -398,8 +404,13 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin
398404
throw new Error('scrypt: missing N parameter');
399405
}
400406
}
407+
408+
// bug on the following line: p can never be detected as invalid if set to zero. It will silently switch to 1.
409+
// recommended fix: p = typeof opts.p === "undefined" ? 1 : opts.p;
401410
p = opts.p || 1;
402411
r = opts.r;
412+
413+
// recommended code: dkLen = typeof opts.dkLen === "undefined" ? 32 : opts.dkLen;
403414
dkLen = opts.dkLen || 32;
404415
interruptStep = opts.interruptStep || 0;
405416
encoding = opts.encoding;

scrypt-async.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/unittests.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@ var inputs = [
248248
dkLen: 256,
249249
encoding: 'hex',
250250
result: 'c3f182ee2dec846e70a6942fb529985a3a09765ef04c612923b17f18555a37076deb2b9830d69de5492651e4506ae5776d96d40f67aaee37e1777b8ad5c3111432bb3b6f7e1264401879e641aea2bd0a21a124fd5c1ece0891338d2c44ba312e497bd93660fc053a5df35ade0ca48fd0f3c6c0f6143bb3548420a7cbf6ce7c82bc6b56c8e33adbf6fbac9e0ffc4aa9fb9fcd97fd393700b7d8eac55d45d4651bdb1a270c35c8d40a22e1b2429d6521c4c673e4ba7e7f4a9638ec3b1adbc6dcab64e211b5a26df8f274511be41228cd9a4fae3ada5236ebf39dfc6cd1864652a16516fb622502205d9fdbf09dc6fa964b57cc468ee8d98e4a00bf064222dafec8'
251+
},
252+
{
253+
password: new Uint8Array(65),
254+
salt: 'salt',
255+
logN: 1,
256+
r: 1,
257+
dkLen: 32,
258+
encoding: 'binary',
259+
result: [236, 122, 177, 168, 83, 62, 253, 45, 27, 145, 154, 151, 66, 174, 56, 101, 91, 130, 207, 52, 20, 52, 161, 66, 241, 202, 39, 120, 158, 73, 124, 69]
251260
}
252261
];
253262

@@ -261,6 +270,7 @@ var shortInput = {
261270
result: [109, 27, 184, 120, 238, 233, 206, 74, 123, 119, 215, 164, 65, 3, 87, 77]
262271
};
263272

273+
264274
var inputsWithP = [
265275
{
266276
password: 'password',
@@ -290,7 +300,8 @@ var inputsWithP = [
290300

291301
describe('limits test', function() {
292302
var v = shortInput;
293-
303+
var v2 = inputs[12];
304+
294305
it('should throw with too small logN', function() {
295306
assert.throws(function() {
296307
scrypt(v.password, v.salt, 0, v.r, v.dkLen);
@@ -305,19 +316,19 @@ describe('limits test', function() {
305316

306317
it('should throw with too big N', function() {
307318
assert.throws(function() {
308-
scrypt(v.password, v.salt, { N: ((-1)>>>0) + 1, r: v.r, dkLen: v.dkLen });
319+
scrypt(v.password, v.salt, { N: ((-1)>>>0) + 1, r: v.r, dkLen: v.dkLen }, function() {});
309320
}, Error);
310321
});
311322

312323
it('should throw with too small N', function() {
313324
assert.throws(function() {
314-
scrypt(v.password, v.salt, { N: 1, r: v.r, dkLen: v.dkLen });
325+
scrypt(v.password, v.salt, { N: 1, r: v.r, dkLen: v.dkLen }, function() {});
315326
}, Error);
316327
});
317328

318329
it('should throw when N is not power of two', function() {
319330
assert.throws(function() {
320-
scrypt(v.password, v.salt, { N: 123, r: v.r, dkLen: v.dkLen });
331+
scrypt(v.password, v.salt, { N: 123, r: v.r, dkLen: v.dkLen }, function() {});
321332
}, Error);
322333
});
323334

@@ -339,6 +350,11 @@ describe('limits test', function() {
339350
}, Error);
340351
});
341352

353+
it('should not throw when password > 64', function() {
354+
assert.doesNotThrow(function() {
355+
scrypt(v2.password, v2.salt, { logN: v2.logN, r: v2.r, dkLen: v2.dkLen }, function() {});
356+
}, Error);
357+
});
342358
});
343359

344360
describe('argument order test', function() {
@@ -473,11 +489,18 @@ describe('async input/output test', function() {
473489
});
474490
it('input 9', function(done) {
475491
async_test(9, step, done);
476-
});
492+
});
493+
// the following two tests take a bit of time (~2.8s each),
477494
it('input 10', function(done) {
478495
async_test(10, step, done);
479496
});
480-
497+
it('input 11', function(done) {
498+
async_test(11, step, done);
499+
});
500+
// the following test tests long input
501+
it('input 12', function(done) {
502+
async_test(12, step, done);
503+
});
481504
});
482505

483506
describe('async input/output test with zero interruptStep', function() {

0 commit comments

Comments
 (0)