| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f4fbcca commit 247d017
12 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,9 @@ | |||
| 2 | 2 | ||
| 3 | 3 | <!-- YAML | |
| 4 | 4 | changes: | |
| 5 | + - version: REPLACEME | ||
| 6 | + pr-url: https://github.com/nodejs/node/pull/59365 | ||
| 7 | + description: SHAKE algorithms are now supported. | ||
| 5 | 8 | - version: REPLACEME | |
| 6 | 9 | pr-url: https://github.com/nodejs/node/pull/59365 | |
| 7 | 10 | description: ML-DSA algorithms are now supported. | |
@@ -91,6 +94,8 @@ WICG proposal: | |||
| 91 | 94 | ||
| 92 | 95 | Algorithms: | |
| 93 | 96 | ||
| 97 | + * `'cSHAKE128'` | ||
| 98 | + * `'cSHAKE256'` | ||
| 94 | 99 | * `'ML-DSA-44'`[^openssl35] | |
| 95 | 100 | * `'ML-DSA-65'`[^openssl35] | |
| 96 | 101 | * `'ML-DSA-87'`[^openssl35] | |
@@ -472,6 +477,8 @@ implementation and the APIs supported for each: | |||
| 472 | 477 | | `'AES-CTR'` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | | | | | | |
| 473 | 478 | | `'AES-GCM'` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | | | | | | |
| 474 | 479 | | `'AES-KW'` | ✔ | ✔ | ✔ | | | ✔ | ✔ | | | | | | | |
| 480 | + | `'cSHAKE128'`[^modern-algos] | | | | | | | | | | | | ✔ | | ||
| 481 | + | `'cSHAKE256'`[^modern-algos] | | | | | | | | | | | | ✔ | | ||
| 475 | 482 | | `'ECDH'` | ✔ | ✔ | ✔ | | | | | ✔ | ✔ | | | | | |
| 476 | 483 | | `'ECDSA'` | ✔ | ✔ | ✔ | | | | | | | ✔ | ✔ | | | |
| 477 | 484 | | `'Ed25519'` | ✔ | ✔ | ✔ | | | | | | | ✔ | ✔ | | | |
@@ -800,9 +807,13 @@ The algorithms currently supported include: | |||
| 800 | 807 | ||
| 801 | 808 | <!-- YAML | |
| 802 | 809 | added: v15.0.0 | |
| 810 | + changes: | ||
| 811 | + - version: REPLACEME | ||
| 812 | + pr-url: https://github.com/nodejs/node/pull/59365 | ||
| 813 | + description: SHAKE algorithms are now supported. | ||
| 803 | 814 | --> | |
| 804 | 815 | ||
| 805 | - * `algorithm` {string|Algorithm} | ||
| 816 | + * `algorithm` {string|Algorithm|CShakeParams} | ||
| 806 | 817 | * `data` {ArrayBuffer|TypedArray|DataView|Buffer} | |
| 807 | 818 | * Returns: {Promise} Fulfills with an {ArrayBuffer} upon success. | |
| 808 | 819 | ||
@@ -812,6 +823,8 @@ with an {ArrayBuffer} containing the computed digest. | |||
| 812 | 823 | ||
| 813 | 824 | If `algorithm` is provided as a {string}, it must be one of: | |
| 814 | 825 | ||
| 826 | + * `'cSHAKE128'`[^modern-algos] | ||
| 827 | + * `'cSHAKE256'`[^modern-algos] | ||
| 815 | 828 | * `'SHA-1'` | |
| 816 | 829 | * `'SHA-256'` | |
| 817 | 830 | * `'SHA-384'` | |
@@ -1423,6 +1436,53 @@ the message. | |||
| 1423 | 1436 | The Node.js Web Crypto API implementation only supports zero-length context | |
| 1424 | 1437 | which is equivalent to not providing context at all. | |
| 1425 | 1438 | ||
| 1439 | + ### Class: `CShakeParams` | ||
| 1440 | + | ||
| 1441 | + <!-- YAML | ||
| 1442 | + added: REPLACEME | ||
| 1443 | + --> | ||
| 1444 | + | ||
| 1445 | + #### `cShakeParams.customization` | ||
| 1446 | + | ||
| 1447 | + <!-- YAML | ||
| 1448 | + added: REPLACEME | ||
| 1449 | + --> | ||
| 1450 | + | ||
| 1451 | + * Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined} | ||
| 1452 | + | ||
| 1453 | + The `customization` member represents the customization string. | ||
| 1454 | + The Node.js Web Crypto API implementation only supports zero-length customization | ||
| 1455 | + which is equivalent to not providing customization at all. | ||
| 1456 | + | ||
| 1457 | + #### `cShakeParams.functionName` | ||
| 1458 | + | ||
| 1459 | + <!-- YAML | ||
| 1460 | + added: REPLACEME | ||
| 1461 | + --> | ||
| 1462 | + | ||
| 1463 | + * Type: {ArrayBuffer|TypedArray|DataView|Buffer|undefined} | ||
| 1464 | + | ||
| 1465 | + The `functionName` member represents represents the function name, used by NIST to define | ||
| 1466 | + functions based on cSHAKE. | ||
| 1467 | + The Node.js Web Crypto API implementation only supports zero-length functionName | ||
| 1468 | + which is equivalent to not providing functionName at all. | ||
| 1469 | + | ||
| 1470 | + #### `cShakeParams.length` | ||
| 1471 | + | ||
| 1472 | + <!-- YAML | ||
| 1473 | + added: REPLACEME | ||
| 1474 | + --> | ||
| 1475 | + | ||
| 1476 | + * Type: {number} represents the requested output length in bits. | ||
| 1477 | + | ||
| 1478 | + #### `cShakeParams.name` | ||
| 1479 | + | ||
| 1480 | + <!-- YAML | ||
| 1481 | + added: REPLACEME | ||
| 1482 | + --> | ||
| 1483 | + | ||
| 1484 | + * Type: {string} Must be `'cSHAKE128'`[^modern-algos] or `'cSHAKE256'`[^modern-algos] | ||
| 1485 | + | ||
| 1426 | 1486 | ### Class: `EcdhKeyDeriveParams` | |
| 1427 | 1487 | ||
| 1428 | 1488 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -211,10 +211,15 @@ async function asyncDigest(algorithm, data) { | |||
| 211 | 211 | case 'SHA-384': | |
| 212 | 212 | // Fall through | |
| 213 | 213 | case 'SHA-512': | |
| 214 | + // Fall through | ||
| 215 | + case 'cSHAKE128': | ||
| 216 | + // Fall through | ||
| 217 | + case 'cSHAKE256': | ||
| 214 | 218 | return jobPromise(() => new HashJob( | |
| 215 | 219 | kCryptoJobAsync, | |
| 216 | 220 | normalizeHashName(algorithm.name), | |
| 217 | - data)); | ||
| 221 | + data, | ||
| 222 | + algorithm.length)); | ||
| 218 | 223 | } | |
| 219 | 224 | ||
| 220 | 225 | throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -49,6 +49,14 @@ const kHashNames = { | |||
| 49 | 49 | [kHashContextJwkRsaOaep]: 'RSA-OAEP-512', | |
| 50 | 50 | [kHashContextJwkHmac]: 'HS512', | |
| 51 | 51 | }, | |
| 52 | + shake128: { | ||
| 53 | + [kHashContextNode]: 'shake128', | ||
| 54 | + [kHashContextWebCrypto]: 'cSHAKE128', | ||
| 55 | + }, | ||
| 56 | + shake256: { | ||
| 57 | + [kHashContextNode]: 'shake256', | ||
| 58 | + [kHashContextWebCrypto]: 'cSHAKE256', | ||
| 59 | + }, | ||
| 52 | 60 | }; | |
| 53 | 61 | ||
| 54 | 62 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -62,7 +62,7 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) { | |||
| 62 | 62 | ||
| 63 | 63 | return new InternalCryptoKey( | |
| 64 | 64 | key, | |
| 65 | - { name, length, hash: { name: hash.name } }, | ||
| 65 | + { name, length, hash }, | ||
| 66 | 66 | ArrayFrom(usageSet), | |
| 67 | 67 | extractable); | |
| 68 | 68 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -161,7 +161,7 @@ async function rsaKeyGenerate( | |||
| 161 | 161 | name, | |
| 162 | 162 | modulusLength, | |
| 163 | 163 | publicExponent, | |
| 164 | - hash: { name: hash.name }, | ||
| 164 | + hash, | ||
| 165 | 165 | }; | |
| 166 | 166 | ||
| 167 | 167 | let publicUsages; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -285,6 +285,8 @@ const experimentalAlgorithms = ObjectEntries({ | |||
| 285 | 285 | importKey: null, | |
| 286 | 286 | exportKey: null, | |
| 287 | 287 | }, | |
| 288 | + 'cSHAKE128': { digest: 'CShakeParams' }, | ||
| 289 | + 'cSHAKE256': { digest: 'CShakeParams' }, | ||
| 288 | 290 | }); | |
| 289 | 291 | ||
| 290 | 292 | for (const { 0: algorithm, 1: nid } of [ | |
@@ -338,6 +340,10 @@ const simpleAlgorithmDictionaries = { | |||
| 338 | 340 | RsaOaepParams: { label: 'BufferSource' }, | |
| 339 | 341 | RsaHashedImportParams: { hash: 'HashAlgorithmIdentifier' }, | |
| 340 | 342 | EcKeyImportParams: {}, | |
| 343 | + CShakeParams: { | ||
| 344 | + functionName: 'BufferSource', | ||
| 345 | + customization: 'BufferSource', | ||
| 346 | + }, | ||
| 341 | 347 | }; | |
| 342 | 348 | ||
| 343 | 349 | function validateMaxBufferLength(data, name) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -192,6 +192,16 @@ converters.object = (V, opts) => { | |||
| 192 | 192 | ||
| 193 | 193 | const isNonSharedArrayBuffer = isArrayBuffer; | |
| 194 | 194 | ||
| 195 | + function ensureSHA(V, label) { | ||
| 196 | + if ( | ||
| 197 | + typeof V === 'string' ? | ||
| 198 | + !V.toLowerCase().startsWith('sha') : | ||
| 199 | + V.name?.toLowerCase?.().startsWith('sha') === false | ||
| 200 | + ) | ||
| 201 | + throw lazyDOMException( | ||
| 202 | + `Only SHA hashes are supported in ${label}`, 'NotSupportedError'); | ||
| 203 | + } | ||
| 204 | + | ||
| 195 | 205 | converters.Uint8Array = (V, opts = kEmptyObject) => { | |
| 196 | 206 | if (!ArrayBufferIsView(V) || | |
| 197 | 207 | TypedArrayPrototypeGetSymbolToStringTag(V) !== 'Uint8Array') { | |
@@ -393,6 +403,7 @@ converters.RsaHashedKeyGenParams = createDictionaryConverter( | |||
| 393 | 403 | { | |
| 394 | 404 | key: 'hash', | |
| 395 | 405 | converter: converters.HashAlgorithmIdentifier, | |
| 406 | + validator: (V, dict) => ensureSHA(V, 'RsaHashedKeyGenParams'), | ||
| 396 | 407 | required: true, | |
| 397 | 408 | }, | |
| 398 | 409 | ]); | |
@@ -403,6 +414,7 @@ converters.RsaHashedImportParams = createDictionaryConverter( | |||
| 403 | 414 | { | |
| 404 | 415 | key: 'hash', | |
| 405 | 416 | converter: converters.HashAlgorithmIdentifier, | |
| 417 | + validator: (V, dict) => ensureSHA(V, 'RsaHashedImportParams'), | ||
| 406 | 418 | required: true, | |
| 407 | 419 | }, | |
| 408 | 420 | ]); | |
@@ -449,6 +461,7 @@ converters.HmacKeyGenParams = createDictionaryConverter( | |||
| 449 | 461 | { | |
| 450 | 462 | key: 'hash', | |
| 451 | 463 | converter: converters.HashAlgorithmIdentifier, | |
| 464 | + validator: (V, dict) => ensureSHA(V, 'HmacKeyGenParams'), | ||
| 452 | 465 | required: true, | |
| 453 | 466 | }, | |
| 454 | 467 | { | |
@@ -503,6 +516,7 @@ converters.EcdsaParams = createDictionaryConverter( | |||
| 503 | 516 | { | |
| 504 | 517 | key: 'hash', | |
| 505 | 518 | converter: converters.HashAlgorithmIdentifier, | |
| 519 | + validator: (V, dict) => ensureSHA(V, 'EcdsaParams'), | ||
| 506 | 520 | required: true, | |
| 507 | 521 | }, | |
| 508 | 522 | ]); | |
@@ -513,6 +527,7 @@ converters.HmacImportParams = createDictionaryConverter( | |||
| 513 | 527 | { | |
| 514 | 528 | key: 'hash', | |
| 515 | 529 | converter: converters.HashAlgorithmIdentifier, | |
| 530 | + validator: (V, dict) => ensureSHA(V, 'HmacImportParams'), | ||
| 516 | 531 | required: true, | |
| 517 | 532 | }, | |
| 518 | 533 | { | |
@@ -573,6 +588,7 @@ converters.HkdfParams = createDictionaryConverter( | |||
| 573 | 588 | { | |
| 574 | 589 | key: 'hash', | |
| 575 | 590 | converter: converters.HashAlgorithmIdentifier, | |
| 591 | + validator: (V, dict) => ensureSHA(V, 'HkdfParams'), | ||
| 576 | 592 | required: true, | |
| 577 | 593 | }, | |
| 578 | 594 | { | |
@@ -587,12 +603,40 @@ converters.HkdfParams = createDictionaryConverter( | |||
| 587 | 603 | }, | |
| 588 | 604 | ]); | |
| 589 | 605 | ||
| 606 | + converters.CShakeParams = createDictionaryConverter( | ||
| 607 | + 'CShakeParams', [ | ||
| 608 | + ...new SafeArrayIterator(dictAlgorithm), | ||
| 609 | + { | ||
| 610 | + key: 'length', | ||
| 611 | + converter: (V, opts) => | ||
| 612 | + converters['unsigned long'](V, { ...opts, enforceRange: true }), | ||
| 613 | + validator: (V, opts) => { | ||
| 614 | + // The Web Crypto spec allows for SHAKE output length that are not multiples of | ||
| 615 | + // 8. We don't. | ||
| 616 | + if (V % 8) | ||
| 617 | + throw lazyDOMException('Unsupported CShakeParams length', 'NotSupportedError'); | ||
| 618 | + }, | ||
| 619 | + required: true, | ||
| 620 | + }, | ||
| 621 | + { | ||
| 622 | + key: 'functionName', | ||
| 623 | + converter: converters.BufferSource, | ||
| 624 | + validator: validateZeroLength('CShakeParams.functionName'), | ||
| 625 | + }, | ||
| 626 | + { | ||
| 627 | + key: 'customization', | ||
| 628 | + converter: converters.BufferSource, | ||
| 629 | + validator: validateZeroLength('CShakeParams.customization'), | ||
| 630 | + }, | ||
| 631 | + ]); | ||
| 632 | + | ||
| 590 | 633 | converters.Pbkdf2Params = createDictionaryConverter( | |
| 591 | 634 | 'Pbkdf2Params', [ | |
| 592 | 635 | ...new SafeArrayIterator(dictAlgorithm), | |
| 593 | 636 | { | |
| 594 | 637 | key: 'hash', | |
| 595 | 638 | converter: converters.HashAlgorithmIdentifier, | |
| 639 | + validator: (V, dict) => ensureSHA(V, 'Pbkdf2Params'), | ||
| 596 | 640 | required: true, | |
| 597 | 641 | }, | |
| 598 | 642 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -306,7 +306,6 @@ async function testDeriveBitsBadHash( | |||
| 306 | 306 | hash: 'PBKDF2' | |
| 307 | 307 | }, | |
| 308 | 308 | baseKeys[size], 256), { | |
| 309 | - message: /Unrecognized algorithm name/, | ||
| 310 | 309 | name: 'NotSupportedError', | |
| 311 | 310 | }), | |
| 312 | 311 | ]); | |
@@ -437,10 +436,7 @@ async function testDeriveKeyBadHash( | |||
| 437 | 436 | keyType, | |
| 438 | 437 | true, | |
| 439 | 438 | usages), | |
| 440 | - { | ||
| 441 | - message: /Unrecognized algorithm name/, | ||
| 442 | - name: 'NotSupportedError', | ||
| 443 | - }), | ||
| 439 | + { name: 'NotSupportedError' }), | ||
| 444 | 440 | assert.rejects( | |
| 445 | 441 | subtle.deriveKey( | |
| 446 | 442 | { | |
@@ -451,10 +447,7 @@ async function testDeriveKeyBadHash( | |||
| 451 | 447 | keyType, | |
| 452 | 448 | true, | |
| 453 | 449 | usages), | |
| 454 | - { | ||
| 455 | - message: /Unrecognized algorithm name/, | ||
| 456 | - name: 'NotSupportedError', | ||
| 457 | - }), | ||
| 450 | + { name: 'NotSupportedError' }), | ||
| 458 | 451 | ]); | |
| 459 | 452 | } | |
| 460 | 453 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments