Skip to content

Commit e51bc56

Browse files
committed
crypto: validate the limit of PBKDF2 iterations
Reject iteration counts outside of OpenSSL supported range Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent f985eea commit e51bc56

3 files changed

Lines changed: 32 additions & 0 deletions

File tree

lib/internal/crypto/webidl.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const {
1515
lazyDOMException,
1616
} = require('internal/util');
1717
const {
18+
isInt32,
1819
isUint32,
1920
} = require('internal/validators');
2021
const { CryptoKey } = require('internal/crypto/webcrypto');
@@ -489,6 +490,11 @@ converters.Pbkdf2Params = createDictionaryConverter(
489490
validator: (V, dict) => {
490491
if (V === 0)
491492
throw lazyDOMException('iterations cannot be zero', 'OperationError');
493+
if (!isInt32(V)) {
494+
throw lazyDOMException(
495+
'iterations exceeds the implementation limit',
496+
'NotSupportedError');
497+
}
492498
},
493499
required: true,
494500
},

test/fixtures/webcrypto/supports-level-2.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ export const vectors = {
124124
[true,
125125
{ name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 },
126126
{ name: 'HMAC', hash: 'SHA-256' }],
127+
[false,
128+
{ name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 2 ** 31 },
129+
{ name: 'AES-CBC', length: 128 }],
127130
[false,
128131
{ name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 },
129132
'HKDF'],
@@ -183,6 +186,7 @@ export const vectors = {
183186
[true, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, 8],
184187
[true, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, 0],
185188
[false, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 0 }, 8],
189+
[false, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 2 ** 31 }, 8],
186190
[false, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, null],
187191
[false, { name: 'PBKDF2', hash: 'SHA-256', salt: Buffer.alloc(0), iterations: 1 }, 7],
188192
[false, { name: 'PBKDF2', hash: 'Invalid', salt: Buffer.alloc(0), iterations: 1 }, 8],

test/parallel/test-webcrypto-derivebits.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,28 @@ const rejectsXCurves = hasFIPS(3, 5);
120120
}
121121
}
122122

123+
// Test PBKDF2 rejects iteration counts beyond the native signed int range
124+
{
125+
async function test() {
126+
const key = await subtle.importKey(
127+
'raw',
128+
new Uint8Array([1]),
129+
'PBKDF2',
130+
false,
131+
['deriveBits']);
132+
await assert.rejects(
133+
subtle.deriveBits({
134+
name: 'PBKDF2',
135+
hash: 'SHA-256',
136+
salt: new Uint8Array([2]),
137+
iterations: 2 ** 31,
138+
}, key, 8),
139+
{ name: 'NotSupportedError' });
140+
}
141+
142+
test().then(common.mustCall());
143+
}
144+
123145
// Test X25519 and X448 bit derivation
124146
{
125147
async function test(name) {

0 commit comments

Comments
 (0)