Skip to content

Commit f985eea

Browse files
committed
crypto: use primordials in HKDF info validation
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent f9ab994 commit f985eea

2 files changed

Lines changed: 45 additions & 21 deletions

File tree

lib/internal/crypto/hkdf.js

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const {
44
ArrayBuffer,
55
FunctionPrototypeCall,
66
PromiseResolve,
7+
TypedArrayPrototypeGetByteLength,
8+
Uint8Array,
79
} = primordials;
810

911
const {
@@ -22,6 +24,7 @@ const {
2224
const { kMaxLength } = require('buffer');
2325

2426
const {
27+
getBufferSourceByteLength,
2528
jobPromise,
2629
normalizeHashName,
2730
toBuf,
@@ -41,6 +44,7 @@ const {
4144
const {
4245
isAnyArrayBuffer,
4346
isArrayBufferView,
47+
isSharedArrayBuffer,
4448
} = require('internal/util/types');
4549

4650
const {
@@ -51,6 +55,13 @@ const {
5155
hideStackFrames,
5256
} = require('internal/errors');
5357

58+
function getByteSourceByteLength(source) {
59+
if (isSharedArrayBuffer(source)) {
60+
return TypedArrayPrototypeGetByteLength(new Uint8Array(source));
61+
}
62+
return getBufferSourceByteLength(source);
63+
}
64+
5465
const validateParameters = hideStackFrames((hash, key, salt, info, length) => {
5566
validateString.withoutStackTrace(hash, 'digest');
5667
key = prepareKey(key);
@@ -61,11 +72,12 @@ const validateParameters = hideStackFrames((hash, key, salt, info, length) => {
6172
// Coerce -0 to +0.
6273
length += 0;
6374

64-
if (info.byteLength > 1024) {
75+
const infoByteLength = getByteSourceByteLength(info);
76+
if (infoByteLength > 1024) {
6577
throw new ERR_OUT_OF_RANGE.HideStackFramesError(
6678
'info',
6779
'must not contain more than 1024 bytes',
68-
info.byteLength);
80+
infoByteLength);
6981
}
7082

7183
return {
@@ -103,18 +115,20 @@ function prepareKey(key) {
103115
return key;
104116
}
105117

106-
function hkdf(hash, key, salt, info, length, callback) {
107-
({
108-
hash,
109-
key,
110-
salt,
111-
info,
112-
length,
113-
} = validateParameters(hash, key, salt, info, length));
118+
function createHkdfJob(mode, params) {
119+
return new HKDFJob(
120+
mode,
121+
params.hash,
122+
params.key,
123+
params.salt,
124+
params.info,
125+
params.length);
126+
}
114127

128+
function hkdf(hash, key, salt, info, length, callback) {
129+
const params = validateParameters(hash, key, salt, info, length);
115130
validateFunction(callback, 'callback');
116-
117-
const job = new HKDFJob(kCryptoJobAsync, hash, key, salt, info, length);
131+
const job = createHkdfJob(kCryptoJobAsync, params);
118132

119133
job.ondone = (error, bits) => {
120134
if (error) return FunctionPrototypeCall(callback, job, error);
@@ -125,15 +139,8 @@ function hkdf(hash, key, salt, info, length, callback) {
125139
}
126140

127141
function hkdfSync(hash, key, salt, info, length) {
128-
({
129-
hash,
130-
key,
131-
salt,
132-
info,
133-
length,
134-
} = validateParameters(hash, key, salt, info, length));
135-
136-
const job = new HKDFJob(kCryptoJobSync, hash, key, salt, info, length);
142+
const params = validateParameters(hash, key, salt, info, length);
143+
const job = createHkdfJob(kCryptoJobSync, params);
137144
const { 0: err, 1: bits } = job.run();
138145
if (err !== undefined)
139146
throw err;

test/parallel/test-crypto-hkdf.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,23 @@ const { hasOpenSSL } = require('../common/crypto');
108108
code: 'ERR_OUT_OF_RANGE'
109109
});
110110

111+
{
112+
const info = new Uint8Array(2048);
113+
Object.defineProperty(info, 'byteLength', {
114+
__proto__: null,
115+
get() {
116+
return 1;
117+
},
118+
});
119+
120+
const calls = [
121+
() => hkdf('sha256', 'a', '', info, 10, common.mustNotCall()),
122+
() => hkdfSync('sha256', 'a', '', info, 10),
123+
];
124+
for (const call of calls)
125+
assert.throws(call, { code: 'ERR_OUT_OF_RANGE' });
126+
}
127+
111128
assert.throws(
112129
() => hkdf('sha512', 'a', '', '', 64 * 255 + 1, common.mustNotCall()), {
113130
code: 'ERR_CRYPTO_INVALID_KEYLEN'

0 commit comments

Comments
 (0)