11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci FunctionPrototypeCall, 51cb0ef41Sopenharmony_ci} = primordials; 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst { 81cb0ef41Sopenharmony_ci HKDFJob, 91cb0ef41Sopenharmony_ci kCryptoJobAsync, 101cb0ef41Sopenharmony_ci kCryptoJobSync, 111cb0ef41Sopenharmony_ci} = internalBinding('crypto'); 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciconst { 141cb0ef41Sopenharmony_ci validateFunction, 151cb0ef41Sopenharmony_ci validateInteger, 161cb0ef41Sopenharmony_ci validateString, 171cb0ef41Sopenharmony_ci} = require('internal/validators'); 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciconst { kMaxLength } = require('buffer'); 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciconst { 221cb0ef41Sopenharmony_ci normalizeHashName, 231cb0ef41Sopenharmony_ci toBuf, 241cb0ef41Sopenharmony_ci validateByteSource, 251cb0ef41Sopenharmony_ci kKeyObject, 261cb0ef41Sopenharmony_ci} = require('internal/crypto/util'); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciconst { 291cb0ef41Sopenharmony_ci createSecretKey, 301cb0ef41Sopenharmony_ci isKeyObject, 311cb0ef41Sopenharmony_ci} = require('internal/crypto/keys'); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciconst { 341cb0ef41Sopenharmony_ci lazyDOMException, 351cb0ef41Sopenharmony_ci promisify, 361cb0ef41Sopenharmony_ci} = require('internal/util'); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciconst { 391cb0ef41Sopenharmony_ci isAnyArrayBuffer, 401cb0ef41Sopenharmony_ci isArrayBufferView, 411cb0ef41Sopenharmony_ci} = require('internal/util/types'); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ciconst { 441cb0ef41Sopenharmony_ci codes: { 451cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 461cb0ef41Sopenharmony_ci ERR_OUT_OF_RANGE, 471cb0ef41Sopenharmony_ci }, 481cb0ef41Sopenharmony_ci hideStackFrames, 491cb0ef41Sopenharmony_ci} = require('internal/errors'); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ciconst validateParameters = hideStackFrames((hash, key, salt, info, length) => { 521cb0ef41Sopenharmony_ci validateString(hash, 'digest'); 531cb0ef41Sopenharmony_ci key = prepareKey(key); 541cb0ef41Sopenharmony_ci salt = validateByteSource(salt, 'salt'); 551cb0ef41Sopenharmony_ci info = validateByteSource(info, 'info'); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci validateInteger(length, 'length', 0, kMaxLength); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci if (info.byteLength > 1024) { 601cb0ef41Sopenharmony_ci throw ERR_OUT_OF_RANGE( 611cb0ef41Sopenharmony_ci 'info', 621cb0ef41Sopenharmony_ci 'must not contain more than 1024 bytes', 631cb0ef41Sopenharmony_ci info.byteLength); 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci return { 671cb0ef41Sopenharmony_ci hash, 681cb0ef41Sopenharmony_ci key, 691cb0ef41Sopenharmony_ci salt, 701cb0ef41Sopenharmony_ci info, 711cb0ef41Sopenharmony_ci length, 721cb0ef41Sopenharmony_ci }; 731cb0ef41Sopenharmony_ci}); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_cifunction prepareKey(key) { 761cb0ef41Sopenharmony_ci if (isKeyObject(key)) 771cb0ef41Sopenharmony_ci return key; 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci if (isAnyArrayBuffer(key)) 801cb0ef41Sopenharmony_ci return createSecretKey(key); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci key = toBuf(key); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci if (!isArrayBufferView(key)) { 851cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 861cb0ef41Sopenharmony_ci 'ikm', 871cb0ef41Sopenharmony_ci [ 881cb0ef41Sopenharmony_ci 'string', 891cb0ef41Sopenharmony_ci 'SecretKeyObject', 901cb0ef41Sopenharmony_ci 'ArrayBuffer', 911cb0ef41Sopenharmony_ci 'TypedArray', 921cb0ef41Sopenharmony_ci 'DataView', 931cb0ef41Sopenharmony_ci 'Buffer', 941cb0ef41Sopenharmony_ci ], 951cb0ef41Sopenharmony_ci key); 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci return createSecretKey(key); 991cb0ef41Sopenharmony_ci} 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_cifunction hkdf(hash, key, salt, info, length, callback) { 1021cb0ef41Sopenharmony_ci ({ 1031cb0ef41Sopenharmony_ci hash, 1041cb0ef41Sopenharmony_ci key, 1051cb0ef41Sopenharmony_ci salt, 1061cb0ef41Sopenharmony_ci info, 1071cb0ef41Sopenharmony_ci length, 1081cb0ef41Sopenharmony_ci } = validateParameters(hash, key, salt, info, length)); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci validateFunction(callback, 'callback'); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci const job = new HKDFJob(kCryptoJobAsync, hash, key, salt, info, length); 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci job.ondone = (error, bits) => { 1151cb0ef41Sopenharmony_ci if (error) return FunctionPrototypeCall(callback, job, error); 1161cb0ef41Sopenharmony_ci FunctionPrototypeCall(callback, job, null, bits); 1171cb0ef41Sopenharmony_ci }; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci job.run(); 1201cb0ef41Sopenharmony_ci} 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cifunction hkdfSync(hash, key, salt, info, length) { 1231cb0ef41Sopenharmony_ci ({ 1241cb0ef41Sopenharmony_ci hash, 1251cb0ef41Sopenharmony_ci key, 1261cb0ef41Sopenharmony_ci salt, 1271cb0ef41Sopenharmony_ci info, 1281cb0ef41Sopenharmony_ci length, 1291cb0ef41Sopenharmony_ci } = validateParameters(hash, key, salt, info, length)); 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci const job = new HKDFJob(kCryptoJobSync, hash, key, salt, info, length); 1321cb0ef41Sopenharmony_ci const { 0: err, 1: bits } = job.run(); 1331cb0ef41Sopenharmony_ci if (err !== undefined) 1341cb0ef41Sopenharmony_ci throw err; 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci return bits; 1371cb0ef41Sopenharmony_ci} 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ciconst hkdfPromise = promisify(hkdf); 1401cb0ef41Sopenharmony_ciasync function hkdfDeriveBits(algorithm, baseKey, length) { 1411cb0ef41Sopenharmony_ci const { hash, salt, info } = algorithm; 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci if (length === 0) 1441cb0ef41Sopenharmony_ci throw lazyDOMException('length cannot be zero', 'OperationError'); 1451cb0ef41Sopenharmony_ci if (length === null) 1461cb0ef41Sopenharmony_ci throw lazyDOMException('length cannot be null', 'OperationError'); 1471cb0ef41Sopenharmony_ci if (length % 8) { 1481cb0ef41Sopenharmony_ci throw lazyDOMException( 1491cb0ef41Sopenharmony_ci 'length must be a multiple of 8', 1501cb0ef41Sopenharmony_ci 'OperationError'); 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci try { 1541cb0ef41Sopenharmony_ci return await hkdfPromise( 1551cb0ef41Sopenharmony_ci normalizeHashName(hash.name), baseKey[kKeyObject], salt, info, length / 8, 1561cb0ef41Sopenharmony_ci ); 1571cb0ef41Sopenharmony_ci } catch (err) { 1581cb0ef41Sopenharmony_ci throw lazyDOMException( 1591cb0ef41Sopenharmony_ci 'The operation failed for an operation-specific reason', 1601cb0ef41Sopenharmony_ci { name: 'OperationError', cause: err }); 1611cb0ef41Sopenharmony_ci } 1621cb0ef41Sopenharmony_ci} 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_cimodule.exports = { 1651cb0ef41Sopenharmony_ci hkdf, 1661cb0ef41Sopenharmony_ci hkdfSync, 1671cb0ef41Sopenharmony_ci hkdfDeriveBits, 1681cb0ef41Sopenharmony_ci}; 169