11cb0ef41Sopenharmony_ci// Flags: --expose-internals --no-warnings
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciconst common = require('../common');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciif (!common.hasCrypto)
71cb0ef41Sopenharmony_ci  common.skip('missing crypto');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst assert = require('assert');
101cb0ef41Sopenharmony_ciconst { subtle } = require('crypto').webcrypto;
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci// This is only a partial test. The WebCrypto Web Platform Tests
131cb0ef41Sopenharmony_ci// will provide much greater coverage.
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// Test ECDH bit derivation
161cb0ef41Sopenharmony_ci{
171cb0ef41Sopenharmony_ci  async function test(namedCurve) {
181cb0ef41Sopenharmony_ci    const [alice, bob] = await Promise.all([
191cb0ef41Sopenharmony_ci      subtle.generateKey({ name: 'ECDH', namedCurve }, true, ['deriveBits']),
201cb0ef41Sopenharmony_ci      subtle.generateKey({ name: 'ECDH', namedCurve }, true, ['deriveBits']),
211cb0ef41Sopenharmony_ci    ]);
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci    const [secret1, secret2] = await Promise.all([
241cb0ef41Sopenharmony_ci      subtle.deriveBits({
251cb0ef41Sopenharmony_ci        name: 'ECDH', namedCurve, public: alice.publicKey
261cb0ef41Sopenharmony_ci      }, bob.privateKey, 128),
271cb0ef41Sopenharmony_ci      subtle.deriveBits({
281cb0ef41Sopenharmony_ci        name: 'ECDH', namedCurve, public: bob.publicKey
291cb0ef41Sopenharmony_ci      }, alice.privateKey, 128),
301cb0ef41Sopenharmony_ci    ]);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci    assert(secret1 instanceof ArrayBuffer);
331cb0ef41Sopenharmony_ci    assert(secret2 instanceof ArrayBuffer);
341cb0ef41Sopenharmony_ci    assert.deepStrictEqual(secret1, secret2);
351cb0ef41Sopenharmony_ci  }
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  test('P-521').then(common.mustCall());
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci// Test HKDF bit derivation
411cb0ef41Sopenharmony_ci{
421cb0ef41Sopenharmony_ci  async function test(pass, info, salt, hash, length, expected) {
431cb0ef41Sopenharmony_ci    const ec = new TextEncoder();
441cb0ef41Sopenharmony_ci    const key = await subtle.importKey(
451cb0ef41Sopenharmony_ci      'raw',
461cb0ef41Sopenharmony_ci      ec.encode(pass),
471cb0ef41Sopenharmony_ci      { name: 'HKDF', hash },
481cb0ef41Sopenharmony_ci      false, ['deriveBits']);
491cb0ef41Sopenharmony_ci    const secret = await subtle.deriveBits({
501cb0ef41Sopenharmony_ci      name: 'HKDF',
511cb0ef41Sopenharmony_ci      hash,
521cb0ef41Sopenharmony_ci      salt: ec.encode(salt),
531cb0ef41Sopenharmony_ci      info: ec.encode(info)
541cb0ef41Sopenharmony_ci    }, key, length);
551cb0ef41Sopenharmony_ci    assert.strictEqual(Buffer.from(secret).toString('hex'), expected);
561cb0ef41Sopenharmony_ci  }
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  const kTests = [
591cb0ef41Sopenharmony_ci    ['hello', 'there', 'my friend', 'SHA-256', 512,
601cb0ef41Sopenharmony_ci     '14d93b0ccd99d4f2cbd9fbfe9c830b5b8a43e3e45e329' +
611cb0ef41Sopenharmony_ci     '41ef21bdeb0fa87b6b6bfa5c54466aa5bf76cdc2685fb' +
621cb0ef41Sopenharmony_ci     'a4408ea5b94c049fe035649b46f92fdc519374'],
631cb0ef41Sopenharmony_ci    ['hello', 'there', 'my friend', 'SHA-384', 128,
641cb0ef41Sopenharmony_ci     'e36cf2cf943d8f3a88adb80f478745c3'],
651cb0ef41Sopenharmony_ci  ];
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  const tests = Promise.all(kTests.map((args) => test(...args)));
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  tests.then(common.mustCall());
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci// Test PBKDF2 bit derivation
731cb0ef41Sopenharmony_ci{
741cb0ef41Sopenharmony_ci  async function test(pass, salt, iterations, hash, length, expected) {
751cb0ef41Sopenharmony_ci    const ec = new TextEncoder();
761cb0ef41Sopenharmony_ci    const key = await subtle.importKey(
771cb0ef41Sopenharmony_ci      'raw',
781cb0ef41Sopenharmony_ci      ec.encode(pass),
791cb0ef41Sopenharmony_ci      { name: 'PBKDF2', hash },
801cb0ef41Sopenharmony_ci      false, ['deriveBits']);
811cb0ef41Sopenharmony_ci    const secret = await subtle.deriveBits({
821cb0ef41Sopenharmony_ci      name: 'PBKDF2',
831cb0ef41Sopenharmony_ci      hash,
841cb0ef41Sopenharmony_ci      salt: ec.encode(salt),
851cb0ef41Sopenharmony_ci      iterations,
861cb0ef41Sopenharmony_ci    }, key, length);
871cb0ef41Sopenharmony_ci    assert.strictEqual(Buffer.from(secret).toString('hex'), expected);
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  const kTests = [
911cb0ef41Sopenharmony_ci    ['hello', 'there', 10, 'SHA-256', 512,
921cb0ef41Sopenharmony_ci     'f72d1cf4853fffbd16a42751765d11f8dc7939498ee7b7' +
931cb0ef41Sopenharmony_ci     'ce7678b4cb16fad88098110a83e71f4483ce73203f7a64' +
941cb0ef41Sopenharmony_ci     '719d293280f780f9fafdcf46925c5c0588b3'],
951cb0ef41Sopenharmony_ci    ['hello', 'there', 5, 'SHA-384', 128,
961cb0ef41Sopenharmony_ci     '201509b012c9cd2fbe7ea938f0c509b3'],
971cb0ef41Sopenharmony_ci  ];
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  const tests = Promise.all(kTests.map((args) => test(...args)));
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  tests.then(common.mustCall());
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci// Test X25519 and X448 bit derivation
1051cb0ef41Sopenharmony_ci{
1061cb0ef41Sopenharmony_ci  async function test(name) {
1071cb0ef41Sopenharmony_ci    const [alice, bob] = await Promise.all([
1081cb0ef41Sopenharmony_ci      subtle.generateKey({ name }, true, ['deriveBits']),
1091cb0ef41Sopenharmony_ci      subtle.generateKey({ name }, true, ['deriveBits']),
1101cb0ef41Sopenharmony_ci    ]);
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci    const [secret1, secret2] = await Promise.all([
1131cb0ef41Sopenharmony_ci      subtle.deriveBits({
1141cb0ef41Sopenharmony_ci        name, public: alice.publicKey
1151cb0ef41Sopenharmony_ci      }, bob.privateKey, 128),
1161cb0ef41Sopenharmony_ci      subtle.deriveBits({
1171cb0ef41Sopenharmony_ci        name, public: bob.publicKey
1181cb0ef41Sopenharmony_ci      }, alice.privateKey, 128),
1191cb0ef41Sopenharmony_ci    ]);
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci    assert(secret1 instanceof ArrayBuffer);
1221cb0ef41Sopenharmony_ci    assert(secret2 instanceof ArrayBuffer);
1231cb0ef41Sopenharmony_ci    assert.deepStrictEqual(secret1, secret2);
1241cb0ef41Sopenharmony_ci  }
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  test('X25519').then(common.mustCall());
1271cb0ef41Sopenharmony_ci  test('X448').then(common.mustCall());
1281cb0ef41Sopenharmony_ci}
129