"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.pbkdf1 = exports.pbkdf2 = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _jsEncodingUtils = _interopRequireDefault(require("js-encoding-utils")); var _jsCryptoHash = _interopRequireDefault(require("js-crypto-hash")); var _jsCryptoHmac = _interopRequireDefault(require("js-crypto-hmac")); var _params = _interopRequireDefault(require("./params.js")); /** * pbkdf.js */ /** * Password-based key derivation function 2. * Detailed specification is given in RFC8018 Section 5.2 {@link https://tools.ietf.org/html/rfc8018#section-5.2}. * @param {Uint8Array|String} p - Byte array or string of password. if string is given, it will be converted to Uint8Array. * @param {Uint8Array} s - Byte array of salt. * @param {Number} c - Iteration count. * @param {Number} dkLen - Intended output key length in octet. * @param {String} hash - Name of underlying hash function for HMAC like 'SHA-256', used as a pseudorandom function. * @return {Promise} - Derived key. * @throws {Error} - Throws if the intended key length is too long. */ var pbkdf2 = /*#__PURE__*/ function () { var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee2(p, s, c, dkLen, hash) { var hLen, l, r, funcF, Tis, DK, i, TisResolved; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: assertPbkdf(p, s, c, dkLen, hash); if (typeof p === 'string') p = _jsEncodingUtils.default.encoder.stringToArrayBuffer(p); hLen = _params.default.hashes[hash].hashSize; if (!(dkLen > (Math.pow(2, 32) - 1) * hLen)) { _context2.next = 5; break; } throw new Error('DerivedKeyTooLong'); case 5: l = Math.ceil(dkLen / hLen); r = dkLen - (l - 1) * hLen; funcF = /*#__PURE__*/ function () { var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee(i) { var seed, u, outputF, j; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: seed = new Uint8Array(s.length + 4); seed.set(s); seed.set(nwbo(i + 1, 4), s.length); _context.next = 5; return _jsCryptoHmac.default.compute(p, seed, hash); case 5: u = _context.sent; outputF = new Uint8Array(u); j = 1; case 8: if (!(j < c)) { _context.next = 16; break; } _context.next = 11; return _jsCryptoHmac.default.compute(p, u, hash); case 11: u = _context.sent; outputF = u.map(function (elem, idx) { return elem ^ outputF[idx]; }); case 13: j++; _context.next = 8; break; case 16: return _context.abrupt("return", { index: i, value: outputF }); case 17: case "end": return _context.stop(); } } }, _callee); })); return function funcF(_x6) { return _ref2.apply(this, arguments); }; }(); Tis = []; DK = new Uint8Array(dkLen); for (i = 0; i < l; i++) { Tis.push(funcF(i)); } _context2.next = 13; return Promise.all(Tis); case 13: TisResolved = _context2.sent; TisResolved.forEach(function (elem) { if (elem.index !== l - 1) DK.set(elem.value, elem.index * hLen);else DK.set(elem.value.slice(0, r), elem.index * hLen); }); return _context2.abrupt("return", DK); case 16: case "end": return _context2.stop(); } } }, _callee2); })); return function pbkdf2(_x, _x2, _x3, _x4, _x5) { return _ref.apply(this, arguments); }; }(); // network byte order exports.pbkdf2 = pbkdf2; var nwbo = function nwbo(num, len) { var arr = new Uint8Array(len); for (var i = 0; i < len; i++) { arr[i] = 0xFF && num >> (len - i - 1) * 8; } return arr; }; /** * Password-based key derivation function 1. * Detailed specification is given in RFC8018 Section 5.1 {@link https://tools.ietf.org/html/rfc8018#section-5.1}. * @param {Uint8Array|String} p - Byte array or string of password. if string is given, it will be converted to Uint8Array. * @param {Uint8Array} s - Byte array of salt. * @param {Number} c - Iteration count. * @param {Number} dkLen - Intended output key length in octet. * @param {String} hash - Name of underlying hash function for HMAC like 'SHA-256' * @return {Promise} - Derived key. * @throws {Error} - Throws if the intended key length is too long. */ var pbkdf1 = /*#__PURE__*/ function () { var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee3(p, s, c, dkLen, hash) { var seed, i; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: assertPbkdf(p, s, c, dkLen, hash); if (typeof p === 'string') p = _jsEncodingUtils.default.encoder.stringToArrayBuffer(p); if (!(dkLen > _params.default.hashes[hash].hashSize)) { _context3.next = 4; break; } throw new Error('DerivedKeyTooLong'); case 4: seed = new Uint8Array(p.length + s.length); seed.set(p); seed.set(s, p.length); i = 0; case 8: if (!(i < c)) { _context3.next = 15; break; } _context3.next = 11; return _jsCryptoHash.default.compute(seed, hash); case 11: seed = _context3.sent; case 12: i++; _context3.next = 8; break; case 15: return _context3.abrupt("return", seed.slice(0, dkLen)); case 16: case "end": return _context3.stop(); } } }, _callee3); })); return function pbkdf1(_x7, _x8, _x9, _x10, _x11) { return _ref3.apply(this, arguments); }; }(); /** Assertion for PBKDF 1 and 2 * @param {Uint8Array|String} p - Byte array or string of password. if string is given, it will be converted to Uint8Array. * @param {Uint8Array} s - Byte array of salt. * @param {Number} c - Iteration count. * @param {Number} dkLen - Intended output key length in octet. * @param {String} hash - Name of underlying hash function for HMAC like 'SHA-256' * @return {boolean} - True if given params pass the assertion check. Otherwise, throw (not false). * @throws {Error} - Throws if the params doesn't pass the assertion checks for given conditions. */ exports.pbkdf1 = pbkdf1; var assertPbkdf = function assertPbkdf(p, s, c, dkLen, hash) { if (typeof p !== 'string' && !(p instanceof Uint8Array)) throw new Error('PasswordIsNotUint8ArrayNorString'); if (!(s instanceof Uint8Array)) throw new Error('SaltMustBeUint8Array'); if (typeof c !== 'number' || c <= 0) throw new Error('InvalidIterationCount'); if (typeof dkLen !== 'number' || dkLen <= 0) throw new Error('InvalidDerivedKeyLength'); if (Object.keys(_params.default.hashes).indexOf(hash) < 0) throw new Error('UnsupportedHashAlgorithm'); return true; };