From a761f0479c224161d2128a29afdc00db6737490b Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 10 Oct 2022 10:15:18 +0200 Subject: [PATCH] crypto: remove webcrypto HKDF and PBKDF2 default-applied lengths --- lib/internal/crypto/hkdf.js | 47 +++++++++---------- lib/internal/crypto/pbkdf2.js | 37 +++++++-------- .../test-webcrypto-derivebits-hkdf.js | 4 ++ .../test-webcrypto-derivebits-pbkdf2.js | 4 ++ 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/internal/crypto/hkdf.js b/lib/internal/crypto/hkdf.js index eeb49171f35599..bee97f26b2d65f 100644 --- a/lib/internal/crypto/hkdf.js +++ b/lib/internal/crypto/hkdf.js @@ -2,7 +2,6 @@ const { FunctionPrototypeCall, - Promise, } = primordials; const { @@ -15,7 +14,6 @@ const { validateFunction, validateInteger, validateString, - validateUint32, } = require('internal/validators'); const { kMaxLength } = require('buffer'); @@ -35,6 +33,7 @@ const { const { lazyDOMException, + promisify, } = require('internal/util'); const { @@ -139,6 +138,7 @@ function hkdfSync(hash, key, salt, info, length) { return bits; } +const hkdfPromise = promisify(hkdf); async function hkdfDeriveBits(algorithm, baseKey, length) { const { hash } = algorithm; const salt = getArrayBufferOrView(algorithm.salt, 'algorithm.salt'); @@ -146,33 +146,28 @@ async function hkdfDeriveBits(algorithm, baseKey, length) { if (hash === undefined) throw new ERR_MISSING_OPTION('algorithm.hash'); - let byteLength = 512 / 8; - if (length !== undefined) { - if (length === 0) - throw lazyDOMException('length cannot be zero', 'OperationError'); - if (length === null) - throw lazyDOMException('length cannot be null', 'OperationError'); - validateUint32(length, 'length'); - if (length % 8) { - throw lazyDOMException( - 'length must be a multiple of 8', - 'OperationError'); - } - byteLength = length / 8; + if (length === 0) + throw lazyDOMException('length cannot be zero', 'OperationError'); + if (length === null) + throw lazyDOMException('length cannot be null', 'OperationError'); + if (length % 8) { + throw lazyDOMException( + 'length must be a multiple of 8', + 'OperationError'); } - return new Promise((resolve, reject) => { - hkdf( - normalizeHashName(hash.name), - baseKey[kKeyObject], - salt, - info, - byteLength, - (err, bits) => { - if (err) return reject(err); - resolve(bits); - }); + const bits = await hkdfPromise( + normalizeHashName(hash.name), + baseKey[kKeyObject], + salt, + info, + length / 8 + ).catch((err) => { + throw lazyDOMException( + 'The operation failed for an operation-specific reason', + { name: 'OperationError', cause: err }); }); + return bits; } module.exports = { diff --git a/lib/internal/crypto/pbkdf2.js b/lib/internal/crypto/pbkdf2.js index a9b5b1590f3b21..e67f3d2bf5d6fa 100644 --- a/lib/internal/crypto/pbkdf2.js +++ b/lib/internal/crypto/pbkdf2.js @@ -2,7 +2,6 @@ const { FunctionPrototypeCall, - Promise, } = primordials; const { Buffer } = require('buffer'); @@ -18,7 +17,6 @@ const { validateInt32, validateInteger, validateString, - validateUint32, } = require('internal/validators'); const { ERR_MISSING_OPTION } = require('internal/errors').codes; @@ -32,6 +30,7 @@ const { const { lazyDOMException, + promisify, } = require('internal/util'); function pbkdf2(password, salt, iterations, keylen, digest, callback) { @@ -100,6 +99,7 @@ function check(password, salt, iterations, keylen, digest) { return { password, salt, iterations, keylen, digest }; } +const pbkdf2Promise = promisify(pbkdf2); async function pbkdf2DeriveBits(algorithm, baseKey, length) { const { iterations } = algorithm; let { hash } = algorithm; @@ -116,27 +116,24 @@ async function pbkdf2DeriveBits(algorithm, baseKey, length) { const raw = baseKey[kKeyObject].export(); - let byteLength = 64; // the default - if (length !== undefined) { - if (length === 0) - throw lazyDOMException('length cannot be zero', 'OperationError'); - if (length === null) - throw lazyDOMException('length cannot be null', 'OperationError'); - validateUint32(length, 'length'); - if (length % 8) { - throw lazyDOMException( - 'length must be a multiple of 8', - 'OperationError'); - } - byteLength = length / 8; + if (length === 0) + throw lazyDOMException('length cannot be zero', 'OperationError'); + if (length === null) + throw lazyDOMException('length cannot be null', 'OperationError'); + if (length % 8) { + throw lazyDOMException( + 'length must be a multiple of 8', + 'OperationError'); } - return new Promise((resolve, reject) => { - pbkdf2(raw, salt, iterations, byteLength, hash, (err, result) => { - if (err) return reject(err); - resolve(result.buffer); - }); + const result = await pbkdf2Promise( + raw, salt, iterations, length / 8, hash + ).catch((err) => { + throw lazyDOMException( + 'The operation failed for an operation-specific reason', + { name: 'OperationError', cause: err }); }); + return result.buffer; } module.exports = { diff --git a/test/parallel/test-webcrypto-derivebits-hkdf.js b/test/parallel/test-webcrypto-derivebits-hkdf.js index 922c1b347e3b0c..7897cad97168df 100644 --- a/test/parallel/test-webcrypto-derivebits-hkdf.js +++ b/test/parallel/test-webcrypto-derivebits-hkdf.js @@ -257,6 +257,10 @@ async function testDeriveBitsBadLengths( }; return Promise.all([ + assert.rejects( + subtle.deriveBits(algorithm, baseKeys[size], undefined), { + name: 'OperationError', + }), assert.rejects( subtle.deriveBits(algorithm, baseKeys[size], 0), { message: /length cannot be zero/, diff --git a/test/pummel/test-webcrypto-derivebits-pbkdf2.js b/test/pummel/test-webcrypto-derivebits-pbkdf2.js index 6e3e7f532bac28..c4b4f44f7064ad 100644 --- a/test/pummel/test-webcrypto-derivebits-pbkdf2.js +++ b/test/pummel/test-webcrypto-derivebits-pbkdf2.js @@ -445,6 +445,10 @@ async function testDeriveBitsBadLengths( }; return Promise.all([ + assert.rejects( + subtle.deriveBits(algorithm, baseKeys[size], undefined), { + name: 'OperationError', + }), assert.rejects( subtle.deriveBits(algorithm, baseKeys[size], 0), { message: /length cannot be zero/,