• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4
5if (!common.hasCrypto) {
6  common.skip('missing crypto');
7}
8
9if (common.isPi) {
10  common.skip('Too slow for Raspberry Pi devices');
11}
12
13const assert = require('assert');
14const { subtle } = require('crypto').webcrypto;
15
16function getDeriveKeyInfo(name, length, hash, ...usages) {
17  return [{ name, length, hash }, usages];
18}
19
20const kDerivedKeyTypes = [
21  ['AES-CBC', 128, undefined, 'encrypt', 'decrypt'],
22  ['AES-CBC', 256, undefined, 'encrypt', 'decrypt'],
23  ['AES-CTR', 128, undefined, 'encrypt', 'decrypt'],
24  ['AES-CTR', 256, undefined, 'encrypt', 'decrypt'],
25  ['AES-GCM', 128, undefined, 'encrypt', 'decrypt'],
26  ['AES-GCM', 256, undefined, 'encrypt', 'decrypt'],
27  ['AES-KW', 128, undefined, 'wrapKey', 'unwrapKey'],
28  ['AES-KW', 256, undefined, 'wrapKey', 'unwrapKey'],
29  ['HMAC', 256, 'SHA-1', 'sign', 'verify'],
30  ['HMAC', 256, 'SHA-256', 'sign', 'verify'],
31  ['HMAC', 256, 'SHA-384', 'sign', 'verify'],
32  ['HMAC', 256, 'SHA-512', 'sign', 'verify'],
33];
34
35const kPasswords = {
36  short: '5040737377307264',
37  long: '55736572732073686f756c64207069636b206c6f6' +
38        'e6720706173737068726173657320286e6f742075' +
39        '73652073686f72742070617373776f7264732921',
40  empty: '',
41};
42
43const kSalts = {
44  short: '4e61436c',
45  long: '536f6469756d2043686c6f7269646520636f6d706f756e64',
46  empty: '',
47};
48
49const kDerivations = {
50  short: {
51    short: {
52      'SHA-384': {
53        '1': '80cd0f15364366a72551c37975f7b637ba89' +
54             'c29b4639ec720f69a70dbbed515c',
55        '1000': 'aaec5a976d4d35cb2024486fc9f9bb9aa' +
56                '3eae7cef2bce62664b5b3751cf50ff1',
57        '100000': '6f5ea3c6c6f5e4833467b47c3a671e6' +
58                  '5714e87071bd1e36d716f846b5cd28980',
59      },
60      'SHA-512': {
61        '1': '69f4d5cef5c7d8ba938e880388c8f63b6b2' +
62             '448b2626d1343fc5cb68bbd7f27b2',
63        '1000': '865c5945e11f5bf3ddf002e7cb1748f6' +
64                '224d2671e806dad4aaf090a04367da29',
65        '100000': '483ba7f2e2fe382cf61d20b29812e2' +
66                  'd49610a60041ae40ecf9fc7ef138e93876',
67      },
68      'SHA-1': {
69        '1': '4624dbd21373ee5659c125b184eedaa26a3' +
70             '3b77ca11314b9f0c9dae1e44e9b04',
71        '1000': '5388ea5e62e1b557981abe5ce4132127' +
72                '58aa6a9d2c5bf08c019d459dba666b90',
73        '100000': 'f58f435fbc5c05865c914fd972108a' +
74                  '09457d5f9a48f14e75e4cc02d98983038a',
75      },
76      'SHA-256': {
77        '1': 'c6bc55a404adcea36a1ab56798085e0aaf6' +
78             '97f6bb2c16a5072f838f17dfe6cb6',
79        '1000': '4e6ca57957439be3a75370424225e221' +
80                '1d55f05af00561df3f3efee9116bc34c',
81        '100000': 'ab25796598e74b29c324f5ba4d90ea' +
82                  '7dc89fc6891041b4d56c94156505f722c0',
83      },
84    },
85    long: {
86      'SHA-384': {
87        '1': '6807346cc53eded1cb964a72628589a6bd4' +
88             '8355990bfdfe7465109710207059d',
89        '1000': 'a310ef3c6b3a95e6d8ca6644e3dcfd88' +
90                '222a59fe8e00c52d6a12631d82c1d24b',
91        '100000': '2c8c6674c879cf1850bc9b7fbdcc6e' +
92                  'a7abb0a1522196a866875305dea57486f3',
93      },
94      'SHA-512': {
95        '1': '5777027aff4051fb9b43c1f1ef0463bd677' +
96             '51175d428a13da3da845a591332cd',
97        '1000': '9c17fe96895eadbfd1cc095fc1bb834f' +
98                '28e5ccc9ec96ca814cff941a4bf40727',
99        '100000': 'b479c9715c421638dce0a705fc0b7b' +
100                  'a7d56fa3063188063580e070dff1db497c',
101      },
102      'SHA-1': {
103        '1': '576f7c165825bef9ef14b4bc2c82469d1e4' +
104             '08ff8e7ba306694797f9e45b766ed',
105        '1000': '89d3b27b5f6e8af015f2f87cf368a143' +
106                '8a206c4ecf5fe681fc3bf94c56213ef6',
107        '100000': '1e39e8bf6676fcd3156655457afa14' +
108                  'bee771dbcbfcd07241c7cee209a7cb1fe9',
109      },
110      'SHA-256': {
111        '1': '12b90f594f0908cf912d655c948f9c2a1ea' +
112             'b855765bc12785ef18aa02b8e7edc',
113        '1000': 'b1a7b7dc20df174a4a0e410dbfaf03b4' +
114                'c375c450a89d7a9ed349b4e52e64dfd8',
115        '100000': 'd4594d8a1b59520a48878922a65d66' +
116                  '3d28f6a5fa49e931d300d8f9baf93d0aeb',
117      },
118    },
119    empty: {
120      'SHA-384': {
121        '1': '4f1089c01e438bde649a379fa418fbc3b85' +
122             '6258772dfe911806f9bd0809fbc7e',
123        '1000': 'aeb5f97d6627eebcde6b139a00895500' +
124                '30f7401c67e01c057a3338175e3f3a17',
125        '100000': 'd7687df6c781dc88d64ef9cbaf95d3' +
126                  'd5d1155f66b230239e6e81c1550c8840cf',
127      },
128      'SHA-512': {
129        '1': '8f7b7d459c752f64bf12be625b65d496ac2' +
130             '4ea36516b168e16fb026845b4e82e',
131        '1000': 'b5ac720b7abe0832fc51a31b1ec5673b' +
132                'eb1e41840adfd3d606e8638f4006eb48',
133        '100000': 'ba1a0f36bad771526564051eb9ca20' +
134                  '7da19b62e53762349976a9a3d1b0ef7e20',
135      },
136      'SHA-1': {
137        '1': 'c0cffb0ce5db351faa24dad5902583cfc30' +
138             'a9f54d9aa6991fe821d03122127e9',
139        '1000': '736f3c3d6ebcc2a7b970403e2696c0eb' +
140                '4cd1770f55f196fc7089e666c11f77da',
141        '100000': '1c5095ac9a7bd410ef0f72c993eca9' +
142                  '1bb0e571e9b2fbab704f8c131191fad16c',
143      },
144      'SHA-256': {
145        '1': '019e54ab42f00485d3aa1b26fcde21ae5f5' +
146             '2cb0f0960ffc9767f25c65e2db2f9',
147        '1000': 'b9d2f2217b4ee5a8bf0345f36b2c9887' +
148                '33f503a975dfeac7b7135f54a5f29971',
149        '100000': 'a7a2869829797807b3e576c17878b4' +
150                  '66449e89e60447d541775a96eb7c1a5ded',
151      },
152    },
153  },
154  long: {
155    short: {
156      'SHA-384': {
157        '1': '5ede8836fdabeec5d3733b434abac443d41' +
158             '5193b599e0926193b000f406a5a7d',
159        '1000': 'faa442fbabf4058cc65368b53d7ec511' +
160                '3c09ea7e5e3743312f4bebedd980ba37',
161        '100000': 'f62ae6c7871b181aa71232f5eb8837' +
162                  '2498ef32ac0a7d715119e8f052eb102d29',
163      },
164      'SHA-512': {
165        '1': '3e9c12b3f6dfb6441594ec7063fca962ffd' +
166             'a10b6cf30b898a31ef9f1306b1119',
167        '1000': 'f0928f50a155f26a8c9c1bc7f3b5cb53' +
168                '1c53a8f51040c9ce5fc79d430ff0c0f4',
169        '100000': '974acfbb0f0f20c81ec92829f38c3d' +
170                  'af086a7df58b912b856d1f5ecc9355ef1b',
171      },
172      'SHA-1': {
173        '1': '8ae72f94e6fcd54fcbfca66200a211a51b2' +
174             'f846787d20b6808bedf156ce46ca0',
175        '1000': '53b42161134e15c871abd71aba1390d0' +
176                '1f4c6a940caaf5c179258d8f1b1d680b',
177        '100000': 'a7fda4c79dd3ba1a875f65e9248b21' +
178                  '0899ca0814ae38995d8ce5a53560cbac31',
179      },
180      'SHA-256': {
181        '1': 'ffa1e9a727a92c27ae6f74b1c7978f9e1af' +
182             '860e106376340ac43d969d136405b',
183        '1000': 'eeeb7714420a00b18acec2b5979d1da6' +
184                '1373202b7f8ba71b086293aab859e0a0',
185        '100000': 'deac70cbe3f1720e353b4e8016ddb5' +
186                  '9475efb70b6a2385e735d2d6ea6d624a4d',
187      },
188    },
189    long: {
190      'SHA-384': {
191        '1': 'cf55422cef6e1bc49e6d082b2273d480e8f' +
192             '2e8822dadd1469c2a32d9657d12f1',
193        '1000': '35658551f0ec13398a7b45e0261cfd65' +
194                '4c1e52411e6e457dee68f4aeabe925a7',
195        '100000': '1abab5f1e461df378b88c0a22be76e' +
196                  'f2f1627df74ac7cbfb84bdccb354bc8889',
197      },
198      'SHA-512': {
199        '1': 'de4afbc0add3e4d32f4bc6e122a88ae44a2' +
200             'b3ccf0148e7762bac05c43e94ef7f',
201        '1000': '43e12024c4d354727f7e58842ccb6033' +
202                'a161d60dc5ae516f076e4a58a1880d38',
203        '100000': 'f9a92384a4eadfc3560649b37fb676' +
204                  'e83c453cbbd99f80bba6f0a10ebd150b52',
205      },
206      'SHA-1': {
207        '1': '1d104ea5d235006a12a80f71b80ee528048' +
208             'b64cc1a7a0f30f7df4ba26b8320c7',
209        '1000': '6e90c86ee07b873e965071025673ff05' +
210                '429f678c30f91b37e1e2da512036d320',
211        '100000': '141030763bf983c8564d5d4c935fe3' +
212                  'ca3549608159ac1934c1599040668c2363',
213      },
214      'SHA-256': {
215        '1': 'fd5caeb8b3abe589bc159c4e51f800570e7' +
216             '4f64397a6c5ee131dfed93f0511aa',
217        '1000': '3fd587c94ba946b8b9dccddd2a5b74f6' +
218                '778d4f61e691f83ac47a2fa9580bfdf8',
219        '100000': '11992d8b813311244c544b62292945' +
220                  'e208d403cebd6b9552a1a562065d9958ea',
221      },
222    },
223    empty: {
224      'SHA-384': {
225        '1': '49ab3f9f882fdb9e528b4d9f1b3e8c71d26' +
226             '39abf1701d56eb99bd51201e420ff',
227        '1000': 'f9ca148b0c041890bff8831db6174719' +
228                '7e94ce68f190edf269694b4d644861ca',
229        '100000': '1749dfcd77e5258519ea2231ba2cd6' +
230                  '543b073339ac9b1545bb643153faf6d17b',
231      },
232      'SHA-512': {
233        '1': 'd1bfa1a6b8a977839f8c3f9d52dd02104e2' +
234             '029c0eb2a6208cc408816e7768a8c',
235        '1000': '457a7955ebecec71a51efb6237e5b1d6' +
236                '2f4deab5c93d7b3d11d1e70faffa417e',
237        '100000': 'e805ac9cc1d8412c42446d237d1b50' +
238                  '4f9540b362bd1b75e451531e853e24753d',
239      },
240      'SHA-1': {
241        '1': 'a46a62986d9c3909f41014dd72cfe34a261' +
242             '247854d7312cf4fbead60b9b69edd',
243        '1000': 'e7375de5036766c40cb85f43b53fce4f' +
244                'fa402ab6be3571007ef5d55453fd7f0a',
245        '100000': '7a403d9a13aed8164e9c072c545462' +
246                  '251fd942f1736a6bf03ce1c88330048e04',
247      },
248      'SHA-256': {
249        '1': '4f510c5181ac5c2c5fd4bd141f9712495be' +
250             'ca279624742b4d6d30d08b96c0a69',
251        '1000': '7e66c84bea888f92c348d9145585186c' +
252                'ae472b12fba7f0ad28179575c1aa815a',
253        '100000': '5f1a6ac4a56d9796a7309a78daaaf9' +
254                  '18badaf5ed1eecc3f0b8a3a44c3d38d654',
255      },
256    },
257  },
258  empty: {
259    short: {
260      'SHA-384': {
261        '1': 'e9f0da1e97dfa455f858ce6b9af1ecc0299' +
262             'f125ff1a847eb5d4955866f43e604',
263        '1000': '7ff7954aeddf41795fc8300666786d49' +
264                '74269aa91cc7e93811c953331d56d609',
265        '100000': '1c73132b6a55e9d9de2cdbfe1f55bf' +
266                  '0ab59fd91f78f109c50096038b8557b147',
267      },
268      'SHA-512': {
269        '1': 'e7e2b41f4887421bcb764eb4a56f63d2502' +
270             'e33c764fbdf60626ad42ed9672342',
271        '1000': 'd561c4c84e9c60ba4752a2d383bf55ef' +
272                'f643fc9e452252d6821e39449350cf72',
273        '100000': 'efd00752bc9ffafb5a399dd1d5834e' +
274                  '8d2c2b676ecd4b2063fb1fe581d0f1380b',
275      },
276      'SHA-1': {
277        '1': 'a667da47b8f857b7c65f70a6c8e7a06ce0d' +
278             '25211a2b6ebaf58dcaaf268b46b1d',
279        '1000': '72c92bbd3ddab4789e88e42ad1cda83c' +
280                'c0729e6cb5106a577e50d5cf61782481',
281        '100000': '06e19e1b83e6480b1554df2b31a2c9' +
282                  '2d1bfcf9bc1bdbc8751ff8685bdeef7dc9',
283      },
284      'SHA-256': {
285        '1': '2ddb49243eb3b5912cb260cdd87fb04ef0d' +
286             '111bfa44d40a45e02a8a5c3c1518d',
287        '1000': '2835f3ed53565420c90951509b0c1173' +
288                'b645174f1546ab3ac3e6c85cb471b53b',
289        '100000': '80aed905ca32ae0bb2a9d8f532f048' +
290                  'a0e672463eef9f83dfa7d88bca726553ea',
291      },
292    },
293    long: {
294      'SHA-384': {
295        '1': '7b0bcca81dd637a3b3398666619716c5f2b1' +
296             'f4a5c24e85c18a9955559e4d7692',
297        '1000': '8bb89cf71972fe5acc16fdc5f8cffd2c2' +
298                'e7178c086b3bbe61cc1314619135958',
299        '100000': '26c6a8ae4bd1fbe715ae478efff3eca' +
300                  'e83afa617ed35bd4a3f63c3da76a42d22',
301      },
302      'SHA-512': {
303        '1': 'bb73f8168a8f391d3d54ca892fb72b8e603' +
304             '5e37f891e5a70491b94dc05510bc4',
305        '1000': '5cacc16cdfbe052cfd73a9891b8c0e78' +
306                'b19b2e07eae2423d48fed5e08aa8494b',
307        '100000': '87fdfc293392cbf33ecc9b5141a2fe' +
308                  'fa74d150499756863c484c0a78b6274d7f',
309      },
310      'SHA-1': {
311        '1': '1f46b40cf2fb3dc41a3d9ced8897b861050' +
312             '36810e2bfac7040814bd65d428d67',
313        '1000': 'cc5748ecc41288a0e13368543aaa2ef6' +
314                '2c97ba7518fa88f6e11c35763fc930b4',
315        '100000': '33e2993bf4729dc993fff66e69cc55' +
316                  '777135ebfabce533575bce4a96645a742c',
317      },
318      'SHA-256': {
319        '1': '61c935c462c3321c89663545d13a4f6b52b' +
320             '5191cfb7479e58dcfe6444d43106c',
321        '1000': '1353f7458237ab332ee052e29f829a2a' +
322                'b90e72630ea10493b4eecffb9ff89e1d',
323        '100000': '79baf80ec582920538801e9d929ce0' +
324                  '7084277987488d733a026852c452f06fb4',
325      },
326    },
327    empty: {
328      'SHA-384': {
329        '1': '4bb042a5c28cee6f66f991c717fd7702677' +
330             '87e2bb3031eae270d87d63ad99534',
331        '1000': '9cbfe72d194da34e17c821dd1569ef50' +
332                'a86eb4d893591776adc6a5c21e0031cf',
333        '100000': 'ed6bd7282567abe48d542d067d09f4' +
334                  '04bd044ae2cefe11dacc531c4764cd35cd',
335      },
336      'SHA-512': {
337        '1': '6d2ecbbbfb2e6dcd7056faf9af6aa06eae5' +
338             '94391db983279a6bf27e0eb228614',
339        '1000': 'cb93096c3a02beeb1c5fac36765c9011' +
340                'fe99f8d8ea62366048fc98cb98dfea8f',
341        '100000': '89e16254ebad5cba72e0aebe1614c7' +
342                  'f9b795a7505f2637206ce10a3449a2b8bb',
343      },
344      'SHA-1': {
345        '1': '1e437a1c79d75be61e91141dae20affc489' +
346             '2cc99abcc3fe753887bccc8920176',
347        '1000': '6e40910ac02ec89cebb9d898b13a09d1' +
348                'cd7adf6f8cc08cc473302c8973aa2e19',
349        '100000': 'a9e1bebb36bc26d7c997d5483cbc8d' +
350                  'e4a419d1e706571342632586ec330a7290',
351      },
352      'SHA-256': {
353        '1': 'f7ce0b653d2d72a4108cf5abe912ffdd777' +
354             '616dbbb27a70e8204f3ae2d0f6fad',
355        '1000': '4fc58a21c100ce1835b8f9991d738b56' +
356                '965d14b24e1761fbdffc69ac5e0b667a',
357        '100000': '64a868d4b23af696d3734d0b814d04' +
358                  'cdd1ac280128e97653a05f32b49c13a29a',
359      },
360    },
361  },
362};
363
364async function setupBaseKeys() {
365  const promises = [];
366
367  const baseKeys = {};
368  const noBits = {};
369  const noKey = {};
370  let wrongKey = null;
371
372  Object.keys(kPasswords).forEach((size) => {
373    promises.push(
374      subtle.importKey(
375        'raw',
376        Buffer.from(kPasswords[size], 'hex'),
377        { name: 'PBKDF2' },
378        false,
379        ['deriveKey', 'deriveBits'])
380        .then((key) => baseKeys[size] = key));
381
382    promises.push(
383      subtle.importKey(
384        'raw',
385        Buffer.from(kPasswords[size], 'hex'),
386        { name: 'PBKDF2' },
387        false,
388        ['deriveBits'])
389        .then((key) => noKey[size] = key));
390
391    promises.push(
392      subtle.importKey(
393        'raw',
394        Buffer.from(kPasswords[size], 'hex'),
395        { name: 'PBKDF2' },
396        false,
397        ['deriveKey'])
398        .then((key) => noBits[size] = key));
399  });
400
401  promises.push(
402    subtle.generateKey(
403      { name: 'ECDH', namedCurve: 'P-521' },
404      false,
405      ['deriveKey', 'deriveBits'])
406      .then((key) => wrongKey = key.privateKey));
407
408  await Promise.all(promises);
409
410  return { baseKeys, noBits, noKey, wrongKey };
411}
412
413async function testDeriveBits(
414  baseKeys,
415  size,
416  saltSize,
417  hash,
418  iterations) {
419  const algorithm = {
420    name: 'PBKDF2',
421    salt: Buffer.from(kSalts[saltSize], 'hex'),
422    hash,
423    iterations,
424  };
425
426  const bits = await subtle.deriveBits(algorithm, baseKeys[size], 256);
427
428  assert(bits instanceof ArrayBuffer);
429  assert.strictEqual(
430    Buffer.from(bits).toString('hex'),
431    kDerivations[size][saltSize][hash][iterations]);
432}
433
434async function testDeriveBitsBadLengths(
435  baseKeys,
436  size,
437  saltSize,
438  hash,
439  iterations) {
440  const algorithm = {
441    name: 'PBKDF2',
442    salt: Buffer.from(kSalts[saltSize], 'hex'),
443    iterations,
444    hash,
445  };
446
447  return Promise.all([
448    assert.rejects(
449      subtle.deriveBits(algorithm, baseKeys[size], undefined), {
450        name: 'OperationError',
451      }),
452    assert.rejects(
453      subtle.deriveBits(algorithm, baseKeys[size], 0), {
454        message: /length cannot be zero/,
455        name: 'OperationError',
456      }),
457    assert.rejects(
458      subtle.deriveBits(algorithm, baseKeys[size], null), {
459        message: 'length cannot be null',
460        name: 'OperationError',
461      }),
462    assert.rejects(
463      subtle.deriveBits(algorithm, baseKeys[size], 15), {
464        message: /length must be a multiple of 8/,
465        name: 'OperationError',
466      }),
467  ]);
468}
469
470async function testDeriveBitsBadHash(
471  baseKeys,
472  size,
473  saltSize,
474  hash,
475  iterations) {
476  const salt = Buffer.from(kSalts[saltSize], 'hex');
477  const algorithm = { name: 'PBKDF2', salt, iterations };
478
479  return Promise.all([
480    assert.rejects(
481      subtle.deriveBits(
482        {
483          ...algorithm,
484          hash: hash.substring(0, 3) + hash.substring(4),
485        }, baseKeys[size], 256), {
486        message: /Unrecognized algorithm name/,
487        name: 'NotSupportedError',
488      }),
489    assert.rejects(
490      subtle.deriveBits(
491        {
492          ...algorithm,
493          hash: 'HKDF',
494        },
495        baseKeys[size], 256), {
496        message: /Unrecognized algorithm name/,
497        name: 'NotSupportedError',
498      }),
499  ]);
500}
501
502async function testDeriveBitsBadUsage(
503  noBits,
504  size,
505  saltSize,
506  hash,
507  iterations) {
508  const algorithm = {
509    name: 'PBKDF2',
510    salt: Buffer.from(kSalts[saltSize], 'hex'),
511    iterations,
512    hash,
513  };
514
515  return assert.rejects(
516    subtle.deriveBits(algorithm, noBits[size], 256), {
517      message: /baseKey does not have deriveBits usage/,
518    });
519}
520
521
522async function testDeriveKey(
523  baseKeys,
524  size,
525  saltSize,
526  hash,
527  iterations,
528  keyType,
529  usages) {
530  const algorithm = {
531    name: 'PBKDF2',
532    salt: Buffer.from(kSalts[saltSize], 'hex'),
533    hash,
534    iterations,
535  };
536
537  const key = await subtle.deriveKey(
538    algorithm,
539    baseKeys[size],
540    keyType,
541    true,
542    usages);
543
544  const bits = await subtle.exportKey('raw', key);
545
546  assert.strictEqual(
547    Buffer.from(bits).toString('hex'),
548    kDerivations[size][saltSize][hash][iterations]
549      .slice(0, keyType.length / 4));
550}
551
552async function testDeriveKeyBadHash(
553  baseKeys,
554  size,
555  saltSize,
556  hash,
557  iterations,
558  keyType,
559  usages) {
560  const salt = Buffer.from(kSalts[saltSize], 'hex');
561  const algorithm = { name: 'PBKDF2', salt, iterations };
562
563  return Promise.all([
564    assert.rejects(
565      subtle.deriveKey(
566        {
567          ...algorithm,
568          hash: hash.substring(0, 3) + hash.substring(4),
569        },
570        baseKeys[size],
571        keyType,
572        true,
573        usages),
574      {
575        message: /Unrecognized algorithm name/,
576        name: 'NotSupportedError',
577      }),
578    assert.rejects(
579      subtle.deriveKey(
580        {
581          ...algorithm,
582          hash: 'HKDF',
583        },
584        baseKeys[size],
585        keyType,
586        true,
587        usages),
588      {
589        message: /Unrecognized algorithm name/,
590        name: 'NotSupportedError',
591      }),
592  ]);
593}
594
595async function testDeriveKeyBadUsage(
596  noKey,
597  size,
598  saltSize,
599  hash,
600  iterations,
601  keyType,
602  usages) {
603  const algorithm = {
604    name: 'PBKDF2',
605    salt: Buffer.from(kSalts[saltSize], 'hex'),
606    iterations,
607    hash,
608  };
609
610  return assert.rejects(
611    subtle.deriveKey(algorithm, noKey[size], keyType, true, usages), {
612      message: /baseKey does not have deriveKey usage/,
613    });
614}
615
616async function testWrongKeyType(
617  wrongKey,
618  saltSize,
619  hash,
620  iterations,
621  keyType,
622  usages,
623) {
624  const algorithm = {
625    name: 'PBKDF2',
626    salt: Buffer.from(kSalts[saltSize], 'hex'),
627    iterations,
628    hash,
629  };
630
631  return assert.rejects(
632    subtle.deriveKey(algorithm, wrongKey, keyType, true, usages), {
633      message: /Key algorithm mismatch/,
634    });
635}
636
637(async function() {
638  const {
639    baseKeys,
640    noBits,
641    noKey,
642    wrongKey,
643  } = await setupBaseKeys();
644
645  const variations = [];
646
647  Object.keys(kDerivations).forEach((size) => {
648    Object.keys(kDerivations[size]).forEach((saltSize) => {
649      Object.keys(kDerivations[size][saltSize]).forEach((hash) => {
650        Object.keys(kDerivations[size][saltSize][hash])
651          .forEach((iterations) => {
652            const args = [baseKeys, size, saltSize, hash, iterations | 0];
653            variations.push(testDeriveBits(...args));
654            variations.push(testDeriveBitsBadLengths(...args));
655            variations.push(testDeriveBitsBadHash(...args));
656            variations.push(
657              testDeriveBitsBadUsage(
658                noBits,
659                size,
660                saltSize,
661                hash,
662                iterations | 0));
663
664            kDerivedKeyTypes.forEach((keyType) => {
665              const keyArgs = getDeriveKeyInfo(...keyType);
666              variations.push(testDeriveKey(...args, ...keyArgs));
667              variations.push(testDeriveKeyBadHash(...args, ...keyArgs));
668              variations.push(
669                testDeriveKeyBadUsage(
670                  noKey,
671                  size,
672                  saltSize,
673                  hash,
674                  iterations | 0,
675                  ...keyArgs));
676              variations.push(
677                testWrongKeyType(
678                  wrongKey,
679                  saltSize,
680                  hash,
681                  iterations,
682                  ...keyArgs));
683            });
684          });
685      });
686    });
687  });
688
689  await Promise.all(variations);
690})().then(common.mustCall());
691