11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayBufferPrototypeSlice, 51cb0ef41Sopenharmony_ci MathCeil, 61cb0ef41Sopenharmony_ci ObjectDefineProperty, 71cb0ef41Sopenharmony_ci SafeSet, 81cb0ef41Sopenharmony_ci} = primordials; 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer'); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst { 131cb0ef41Sopenharmony_ci DiffieHellman: _DiffieHellman, 141cb0ef41Sopenharmony_ci DiffieHellmanGroup: _DiffieHellmanGroup, 151cb0ef41Sopenharmony_ci ECDH: _ECDH, 161cb0ef41Sopenharmony_ci ECDHBitsJob, 171cb0ef41Sopenharmony_ci ECDHConvertKey: _ECDHConvertKey, 181cb0ef41Sopenharmony_ci statelessDH, 191cb0ef41Sopenharmony_ci kCryptoJobAsync, 201cb0ef41Sopenharmony_ci} = internalBinding('crypto'); 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciconst { 231cb0ef41Sopenharmony_ci codes: { 241cb0ef41Sopenharmony_ci ERR_CRYPTO_ECDH_INVALID_FORMAT, 251cb0ef41Sopenharmony_ci ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY, 261cb0ef41Sopenharmony_ci ERR_CRYPTO_INCOMPATIBLE_KEY, 271cb0ef41Sopenharmony_ci ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, 281cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 291cb0ef41Sopenharmony_ci ERR_INVALID_ARG_VALUE, 301cb0ef41Sopenharmony_ci }, 311cb0ef41Sopenharmony_ci} = require('internal/errors'); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciconst { 341cb0ef41Sopenharmony_ci validateInt32, 351cb0ef41Sopenharmony_ci validateObject, 361cb0ef41Sopenharmony_ci validateString, 371cb0ef41Sopenharmony_ci} = require('internal/validators'); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciconst { 401cb0ef41Sopenharmony_ci isArrayBufferView, 411cb0ef41Sopenharmony_ci isAnyArrayBuffer, 421cb0ef41Sopenharmony_ci} = require('internal/util/types'); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ciconst { 451cb0ef41Sopenharmony_ci lazyDOMException, 461cb0ef41Sopenharmony_ci} = require('internal/util'); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciconst { 491cb0ef41Sopenharmony_ci KeyObject, 501cb0ef41Sopenharmony_ci} = require('internal/crypto/keys'); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ciconst { 531cb0ef41Sopenharmony_ci getArrayBufferOrView, 541cb0ef41Sopenharmony_ci getDefaultEncoding, 551cb0ef41Sopenharmony_ci jobPromise, 561cb0ef41Sopenharmony_ci toBuf, 571cb0ef41Sopenharmony_ci kHandle, 581cb0ef41Sopenharmony_ci kKeyObject, 591cb0ef41Sopenharmony_ci} = require('internal/crypto/util'); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ciconst { 621cb0ef41Sopenharmony_ci crypto: { 631cb0ef41Sopenharmony_ci POINT_CONVERSION_COMPRESSED, 641cb0ef41Sopenharmony_ci POINT_CONVERSION_HYBRID, 651cb0ef41Sopenharmony_ci POINT_CONVERSION_UNCOMPRESSED, 661cb0ef41Sopenharmony_ci }, 671cb0ef41Sopenharmony_ci} = internalBinding('constants'); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ciconst DH_GENERATOR = 2; 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_cifunction DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) { 721cb0ef41Sopenharmony_ci if (!(this instanceof DiffieHellman)) 731cb0ef41Sopenharmony_ci return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci if (typeof sizeOrKey !== 'number' && 761cb0ef41Sopenharmony_ci typeof sizeOrKey !== 'string' && 771cb0ef41Sopenharmony_ci !isArrayBufferView(sizeOrKey) && 781cb0ef41Sopenharmony_ci !isAnyArrayBuffer(sizeOrKey)) { 791cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 801cb0ef41Sopenharmony_ci 'sizeOrKey', 811cb0ef41Sopenharmony_ci ['number', 'string', 'ArrayBuffer', 'Buffer', 'TypedArray', 'DataView'], 821cb0ef41Sopenharmony_ci sizeOrKey, 831cb0ef41Sopenharmony_ci ); 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // Sizes < 0 don't make sense but they _are_ accepted (and subsequently 871cb0ef41Sopenharmony_ci // rejected with ERR_OSSL_BN_BITS_TOO_SMALL) by OpenSSL. The glue code 881cb0ef41Sopenharmony_ci // in node_crypto.cc accepts values that are IsInt32() for that reason 891cb0ef41Sopenharmony_ci // and that's why we do that here too. 901cb0ef41Sopenharmony_ci if (typeof sizeOrKey === 'number') 911cb0ef41Sopenharmony_ci validateInt32(sizeOrKey, 'sizeOrKey'); 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci if (keyEncoding && !Buffer.isEncoding(keyEncoding) && 941cb0ef41Sopenharmony_ci keyEncoding !== 'buffer') { 951cb0ef41Sopenharmony_ci genEncoding = generator; 961cb0ef41Sopenharmony_ci generator = keyEncoding; 971cb0ef41Sopenharmony_ci keyEncoding = false; 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci const encoding = getDefaultEncoding(); 1011cb0ef41Sopenharmony_ci keyEncoding = keyEncoding || encoding; 1021cb0ef41Sopenharmony_ci genEncoding = genEncoding || encoding; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci if (typeof sizeOrKey !== 'number') 1051cb0ef41Sopenharmony_ci sizeOrKey = toBuf(sizeOrKey, keyEncoding); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci if (!generator) { 1081cb0ef41Sopenharmony_ci generator = DH_GENERATOR; 1091cb0ef41Sopenharmony_ci } else if (typeof generator === 'number') { 1101cb0ef41Sopenharmony_ci validateInt32(generator, 'generator'); 1111cb0ef41Sopenharmony_ci } else if (typeof generator === 'string') { 1121cb0ef41Sopenharmony_ci generator = toBuf(generator, genEncoding); 1131cb0ef41Sopenharmony_ci } else if (!isArrayBufferView(generator) && !isAnyArrayBuffer(generator)) { 1141cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 1151cb0ef41Sopenharmony_ci 'generator', 1161cb0ef41Sopenharmony_ci ['number', 'string', 'ArrayBuffer', 'Buffer', 'TypedArray', 'DataView'], 1171cb0ef41Sopenharmony_ci generator, 1181cb0ef41Sopenharmony_ci ); 1191cb0ef41Sopenharmony_ci } 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci this[kHandle] = new _DiffieHellman(sizeOrKey, generator); 1231cb0ef41Sopenharmony_ci ObjectDefineProperty(this, 'verifyError', { 1241cb0ef41Sopenharmony_ci __proto__: null, 1251cb0ef41Sopenharmony_ci enumerable: true, 1261cb0ef41Sopenharmony_ci value: this[kHandle].verifyError, 1271cb0ef41Sopenharmony_ci writable: false, 1281cb0ef41Sopenharmony_ci }); 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_cifunction DiffieHellmanGroup(name) { 1331cb0ef41Sopenharmony_ci if (!(this instanceof DiffieHellmanGroup)) 1341cb0ef41Sopenharmony_ci return new DiffieHellmanGroup(name); 1351cb0ef41Sopenharmony_ci this[kHandle] = new _DiffieHellmanGroup(name); 1361cb0ef41Sopenharmony_ci ObjectDefineProperty(this, 'verifyError', { 1371cb0ef41Sopenharmony_ci __proto__: null, 1381cb0ef41Sopenharmony_ci enumerable: true, 1391cb0ef41Sopenharmony_ci value: this[kHandle].verifyError, 1401cb0ef41Sopenharmony_ci writable: false, 1411cb0ef41Sopenharmony_ci }); 1421cb0ef41Sopenharmony_ci} 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ciDiffieHellmanGroup.prototype.generateKeys = 1461cb0ef41Sopenharmony_ci DiffieHellman.prototype.generateKeys = 1471cb0ef41Sopenharmony_ci dhGenerateKeys; 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_cifunction dhGenerateKeys(encoding) { 1501cb0ef41Sopenharmony_ci const keys = this[kHandle].generateKeys(); 1511cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 1521cb0ef41Sopenharmony_ci return encode(keys, encoding); 1531cb0ef41Sopenharmony_ci} 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ciDiffieHellmanGroup.prototype.computeSecret = 1571cb0ef41Sopenharmony_ci DiffieHellman.prototype.computeSecret = 1581cb0ef41Sopenharmony_ci dhComputeSecret; 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_cifunction dhComputeSecret(key, inEnc, outEnc) { 1611cb0ef41Sopenharmony_ci const encoding = getDefaultEncoding(); 1621cb0ef41Sopenharmony_ci inEnc = inEnc || encoding; 1631cb0ef41Sopenharmony_ci outEnc = outEnc || encoding; 1641cb0ef41Sopenharmony_ci key = getArrayBufferOrView(key, 'key', inEnc); 1651cb0ef41Sopenharmony_ci const ret = this[kHandle].computeSecret(key); 1661cb0ef41Sopenharmony_ci if (typeof ret === 'string') 1671cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY(); 1681cb0ef41Sopenharmony_ci return encode(ret, outEnc); 1691cb0ef41Sopenharmony_ci} 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ciDiffieHellmanGroup.prototype.getPrime = 1731cb0ef41Sopenharmony_ci DiffieHellman.prototype.getPrime = 1741cb0ef41Sopenharmony_ci dhGetPrime; 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_cifunction dhGetPrime(encoding) { 1771cb0ef41Sopenharmony_ci const prime = this[kHandle].getPrime(); 1781cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 1791cb0ef41Sopenharmony_ci return encode(prime, encoding); 1801cb0ef41Sopenharmony_ci} 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ciDiffieHellmanGroup.prototype.getGenerator = 1841cb0ef41Sopenharmony_ci DiffieHellman.prototype.getGenerator = 1851cb0ef41Sopenharmony_ci dhGetGenerator; 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_cifunction dhGetGenerator(encoding) { 1881cb0ef41Sopenharmony_ci const generator = this[kHandle].getGenerator(); 1891cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 1901cb0ef41Sopenharmony_ci return encode(generator, encoding); 1911cb0ef41Sopenharmony_ci} 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ciDiffieHellmanGroup.prototype.getPublicKey = 1951cb0ef41Sopenharmony_ci DiffieHellman.prototype.getPublicKey = 1961cb0ef41Sopenharmony_ci dhGetPublicKey; 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_cifunction dhGetPublicKey(encoding) { 1991cb0ef41Sopenharmony_ci const key = this[kHandle].getPublicKey(); 2001cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 2011cb0ef41Sopenharmony_ci return encode(key, encoding); 2021cb0ef41Sopenharmony_ci} 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ciDiffieHellmanGroup.prototype.getPrivateKey = 2061cb0ef41Sopenharmony_ci DiffieHellman.prototype.getPrivateKey = 2071cb0ef41Sopenharmony_ci dhGetPrivateKey; 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_cifunction dhGetPrivateKey(encoding) { 2101cb0ef41Sopenharmony_ci const key = this[kHandle].getPrivateKey(); 2111cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 2121cb0ef41Sopenharmony_ci return encode(key, encoding); 2131cb0ef41Sopenharmony_ci} 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ciDiffieHellman.prototype.setPublicKey = function setPublicKey(key, encoding) { 2171cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 2181cb0ef41Sopenharmony_ci key = getArrayBufferOrView(key, 'key', encoding); 2191cb0ef41Sopenharmony_ci this[kHandle].setPublicKey(key); 2201cb0ef41Sopenharmony_ci return this; 2211cb0ef41Sopenharmony_ci}; 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ciDiffieHellman.prototype.setPrivateKey = function setPrivateKey(key, encoding) { 2251cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 2261cb0ef41Sopenharmony_ci key = getArrayBufferOrView(key, 'key', encoding); 2271cb0ef41Sopenharmony_ci this[kHandle].setPrivateKey(key); 2281cb0ef41Sopenharmony_ci return this; 2291cb0ef41Sopenharmony_ci}; 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_cifunction ECDH(curve) { 2331cb0ef41Sopenharmony_ci if (!(this instanceof ECDH)) 2341cb0ef41Sopenharmony_ci return new ECDH(curve); 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci validateString(curve, 'curve'); 2371cb0ef41Sopenharmony_ci this[kHandle] = new _ECDH(curve); 2381cb0ef41Sopenharmony_ci} 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ciECDH.prototype.computeSecret = DiffieHellman.prototype.computeSecret; 2411cb0ef41Sopenharmony_ciECDH.prototype.setPrivateKey = DiffieHellman.prototype.setPrivateKey; 2421cb0ef41Sopenharmony_ciECDH.prototype.setPublicKey = DiffieHellman.prototype.setPublicKey; 2431cb0ef41Sopenharmony_ciECDH.prototype.getPrivateKey = DiffieHellman.prototype.getPrivateKey; 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ciECDH.prototype.generateKeys = function generateKeys(encoding, format) { 2461cb0ef41Sopenharmony_ci this[kHandle].generateKeys(); 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci return this.getPublicKey(encoding, format); 2491cb0ef41Sopenharmony_ci}; 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ciECDH.prototype.getPublicKey = function getPublicKey(encoding, format) { 2521cb0ef41Sopenharmony_ci const f = getFormat(format); 2531cb0ef41Sopenharmony_ci const key = this[kHandle].getPublicKey(f); 2541cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 2551cb0ef41Sopenharmony_ci return encode(key, encoding); 2561cb0ef41Sopenharmony_ci}; 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ciECDH.convertKey = function convertKey(key, curve, inEnc, outEnc, format) { 2591cb0ef41Sopenharmony_ci validateString(curve, 'curve'); 2601cb0ef41Sopenharmony_ci const encoding = inEnc || getDefaultEncoding(); 2611cb0ef41Sopenharmony_ci key = getArrayBufferOrView(key, 'key', encoding); 2621cb0ef41Sopenharmony_ci outEnc = outEnc || encoding; 2631cb0ef41Sopenharmony_ci const f = getFormat(format); 2641cb0ef41Sopenharmony_ci const convertedKey = _ECDHConvertKey(key, curve, f); 2651cb0ef41Sopenharmony_ci return encode(convertedKey, outEnc); 2661cb0ef41Sopenharmony_ci}; 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_cifunction encode(buffer, encoding) { 2691cb0ef41Sopenharmony_ci if (encoding && encoding !== 'buffer') 2701cb0ef41Sopenharmony_ci buffer = buffer.toString(encoding); 2711cb0ef41Sopenharmony_ci return buffer; 2721cb0ef41Sopenharmony_ci} 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_cifunction getFormat(format) { 2751cb0ef41Sopenharmony_ci if (format) { 2761cb0ef41Sopenharmony_ci if (format === 'compressed') 2771cb0ef41Sopenharmony_ci return POINT_CONVERSION_COMPRESSED; 2781cb0ef41Sopenharmony_ci if (format === 'hybrid') 2791cb0ef41Sopenharmony_ci return POINT_CONVERSION_HYBRID; 2801cb0ef41Sopenharmony_ci if (format !== 'uncompressed') 2811cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_ECDH_INVALID_FORMAT(format); 2821cb0ef41Sopenharmony_ci } 2831cb0ef41Sopenharmony_ci return POINT_CONVERSION_UNCOMPRESSED; 2841cb0ef41Sopenharmony_ci} 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ciconst dhEnabledKeyTypes = new SafeSet(['dh', 'ec', 'x448', 'x25519']); 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_cifunction diffieHellman(options) { 2891cb0ef41Sopenharmony_ci validateObject(options, 'options'); 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ci const { privateKey, publicKey } = options; 2921cb0ef41Sopenharmony_ci if (!(privateKey instanceof KeyObject)) 2931cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('options.privateKey', privateKey); 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci if (!(publicKey instanceof KeyObject)) 2961cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('options.publicKey', publicKey); 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci if (privateKey.type !== 'private') 2991cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(privateKey.type, 'private'); 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ci if (publicKey.type !== 'public' && publicKey.type !== 'private') { 3021cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(publicKey.type, 3031cb0ef41Sopenharmony_ci 'private or public'); 3041cb0ef41Sopenharmony_ci } 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci const privateType = privateKey.asymmetricKeyType; 3071cb0ef41Sopenharmony_ci const publicType = publicKey.asymmetricKeyType; 3081cb0ef41Sopenharmony_ci if (privateType !== publicType || !dhEnabledKeyTypes.has(privateType)) { 3091cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INCOMPATIBLE_KEY('key types for Diffie-Hellman', 3101cb0ef41Sopenharmony_ci `${privateType} and ${publicType}`); 3111cb0ef41Sopenharmony_ci } 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci return statelessDH(privateKey[kHandle], publicKey[kHandle]); 3141cb0ef41Sopenharmony_ci} 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ci// The ecdhDeriveBits function is part of the Web Crypto API and serves both 3171cb0ef41Sopenharmony_ci// deriveKeys and deriveBits functions. 3181cb0ef41Sopenharmony_ciasync function ecdhDeriveBits(algorithm, baseKey, length) { 3191cb0ef41Sopenharmony_ci const { 'public': key } = algorithm; 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci if (key.type !== 'public') { 3221cb0ef41Sopenharmony_ci throw lazyDOMException( 3231cb0ef41Sopenharmony_ci 'algorithm.public must be a public key', 'InvalidAccessError'); 3241cb0ef41Sopenharmony_ci } 3251cb0ef41Sopenharmony_ci if (baseKey.type !== 'private') { 3261cb0ef41Sopenharmony_ci throw lazyDOMException( 3271cb0ef41Sopenharmony_ci 'baseKey must be a private key', 'InvalidAccessError'); 3281cb0ef41Sopenharmony_ci } 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_ci if ( 3311cb0ef41Sopenharmony_ci key.algorithm.name !== 'ECDH' && 3321cb0ef41Sopenharmony_ci key.algorithm.name !== 'X25519' && 3331cb0ef41Sopenharmony_ci key.algorithm.name !== 'X448' 3341cb0ef41Sopenharmony_ci ) { 3351cb0ef41Sopenharmony_ci throw lazyDOMException('Keys must be ECDH, X25519, or X448 keys', 'InvalidAccessError'); 3361cb0ef41Sopenharmony_ci } 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci if (key.algorithm.name !== baseKey.algorithm.name) { 3391cb0ef41Sopenharmony_ci throw lazyDOMException( 3401cb0ef41Sopenharmony_ci 'The public and private keys must be of the same type', 3411cb0ef41Sopenharmony_ci 'InvalidAccessError'); 3421cb0ef41Sopenharmony_ci } 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_ci if ( 3451cb0ef41Sopenharmony_ci key.algorithm.name === 'ECDH' && 3461cb0ef41Sopenharmony_ci key.algorithm.namedCurve !== baseKey.algorithm.namedCurve 3471cb0ef41Sopenharmony_ci ) { 3481cb0ef41Sopenharmony_ci throw lazyDOMException('Named curve mismatch', 'InvalidAccessError'); 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci 3511cb0ef41Sopenharmony_ci const bits = await jobPromise(() => new ECDHBitsJob( 3521cb0ef41Sopenharmony_ci kCryptoJobAsync, 3531cb0ef41Sopenharmony_ci key.algorithm.name === 'ECDH' ? baseKey.algorithm.namedCurve : baseKey.algorithm.name, 3541cb0ef41Sopenharmony_ci key[kKeyObject][kHandle], 3551cb0ef41Sopenharmony_ci baseKey[kKeyObject][kHandle])); 3561cb0ef41Sopenharmony_ci 3571cb0ef41Sopenharmony_ci // If a length is not specified, return the full derived secret 3581cb0ef41Sopenharmony_ci if (length === null) 3591cb0ef41Sopenharmony_ci return bits; 3601cb0ef41Sopenharmony_ci 3611cb0ef41Sopenharmony_ci // If the length is not a multiple of 8 the nearest ceiled 3621cb0ef41Sopenharmony_ci // multiple of 8 is sliced. 3631cb0ef41Sopenharmony_ci length = MathCeil(length / 8); 3641cb0ef41Sopenharmony_ci const { byteLength } = bits; 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ci // If the length is larger than the derived secret, throw. 3671cb0ef41Sopenharmony_ci // Otherwise, we either return the secret or a truncated 3681cb0ef41Sopenharmony_ci // slice. 3691cb0ef41Sopenharmony_ci if (byteLength < length) 3701cb0ef41Sopenharmony_ci throw lazyDOMException('derived bit length is too small', 'OperationError'); 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci return length === byteLength ? 3731cb0ef41Sopenharmony_ci bits : 3741cb0ef41Sopenharmony_ci ArrayBufferPrototypeSlice(bits, 0, length); 3751cb0ef41Sopenharmony_ci} 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_cimodule.exports = { 3781cb0ef41Sopenharmony_ci DiffieHellman, 3791cb0ef41Sopenharmony_ci DiffieHellmanGroup, 3801cb0ef41Sopenharmony_ci ECDH, 3811cb0ef41Sopenharmony_ci diffieHellman, 3821cb0ef41Sopenharmony_ci ecdhDeriveBits, 3831cb0ef41Sopenharmony_ci}; 384