|
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