Skip to content

Commit

Permalink
crypto: make deriveBits length parameter optional and nullable
Browse files Browse the repository at this point in the history
PR-URL: #53601
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
  • Loading branch information
panva authored and aduh95 committed Nov 2, 2024
1 parent d6114cb commit 5c46782
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
20 changes: 12 additions & 8 deletions doc/api/webcrypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -552,11 +552,15 @@ The algorithms currently supported include:
* `'AES-CBC'`
* `'AES-GCM`'

### `subtle.deriveBits(algorithm, baseKey, length)`
### `subtle.deriveBits(algorithm, baseKey[, length])`

<!-- YAML
added: v15.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/53601
description: The length parameter is now optional for `'ECDH'`, `'X25519'`,
and `'X448'`.
- version: v18.4.0
pr-url: https://github.com/nodejs/node/pull/42507
description: Added `'X25519'`, and `'X448'` algorithms.
Expand All @@ -566,21 +570,21 @@ changes:

* `algorithm`: {AlgorithmIdentifier|EcdhKeyDeriveParams|HkdfParams|Pbkdf2Params}
* `baseKey`: {CryptoKey}
* `length`: {number|null}
* Returns: {Promise} containing {ArrayBuffer}
* `length`: {number|null} **Default:** `null`
* Returns: {Promise} Fulfills with an {ArrayBuffer}

<!--lint enable maximum-line-length remark-lint-->

Using the method and parameters specified in `algorithm` and the keying
material provided by `baseKey`, `subtle.deriveBits()` attempts to generate
`length` bits.

The Node.js implementation requires that when `length` is a
number it must be multiple of `8`.
The Node.js implementation requires that `length`, when a number, is a multiple
of `8`.

When `length` is `null` the maximum number of bits for a given algorithm is
generated. This is allowed for the `'ECDH'`, `'X25519'`, and `'X448'`
algorithms.
When `length` is not provided or `null` the maximum number of bits for a given
algorithm is generated. This is allowed for the `'ECDH'`, `'X25519'`, and `'X448'`
algorithms, for other algorithms `length` is required to be a number.

If successful, the returned promise will be resolved with an {ArrayBuffer}
containing the generated data.
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/crypto/webcrypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,12 @@ async function generateKey(
return result;
}

async function deriveBits(algorithm, baseKey, length) {
async function deriveBits(algorithm, baseKey, length = null) {
if (this !== subtle) throw new ERR_INVALID_THIS('SubtleCrypto');

webidl ??= require('internal/crypto/webidl');
const prefix = "Failed to execute 'deriveBits' on 'SubtleCrypto'";
webidl.requiredArguments(arguments.length, 3, { prefix });
webidl.requiredArguments(arguments.length, 2, { prefix });
algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
prefix,
context: '1st argument',
Expand Down
10 changes: 10 additions & 0 deletions test/parallel/test-webcrypto-derivebits-cfrg.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ async function prepareKeys() {
assert.strictEqual(Buffer.from(bits).toString('hex'), result);
}

{
// Default length
const bits = await subtle.deriveBits({
name,
public: publicKey
}, privateKey);

assert.strictEqual(Buffer.from(bits).toString('hex'), result);
}

{
// Short Result
const bits = await subtle.deriveBits({
Expand Down
10 changes: 10 additions & 0 deletions test/parallel/test-webcrypto-derivebits-ecdh.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ async function prepareKeys() {
assert.strictEqual(Buffer.from(bits).toString('hex'), result);
}

{
// Default length
const bits = await subtle.deriveBits({
name: 'ECDH',
public: publicKey
}, privateKey);

assert.strictEqual(Buffer.from(bits).toString('hex'), result);
}

{
// Short Result
const bits = await subtle.deriveBits({
Expand Down
5 changes: 5 additions & 0 deletions test/parallel/test-webcrypto-derivebits-hkdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ async function testDeriveBitsBadLengths(
message: 'length cannot be null',
name: 'OperationError',
}),
assert.rejects(
subtle.deriveBits(algorithm, baseKeys[size]), {
message: 'length cannot be null',
name: 'OperationError',
}),
assert.rejects(
subtle.deriveBits(algorithm, baseKeys[size], 15), {
message: /length must be a multiple of 8/,
Expand Down
5 changes: 5 additions & 0 deletions test/pummel/test-webcrypto-derivebits-pbkdf2.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,11 @@ async function testDeriveBitsBadLengths(
message: 'length cannot be null',
name: 'OperationError',
}),
assert.rejects(
subtle.deriveBits(algorithm, baseKeys[size]), {
message: 'length cannot be null',
name: 'OperationError',
}),
assert.rejects(
subtle.deriveBits(algorithm, baseKeys[size], 15), {
message: /length must be a multiple of 8/,
Expand Down

0 comments on commit 5c46782

Please sign in to comment.