11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  FunctionPrototypeCall,
51cb0ef41Sopenharmony_ci} = primordials;
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst {
101cb0ef41Sopenharmony_ci  ScryptJob,
111cb0ef41Sopenharmony_ci  kCryptoJobAsync,
121cb0ef41Sopenharmony_ci  kCryptoJobSync,
131cb0ef41Sopenharmony_ci} = internalBinding('crypto');
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciconst {
161cb0ef41Sopenharmony_ci  validateFunction,
171cb0ef41Sopenharmony_ci  validateInteger,
181cb0ef41Sopenharmony_ci  validateInt32,
191cb0ef41Sopenharmony_ci  validateUint32,
201cb0ef41Sopenharmony_ci} = require('internal/validators');
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ciconst {
231cb0ef41Sopenharmony_ci  codes: {
241cb0ef41Sopenharmony_ci    ERR_CRYPTO_SCRYPT_INVALID_PARAMETER,
251cb0ef41Sopenharmony_ci    ERR_CRYPTO_SCRYPT_NOT_SUPPORTED,
261cb0ef41Sopenharmony_ci  },
271cb0ef41Sopenharmony_ci} = require('internal/errors');
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ciconst {
301cb0ef41Sopenharmony_ci  getArrayBufferOrView,
311cb0ef41Sopenharmony_ci  getDefaultEncoding,
321cb0ef41Sopenharmony_ci} = require('internal/crypto/util');
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciconst defaults = {
351cb0ef41Sopenharmony_ci  N: 16384,
361cb0ef41Sopenharmony_ci  r: 8,
371cb0ef41Sopenharmony_ci  p: 1,
381cb0ef41Sopenharmony_ci  maxmem: 32 << 20,  // 32 MiB, matches SCRYPT_MAX_MEM.
391cb0ef41Sopenharmony_ci};
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_cifunction scrypt(password, salt, keylen, options, callback = defaults) {
421cb0ef41Sopenharmony_ci  if (callback === defaults) {
431cb0ef41Sopenharmony_ci    callback = options;
441cb0ef41Sopenharmony_ci    options = defaults;
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  options = check(password, salt, keylen, options);
481cb0ef41Sopenharmony_ci  const { N, r, p, maxmem } = options;
491cb0ef41Sopenharmony_ci  ({ password, salt, keylen } = options);
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  validateFunction(callback, 'callback');
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  const job = new ScryptJob(
541cb0ef41Sopenharmony_ci    kCryptoJobAsync, password, salt, N, r, p, maxmem, keylen);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  const encoding = getDefaultEncoding();
571cb0ef41Sopenharmony_ci  job.ondone = (error, result) => {
581cb0ef41Sopenharmony_ci    if (error !== undefined)
591cb0ef41Sopenharmony_ci      return FunctionPrototypeCall(callback, job, error);
601cb0ef41Sopenharmony_ci    const buf = Buffer.from(result);
611cb0ef41Sopenharmony_ci    if (encoding === 'buffer')
621cb0ef41Sopenharmony_ci      return FunctionPrototypeCall(callback, job, null, buf);
631cb0ef41Sopenharmony_ci    FunctionPrototypeCall(callback, job, null, buf.toString(encoding));
641cb0ef41Sopenharmony_ci  };
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  job.run();
671cb0ef41Sopenharmony_ci}
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_cifunction scryptSync(password, salt, keylen, options = defaults) {
701cb0ef41Sopenharmony_ci  options = check(password, salt, keylen, options);
711cb0ef41Sopenharmony_ci  const { N, r, p, maxmem } = options;
721cb0ef41Sopenharmony_ci  ({ password, salt, keylen } = options);
731cb0ef41Sopenharmony_ci  const job = new ScryptJob(
741cb0ef41Sopenharmony_ci    kCryptoJobSync, password, salt, N, r, p, maxmem, keylen);
751cb0ef41Sopenharmony_ci  const { 0: err, 1: result } = job.run();
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  if (err !== undefined)
781cb0ef41Sopenharmony_ci    throw err;
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  const buf = Buffer.from(result);
811cb0ef41Sopenharmony_ci  const encoding = getDefaultEncoding();
821cb0ef41Sopenharmony_ci  return encoding === 'buffer' ? buf : buf.toString(encoding);
831cb0ef41Sopenharmony_ci}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_cifunction check(password, salt, keylen, options) {
861cb0ef41Sopenharmony_ci  if (ScryptJob === undefined)
871cb0ef41Sopenharmony_ci    throw new ERR_CRYPTO_SCRYPT_NOT_SUPPORTED();
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  password = getArrayBufferOrView(password, 'password');
901cb0ef41Sopenharmony_ci  salt = getArrayBufferOrView(salt, 'salt');
911cb0ef41Sopenharmony_ci  validateInt32(keylen, 'keylen', 0);
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  let { N, r, p, maxmem } = defaults;
941cb0ef41Sopenharmony_ci  if (options && options !== defaults) {
951cb0ef41Sopenharmony_ci    const has_N = options.N !== undefined;
961cb0ef41Sopenharmony_ci    if (has_N) {
971cb0ef41Sopenharmony_ci      N = options.N;
981cb0ef41Sopenharmony_ci      validateUint32(N, 'N');
991cb0ef41Sopenharmony_ci    }
1001cb0ef41Sopenharmony_ci    if (options.cost !== undefined) {
1011cb0ef41Sopenharmony_ci      if (has_N) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER();
1021cb0ef41Sopenharmony_ci      N = options.cost;
1031cb0ef41Sopenharmony_ci      validateUint32(N, 'cost');
1041cb0ef41Sopenharmony_ci    }
1051cb0ef41Sopenharmony_ci    const has_r = (options.r !== undefined);
1061cb0ef41Sopenharmony_ci    if (has_r) {
1071cb0ef41Sopenharmony_ci      r = options.r;
1081cb0ef41Sopenharmony_ci      validateUint32(r, 'r');
1091cb0ef41Sopenharmony_ci    }
1101cb0ef41Sopenharmony_ci    if (options.blockSize !== undefined) {
1111cb0ef41Sopenharmony_ci      if (has_r) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER();
1121cb0ef41Sopenharmony_ci      r = options.blockSize;
1131cb0ef41Sopenharmony_ci      validateUint32(r, 'blockSize');
1141cb0ef41Sopenharmony_ci    }
1151cb0ef41Sopenharmony_ci    const has_p = options.p !== undefined;
1161cb0ef41Sopenharmony_ci    if (has_p) {
1171cb0ef41Sopenharmony_ci      p = options.p;
1181cb0ef41Sopenharmony_ci      validateUint32(p, 'p');
1191cb0ef41Sopenharmony_ci    }
1201cb0ef41Sopenharmony_ci    if (options.parallelization !== undefined) {
1211cb0ef41Sopenharmony_ci      if (has_p) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER();
1221cb0ef41Sopenharmony_ci      p = options.parallelization;
1231cb0ef41Sopenharmony_ci      validateUint32(p, 'parallelization');
1241cb0ef41Sopenharmony_ci    }
1251cb0ef41Sopenharmony_ci    if (options.maxmem !== undefined) {
1261cb0ef41Sopenharmony_ci      maxmem = options.maxmem;
1271cb0ef41Sopenharmony_ci      validateInteger(maxmem, 'maxmem', 0);
1281cb0ef41Sopenharmony_ci    }
1291cb0ef41Sopenharmony_ci    if (N === 0) N = defaults.N;
1301cb0ef41Sopenharmony_ci    if (r === 0) r = defaults.r;
1311cb0ef41Sopenharmony_ci    if (p === 0) p = defaults.p;
1321cb0ef41Sopenharmony_ci    if (maxmem === 0) maxmem = defaults.maxmem;
1331cb0ef41Sopenharmony_ci  }
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  return { password, salt, keylen, N, r, p, maxmem };
1361cb0ef41Sopenharmony_ci}
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_cimodule.exports = {
1391cb0ef41Sopenharmony_ci  scrypt,
1401cb0ef41Sopenharmony_ci  scryptSync,
1411cb0ef41Sopenharmony_ci};
142