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