|
5 | 5 | MathCeil, |
6 | 6 | ObjectDefineProperty, |
7 | 7 | SafeSet, |
| 8 | + Uint8Array, |
8 | 9 | } = primordials; |
9 | 10 |
|
10 | 11 | const { Buffer } = require('buffer'); |
@@ -295,6 +296,8 @@ function diffieHellman(options) { |
295 | 296 | return statelessDH(privateKey[kHandle], publicKey[kHandle]); |
296 | 297 | } |
297 | 298 |
|
| 299 | +let masks; |
| 300 | + |
298 | 301 | // The ecdhDeriveBits function is part of the Web Crypto API and serves both |
299 | 302 | // deriveKeys and deriveBits functions. |
300 | 303 | async function ecdhDeriveBits(algorithm, baseKey, length) { |
@@ -341,18 +344,25 @@ async function ecdhDeriveBits(algorithm, baseKey, length) { |
341 | 344 |
|
342 | 345 | // If the length is not a multiple of 8 the nearest ceiled |
343 | 346 | // multiple of 8 is sliced. |
344 | | - length = MathCeil(length / 8); |
345 | | - const { byteLength } = bits; |
| 347 | + const sliceLength = MathCeil(length / 8); |
346 | 348 |
|
| 349 | + const { byteLength } = bits; |
347 | 350 | // If the length is larger than the derived secret, throw. |
348 | | - // Otherwise, we either return the secret or a truncated |
349 | | - // slice. |
350 | | - if (byteLength < length) |
| 351 | + if (byteLength < sliceLength) |
351 | 352 | throw lazyDOMException('derived bit length is too small', 'OperationError'); |
352 | 353 |
|
353 | | - return length === byteLength ? |
354 | | - bits : |
355 | | - ArrayBufferPrototypeSlice(bits, 0, length); |
| 354 | + const slice = ArrayBufferPrototypeSlice(bits, 0, sliceLength); |
| 355 | + |
| 356 | + const mod = length % 8; |
| 357 | + if (mod === 0) |
| 358 | + return slice; |
| 359 | + |
| 360 | + // eslint-disable-next-line no-sparse-arrays |
| 361 | + masks ||= [, 0b10000000, 0b11000000, 0b11100000, 0b11110000, 0b11111000, 0b11111100, 0b11111110]; |
| 362 | + |
| 363 | + const masked = new Uint8Array(slice); |
| 364 | + masked[sliceLength - 1] = masked[sliceLength - 1] & masks[mod]; |
| 365 | + return masked.buffer; |
356 | 366 | } |
357 | 367 |
|
358 | 368 | module.exports = { |
|
0 commit comments