• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals --no-warnings
2'use strict';
3
4const common = require('../common');
5
6if (!common.hasCrypto)
7  common.skip('missing crypto');
8
9const assert = require('assert');
10const { subtle } = require('crypto').webcrypto;
11
12// This is only a partial test. The WebCrypto Web Platform Tests
13// will provide much greater coverage.
14
15// Test ECDH bit derivation
16{
17  async function test(namedCurve) {
18    const [alice, bob] = await Promise.all([
19      subtle.generateKey({ name: 'ECDH', namedCurve }, true, ['deriveBits']),
20      subtle.generateKey({ name: 'ECDH', namedCurve }, true, ['deriveBits']),
21    ]);
22
23    const [secret1, secret2] = await Promise.all([
24      subtle.deriveBits({
25        name: 'ECDH', namedCurve, public: alice.publicKey
26      }, bob.privateKey, 128),
27      subtle.deriveBits({
28        name: 'ECDH', namedCurve, public: bob.publicKey
29      }, alice.privateKey, 128),
30    ]);
31
32    assert(secret1 instanceof ArrayBuffer);
33    assert(secret2 instanceof ArrayBuffer);
34    assert.deepStrictEqual(secret1, secret2);
35  }
36
37  test('P-521').then(common.mustCall());
38}
39
40// Test HKDF bit derivation
41{
42  async function test(pass, info, salt, hash, length, expected) {
43    const ec = new TextEncoder();
44    const key = await subtle.importKey(
45      'raw',
46      ec.encode(pass),
47      { name: 'HKDF', hash },
48      false, ['deriveBits']);
49    const secret = await subtle.deriveBits({
50      name: 'HKDF',
51      hash,
52      salt: ec.encode(salt),
53      info: ec.encode(info)
54    }, key, length);
55    assert.strictEqual(Buffer.from(secret).toString('hex'), expected);
56  }
57
58  const kTests = [
59    ['hello', 'there', 'my friend', 'SHA-256', 512,
60     '14d93b0ccd99d4f2cbd9fbfe9c830b5b8a43e3e45e329' +
61     '41ef21bdeb0fa87b6b6bfa5c54466aa5bf76cdc2685fb' +
62     'a4408ea5b94c049fe035649b46f92fdc519374'],
63    ['hello', 'there', 'my friend', 'SHA-384', 128,
64     'e36cf2cf943d8f3a88adb80f478745c3'],
65  ];
66
67  const tests = Promise.all(kTests.map((args) => test(...args)));
68
69  tests.then(common.mustCall());
70}
71
72// Test PBKDF2 bit derivation
73{
74  async function test(pass, salt, iterations, hash, length, expected) {
75    const ec = new TextEncoder();
76    const key = await subtle.importKey(
77      'raw',
78      ec.encode(pass),
79      { name: 'PBKDF2', hash },
80      false, ['deriveBits']);
81    const secret = await subtle.deriveBits({
82      name: 'PBKDF2',
83      hash,
84      salt: ec.encode(salt),
85      iterations,
86    }, key, length);
87    assert.strictEqual(Buffer.from(secret).toString('hex'), expected);
88  }
89
90  const kTests = [
91    ['hello', 'there', 10, 'SHA-256', 512,
92     'f72d1cf4853fffbd16a42751765d11f8dc7939498ee7b7' +
93     'ce7678b4cb16fad88098110a83e71f4483ce73203f7a64' +
94     '719d293280f780f9fafdcf46925c5c0588b3'],
95    ['hello', 'there', 5, 'SHA-384', 128,
96     '201509b012c9cd2fbe7ea938f0c509b3'],
97  ];
98
99  const tests = Promise.all(kTests.map((args) => test(...args)));
100
101  tests.then(common.mustCall());
102}
103
104// Test X25519 and X448 bit derivation
105{
106  async function test(name) {
107    const [alice, bob] = await Promise.all([
108      subtle.generateKey({ name }, true, ['deriveBits']),
109      subtle.generateKey({ name }, true, ['deriveBits']),
110    ]);
111
112    const [secret1, secret2] = await Promise.all([
113      subtle.deriveBits({
114        name, public: alice.publicKey
115      }, bob.privateKey, 128),
116      subtle.deriveBits({
117        name, public: bob.publicKey
118      }, alice.privateKey, 128),
119    ]);
120
121    assert(secret1 instanceof ArrayBuffer);
122    assert(secret2 instanceof ArrayBuffer);
123    assert.deepStrictEqual(secret1, secret2);
124  }
125
126  test('X25519').then(common.mustCall());
127  test('X448').then(common.mustCall());
128}
129