11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciif (!common.hasCrypto)
61cb0ef41Sopenharmony_ci  common.skip('missing crypto');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst { kMaxLength } = require('buffer');
91cb0ef41Sopenharmony_ciconst assert = require('assert');
101cb0ef41Sopenharmony_ciconst {
111cb0ef41Sopenharmony_ci  createSecretKey,
121cb0ef41Sopenharmony_ci  hkdf,
131cb0ef41Sopenharmony_ci  hkdfSync,
141cb0ef41Sopenharmony_ci  getHashes
151cb0ef41Sopenharmony_ci} = require('crypto');
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci{
181cb0ef41Sopenharmony_ci  assert.throws(() => hkdf(), {
191cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
201cb0ef41Sopenharmony_ci    message: /The "digest" argument must be of type string/
211cb0ef41Sopenharmony_ci  });
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci  [1, {}, [], false, Infinity].forEach((i) => {
241cb0ef41Sopenharmony_ci    assert.throws(() => hkdf(i, 'a'), {
251cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
261cb0ef41Sopenharmony_ci      message: /^The "digest" argument must be of type string/
271cb0ef41Sopenharmony_ci    });
281cb0ef41Sopenharmony_ci    assert.throws(() => hkdfSync(i, 'a'), {
291cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
301cb0ef41Sopenharmony_ci      message: /^The "digest" argument must be of type string/
311cb0ef41Sopenharmony_ci    });
321cb0ef41Sopenharmony_ci  });
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  [1, {}, [], false, Infinity].forEach((i) => {
351cb0ef41Sopenharmony_ci    assert.throws(() => hkdf('sha256', i), {
361cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
371cb0ef41Sopenharmony_ci      message: /^The "ikm" argument must be /
381cb0ef41Sopenharmony_ci    });
391cb0ef41Sopenharmony_ci    assert.throws(() => hkdfSync('sha256', i), {
401cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
411cb0ef41Sopenharmony_ci      message: /^The "ikm" argument must be /
421cb0ef41Sopenharmony_ci    });
431cb0ef41Sopenharmony_ci  });
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  [1, {}, [], false, Infinity].forEach((i) => {
461cb0ef41Sopenharmony_ci    assert.throws(() => hkdf('sha256', 'secret', i), {
471cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
481cb0ef41Sopenharmony_ci      message: /^The "salt" argument must be /
491cb0ef41Sopenharmony_ci    });
501cb0ef41Sopenharmony_ci    assert.throws(() => hkdfSync('sha256', 'secret', i), {
511cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
521cb0ef41Sopenharmony_ci      message: /^The "salt" argument must be /
531cb0ef41Sopenharmony_ci    });
541cb0ef41Sopenharmony_ci  });
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  [1, {}, [], false, Infinity].forEach((i) => {
571cb0ef41Sopenharmony_ci    assert.throws(() => hkdf('sha256', 'secret', 'salt', i), {
581cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
591cb0ef41Sopenharmony_ci      message: /^The "info" argument must be /
601cb0ef41Sopenharmony_ci    });
611cb0ef41Sopenharmony_ci    assert.throws(() => hkdfSync('sha256', 'secret', 'salt', i), {
621cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
631cb0ef41Sopenharmony_ci      message: /^The "info" argument must be /
641cb0ef41Sopenharmony_ci    });
651cb0ef41Sopenharmony_ci  });
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  ['test', {}, [], false].forEach((i) => {
681cb0ef41Sopenharmony_ci    assert.throws(() => hkdf('sha256', 'secret', 'salt', 'info', i), {
691cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
701cb0ef41Sopenharmony_ci      message: /^The "length" argument must be of type number/
711cb0ef41Sopenharmony_ci    });
721cb0ef41Sopenharmony_ci    assert.throws(() => hkdfSync('sha256', 'secret', 'salt', 'info', i), {
731cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
741cb0ef41Sopenharmony_ci      message: /^The "length" argument must be of type number/
751cb0ef41Sopenharmony_ci    });
761cb0ef41Sopenharmony_ci  });
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  assert.throws(() => hkdf('sha256', 'secret', 'salt', 'info', -1), {
791cb0ef41Sopenharmony_ci    code: 'ERR_OUT_OF_RANGE'
801cb0ef41Sopenharmony_ci  });
811cb0ef41Sopenharmony_ci  assert.throws(() => hkdfSync('sha256', 'secret', 'salt', 'info', -1), {
821cb0ef41Sopenharmony_ci    code: 'ERR_OUT_OF_RANGE'
831cb0ef41Sopenharmony_ci  });
841cb0ef41Sopenharmony_ci  assert.throws(() => hkdf('sha256', 'secret', 'salt', 'info',
851cb0ef41Sopenharmony_ci                           kMaxLength + 1), {
861cb0ef41Sopenharmony_ci    code: 'ERR_OUT_OF_RANGE'
871cb0ef41Sopenharmony_ci  });
881cb0ef41Sopenharmony_ci  assert.throws(() => hkdfSync('sha256', 'secret', 'salt', 'info',
891cb0ef41Sopenharmony_ci                               kMaxLength + 1), {
901cb0ef41Sopenharmony_ci    code: 'ERR_OUT_OF_RANGE'
911cb0ef41Sopenharmony_ci  });
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  assert.throws(() => hkdfSync('unknown', 'a', '', '', 10), {
941cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_INVALID_DIGEST'
951cb0ef41Sopenharmony_ci  });
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  assert.throws(() => hkdf('unknown', 'a', '', '', 10, common.mustNotCall()), {
981cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_INVALID_DIGEST'
991cb0ef41Sopenharmony_ci  });
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  assert.throws(() => hkdf('unknown', 'a', '', Buffer.alloc(1025), 10,
1021cb0ef41Sopenharmony_ci                           common.mustNotCall()), {
1031cb0ef41Sopenharmony_ci    code: 'ERR_OUT_OF_RANGE'
1041cb0ef41Sopenharmony_ci  });
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  assert.throws(() => hkdfSync('unknown', 'a', '', Buffer.alloc(1025), 10), {
1071cb0ef41Sopenharmony_ci    code: 'ERR_OUT_OF_RANGE'
1081cb0ef41Sopenharmony_ci  });
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  assert.throws(
1111cb0ef41Sopenharmony_ci    () => hkdf('sha512', 'a', '', '', 64 * 255 + 1, common.mustNotCall()), {
1121cb0ef41Sopenharmony_ci      code: 'ERR_CRYPTO_INVALID_KEYLEN'
1131cb0ef41Sopenharmony_ci    });
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  assert.throws(
1161cb0ef41Sopenharmony_ci    () => hkdfSync('sha512', 'a', '', '', 64 * 255 + 1), {
1171cb0ef41Sopenharmony_ci      code: 'ERR_CRYPTO_INVALID_KEYLEN'
1181cb0ef41Sopenharmony_ci    });
1191cb0ef41Sopenharmony_ci}
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ciconst algorithms = [
1221cb0ef41Sopenharmony_ci  ['sha256', 'secret', 'salt', 'info', 10],
1231cb0ef41Sopenharmony_ci  ['sha256', '', '', '', 10],
1241cb0ef41Sopenharmony_ci  ['sha256', '', 'salt', '', 10],
1251cb0ef41Sopenharmony_ci  ['sha512', 'secret', 'salt', '', 15],
1261cb0ef41Sopenharmony_ci];
1271cb0ef41Sopenharmony_ciif (!common.hasOpenSSL3)
1281cb0ef41Sopenharmony_ci  algorithms.push(['whirlpool', 'secret', '', 'info', 20]);
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_cialgorithms.forEach(([ hash, secret, salt, info, length ]) => {
1311cb0ef41Sopenharmony_ci  {
1321cb0ef41Sopenharmony_ci    const syncResult = hkdfSync(hash, secret, salt, info, length);
1331cb0ef41Sopenharmony_ci    assert(syncResult instanceof ArrayBuffer);
1341cb0ef41Sopenharmony_ci    let is_async = false;
1351cb0ef41Sopenharmony_ci    hkdf(hash, secret, salt, info, length,
1361cb0ef41Sopenharmony_ci         common.mustSucceed((asyncResult) => {
1371cb0ef41Sopenharmony_ci           assert(is_async);
1381cb0ef41Sopenharmony_ci           assert(asyncResult instanceof ArrayBuffer);
1391cb0ef41Sopenharmony_ci           assert.deepStrictEqual(syncResult, asyncResult);
1401cb0ef41Sopenharmony_ci         }));
1411cb0ef41Sopenharmony_ci    // Keep this after the hkdf call above. This verifies
1421cb0ef41Sopenharmony_ci    // that the callback is invoked asynchronously.
1431cb0ef41Sopenharmony_ci    is_async = true;
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  {
1471cb0ef41Sopenharmony_ci    const buf_secret = Buffer.from(secret);
1481cb0ef41Sopenharmony_ci    const buf_salt = Buffer.from(salt);
1491cb0ef41Sopenharmony_ci    const buf_info = Buffer.from(info);
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci    const syncResult = hkdfSync(hash, buf_secret, buf_salt, buf_info, length);
1521cb0ef41Sopenharmony_ci    hkdf(hash, buf_secret, buf_salt, buf_info, length,
1531cb0ef41Sopenharmony_ci         common.mustSucceed((asyncResult) => {
1541cb0ef41Sopenharmony_ci           assert.deepStrictEqual(syncResult, asyncResult);
1551cb0ef41Sopenharmony_ci         }));
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  {
1591cb0ef41Sopenharmony_ci    const key_secret = createSecretKey(Buffer.from(secret));
1601cb0ef41Sopenharmony_ci    const buf_salt = Buffer.from(salt);
1611cb0ef41Sopenharmony_ci    const buf_info = Buffer.from(info);
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci    const syncResult = hkdfSync(hash, key_secret, buf_salt, buf_info, length);
1641cb0ef41Sopenharmony_ci    hkdf(hash, key_secret, buf_salt, buf_info, length,
1651cb0ef41Sopenharmony_ci         common.mustSucceed((asyncResult) => {
1661cb0ef41Sopenharmony_ci           assert.deepStrictEqual(syncResult, asyncResult);
1671cb0ef41Sopenharmony_ci         }));
1681cb0ef41Sopenharmony_ci  }
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  {
1711cb0ef41Sopenharmony_ci    const ta_secret = new Uint8Array(Buffer.from(secret));
1721cb0ef41Sopenharmony_ci    const ta_salt = new Uint16Array(Buffer.from(salt));
1731cb0ef41Sopenharmony_ci    const ta_info = new Uint32Array(Buffer.from(info));
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci    const syncResult = hkdfSync(hash, ta_secret, ta_salt, ta_info, length);
1761cb0ef41Sopenharmony_ci    hkdf(hash, ta_secret, ta_salt, ta_info, length,
1771cb0ef41Sopenharmony_ci         common.mustSucceed((asyncResult) => {
1781cb0ef41Sopenharmony_ci           assert.deepStrictEqual(syncResult, asyncResult);
1791cb0ef41Sopenharmony_ci         }));
1801cb0ef41Sopenharmony_ci  }
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  {
1831cb0ef41Sopenharmony_ci    const ta_secret = new Uint8Array(Buffer.from(secret));
1841cb0ef41Sopenharmony_ci    const ta_salt = new Uint16Array(Buffer.from(salt));
1851cb0ef41Sopenharmony_ci    const ta_info = new Uint32Array(Buffer.from(info));
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci    const syncResult = hkdfSync(
1881cb0ef41Sopenharmony_ci      hash,
1891cb0ef41Sopenharmony_ci      ta_secret.buffer,
1901cb0ef41Sopenharmony_ci      ta_salt.buffer,
1911cb0ef41Sopenharmony_ci      ta_info.buffer,
1921cb0ef41Sopenharmony_ci      length);
1931cb0ef41Sopenharmony_ci    hkdf(hash, ta_secret, ta_salt, ta_info, length,
1941cb0ef41Sopenharmony_ci         common.mustSucceed((asyncResult) => {
1951cb0ef41Sopenharmony_ci           assert.deepStrictEqual(syncResult, asyncResult);
1961cb0ef41Sopenharmony_ci         }));
1971cb0ef41Sopenharmony_ci  }
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  {
2001cb0ef41Sopenharmony_ci    const ta_secret = new Uint8Array(Buffer.from(secret));
2011cb0ef41Sopenharmony_ci    const sa_salt = new SharedArrayBuffer(0);
2021cb0ef41Sopenharmony_ci    const sa_info = new SharedArrayBuffer(1);
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci    const syncResult = hkdfSync(
2051cb0ef41Sopenharmony_ci      hash,
2061cb0ef41Sopenharmony_ci      ta_secret.buffer,
2071cb0ef41Sopenharmony_ci      sa_salt,
2081cb0ef41Sopenharmony_ci      sa_info,
2091cb0ef41Sopenharmony_ci      length);
2101cb0ef41Sopenharmony_ci    hkdf(hash, ta_secret, sa_salt, sa_info, length,
2111cb0ef41Sopenharmony_ci         common.mustSucceed((asyncResult) => {
2121cb0ef41Sopenharmony_ci           assert.deepStrictEqual(syncResult, asyncResult);
2131cb0ef41Sopenharmony_ci         }));
2141cb0ef41Sopenharmony_ci  }
2151cb0ef41Sopenharmony_ci});
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ciif (!common.hasOpenSSL3) {
2191cb0ef41Sopenharmony_ci  const kKnownUnsupported = ['shake128', 'shake256'];
2201cb0ef41Sopenharmony_ci  getHashes()
2211cb0ef41Sopenharmony_ci    .filter((hash) => !kKnownUnsupported.includes(hash))
2221cb0ef41Sopenharmony_ci    .forEach((hash) => {
2231cb0ef41Sopenharmony_ci      assert(hkdfSync(hash, 'key', 'salt', 'info', 5));
2241cb0ef41Sopenharmony_ci    });
2251cb0ef41Sopenharmony_ci}
226