11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  ObjectSetPrototypeOf,
51cb0ef41Sopenharmony_ci  ReflectApply,
61cb0ef41Sopenharmony_ci  Symbol,
71cb0ef41Sopenharmony_ci} = primordials;
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst {
101cb0ef41Sopenharmony_ci  Hash: _Hash,
111cb0ef41Sopenharmony_ci  HashJob,
121cb0ef41Sopenharmony_ci  Hmac: _Hmac,
131cb0ef41Sopenharmony_ci  kCryptoJobAsync,
141cb0ef41Sopenharmony_ci} = internalBinding('crypto');
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciconst {
171cb0ef41Sopenharmony_ci  getDefaultEncoding,
181cb0ef41Sopenharmony_ci  getStringOption,
191cb0ef41Sopenharmony_ci  jobPromise,
201cb0ef41Sopenharmony_ci  normalizeHashName,
211cb0ef41Sopenharmony_ci  validateMaxBufferLength,
221cb0ef41Sopenharmony_ci  kHandle,
231cb0ef41Sopenharmony_ci} = require('internal/crypto/util');
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciconst {
261cb0ef41Sopenharmony_ci  prepareSecretKey,
271cb0ef41Sopenharmony_ci} = require('internal/crypto/keys');
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ciconst {
301cb0ef41Sopenharmony_ci  lazyDOMException,
311cb0ef41Sopenharmony_ci} = require('internal/util');
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ciconst {
341cb0ef41Sopenharmony_ci  Buffer,
351cb0ef41Sopenharmony_ci} = require('buffer');
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ciconst {
381cb0ef41Sopenharmony_ci  codes: {
391cb0ef41Sopenharmony_ci    ERR_CRYPTO_HASH_FINALIZED,
401cb0ef41Sopenharmony_ci    ERR_CRYPTO_HASH_UPDATE_FAILED,
411cb0ef41Sopenharmony_ci    ERR_INVALID_ARG_TYPE,
421cb0ef41Sopenharmony_ci  },
431cb0ef41Sopenharmony_ci} = require('internal/errors');
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ciconst {
461cb0ef41Sopenharmony_ci  validateEncoding,
471cb0ef41Sopenharmony_ci  validateString,
481cb0ef41Sopenharmony_ci  validateUint32,
491cb0ef41Sopenharmony_ci} = require('internal/validators');
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ciconst {
521cb0ef41Sopenharmony_ci  isArrayBufferView,
531cb0ef41Sopenharmony_ci} = require('internal/util/types');
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ciconst LazyTransform = require('internal/streams/lazy_transform');
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ciconst kState = Symbol('kState');
581cb0ef41Sopenharmony_ciconst kFinalized = Symbol('kFinalized');
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_cifunction Hash(algorithm, options) {
611cb0ef41Sopenharmony_ci  if (!(this instanceof Hash))
621cb0ef41Sopenharmony_ci    return new Hash(algorithm, options);
631cb0ef41Sopenharmony_ci  if (!(algorithm instanceof _Hash))
641cb0ef41Sopenharmony_ci    validateString(algorithm, 'algorithm');
651cb0ef41Sopenharmony_ci  const xofLen = typeof options === 'object' && options !== null ?
661cb0ef41Sopenharmony_ci    options.outputLength : undefined;
671cb0ef41Sopenharmony_ci  if (xofLen !== undefined)
681cb0ef41Sopenharmony_ci    validateUint32(xofLen, 'options.outputLength');
691cb0ef41Sopenharmony_ci  this[kHandle] = new _Hash(algorithm, xofLen);
701cb0ef41Sopenharmony_ci  this[kState] = {
711cb0ef41Sopenharmony_ci    [kFinalized]: false,
721cb0ef41Sopenharmony_ci  };
731cb0ef41Sopenharmony_ci  ReflectApply(LazyTransform, this, [options]);
741cb0ef41Sopenharmony_ci}
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Hash.prototype, LazyTransform.prototype);
771cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Hash, LazyTransform);
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ciHash.prototype.copy = function copy(options) {
801cb0ef41Sopenharmony_ci  const state = this[kState];
811cb0ef41Sopenharmony_ci  if (state[kFinalized])
821cb0ef41Sopenharmony_ci    throw new ERR_CRYPTO_HASH_FINALIZED();
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  return new Hash(this[kHandle], options);
851cb0ef41Sopenharmony_ci};
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciHash.prototype._transform = function _transform(chunk, encoding, callback) {
881cb0ef41Sopenharmony_ci  this[kHandle].update(chunk, encoding);
891cb0ef41Sopenharmony_ci  callback();
901cb0ef41Sopenharmony_ci};
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciHash.prototype._flush = function _flush(callback) {
931cb0ef41Sopenharmony_ci  this.push(this[kHandle].digest());
941cb0ef41Sopenharmony_ci  callback();
951cb0ef41Sopenharmony_ci};
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ciHash.prototype.update = function update(data, encoding) {
981cb0ef41Sopenharmony_ci  encoding = encoding || getDefaultEncoding();
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  const state = this[kState];
1011cb0ef41Sopenharmony_ci  if (state[kFinalized])
1021cb0ef41Sopenharmony_ci    throw new ERR_CRYPTO_HASH_FINALIZED();
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  if (typeof data === 'string') {
1051cb0ef41Sopenharmony_ci    validateEncoding(data, encoding);
1061cb0ef41Sopenharmony_ci  } else if (!isArrayBufferView(data)) {
1071cb0ef41Sopenharmony_ci    throw new ERR_INVALID_ARG_TYPE(
1081cb0ef41Sopenharmony_ci      'data', ['string', 'Buffer', 'TypedArray', 'DataView'], data);
1091cb0ef41Sopenharmony_ci  }
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci  if (!this[kHandle].update(data, encoding))
1121cb0ef41Sopenharmony_ci    throw new ERR_CRYPTO_HASH_UPDATE_FAILED();
1131cb0ef41Sopenharmony_ci  return this;
1141cb0ef41Sopenharmony_ci};
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ciHash.prototype.digest = function digest(outputEncoding) {
1181cb0ef41Sopenharmony_ci  const state = this[kState];
1191cb0ef41Sopenharmony_ci  if (state[kFinalized])
1201cb0ef41Sopenharmony_ci    throw new ERR_CRYPTO_HASH_FINALIZED();
1211cb0ef41Sopenharmony_ci  outputEncoding = outputEncoding || getDefaultEncoding();
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  // Explicit conversion for backward compatibility.
1241cb0ef41Sopenharmony_ci  const ret = this[kHandle].digest(`${outputEncoding}`);
1251cb0ef41Sopenharmony_ci  state[kFinalized] = true;
1261cb0ef41Sopenharmony_ci  return ret;
1271cb0ef41Sopenharmony_ci};
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_cifunction Hmac(hmac, key, options) {
1301cb0ef41Sopenharmony_ci  if (!(this instanceof Hmac))
1311cb0ef41Sopenharmony_ci    return new Hmac(hmac, key, options);
1321cb0ef41Sopenharmony_ci  validateString(hmac, 'hmac');
1331cb0ef41Sopenharmony_ci  const encoding = getStringOption(options, 'encoding');
1341cb0ef41Sopenharmony_ci  key = prepareSecretKey(key, encoding);
1351cb0ef41Sopenharmony_ci  this[kHandle] = new _Hmac();
1361cb0ef41Sopenharmony_ci  this[kHandle].init(hmac, key);
1371cb0ef41Sopenharmony_ci  this[kState] = {
1381cb0ef41Sopenharmony_ci    [kFinalized]: false,
1391cb0ef41Sopenharmony_ci  };
1401cb0ef41Sopenharmony_ci  ReflectApply(LazyTransform, this, [options]);
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Hmac.prototype, LazyTransform.prototype);
1441cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Hmac, LazyTransform);
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ciHmac.prototype.update = Hash.prototype.update;
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ciHmac.prototype.digest = function digest(outputEncoding) {
1491cb0ef41Sopenharmony_ci  const state = this[kState];
1501cb0ef41Sopenharmony_ci  outputEncoding = outputEncoding || getDefaultEncoding();
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  if (state[kFinalized]) {
1531cb0ef41Sopenharmony_ci    const buf = Buffer.from('');
1541cb0ef41Sopenharmony_ci    return outputEncoding === 'buffer' ? buf : buf.toString(outputEncoding);
1551cb0ef41Sopenharmony_ci  }
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci  // Explicit conversion for backward compatibility.
1581cb0ef41Sopenharmony_ci  const ret = this[kHandle].digest(`${outputEncoding}`);
1591cb0ef41Sopenharmony_ci  state[kFinalized] = true;
1601cb0ef41Sopenharmony_ci  return ret;
1611cb0ef41Sopenharmony_ci};
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ciHmac.prototype._flush = Hash.prototype._flush;
1641cb0ef41Sopenharmony_ciHmac.prototype._transform = Hash.prototype._transform;
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci// Implementation for WebCrypto subtle.digest()
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ciasync function asyncDigest(algorithm, data) {
1691cb0ef41Sopenharmony_ci  validateMaxBufferLength(data, 'data');
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  switch (algorithm.name) {
1721cb0ef41Sopenharmony_ci    case 'SHA-1':
1731cb0ef41Sopenharmony_ci      // Fall through
1741cb0ef41Sopenharmony_ci    case 'SHA-256':
1751cb0ef41Sopenharmony_ci      // Fall through
1761cb0ef41Sopenharmony_ci    case 'SHA-384':
1771cb0ef41Sopenharmony_ci      // Fall through
1781cb0ef41Sopenharmony_ci    case 'SHA-512':
1791cb0ef41Sopenharmony_ci      return jobPromise(() => new HashJob(
1801cb0ef41Sopenharmony_ci        kCryptoJobAsync,
1811cb0ef41Sopenharmony_ci        normalizeHashName(algorithm.name),
1821cb0ef41Sopenharmony_ci        data));
1831cb0ef41Sopenharmony_ci  }
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
1861cb0ef41Sopenharmony_ci}
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_cimodule.exports = {
1891cb0ef41Sopenharmony_ci  Hash,
1901cb0ef41Sopenharmony_ci  Hmac,
1911cb0ef41Sopenharmony_ci  asyncDigest,
1921cb0ef41Sopenharmony_ci};
193