return createSecretKey(key); } function hkdf(hash, key, salt, info, length, callback) { ({ hash, key, salt, info, length, } = validateParameters(hash, key, salt, info, length)); validateFunction(callback, 'callback'); const job = new HKDFJob(kCryptoJobAsync, hash, key, salt, info, length); job.ondone = (error, bits) => { if (error) return FunctionPrototypeCall(callback, job, error); FunctionPrototypeCall(callback, job, null, bits); }; job.run(); } function hkdfSync(hash, key, salt, info, length) { ({ hash, key, salt, info, length, } = validateParameters(hash, key, salt, info, length)); const job = new HKDFJob(kCryptoJobSync, hash, key, salt, info, length); const { 0: err, 1: bits } = job.run(); if (err !== undefined) throw err; return bits; } const hkdfPromise = promisify(hkdf); async function hkdfDeriveBits(algorithm, baseKey, length) { const { hash, salt, info } = algorithm; if (length === 0) return new ArrayBuffer(0); if (length === null) throw lazyDOMException('length cannot be null', 'OperationError'); if (length % 8) { throw lazyDOMException( 'length must be a multiple of 8', 'OperationError'); } try { return await hkdfPromise( normalizeHashName(hash.name), baseKey[kKeyObject], salt, info, length / 8, ); } catch (err) { throw lazyDOMException( 'The operation failed for an operation-specific reason', { name: 'OperationError', cause: err }); } } module.exports = { hkdf, hkdfSync, hkdfDeriveBits, };