| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -598,9 +598,6 @@ Using the method and parameters specified in `algorithm` and the keying | |||
| 598 | 598 | material provided by `baseKey`, `subtle.deriveBits()` attempts to generate | |
| 599 | 599 | `length` bits. | |
| 600 | 600 | ||
| 601 | - The Node.js implementation requires that `length`, when a number, is a multiple | ||
| 602 | - of `8`. | ||
| 603 | - | ||
| 604 | 601 | When `length` is not provided or `null` the maximum number of bits for a given | |
| 605 | 602 | algorithm is generated. This is allowed for the `'ECDH'`, `'X25519'`, and `'X448'` | |
| 606 | 603 | algorithms, for other algorithms `length` is required to be a number. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,6 +5,7 @@ const { | |||
| 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 = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -140,9 +140,11 @@ async function prepareKeys() { | |||
| 140 | 140 | public: publicKey | |
| 141 | 141 | }, privateKey, 8 * size - 11); | |
| 142 | 142 | ||
| 143 | - assert.strictEqual( | ||
| 144 | - Buffer.from(bits).toString('hex'), | ||
| 145 | - result.slice(0, -2)); | ||
| 143 | + const expected = Buffer.from(result.slice(0, -2), 'hex'); | ||
| 144 | + expected[size - 2] = expected[size - 2] & 0b11111000; | ||
| 145 | + assert.deepStrictEqual( | ||
| 146 | + Buffer.from(bits), | ||
| 147 | + expected); | ||
| 146 | 148 | } | |
| 147 | 149 | })); | |
| 148 | 150 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -161,9 +161,11 @@ async function prepareKeys() { | |||
| 161 | 161 | public: publicKey | |
| 162 | 162 | }, privateKey, 8 * size - 11); | |
| 163 | 163 | ||
| 164 | - assert.strictEqual( | ||
| 165 | - Buffer.from(bits).toString('hex'), | ||
| 166 | - result.slice(0, -2)); | ||
| 164 | + const expected = Buffer.from(result.slice(0, -2), 'hex'); | ||
| 165 | + expected[size - 2] = expected[size - 2] & 0b11111000; | ||
| 166 | + assert.deepStrictEqual( | ||
| 167 | + Buffer.from(bits), | ||
| 168 | + expected); | ||
| 167 | 169 | } | |
| 168 | 170 | })); | |
| 169 | 171 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,16 +8,6 @@ module.exports = { | |||
| 8 | 8 | 'algorithm-discards-context.https.window.js': { | |
| 9 | 9 | 'skip': 'Not relevant in Node.js context', | |
| 10 | 10 | }, | |
| 11 | - 'derive_bits_keys/derived_bits_length.https.any.js': { | ||
| 12 | - 'fail': { | ||
| 13 | - // See https://github.com/nodejs/node/pull/55296 | ||
| 14 | - // The fix is pending a decision whether truncation in ECDH/X* will be removed from the spec entirely | ||
| 15 | - 'expected': [ | ||
| 16 | - "ECDH derivation with 230 as 'length' parameter", | ||
| 17 | - "X25519 derivation with 230 as 'length' parameter", | ||
| 18 | - ], | ||
| 19 | - }, | ||
| 20 | - }, | ||
| 21 | 11 | 'historical.any.js': { | |
| 22 | 12 | 'skip': 'Not relevant in Node.js context', | |
| 23 | 13 | }, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments