/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
lib/internal/crypto/hkdf.js
175 строк
3 KB
Filip Skokan
crypto: coerce -0 to +0 before native calls
31 май 2026, 17:25
31 май 2026, 17:25
9b7e761
Код
Авторство
О чём код?
'use strict'; const { ArrayBuffer, FunctionPrototypeCall, PromiseResolve, } = primordials; const { HKDFJob, kCryptoJobAsync, kCryptoJobSync, kCryptoJobWebCrypto, } = internalBinding('crypto'); const { validateFunction, validateInteger, validateString, } = require('internal/validators'); const { kMaxLength } = require('buffer'); const { jobPromise, normalizeHashName, toBuf, validateByteSource, } = require('internal/crypto/util'); const { getCryptoKeyHandle, isKeyObject, prepareSecretKey, } = require('internal/crypto/keys'); const { lazyDOMException, } = require('internal/util'); const { isAnyArrayBuffer, isArrayBufferView, } = require('internal/util/types'); const { codes: { ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE, }, hideStackFrames, } = require('internal/errors'); const validateParameters = hideStackFrames((hash, key, salt, info, length) => { validateString.withoutStackTrace(hash, 'digest'); key = prepareKey(key); salt = validateByteSource.withoutStackTrace(salt, 'salt'); info = validateByteSource.withoutStackTrace(info, 'info'); validateInteger.withoutStackTrace(length, 'length', 0, kMaxLength); // Coerce -0 to +0. length += 0; if (info.byteLength > 1024) { throw new ERR_OUT_OF_RANGE.HideStackFramesError( 'info', 'must not contain more than 1024 bytes', info.byteLength); } return { hash, key, salt, info, length, }; }); function prepareKey(key) { if (isKeyObject(key)) return prepareSecretKey(key); if (isAnyArrayBuffer(key)) return key; key = toBuf(key); if (!isArrayBufferView(key)) { throw new ERR_INVALID_ARG_TYPE( 'ikm', [ 'string', 'SecretKeyObject', 'ArrayBuffer', 'TypedArray', 'DataView', 'Buffer', ], key); } return 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; } function validateHkdfDeriveBitsLength(length) { if (length === null) throw lazyDOMException('length cannot be null', 'OperationError'); if (length % 8) { throw lazyDOMException( 'length must be a multiple of 8', 'OperationError'); } } function hkdfDeriveBits(algorithm, baseKey, length) { validateHkdfDeriveBitsLength(length); const { hash, salt, info } = algorithm; if (length === 0) return PromiseResolve(new ArrayBuffer(0)); return jobPromise(() => new HKDFJob( kCryptoJobWebCrypto, normalizeHashName(hash.name), getCryptoKeyHandle(baseKey), salt, info, length / 8)); } module.exports = { hkdf, hkdfSync, hkdfDeriveBits, validateHkdfDeriveBitsLength, };