Skip to content

Commit 9568492

Browse files
committed
crypto: limit KangarooTwelveParams customization to 512 bytes
To align with a futute OpenSSL-imposed limit. Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent a27fe21 commit 9568492

6 files changed

Lines changed: 38 additions & 9 deletions

File tree

doc/api/webcrypto.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2383,11 +2383,16 @@ added:
23832383
added:
23842384
- v25.9.0
23852385
- v24.18.0
2386+
changes:
2387+
- version: REPLACEME
2388+
pr-url: https://github.com/nodejs/node/pull/00000
2389+
description: Limit customization to 512 bytes.
23862390
-->
23872391
23882392
* Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined}
23892393
2390-
The optional customization string for KangarooTwelve.
2394+
The optional customization string for KangarooTwelve. It must not exceed 512
2395+
bytes.
23912396
23922397
#### `kangarooTwelveParams.name`
23932398

lib/internal/crypto/webidl.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,6 @@ function validateCShakeFunctionName(V) {
272272
'NotSupportedError');
273273
}
274274

275-
function validateCShakeCustomization(V) {
276-
validateMaxBufferLength(V, 'CShakeParams.customization', 512);
277-
}
278-
279275
converters.RsaPssParams = createDictionaryConverter(
280276
'RsaPssParams', [
281277
dictAlgorithm,
@@ -428,7 +424,7 @@ converters.CShakeParams = createDictionaryConverter(
428424
{
429425
key: 'customization',
430426
converter: converters.BufferSource,
431-
validator: validateCShakeCustomization,
427+
validator: (V, opts) => validateMaxBufferLength(V, 'CShakeParams.customization', 512),
432428
},
433429
],
434430
]);
@@ -750,6 +746,7 @@ converters.KangarooTwelveParams = createDictionaryConverter(
750746
{
751747
key: 'customization',
752748
converter: converters.BufferSource,
749+
validator: (V, opts) => validateMaxBufferLength(V, 'KangarooTwelveParams.customization', 512),
753750
},
754751
],
755752
]);

test/fixtures/webcrypto/supports-modern-algorithms.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,15 @@ export const vectors = {
4848
[false, 'KT128'],
4949
[true, { name: 'KT128', outputLength: 128 }],
5050
[true, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(0) }],
51+
[true, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(512) }],
52+
[false, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(513) }],
5153
[false, { name: 'KT128', outputLength: 0 }],
5254
[false, { name: 'KT128', outputLength: 127 }],
5355
[false, 'KT256'],
5456
[true, { name: 'KT256', outputLength: 256 }],
5557
[true, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(0) }],
58+
[true, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(512) }],
59+
[false, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(513) }],
5660
[false, { name: 'KT256', outputLength: 0 }],
5761
[false, { name: 'KT256', outputLength: 255 }],
5862
],

test/parallel/test-webcrypto-digest-turboshake-rfc.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,15 @@ async function checkDigest(name, vectors) {
326326
else
327327
algorithm.domainSeparation = rest[0];
328328
}
329+
330+
if (isKT && algorithm.customization?.byteLength > 512) {
331+
await assert.rejects(subtle.digest(algorithm, input), {
332+
name: 'OperationError',
333+
message: 'KangarooTwelveParams.customization must be at most 512 bytes',
334+
});
335+
continue;
336+
}
337+
329338
const result = await subtle.digest(algorithm, input);
330339
assert.deepStrictEqual(
331340
Buffer.from(result).toString('hex'),

test/parallel/test-webcrypto-digest-turboshake.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,22 @@ async function testDigest(size, alg) {
155155

156156
// KT128 with customization string
157157
(async () => {
158-
const digest = await subtle.digest(
159-
{ name: 'KT128', outputLength: 256, customization: Buffer.from('test') },
160-
Buffer.from('hello'));
158+
const digest = await subtle.digest({
159+
name: 'KT128',
160+
outputLength: 256,
161+
customization: Buffer.alloc(512),
162+
}, Buffer.from('hello'));
161163
assert(digest instanceof ArrayBuffer);
162164
assert.strictEqual(digest.byteLength, 32);
165+
166+
await assert.rejects(subtle.digest({
167+
name: 'KT128',
168+
outputLength: 256,
169+
customization: Buffer.alloc(513),
170+
}, Buffer.from('hello')), {
171+
name: 'OperationError',
172+
message: 'KangarooTwelveParams.customization must be at most 512 bytes',
173+
});
163174
})().then(common.mustCall());
164175

165176
// TurboSHAKE domain separation out of range

test/wpt/status/WebCryptoAPI.cjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ if (process.features.openssl_is_boringssl) {
9191
['supports-modern.tentative.https.any.js', /ml-kem-512/i]);
9292
}
9393

94+
skipSubtests(
95+
['digest/kangarootwelve.tentative.https.any.js', /C=(?:\d{4,}|5(?:1[3-9]|[2-9]\d)|[6-9]\d{2}) bytes/]);
96+
9497
function assertNoOverlap(fileSkips, subtestSkips) {
9598
const subtestSkipFiles = new Set(Object.keys(subtestSkips));
9699
const overlap = Object.keys(fileSkips).filter((file) => subtestSkipFiles.has(file));

0 commit comments

Comments
 (0)