diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 59e876d4f19185..5597132f9b2f04 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -2383,11 +2383,16 @@ added: added: - v25.9.0 - v24.18.0 +changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/64557 + description: Limit customization to 512 bytes. --> * Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined} -The optional customization string for KangarooTwelve. +The optional customization string for KangarooTwelve. It must not exceed 512 +bytes. #### `kangarooTwelveParams.name` diff --git a/lib/internal/crypto/webidl.js b/lib/internal/crypto/webidl.js index c886a4a2280ad2..d0d6036a1ab3ce 100644 --- a/lib/internal/crypto/webidl.js +++ b/lib/internal/crypto/webidl.js @@ -272,10 +272,6 @@ function validateCShakeFunctionName(V) { 'NotSupportedError'); } -function validateCShakeCustomization(V) { - validateMaxBufferLength(V, 'CShakeParams.customization', 512); -} - converters.RsaPssParams = createDictionaryConverter( 'RsaPssParams', [ dictAlgorithm, @@ -428,7 +424,7 @@ converters.CShakeParams = createDictionaryConverter( { key: 'customization', converter: converters.BufferSource, - validator: validateCShakeCustomization, + validator: (V, opts) => validateMaxBufferLength(V, 'CShakeParams.customization', 512), }, ], ]); @@ -750,6 +746,7 @@ converters.KangarooTwelveParams = createDictionaryConverter( { key: 'customization', converter: converters.BufferSource, + validator: (V, opts) => validateMaxBufferLength(V, 'KangarooTwelveParams.customization', 512), }, ], ]); diff --git a/test/fixtures/webcrypto/supports-modern-algorithms.mjs b/test/fixtures/webcrypto/supports-modern-algorithms.mjs index a3e5fc54976483..acb0e249dd3886 100644 --- a/test/fixtures/webcrypto/supports-modern-algorithms.mjs +++ b/test/fixtures/webcrypto/supports-modern-algorithms.mjs @@ -48,11 +48,15 @@ export const vectors = { [false, 'KT128'], [true, { name: 'KT128', outputLength: 128 }], [true, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(0) }], + [true, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(512) }], + [false, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(513) }], [false, { name: 'KT128', outputLength: 0 }], [false, { name: 'KT128', outputLength: 127 }], [false, 'KT256'], [true, { name: 'KT256', outputLength: 256 }], [true, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(0) }], + [true, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(512) }], + [false, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(513) }], [false, { name: 'KT256', outputLength: 0 }], [false, { name: 'KT256', outputLength: 255 }], ], diff --git a/test/parallel/test-webcrypto-digest-turboshake-rfc.js b/test/parallel/test-webcrypto-digest-turboshake-rfc.js index 43762fecc2c41e..271fde76ab23ef 100644 --- a/test/parallel/test-webcrypto-digest-turboshake-rfc.js +++ b/test/parallel/test-webcrypto-digest-turboshake-rfc.js @@ -326,6 +326,15 @@ async function checkDigest(name, vectors) { else algorithm.domainSeparation = rest[0]; } + + if (isKT && algorithm.customization?.byteLength > 512) { + await assert.rejects(subtle.digest(algorithm, input), { + name: 'OperationError', + message: 'KangarooTwelveParams.customization must be at most 512 bytes', + }); + continue; + } + const result = await subtle.digest(algorithm, input); assert.deepStrictEqual( Buffer.from(result).toString('hex'), diff --git a/test/parallel/test-webcrypto-digest-turboshake.js b/test/parallel/test-webcrypto-digest-turboshake.js index 0b5586b19286be..a6f4b2d50f948f 100644 --- a/test/parallel/test-webcrypto-digest-turboshake.js +++ b/test/parallel/test-webcrypto-digest-turboshake.js @@ -155,11 +155,22 @@ async function testDigest(size, alg) { // KT128 with customization string (async () => { - const digest = await subtle.digest( - { name: 'KT128', outputLength: 256, customization: Buffer.from('test') }, - Buffer.from('hello')); + const digest = await subtle.digest({ + name: 'KT128', + outputLength: 256, + customization: Buffer.alloc(512), + }, Buffer.from('hello')); assert(digest instanceof ArrayBuffer); assert.strictEqual(digest.byteLength, 32); + + await assert.rejects(subtle.digest({ + name: 'KT128', + outputLength: 256, + customization: Buffer.alloc(513), + }, Buffer.from('hello')), { + name: 'OperationError', + message: 'KangarooTwelveParams.customization must be at most 512 bytes', + }); })().then(common.mustCall()); // TurboSHAKE domain separation out of range diff --git a/test/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index 4572f7e1dbcb94..8ec27109eeca41 100644 --- a/test/wpt/status/WebCryptoAPI.cjs +++ b/test/wpt/status/WebCryptoAPI.cjs @@ -91,6 +91,9 @@ if (process.features.openssl_is_boringssl) { ['supports-modern.tentative.https.any.js', /ml-kem-512/i]); } +skipSubtests( + ['digest/kangarootwelve.tentative.https.any.js', /C=(?:\d{4,}|5(?:1[3-9]|[2-9]\d)|[6-9]\d{2}) bytes/]); + function assertNoOverlap(fileSkips, subtestSkips) { const subtestSkipFiles = new Set(Object.keys(subtestSkips)); const overlap = Object.keys(fileSkips).filter((file) => subtestSkipFiles.has(file));