Skip to content

Commit

Permalink
crypto: remove webcrypto HKDF and PBKDF2 default-applied lengths
Browse files Browse the repository at this point in the history
PR-URL: #44945
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
  • Loading branch information
panva authored and danielleadams committed Jan 3, 2023
1 parent 631421e commit 7565a75
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 48 deletions.
46 changes: 19 additions & 27 deletions lib/internal/crypto/hkdf.js
Expand Up @@ -2,7 +2,6 @@

const {
FunctionPrototypeCall,
Promise,
} = primordials;

const {
Expand All @@ -15,7 +14,6 @@ const {
validateFunction,
validateInteger,
validateString,
validateUint32,
} = require('internal/validators');

const { kMaxLength } = require('buffer');
Expand All @@ -35,6 +33,7 @@ const {

const {
lazyDOMException,
promisify,
} = require('internal/util');

const {
Expand Down Expand Up @@ -139,40 +138,33 @@ 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');
const info = getArrayBufferOrView(algorithm.info, 'algorithm.info');
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);
});
});
try {
return 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 });
}
}

module.exports = {
Expand Down
41 changes: 20 additions & 21 deletions lib/internal/crypto/pbkdf2.js
Expand Up @@ -2,7 +2,6 @@

const {
FunctionPrototypeCall,
Promise,
} = primordials;

const { Buffer } = require('buffer');
Expand All @@ -18,7 +17,6 @@ const {
validateInt32,
validateInteger,
validateString,
validateUint32,
} = require('internal/validators');

const { ERR_MISSING_OPTION } = require('internal/errors').codes;
Expand All @@ -32,6 +30,7 @@ const {

const {
lazyDOMException,
promisify,
} = require('internal/util');

function pbkdf2(password, salt, iterations, keylen, digest, callback) {
Expand Down Expand Up @@ -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;
Expand All @@ -116,27 +116,26 @@ 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');
}

let result;
try {
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 new Promise((resolve, reject) => {
pbkdf2(raw, salt, iterations, byteLength, hash, (err, result) => {
if (err) return reject(err);
resolve(result.buffer);
});
});
return result.buffer;
}

module.exports = {
Expand Down
4 changes: 4 additions & 0 deletions test/parallel/test-webcrypto-derivebits-hkdf.js
Expand Up @@ -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/,
Expand Down
4 changes: 4 additions & 0 deletions test/pummel/test-webcrypto-derivebits-pbkdf2.js
Expand Up @@ -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/,
Expand Down

0 comments on commit 7565a75

Please sign in to comment.