11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ciif (!common.hasCrypto)
41cb0ef41Sopenharmony_ci  common.skip('missing crypto');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst crypto = require('crypto');
81cb0ef41Sopenharmony_ciconst fs = require('fs');
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cilet cryptoType;
131cb0ef41Sopenharmony_cilet digest;
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// Test hashing
161cb0ef41Sopenharmony_ciconst a1 = crypto.createHash('sha1').update('Test123').digest('hex');
171cb0ef41Sopenharmony_ciconst a2 = crypto.createHash('sha256').update('Test123').digest('base64');
181cb0ef41Sopenharmony_ciconst a3 = crypto.createHash('sha512').update('Test123').digest(); // buffer
191cb0ef41Sopenharmony_ciconst a4 = crypto.createHash('sha1').update('Test123').digest('buffer');
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci// stream interface
221cb0ef41Sopenharmony_cilet a5 = crypto.createHash('sha512');
231cb0ef41Sopenharmony_cia5.end('Test123');
241cb0ef41Sopenharmony_cia5 = a5.read();
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_cilet a6 = crypto.createHash('sha512');
271cb0ef41Sopenharmony_cia6.write('Te');
281cb0ef41Sopenharmony_cia6.write('st');
291cb0ef41Sopenharmony_cia6.write('123');
301cb0ef41Sopenharmony_cia6.end();
311cb0ef41Sopenharmony_cia6 = a6.read();
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cilet a7 = crypto.createHash('sha512');
341cb0ef41Sopenharmony_cia7.end();
351cb0ef41Sopenharmony_cia7 = a7.read();
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cilet a8 = crypto.createHash('sha512');
381cb0ef41Sopenharmony_cia8.write('');
391cb0ef41Sopenharmony_cia8.end();
401cb0ef41Sopenharmony_cia8 = a8.read();
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ciif (!common.hasFipsCrypto) {
431cb0ef41Sopenharmony_ci  cryptoType = 'md5';
441cb0ef41Sopenharmony_ci  digest = 'latin1';
451cb0ef41Sopenharmony_ci  const a0 = crypto.createHash(cryptoType).update('Test123').digest(digest);
461cb0ef41Sopenharmony_ci  assert.strictEqual(
471cb0ef41Sopenharmony_ci    a0,
481cb0ef41Sopenharmony_ci    'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca\u00bd\u008c',
491cb0ef41Sopenharmony_ci    `${cryptoType} with ${digest} digest failed to evaluate to expected hash`
501cb0ef41Sopenharmony_ci  );
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_cicryptoType = 'md5';
531cb0ef41Sopenharmony_cidigest = 'hex';
541cb0ef41Sopenharmony_ciassert.strictEqual(
551cb0ef41Sopenharmony_ci  a1,
561cb0ef41Sopenharmony_ci  '8308651804facb7b9af8ffc53a33a22d6a1c8ac2',
571cb0ef41Sopenharmony_ci  `${cryptoType} with ${digest} digest failed to evaluate to expected hash`);
581cb0ef41Sopenharmony_cicryptoType = 'sha256';
591cb0ef41Sopenharmony_cidigest = 'base64';
601cb0ef41Sopenharmony_ciassert.strictEqual(
611cb0ef41Sopenharmony_ci  a2,
621cb0ef41Sopenharmony_ci  '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=',
631cb0ef41Sopenharmony_ci  `${cryptoType} with ${digest} digest failed to evaluate to expected hash`);
641cb0ef41Sopenharmony_cicryptoType = 'sha512';
651cb0ef41Sopenharmony_cidigest = 'latin1';
661cb0ef41Sopenharmony_ciassert.deepStrictEqual(
671cb0ef41Sopenharmony_ci  a3,
681cb0ef41Sopenharmony_ci  Buffer.from(
691cb0ef41Sopenharmony_ci    '\u00c1(4\u00f1\u0003\u001fd\u0097!O\'\u00d4C/&Qz\u00d4' +
701cb0ef41Sopenharmony_ci    '\u0094\u0015l\u00b8\u008dQ+\u00db\u001d\u00c4\u00b5}\u00b2' +
711cb0ef41Sopenharmony_ci    '\u00d6\u0092\u00a3\u00df\u00a2i\u00a1\u009b\n\n*\u000f' +
721cb0ef41Sopenharmony_ci    '\u00d7\u00d6\u00a2\u00a8\u0085\u00e3<\u0083\u009c\u0093' +
731cb0ef41Sopenharmony_ci    '\u00c2\u0006\u00da0\u00a1\u00879(G\u00ed\'',
741cb0ef41Sopenharmony_ci    'latin1'),
751cb0ef41Sopenharmony_ci  `${cryptoType} with ${digest} digest failed to evaluate to expected hash`);
761cb0ef41Sopenharmony_cicryptoType = 'sha1';
771cb0ef41Sopenharmony_cidigest = 'hex';
781cb0ef41Sopenharmony_ciassert.deepStrictEqual(
791cb0ef41Sopenharmony_ci  a4,
801cb0ef41Sopenharmony_ci  Buffer.from('8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'hex'),
811cb0ef41Sopenharmony_ci  `${cryptoType} with ${digest} digest failed to evaluate to expected hash`
821cb0ef41Sopenharmony_ci);
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci// Stream interface should produce the same result.
851cb0ef41Sopenharmony_ciassert.deepStrictEqual(a5, a3);
861cb0ef41Sopenharmony_ciassert.deepStrictEqual(a6, a3);
871cb0ef41Sopenharmony_ciassert.notStrictEqual(a7, undefined);
881cb0ef41Sopenharmony_ciassert.notStrictEqual(a8, undefined);
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci// Test multiple updates to same hash
911cb0ef41Sopenharmony_ciconst h1 = crypto.createHash('sha1').update('Test123').digest('hex');
921cb0ef41Sopenharmony_ciconst h2 = crypto.createHash('sha1').update('Test').update('123').digest('hex');
931cb0ef41Sopenharmony_ciassert.strictEqual(h1, h2);
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci// Test hashing for binary files
961cb0ef41Sopenharmony_ciconst fn = fixtures.path('sample.png');
971cb0ef41Sopenharmony_ciconst sha1Hash = crypto.createHash('sha1');
981cb0ef41Sopenharmony_ciconst fileStream = fs.createReadStream(fn);
991cb0ef41Sopenharmony_cifileStream.on('data', function(data) {
1001cb0ef41Sopenharmony_ci  sha1Hash.update(data);
1011cb0ef41Sopenharmony_ci});
1021cb0ef41Sopenharmony_cifileStream.on('close', common.mustCall(function() {
1031cb0ef41Sopenharmony_ci  // Test SHA1 of sample.png
1041cb0ef41Sopenharmony_ci  assert.strictEqual(sha1Hash.digest('hex'),
1051cb0ef41Sopenharmony_ci                     '22723e553129a336ad96e10f6aecdf0f45e4149e');
1061cb0ef41Sopenharmony_ci}));
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci// Issue https://github.com/nodejs/node-v0.x-archive/issues/2227: unknown digest
1091cb0ef41Sopenharmony_ci// method should throw an error.
1101cb0ef41Sopenharmony_ciassert.throws(function() {
1111cb0ef41Sopenharmony_ci  crypto.createHash('xyzzy');
1121cb0ef41Sopenharmony_ci}, /Digest method not supported/);
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci// Issue https://github.com/nodejs/node/issues/9819: throwing encoding used to
1151cb0ef41Sopenharmony_ci// segfault.
1161cb0ef41Sopenharmony_ciassert.throws(
1171cb0ef41Sopenharmony_ci  () => crypto.createHash('sha256').digest({
1181cb0ef41Sopenharmony_ci    toString: () => { throw new Error('boom'); },
1191cb0ef41Sopenharmony_ci  }),
1201cb0ef41Sopenharmony_ci  {
1211cb0ef41Sopenharmony_ci    name: 'Error',
1221cb0ef41Sopenharmony_ci    message: 'boom'
1231cb0ef41Sopenharmony_ci  });
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci// Issue https://github.com/nodejs/node/issues/25487: error message for invalid
1261cb0ef41Sopenharmony_ci// arg type to update method should include all possible types
1271cb0ef41Sopenharmony_ciassert.throws(
1281cb0ef41Sopenharmony_ci  () => crypto.createHash('sha256').update(),
1291cb0ef41Sopenharmony_ci  {
1301cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
1311cb0ef41Sopenharmony_ci    name: 'TypeError',
1321cb0ef41Sopenharmony_ci  });
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci// Default UTF-8 encoding
1351cb0ef41Sopenharmony_ciconst hutf8 = crypto.createHash('sha512').update('УТФ-8 text').digest('hex');
1361cb0ef41Sopenharmony_ciassert.strictEqual(
1371cb0ef41Sopenharmony_ci  hutf8,
1381cb0ef41Sopenharmony_ci  '4b21bbd1a68e690a730ddcb5a8bc94ead9879ffe82580767ad7ec6fa8ba2dea6' +
1391cb0ef41Sopenharmony_ci        '43a821af66afa9a45b6a78c712fecf0e56dc7f43aef4bcfc8eb5b4d8dca6ea5b');
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ciassert.notStrictEqual(
1421cb0ef41Sopenharmony_ci  hutf8,
1431cb0ef41Sopenharmony_ci  crypto.createHash('sha512').update('УТФ-8 text', 'latin1').digest('hex'));
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ciconst h3 = crypto.createHash('sha256');
1461cb0ef41Sopenharmony_cih3.digest();
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ciassert.throws(
1491cb0ef41Sopenharmony_ci  () => h3.digest(),
1501cb0ef41Sopenharmony_ci  {
1511cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_HASH_FINALIZED',
1521cb0ef41Sopenharmony_ci    name: 'Error'
1531cb0ef41Sopenharmony_ci  });
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ciassert.throws(
1561cb0ef41Sopenharmony_ci  () => h3.update('foo'),
1571cb0ef41Sopenharmony_ci  {
1581cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_HASH_FINALIZED',
1591cb0ef41Sopenharmony_ci    name: 'Error'
1601cb0ef41Sopenharmony_ci  });
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ciassert.strictEqual(
1631cb0ef41Sopenharmony_ci  crypto.createHash('sha256').update('test').digest('ucs2'),
1641cb0ef41Sopenharmony_ci  crypto.createHash('sha256').update('test').digest().toString('ucs2'));
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ciassert.throws(
1671cb0ef41Sopenharmony_ci  () => crypto.createHash(),
1681cb0ef41Sopenharmony_ci  {
1691cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
1701cb0ef41Sopenharmony_ci    name: 'TypeError',
1711cb0ef41Sopenharmony_ci    message: 'The "algorithm" argument must be of type string. ' +
1721cb0ef41Sopenharmony_ci             'Received undefined'
1731cb0ef41Sopenharmony_ci  }
1741cb0ef41Sopenharmony_ci);
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci{
1771cb0ef41Sopenharmony_ci  const Hash = crypto.Hash;
1781cb0ef41Sopenharmony_ci  const instance = crypto.Hash('sha256');
1791cb0ef41Sopenharmony_ci  assert(instance instanceof Hash, 'Hash is expected to return a new instance' +
1801cb0ef41Sopenharmony_ci                                   ' when called without `new`');
1811cb0ef41Sopenharmony_ci}
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci// Test XOF hash functions and the outputLength option.
1841cb0ef41Sopenharmony_ci{
1851cb0ef41Sopenharmony_ci  // Default outputLengths.
1861cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128').digest('hex'),
1871cb0ef41Sopenharmony_ci                     '7f9c2ba4e88f827d616045507605853e');
1881cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128', null).digest('hex'),
1891cb0ef41Sopenharmony_ci                     '7f9c2ba4e88f827d616045507605853e');
1901cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake256').digest('hex'),
1911cb0ef41Sopenharmony_ci                     '46b9dd2b0ba88d13233b3feb743eeb24' +
1921cb0ef41Sopenharmony_ci                     '3fcd52ea62b81b82b50c27646ed5762f');
1931cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake256', { outputLength: 0 })
1941cb0ef41Sopenharmony_ci                           .copy()  // Default outputLength.
1951cb0ef41Sopenharmony_ci                           .digest('hex'),
1961cb0ef41Sopenharmony_ci                     '46b9dd2b0ba88d13233b3feb743eeb24' +
1971cb0ef41Sopenharmony_ci                     '3fcd52ea62b81b82b50c27646ed5762f');
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  // Short outputLengths.
2001cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128', { outputLength: 0 })
2011cb0ef41Sopenharmony_ci                           .digest('hex'),
2021cb0ef41Sopenharmony_ci                     '');
2031cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128', { outputLength: 5 })
2041cb0ef41Sopenharmony_ci                           .copy({ outputLength: 0 })
2051cb0ef41Sopenharmony_ci                           .digest('hex'),
2061cb0ef41Sopenharmony_ci                     '');
2071cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128', { outputLength: 5 })
2081cb0ef41Sopenharmony_ci                           .digest('hex'),
2091cb0ef41Sopenharmony_ci                     '7f9c2ba4e8');
2101cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128', { outputLength: 0 })
2111cb0ef41Sopenharmony_ci                           .copy({ outputLength: 5 })
2121cb0ef41Sopenharmony_ci                           .digest('hex'),
2131cb0ef41Sopenharmony_ci                     '7f9c2ba4e8');
2141cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128', { outputLength: 15 })
2151cb0ef41Sopenharmony_ci                           .digest('hex'),
2161cb0ef41Sopenharmony_ci                     '7f9c2ba4e88f827d61604550760585');
2171cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake256', { outputLength: 16 })
2181cb0ef41Sopenharmony_ci                           .digest('hex'),
2191cb0ef41Sopenharmony_ci                     '46b9dd2b0ba88d13233b3feb743eeb24');
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci  // Large outputLengths.
2221cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('shake128', { outputLength: 128 })
2231cb0ef41Sopenharmony_ci                           .digest('hex'),
2241cb0ef41Sopenharmony_ci                     '7f9c2ba4e88f827d616045507605853e' +
2251cb0ef41Sopenharmony_ci                     'd73b8093f6efbc88eb1a6eacfa66ef26' +
2261cb0ef41Sopenharmony_ci                     '3cb1eea988004b93103cfb0aeefd2a68' +
2271cb0ef41Sopenharmony_ci                     '6e01fa4a58e8a3639ca8a1e3f9ae57e2' +
2281cb0ef41Sopenharmony_ci                     '35b8cc873c23dc62b8d260169afa2f75' +
2291cb0ef41Sopenharmony_ci                     'ab916a58d974918835d25e6a435085b2' +
2301cb0ef41Sopenharmony_ci                     'badfd6dfaac359a5efbb7bcc4b59d538' +
2311cb0ef41Sopenharmony_ci                     'df9a04302e10c8bc1cbf1a0b3a5120ea');
2321cb0ef41Sopenharmony_ci  const superLongHash = crypto.createHash('shake256', {
2331cb0ef41Sopenharmony_ci    outputLength: 1024 * 1024
2341cb0ef41Sopenharmony_ci  }).update('The message is shorter than the hash!')
2351cb0ef41Sopenharmony_ci    .digest('hex');
2361cb0ef41Sopenharmony_ci  assert.strictEqual(superLongHash.length, 2 * 1024 * 1024);
2371cb0ef41Sopenharmony_ci  assert.ok(superLongHash.endsWith('193414035ddba77bf7bba97981e656ec'));
2381cb0ef41Sopenharmony_ci  assert.ok(superLongHash.startsWith('a2a28dbc49cfd6e5d6ceea3d03e77748'));
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  // Non-XOF hash functions should accept valid outputLength options as well.
2411cb0ef41Sopenharmony_ci  assert.strictEqual(crypto.createHash('sha224', { outputLength: 28 })
2421cb0ef41Sopenharmony_ci                           .digest('hex'),
2431cb0ef41Sopenharmony_ci                     'd14a028c2a3a2bc9476102bb288234c4' +
2441cb0ef41Sopenharmony_ci                     '15a2b01f828ea62ac5b3e42f');
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci  // Passing invalid sizes should throw during creation.
2471cb0ef41Sopenharmony_ci  assert.throws(() => {
2481cb0ef41Sopenharmony_ci    crypto.createHash('sha256', { outputLength: 28 });
2491cb0ef41Sopenharmony_ci  }, {
2501cb0ef41Sopenharmony_ci    code: 'ERR_OSSL_EVP_NOT_XOF_OR_INVALID_LENGTH'
2511cb0ef41Sopenharmony_ci  });
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ci  for (const outputLength of [null, {}, 'foo', false]) {
2541cb0ef41Sopenharmony_ci    assert.throws(() => crypto.createHash('sha256', { outputLength }),
2551cb0ef41Sopenharmony_ci                  { code: 'ERR_INVALID_ARG_TYPE' });
2561cb0ef41Sopenharmony_ci  }
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  for (const outputLength of [-1, .5, Infinity, 2 ** 90]) {
2591cb0ef41Sopenharmony_ci    assert.throws(() => crypto.createHash('sha256', { outputLength }),
2601cb0ef41Sopenharmony_ci                  { code: 'ERR_OUT_OF_RANGE' });
2611cb0ef41Sopenharmony_ci  }
2621cb0ef41Sopenharmony_ci}
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci{
2651cb0ef41Sopenharmony_ci  const h = crypto.createHash('sha512');
2661cb0ef41Sopenharmony_ci  h.digest();
2671cb0ef41Sopenharmony_ci  assert.throws(() => h.copy(), { code: 'ERR_CRYPTO_HASH_FINALIZED' });
2681cb0ef41Sopenharmony_ci  assert.throws(() => h.digest(), { code: 'ERR_CRYPTO_HASH_FINALIZED' });
2691cb0ef41Sopenharmony_ci}
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci{
2721cb0ef41Sopenharmony_ci  const a = crypto.createHash('sha512').update('abc');
2731cb0ef41Sopenharmony_ci  const b = a.copy();
2741cb0ef41Sopenharmony_ci  const c = b.copy().update('def');
2751cb0ef41Sopenharmony_ci  const d = crypto.createHash('sha512').update('abcdef');
2761cb0ef41Sopenharmony_ci  assert.strictEqual(a.digest('hex'), b.digest('hex'));
2771cb0ef41Sopenharmony_ci  assert.strictEqual(c.digest('hex'), d.digest('hex'));
2781cb0ef41Sopenharmony_ci}
279