From 1c4d534b756589b5a6dc1b13c1c51b1dc2ba1b53 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Wed, 28 Aug 2024 10:21:55 +0200 Subject: [PATCH] crypto: add SHA-3 Web Cryptography digest algorithms PR-URL: https://github.com/nodejs/node/pull/59365 Reviewed-By: James M Snell Reviewed-By: Ethan Arrowood Reviewed-By: Yagiz Nizipli Reviewed-By: Joyee Cheung --- doc/api/webcrypto.md | 64 +++++++ lib/internal/crypto/hash.js | 6 + lib/internal/crypto/hashnames.js | 24 ++- lib/internal/crypto/mac.js | 16 +- lib/internal/crypto/rsa.js | 2 +- lib/internal/crypto/util.js | 24 ++- lib/internal/crypto/webcrypto.js | 24 ++- test/fixtures/crypto/ecdsa.js | 76 +++++++- test/fixtures/crypto/hmac.js | 20 ++ test/fixtures/crypto/rsa_pkcs.js | 55 +++++- test/fixtures/crypto/rsa_pss.js | 174 +++++++++++++++++- test/fixtures/webcrypto/supports-sha3.mjs | 88 +++++++++ .../test-webcrypto-derivebits-hkdf.js | 63 ++++++- test/parallel/test-webcrypto-derivekey.js | 55 ++++-- test/parallel/test-webcrypto-digest.js | 37 ++++ .../test-webcrypto-encrypt-decrypt.js | 47 ++++- .../test-webcrypto-export-import-ec.js | 6 +- .../test-webcrypto-export-import-rsa.js | 15 +- test/parallel/test-webcrypto-export-import.js | 40 ++++ test/parallel/test-webcrypto-keygen.js | 14 +- .../test-webcrypto-sign-verify-rsa.js | 10 +- test/parallel/test-webcrypto-supports.mjs | 1 + 22 files changed, 784 insertions(+), 77 deletions(-) create mode 100644 test/fixtures/webcrypto/supports-sha3.mjs diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 1ef7174574..4607d71f57 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -2,6 +2,9 @@ * Type: {string|Algorithm} @@ -1531,6 +1550,9 @@ If represented as a {string}, the value must be one of: * `'SHA-256'` * `'SHA-384'` * `'SHA-512'` +* `'SHA3-256'`[^modern-algos] +* `'SHA3-384'`[^modern-algos] +* `'SHA3-512'`[^modern-algos] If represented as an {Algorithm}, the object's `name` property must be one of the above listed values. @@ -1650,6 +1672,10 @@ added: v15.0.0 * Type: {string|Algorithm} @@ -1660,6 +1686,9 @@ If represented as a {string}, the value must be one of: * `'SHA-256'` * `'SHA-384'` * `'SHA-512'` +* `'SHA3-256'`[^modern-algos] +* `'SHA3-384'`[^modern-algos] +* `'SHA3-512'`[^modern-algos] If represented as an {Algorithm}, the object's `name` property must be one of the above listed values. @@ -1706,6 +1735,10 @@ added: v15.0.0 * Type: {string|Algorithm} @@ -1716,6 +1749,9 @@ If represented as a {string}, the value must be one of: * `'SHA-256'` * `'SHA-384'` * `'SHA-512'` +* `'SHA3-256'`[^modern-algos] +* `'SHA3-384'`[^modern-algos] +* `'SHA3-512'`[^modern-algos] If represented as an {Algorithm}, the object's `name` property must be one of the above listed values. @@ -1781,6 +1817,10 @@ added: v15.0.0 * Type: {string|Algorithm} @@ -1791,6 +1831,9 @@ If represented as a {string}, the value must be one of: * `'SHA-256'` * `'SHA-384'` * `'SHA-512'` +* `'SHA3-256'`[^modern-algos] +* `'SHA3-384'`[^modern-algos] +* `'SHA3-512'`[^modern-algos] If represented as an {Algorithm}, the object's `name` property must be one of the above listed values. @@ -1839,6 +1882,10 @@ added: v15.0.0 * Type: {string|Algorithm} @@ -1849,6 +1896,9 @@ If represented as a {string}, the value must be one of: * `'SHA-256'` * `'SHA-384'` * `'SHA-512'` +* `'SHA3-256'`[^modern-algos] +* `'SHA3-384'`[^modern-algos] +* `'SHA3-512'`[^modern-algos] If represented as an {Algorithm}, the object's `name` property must be one of the above listed values. @@ -1891,6 +1941,10 @@ added: v15.0.0 * Type: {string|Algorithm} @@ -1901,6 +1955,9 @@ If represented as a {string}, the value must be one of: * `'SHA-256'` * `'SHA-384'` * `'SHA-512'` +* `'SHA3-256'`[^modern-algos] +* `'SHA3-384'`[^modern-algos] +* `'SHA3-512'`[^modern-algos] If represented as an {Algorithm}, the object's `name` property must be one of the above listed values. @@ -1966,6 +2023,10 @@ added: v15.0.0 * Type: {string|Algorithm} @@ -1976,6 +2037,9 @@ If represented as a {string}, the value must be one of: * `'SHA-256'` * `'SHA-384'` * `'SHA-512'` +* `'SHA3-256'`[^modern-algos] +* `'SHA3-384'`[^modern-algos] +* `'SHA3-512'`[^modern-algos] If represented as an {Algorithm}, the object's `name` property must be one of the above listed values. diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js index 9bce9adf4c..1c4d1285ec 100644 --- a/lib/internal/crypto/hash.js +++ b/lib/internal/crypto/hash.js @@ -210,6 +210,12 @@ async function asyncDigest(algorithm, data) { // Fall through case 'SHA-512': // Fall through + case 'SHA3-256': + // Fall through + case 'SHA3-384': + // Fall through + case 'SHA3-512': + // Fall through case 'cSHAKE128': // Fall through case 'cSHAKE256': diff --git a/lib/internal/crypto/hashnames.js b/lib/internal/crypto/hashnames.js index 70fddd6aaf..7a625c47e2 100644 --- a/lib/internal/crypto/hashnames.js +++ b/lib/internal/crypto/hashnames.js @@ -17,7 +17,7 @@ const kHashContextJwkHmac = 6; // make it easier in the code. const kHashNames = { - sha1: { + 'sha1': { [kHashContextNode]: 'sha1', [kHashContextWebCrypto]: 'SHA-1', [kHashContextJwkRsa]: 'RS1', @@ -25,7 +25,7 @@ const kHashNames = { [kHashContextJwkRsaOaep]: 'RSA-OAEP', [kHashContextJwkHmac]: 'HS1', }, - sha256: { + 'sha256': { [kHashContextNode]: 'sha256', [kHashContextWebCrypto]: 'SHA-256', [kHashContextJwkRsa]: 'RS256', @@ -33,7 +33,7 @@ const kHashNames = { [kHashContextJwkRsaOaep]: 'RSA-OAEP-256', [kHashContextJwkHmac]: 'HS256', }, - sha384: { + 'sha384': { [kHashContextNode]: 'sha384', [kHashContextWebCrypto]: 'SHA-384', [kHashContextJwkRsa]: 'RS384', @@ -41,7 +41,7 @@ const kHashNames = { [kHashContextJwkRsaOaep]: 'RSA-OAEP-384', [kHashContextJwkHmac]: 'HS384', }, - sha512: { + 'sha512': { [kHashContextNode]: 'sha512', [kHashContextWebCrypto]: 'SHA-512', [kHashContextJwkRsa]: 'RS512', @@ -49,14 +49,26 @@ const kHashNames = { [kHashContextJwkRsaOaep]: 'RSA-OAEP-512', [kHashContextJwkHmac]: 'HS512', }, - shake128: { + 'shake128': { [kHashContextNode]: 'shake128', [kHashContextWebCrypto]: 'cSHAKE128', }, - shake256: { + 'shake256': { [kHashContextNode]: 'shake256', [kHashContextWebCrypto]: 'cSHAKE256', }, + 'sha3-256': { + [kHashContextNode]: 'sha3-256', + [kHashContextWebCrypto]: 'SHA3-256', + }, + 'sha3-384': { + [kHashContextNode]: 'sha3-384', + [kHashContextWebCrypto]: 'SHA3-384', + }, + 'sha3-512': { + [kHashContextNode]: 'sha3-512', + [kHashContextWebCrypto]: 'SHA3-512', + }, }; { diff --git a/lib/internal/crypto/mac.js b/lib/internal/crypto/mac.js index 170292f0bb..4a78c45c70 100644 --- a/lib/internal/crypto/mac.js +++ b/lib/internal/crypto/mac.js @@ -67,18 +67,6 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) { extractable); } -function getAlgorithmName(hash) { - switch (hash) { - case 'SHA-1': // Fall through - case 'SHA-256': // Fall through - case 'SHA-384': // Fall through - case 'SHA-512': // Fall through - return `HS${hash.slice(4)}`; - default: - throw lazyDOMException('Unsupported digest algorithm', 'DataError'); - } -} - function hmacImportKey( format, keyData, @@ -126,7 +114,9 @@ function hmacImportKey( } if (keyData.alg !== undefined) { - if (keyData.alg !== getAlgorithmName(algorithm.hash.name)) + const expected = + normalizeHashName(algorithm.hash.name, normalizeHashName.kContextJwkHmac); + if (expected && keyData.alg !== expected) throw lazyDOMException( 'JWK "alg" does not match the requested algorithm', 'DataError'); diff --git a/lib/internal/crypto/rsa.js b/lib/internal/crypto/rsa.js index 4ecbaa89c6..dd0669df4e 100644 --- a/lib/internal/crypto/rsa.js +++ b/lib/internal/crypto/rsa.js @@ -281,7 +281,7 @@ function rsaImportKey( algorithm.name === 'RSA-PSS' ? normalizeHashName.kContextJwkRsaPss : normalizeHashName.kContextJwkRsaOaep); - if (keyData.alg !== expected) + if (expected && keyData.alg !== expected) throw lazyDOMException( 'JWK "alg" does not match the requested algorithm', 'DataError'); diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index adbafed023..ce89fc7a6f 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -287,6 +287,9 @@ const experimentalAlgorithms = ObjectEntries({ }, 'cSHAKE128': { digest: 'CShakeParams' }, 'cSHAKE256': { digest: 'CShakeParams' }, + 'SHA3-256': { digest: null }, + 'SHA3-384': { digest: null }, + 'SHA3-512': { digest: null }, }); for (const { 0: algorithm, 1: nid } of [ @@ -552,15 +555,28 @@ function getBlockSize(name) { // Fall through case 'SHA-512': return 1024; + case 'SHA3-256': + return 1088; + case 'SHA3-384': + return 832; + case 'SHA3-512': + return 576; } } function getDigestSizeInBytes(name) { switch (name) { - case 'SHA-1': return 20; - case 'SHA-256': return 32; - case 'SHA-384': return 48; - case 'SHA-512': return 64; + case 'SHA-1': + return 20; + case 'SHA-256': // Fall through + case 'SHA3-256': + return 32; + case 'SHA-384': // Fall through + case 'SHA3-384': + return 48; + case 'SHA-512': // Fall through + case 'SHA3-512': + return 64; } } diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js index db05e7747e..742204b160 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -452,21 +452,27 @@ async function exportKeyJWK(key) { ext: key.extractable, }; switch (key.algorithm.name) { - case 'RSASSA-PKCS1-v1_5': - parameters.alg = normalizeHashName( + case 'RSASSA-PKCS1-v1_5': { + const alg = normalizeHashName( key.algorithm.hash.name, normalizeHashName.kContextJwkRsa); + if (alg) parameters.alg = alg; break; - case 'RSA-PSS': - parameters.alg = normalizeHashName( + } + case 'RSA-PSS': { + const alg = normalizeHashName( key.algorithm.hash.name, normalizeHashName.kContextJwkRsaPss); + if (alg) parameters.alg = alg; break; - case 'RSA-OAEP': - parameters.alg = normalizeHashName( + } + case 'RSA-OAEP': { + const alg = normalizeHashName( key.algorithm.hash.name, normalizeHashName.kContextJwkRsaOaep); + if (alg) parameters.alg = alg; break; + } case 'ECDSA': // Fall through case 'ECDH': @@ -496,11 +502,13 @@ async function exportKeyJWK(key) { parameters.alg = require('internal/crypto/aes') .getAlgorithmName(key.algorithm.name, key.algorithm.length); break; - case 'HMAC': - parameters.alg = normalizeHashName( + case 'HMAC': { + const alg = normalizeHashName( key.algorithm.hash.name, normalizeHashName.kContextJwkHmac); + if (alg) parameters.alg = alg; break; + } default: return undefined; } diff --git a/test/fixtures/crypto/ecdsa.js b/test/fixtures/crypto/ecdsa.js index 4b3539edb1..b8827b24d4 100644 --- a/test/fixtures/crypto/ecdsa.js +++ b/test/fixtures/crypto/ecdsa.js @@ -2,6 +2,12 @@ module.exports = function() { const pkcs8 = { + 'P-256': Buffer.from( + '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b020101' + + '04205119f596e17f3c55a170b674c96e6bea7269dc9240047c76c841ff49106c4989' + + 'a14403420004b1d1e7da708dfadf90bc013a4009184bdb3f9065078f5598f6ad2638' + + '65a387e249ebf1a514ad8c943635a66d8acd64ebf2c876e55448813f10026a5e1f0a' + + '9817', 'hex'), 'P-384': Buffer.from( '3081b6020100301006072a8648ce3d020106052b8104002204819e30819b02010104' + '3002a9a0d899efa87e7564110907e9d82c21bd6265a37abd9a6fdb0f80ec844dd3a1' + @@ -21,6 +27,10 @@ module.exports = function() { } const spki = { + 'P-256': Buffer.from( + '3059301306072a8648ce3d020106082a8648ce3d03010703420004b1d1e7da708dfa' + + 'df90bc013a4009184bdb3f9065078f5598f6ad263865a387e249ebf1a514ad8c9436' + + '35a66d8acd64ebf2c876e55448813f10026a5e1f0a9817', 'hex'), 'P-384': Buffer.from( '3076301006072a8648ce3d020106052b81040022036200041d319d692dca5f5754ba' + '7b32c11642c6d8d2b4fb8249c3f214d71e90b5252966d97f7beb1faab1e4f3e26055' + @@ -45,6 +55,36 @@ module.exports = function() { // For verification tests. const signatures = { + 'P-256': { + 'SHA-1': Buffer.from( + 'a6f9548fa945bca4ce6e41d4099623b409e21070c03179161867d3ca411ee4f39e' + + '51ba999723e609d0abb2cc48450e886544ca400bae09841651211b43907672', + 'hex'), + 'SHA-256': Buffer.from( + '15f4adec59122298cd1642ee9104748c705dc6a3f70ed8222a52ee0420a35ce4c8' + + '293db29689acf24f6009b98df0cb8ec1aab17f8ad448a8c0e86843dfa824a3', + 'hex'), + 'SHA-384': Buffer.from( + 'b860be71578d07ad137c2a75ac29528114b23f58021b2c2875ac1374ed3143a928' + + '4efd9402b950cfc738fc9df4e33d917594f2078b96a02d5fbf17efe94e72a6', + 'hex'), + 'SHA-512': Buffer.from( + 'b6a0a14d7e4bc6dd2eda82c9234f174b670b60c8f7d101f68fdf5889e02373b025' + + 'dcbc4c82f2929b8e06c68535da98e38fe399c53a814b097935581ef21535eb', + 'hex'), + 'SHA3-256': Buffer.from( + 'f6a48eb5557f484ed0c3e4b5c78a3cf497cbd346db06a4165d429248aa2cc51a69' + + '747d09f57af145469a8b607a9b8b9709629d74e8f5ca337c6ddc581b6f6103', + 'hex'), + 'SHA3-384': Buffer.from( + '777785978eb59da32888554dc7fd62d1ba1a3033cddaa8c36b8f3dcea8f85e1c8e' + + '6db26f509747bd144dfa9436784bf4abbcaa6abcf1ecc09cea3b921d46738c', + 'hex'), + 'SHA3-512': Buffer.from( + '0f01c2083b5dd7fccb2784563f88cd9a815d570a1690695e426643ab725780760d' + + 'e972e26e18d67f5557be89f17b4cd0065ce2937de299bdb2e972ebf7635084', + 'hex') + }, 'P-384': { 'SHA-1': Buffer.from( '65fe070ec3eac35250d00b9ee6db4d2dadd5f3bbb9c495c8671d2a0d2b99149fb2' + @@ -61,7 +101,19 @@ module.exports = function() { 'SHA-512': Buffer.from( '72fbdb369fd34c1c54264d07f4facd69b02e4206f8a8bb259b882a305c56fde2d3' + '5107e493c53cd6b4af0b31306f4d03fd43cfc762a1030e17a3d775453a1212b142' + - '9f7b3d93066a5f42a10b138cd177dc09616e827d598822d78d4627b754e6', 'hex') + '9f7b3d93066a5f42a10b138cd177dc09616e827d598822d78d4627b754e6', 'hex'), + 'SHA3-256': Buffer.from( + '0b07c078be30fa5925a307d6fc559c5f398e63fb5d007d6b24a834847f2d3d18d5' + + 'b5e840711c52a7bc6626c3ced93301e873c013a706f6b297c12cc6d47a71e0529e' + + '719f43957de9995621d3cb0217469adaa6fd3135470771d0aa9d05d7a9c6', 'hex'), + 'SHA3-384': Buffer.from( + '2f36e8b04af46f68ef900c2720e3518b06f5440865d44072bbad5d62288c575042' + + 'b183a372acd70328c738668dcecb9866801462d62df3c35450fdc6c95433103fcd' + + 'c77999b640e3f92bd4e9be6e27ab129d1bc4f0b2a4c829388666920892d3', 'hex'), + 'SHA3-512': Buffer.from( + '32a951e886c33ac57a008efe9643bc92aa3ece9521d115e0c7240caecf124d1f7c' + + 'dcba7fabb9ad5202e04f7aa591ab01ed3f060f04f493e4f24430fe8159200612f0' + + '2849108b8be6edc8494c328097ad9265928efe5cb9d91be2f013ee17ee4e', 'hex') }, 'P-521': { 'SHA-1': Buffer.from( @@ -87,12 +139,30 @@ module.exports = function() { '5ae23cfcca0aad78f6b6dee6b4718b95d0d1a715aa3378470e50b516c18e0f3305' + '01f0071e6a32867fa70f695cd39c4e87e142b9e4134d38740bd6fee354a575167e' + '13524e94832637910fe11e53a85fb21b91adb81bb1779c4e2b8bc87c717dc35084', + 'hex'), + 'SHA3-256': Buffer.from( + '00463679f47a4c705e03447360dcf34d1743e0d4b2591cc66832a6bc80d92e538c' + + '169a1fd330f98e7235ca7fec7e16ac44fb13095b8edf2c76b75c4845177d59e425' + + '0127c4359f6a4c9ccb63e7a9ff8122c0b4a8b7408e28c96817ecc3baf8c559c413' + + 'c3bb580447dec9f52139b2afde369cd51730f050bc94137556ae137f0509464219', + 'hex'), + 'SHA3-384': Buffer.from( + '01969a4db0888bc067a68a31fe5d0fc97e0b701f570565f7b25cb27707c6f020ff' + + '680f8553ec5c2d6885e9e91b39262ed1bde375525eb13fdf12089b7939c7689735' + + '0101c8b8d1129a217e8e956bef78cf7b9a0458523b04ac8e0b84ce73d54326f7a8' + + '704ee42fe183f3ef79d83e676f34dc5476e2342641a5b973d3d94e8503676fbbc5', + 'hex'), + 'SHA3-512': Buffer.from( + '000f362e914ee0136663cf57bf4085c25604af6dc198b4818751e1195ee7e41a16' + + '91be909dcbc2bae00b8917f6bb918eae3740ac1b76e0913137c2da1171d6400b55' + + '01ec6e1dc5987a27fe16fc2ce5c8e954088f898a9bbefb176eaa8bbd9ccc264c4c' + + 'cc38c83ac8b5a168f90228daf8405a2b9bf7829c263a646b4e1098e2ace38deec7', 'hex') } } - const curves = ['P-384', 'P-521']; - const hashes = ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512']; + const curves = ['P-256', 'P-384', 'P-521']; + const hashes = ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512', 'SHA3-256', 'SHA3-384', 'SHA3-512']; const vectors = []; curves.forEach((namedCurve) => { diff --git a/test/fixtures/crypto/hmac.js b/test/fixtures/crypto/hmac.js index c4942976ad..6505c6e2ae 100644 --- a/test/fixtures/crypto/hmac.js +++ b/test/fixtures/crypto/hmac.js @@ -19,6 +19,16 @@ module.exports = function () { '6b1da28eab1f582ad9718effe05e23d5fd2c9877a2d9443f90bec093bece2ea7' + 'd2354cd0bdc5e147d2e9009373494488', 'hex'), 'SHA-512': Buffer.from( + '5dcc359443aaf652fa1375d6b3e61fdcf29bb4a28bd5d3dcfa40f82f906bb280' + + '0455db03b5d31fb972a15a6d0103a24e56d156a119c0e5a1e92a44c3c5657cf9', + 'hex'), + 'SHA3-256': Buffer.from( + 'e588ec0811463d767241df1074b47ae4071b51f2ce36537ba69ccdc3fdc2b7a8', + 'hex'), + 'SHA3-384': Buffer.from( + '6b1da28eab1f582ad9718effe05e23d5fd2c9877a2d9443f90bec093bece2ea7' + + 'd2354cd0bdc5e147d2e9009373494488', 'hex'), + 'SHA3-512': Buffer.from( '5dcc359443aaf652fa1375d6b3e61fdcf29bb4a28bd5d3dcfa40f82f906bb280' + '0455db03b5d31fb972a15a6d0103a24e56d156a119c0e5a1e92a44c3c5657cf9', 'hex') @@ -35,6 +45,16 @@ module.exports = function () { 'SHA-512': Buffer.from( '61fb278c3ffb0cce2bf1cf723ddfd8ef1f931c0c618c25907324605939e3f9a2' + 'c6f4af690bda3407dc2f5770f6a0a44b954d64a332e3ee0821abf82b7f3e99c1', + 'hex'), + 'SHA3-256': Buffer.from( + 'c1ac5e11fcd50c48bf567f6e296632f5801c4eb07a8a47579b41dee971a3099b', + 'hex'), + 'SHA3-384': Buffer.from( + 'ac8c97f6dd8d9e16101063077c16b23fe291a5e6d149653e9ac7002365159317' + + 'adcfad511996578b0053a5c14b75f16c', 'hex'), + 'SHA3-512': Buffer.from( + '2162c2a8907e6b2f68599a69e81a464d8f076b5eeb555d98b4d20330034df3c7' + + 'cf35b1fa958a074ca12f0d242df39f0da3d4f1dbfb3629057798fe1f883974ee', 'hex') } diff --git a/test/fixtures/crypto/rsa_pkcs.js b/test/fixtures/crypto/rsa_pkcs.js index 49e202c512..4630e4af91 100644 --- a/test/fixtures/crypto/rsa_pkcs.js +++ b/test/fixtures/crypto/rsa_pkcs.js @@ -96,7 +96,34 @@ module.exports = function () { '688c993b58a0ed35e8f0a106d4e8b1b360e334415c742e94675823db0fd25e22cff' + '7a6335c70e193235dcda48add6858626bd96311e60f7e5ea4491b6c1e6248afe12b' + 'bbd54f8869b043a5b0444562813f0a98b300356f306e6b783a29f3bec97ca40ea20' + - '062cab8926ec5d96aa387cc84821a6d72b8ea126e7d', 'hex') + '062cab8926ec5d96aa387cc84821a6d72b8ea126e7d', 'hex'), + 'sha3-256': Buffer.from( + 'be1b476c1911a01d71710fd8a2f3158d6f7839e91443b01bed30dfdd04336d80c6b' + + 'f692c06fad254877901c10a73853e8fb202a29cddefdf16c3adcda1fc123625897d' + + '1b81b32a9dec38957e023be221d8f31e7470ad32e761edce9170eefa37ec19bd0c3' + + 'e0b0ad2a244e98f54a08f873efb63c6fad14d7322b50eb05b6bae767305da92a90a' + + '53cdae52b0d81e158a00003ec626e50423b7377a34a7b28cc7483b55bfde05bd431' + + 'cfa436c38c285531e0d476ee13f151c8ae832ffd51ba00f2ab06f1844e73c0fe0f6' + + 'ce17d966b1e07727af4161368aa0a74a594a6fdb782b46a9ae6098799c366fc0d71' + + '1b2d965cf5eeeed9175b39b1d0bcefdd7df376e8ac9', 'hex'), + 'sha3-384': Buffer.from( + '002eaf5837443f1a33dc03729a308c503888d7a8cc013be424a91bce18105f7334a' + + '499a5eddc5f4fab2fdf80f52988d53bf8bd5e78c3ce1a43abaf3b8146c260b6ce8b' + + 'ffc9857f4b35c190cea85921c46d3ab573113744472d1afb637a0e9ab5021bcb355' + + '7f5b52faf89fa864a7d3bf5799096c54ee53fa139e1bc13842a2a5bf0f1d85f041d' + + 'a4e0e87425b421f22f0240ad62ef77ba6f090e0d48e17c07fd1e477c7e16a3196f5' + + '0142d0f0c5e525a10325569e5a1f50cb4577e782a643972857cc918ae5409587d9e' + + '44e1c1e89540e87deed7dda5005ac63ba609f522fdd92c81d95c1ffa383558a10f3' + + '064f59ca0534bfad31acbf3e2807cb7d3147c59ee4d', 'hex'), + 'sha3-512': Buffer.from( + '561585b621c916453762285c8bb6ede3f303074ad6f2826ca15b3900e49c4d94c07' + + 'aab0b875eaa79049ba2ed97e9a87c44fff9bffe638a1bf8c4db69c627b6adbe8fca' + + '2b38cb8b4c2810a16286bef498327b9db4b53043ed5012c7c58f037edf669baf772' + + '9b58e413e133ebb90a5fcb6dc3936f4f87971c0e85f362189b4279bbb2d9293a427' + + '5653068c1bc8772cebc4733a5d1df0b454d4f628c645c22bb1c8cc601fbc92dc091' + + 'db38fad4a36289ae9ed424c46643a8161a102ae511877d25f2eab7342dff6b92bf3' + + '65951e76ee84c2bd84a595f63d7cc04d00e1589870956491e518b3ba245efc37a28' + + 'ec018d8788a92ab93a90bb314f9ab0788a0b5b50489', 'hex') } const vectors = [ @@ -131,7 +158,31 @@ module.exports = function () { hash: 'SHA-512', plaintext, signature: signatures['sha-512'] - } + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSASSA-PKCS1-v1_5' }, + hash: 'SHA3-256', + plaintext, + signature: signatures['sha3-256'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSASSA-PKCS1-v1_5' }, + hash: 'SHA3-384', + plaintext, + signature: signatures['sha3-384'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSASSA-PKCS1-v1_5' }, + hash: 'SHA3-512', + plaintext, + signature: signatures['sha3-512'] + }, ]; return vectors; diff --git a/test/fixtures/crypto/rsa_pss.js b/test/fixtures/crypto/rsa_pss.js index effb3605a7..101122b2ff 100644 --- a/test/fixtures/crypto/rsa_pss.js +++ b/test/fixtures/crypto/rsa_pss.js @@ -61,21 +61,131 @@ module.exports = function() { const signatures = { 'sha-1, no salt': Buffer.from( - '1f1cd81ecb3bb31df2e5f0f64c5c0a310c7cf88d19eb512a5078e156d823727af88' + '68a12e5dfbfa976386784ba982c39928789b134952a4a28c6241177bcf2248f2adb' + '60077f545dd17e4f809b3b859fd430d1681e8047126d77369519eed5b618f3297a5' + '75085f0c931ed248cf60bbd7efffa0a8c2b874ba7f81ecd6bf391d01f1e881d827a' + '7b95df874d9adabb7b07f131ab33142a8b0b6d5ca9685671d49b982b67651909eaa' + '17b96b393e04fb36d972f9b258f1b79123df212d39924a4deaec506cf640f1dedd0' + '2d28845f3548d8488652788e2e2146f3ce8a86a556d84b4578f10da29abdb176a68' + '718cc1b2270b0735c2e5ca6c6bb0afac23a5bfa817a', 'hex'), + '1f1cd81ecb3bb31df2e5f0f64c5c0a310c7cf88d19eb512a5078e156d823727af88' + + '68a12e5dfbfa976386784ba982c39928789b134952a4a28c6241177bcf2248f2adb' + + '60077f545dd17e4f809b3b859fd430d1681e8047126d77369519eed5b618f3297a5' + + '75085f0c931ed248cf60bbd7efffa0a8c2b874ba7f81ecd6bf391d01f1e881d827a' + + '7b95df874d9adabb7b07f131ab33142a8b0b6d5ca9685671d49b982b67651909eaa' + + '17b96b393e04fb36d972f9b258f1b79123df212d39924a4deaec506cf640f1dedd0' + + '2d28845f3548d8488652788e2e2146f3ce8a86a556d84b4578f10da29abdb176a68' + + '718cc1b2270b0735c2e5ca6c6bb0afac23a5bfa817a', 'hex'), 'sha-256, no salt': Buffer.from( - '6157d668ed655d978b4c158c8419eb80718dfdfc7d4b34357f9917e9e116b6f3b65' + '040c9d16155c081d6887abcb3ba4ffa0191e4807ee206681aa1d4809ea20de5186b' + '77e3caced07fc9b3d71b9df0ac81b5c3273ff3f74f32a7ad34c65062a31540ced30' + '527efa4b7aa2d27ff7f80535f3e65ce352eb9e18b5054416de959354a4dcccb2542' + 'e33a8358eda620a8653dd6458f56ab94fee1dc01ef42fb8958aa134810e4d8fe1dd' + '4feee6af04742f80da5793875a78a2a4cc08d4e0a68ab03f1c022a0e8a7d3096089' + '92d24ecdd7e8f1895e3e5cd36e49906b531932d9ff958618b1a50f98455f515e0c6' + '3103d2e4e1651afc566eb9cad1e7efae1a9750c3880', 'hex'), + '6157d668ed655d978b4c158c8419eb80718dfdfc7d4b34357f9917e9e116b6f3b65' + + '040c9d16155c081d6887abcb3ba4ffa0191e4807ee206681aa1d4809ea20de5186b' + + '77e3caced07fc9b3d71b9df0ac81b5c3273ff3f74f32a7ad34c65062a31540ced30' + + '527efa4b7aa2d27ff7f80535f3e65ce352eb9e18b5054416de959354a4dcccb2542' + + 'e33a8358eda620a8653dd6458f56ab94fee1dc01ef42fb8958aa134810e4d8fe1dd' + + '4feee6af04742f80da5793875a78a2a4cc08d4e0a68ab03f1c022a0e8a7d3096089' + + '92d24ecdd7e8f1895e3e5cd36e49906b531932d9ff958618b1a50f98455f515e0c6' + + '3103d2e4e1651afc566eb9cad1e7efae1a9750c3880', 'hex'), 'sha-384, no salt': Buffer.from( - '7b95aab6b34c0962d228409e30df9b043c1b0baada08e73d887422552b8f1522e2e' + '42bf2b9ff2c6c9aa3eb0cd2370618e8f1a36873595e00bde75a9ce062ec32b5f639' + '4f2267a3f5c11840ff92e6e15bf31cc53e917ca8efc0895fb112c2ef8f681cbb6a4' + '10152f6e930caff1f260e31f983542e68cd15dea17ed3139cac735106fb05fc163b' + '2ed05a0ded939059a10c5cd7619e21b2d206907994274b34a4daefa1ce59b6b319f' + '73955a0918a5e237e1bbfdadb45c907a50083577e7192818845995b4a6d3ff1978e' + '0f9a42695853282e35c3b78133b3e0c624125aff14a1873d198f6304ffec7fc1cf2' + 'adecc6cd14b1f89b1a637f72ed1ff5de7c6b4d96599', 'hex'), + '7b95aab6b34c0962d228409e30df9b043c1b0baada08e73d887422552b8f1522e2e' + + '42bf2b9ff2c6c9aa3eb0cd2370618e8f1a36873595e00bde75a9ce062ec32b5f639' + + '4f2267a3f5c11840ff92e6e15bf31cc53e917ca8efc0895fb112c2ef8f681cbb6a4' + + '10152f6e930caff1f260e31f983542e68cd15dea17ed3139cac735106fb05fc163b' + + '2ed05a0ded939059a10c5cd7619e21b2d206907994274b34a4daefa1ce59b6b319f' + + '73955a0918a5e237e1bbfdadb45c907a50083577e7192818845995b4a6d3ff1978e' + + '0f9a42695853282e35c3b78133b3e0c624125aff14a1873d198f6304ffec7fc1cf2' + + 'adecc6cd14b1f89b1a637f72ed1ff5de7c6b4d96599', 'hex'), 'sha-512, no salt': Buffer.from( - 'af1bc07fa70add19f3ce1f1bef8dfc6e24af43671cfb97e6b869e86b7ef03550a65' + '81318fff6449afa8b67e73e2a6a14e20677d8b067145a84422574ae0cfd2a5dff70' + 'c6d7e97f6a0e166505079eb4264a43c493f2eb3fb06facc01be60774c277646a280' + '81247679622b220227e9249754867aa8fe1804015c4f98700982eda40e84d0ba033' + '6cf44f582fb8781374804e8fb43eb9d577acf4723587a39a2b4a9e168b767632b7a' + '554f77bc5272821c938c0994b162f7482636f7ffac564a19bd733f4877801dc324d' + 'c47196ef12ca9a8f4921a5496cd6737935ca555b73466ddd817eaff03feda0eb2d6' + '12e3cdb59b1989eeffdc18101d46e56b9ff5c91f95d', 'hex'), + 'af1bc07fa70add19f3ce1f1bef8dfc6e24af43671cfb97e6b869e86b7ef03550a65' + + '81318fff6449afa8b67e73e2a6a14e20677d8b067145a84422574ae0cfd2a5dff70' + + 'c6d7e97f6a0e166505079eb4264a43c493f2eb3fb06facc01be60774c277646a280' + + '81247679622b220227e9249754867aa8fe1804015c4f98700982eda40e84d0ba033' + + '6cf44f582fb8781374804e8fb43eb9d577acf4723587a39a2b4a9e168b767632b7a' + + '554f77bc5272821c938c0994b162f7482636f7ffac564a19bd733f4877801dc324d' + + 'c47196ef12ca9a8f4921a5496cd6737935ca555b73466ddd817eaff03feda0eb2d6' + + '12e3cdb59b1989eeffdc18101d46e56b9ff5c91f95d', 'hex'), 'sha-1, salted': Buffer.from( - '1f608a71d1884cfe2183b49037aa8555b0139a8a1267a5c5b9cce20701f2ad4bbd5' + 'b329740bff31accc34bf9afd1439a0536bb32b6d427d26968dbc9e9c80d2111d948' + 'c481cb1731778acd3110463241c4f23b3e13b855d162cb153851290fd95f781519e' + '2cef93745a413cfeec8e94fba7822b725d4744318458cf6b4a917b65b15ee6f54b9' + 'c391f6064a9e031f7009f592449c0b46d5457a2799cb0ebd78a102a055ee0470b26' + '0c2b3d8ffbdee0fd47644822090ec55ae6233be1062f441c432ed3c275e74d62013' + '2681ec2e801e9b5b6acc1ad71f8935388f7e2c03370d12e944e3418c2ab63bb42ab' + 'e1bb9e69530f02458ba28400b36806ff78da5791ace', 'hex'), + '1f608a71d1884cfe2183b49037aa8555b0139a8a1267a5c5b9cce20701f2ad4bbd5' + + 'b329740bff31accc34bf9afd1439a0536bb32b6d427d26968dbc9e9c80d2111d948' + + 'c481cb1731778acd3110463241c4f23b3e13b855d162cb153851290fd95f781519e' + + '2cef93745a413cfeec8e94fba7822b725d4744318458cf6b4a917b65b15ee6f54b9' + + 'c391f6064a9e031f7009f592449c0b46d5457a2799cb0ebd78a102a055ee0470b26' + + '0c2b3d8ffbdee0fd47644822090ec55ae6233be1062f441c432ed3c275e74d62013' + + '2681ec2e801e9b5b6acc1ad71f8935388f7e2c03370d12e944e3418c2ab63bb42ab' + + 'e1bb9e69530f02458ba28400b36806ff78da5791ace', 'hex'), 'sha-256, salted': Buffer.from( - '8c3d03bde8c42d9453631b0baac89e6296da20543713c004df35bc1a6fae205ab2b' + 'f585369689073cdee345ad6e2783b2dda187b4979ea0457463758156e103eedd0ef' + '1834d35bd6ad540d9b8b225fd1770e514ea0af35f707f2e7a0382be6f5ed9d6b591' + 'd536ce1215b17ef3eeb450bb48a0017497c67be0240470addd2891a81a8f1cf6e80' + 'e3f837fe42376292df555b8b05931b69530597fae36dcd01b1c81767d4ecd4caf06' + 'befc035224bdd2a5e6b89d51539235ac95570e757dbd70fdc15040001b07b937bf0' + '148ccc005f4c272acf5f8fc096a37d26208e96ac341c2d1d212c44d6d5156c934f6' + '6ef42fdbac77a208681550b048b466e32c76c7a7b07', 'hex'), + '8c3d03bde8c42d9453631b0baac89e6296da20543713c004df35bc1a6fae205ab2b' + + 'f585369689073cdee345ad6e2783b2dda187b4979ea0457463758156e103eedd0ef' + + '1834d35bd6ad540d9b8b225fd1770e514ea0af35f707f2e7a0382be6f5ed9d6b591' + + 'd536ce1215b17ef3eeb450bb48a0017497c67be0240470addd2891a81a8f1cf6e80' + + 'e3f837fe42376292df555b8b05931b69530597fae36dcd01b1c81767d4ecd4caf06' + + 'befc035224bdd2a5e6b89d51539235ac95570e757dbd70fdc15040001b07b937bf0' + + '148ccc005f4c272acf5f8fc096a37d26208e96ac341c2d1d212c44d6d5156c934f6' + + '6ef42fdbac77a208681550b048b466e32c76c7a7b07', 'hex'), 'sha-384, salted': Buffer.from( - '79f7284bb4216de68429854edb4218ef78ad1740848567377315db8867a15733c70' + '42e8bf90762e673c90c0e2c58c6c5cef497568bd92a6d219612c4756c55fac45507' + 'f81608bc2720da4eedd5b23e1f3c8740c6b4cd7e4cf0e04342b184c1110199e6508' + '0d73b985e611d66f8e97990816e4917badbb0425dd94383892e2aa96de4db0de093' + '6aee84d5482a3da31b27319f43830fc48703cc7d4eaedb20fd30323dbf3f22608db' + '51637d3b305b3197962658d80935c266d33ccfb297590621f4a967c7245e92b0158' + 'c0dcea943e2ace719ebdb196a9bae7df3ed9cc62765e27b63571743e28a0538db08' + '25cad2539eb5de5e6a320a88b573ec1972c26401530', 'hex'), + '79f7284bb4216de68429854edb4218ef78ad1740848567377315db8867a15733c70' + + '42e8bf90762e673c90c0e2c58c6c5cef497568bd92a6d219612c4756c55fac45507' + + 'f81608bc2720da4eedd5b23e1f3c8740c6b4cd7e4cf0e04342b184c1110199e6508' + + '0d73b985e611d66f8e97990816e4917badbb0425dd94383892e2aa96de4db0de093' + + '6aee84d5482a3da31b27319f43830fc48703cc7d4eaedb20fd30323dbf3f22608db' + + '51637d3b305b3197962658d80935c266d33ccfb297590621f4a967c7245e92b0158' + + 'c0dcea943e2ace719ebdb196a9bae7df3ed9cc62765e27b63571743e28a0538db08' + + '25cad2539eb5de5e6a320a88b573ec1972c26401530', 'hex'), 'sha-512, salted': Buffer.from( - 'b74f3099d80787118b1f9de79fc207893e0d2d75c4110f4b159b85ba07d63a0256f' + 'c3cd0f66ce8d9a2e3cf7a3d5a7b9c0befac6638894a3e36ce75e649ee069dd8dd98' + 'aa8b602474c98b14bb03492de551a9e8e77934ef9b684583934f218d9576be240b5' + 'c4f362eaf5e0140c8ea92639085a6269653505dcfa004226db9f63277653a64a182' + '6e4babb17ab54dd8543dcf1ce809706d6816e6a75ff846a3d4c18d11bdeb1f31b10' + 'd55a3795b6496319e6e751504d86a4e7bb6535b9f0415e815d8c789c5b1e387f2a8' + 'c00fef6e327462cb7e525b8f945be5b17248e0e0a4d855d397e22d067ce4539373d' + 'fba46d1799250afc70f535006cacd2766f5ddcf8f91', 'hex') + 'b74f3099d80787118b1f9de79fc207893e0d2d75c4110f4b159b85ba07d63a0256f' + + 'c3cd0f66ce8d9a2e3cf7a3d5a7b9c0befac6638894a3e36ce75e649ee069dd8dd98' + + 'aa8b602474c98b14bb03492de551a9e8e77934ef9b684583934f218d9576be240b5' + + 'c4f362eaf5e0140c8ea92639085a6269653505dcfa004226db9f63277653a64a182' + + '6e4babb17ab54dd8543dcf1ce809706d6816e6a75ff846a3d4c18d11bdeb1f31b10' + + 'd55a3795b6496319e6e751504d86a4e7bb6535b9f0415e815d8c789c5b1e387f2a8' + + 'c00fef6e327462cb7e525b8f945be5b17248e0e0a4d855d397e22d067ce4539373d' + + 'fba46d1799250afc70f535006cacd2766f5ddcf8f91', 'hex'), + 'sha3-256, no salt': Buffer.from( + '98787732f107a5390abc9ba3c93c2a0e30f6f31c3c76d73afee951a04525897df94' + + '67c7532ff1b5c12601369339edcac4654a173e61780a12a21b5f0500bf16e2445f9' + + 'f7e9adab1ea2bb7e901f615b514965047d53b12ff2ff19f94f320179946bbf1b19d' + + '88248e4fba7f49dc3c5af14de7a892a7718bd5962db33aa2b529c49e75d8fe936de' + + '45e1db225ed875486516cd7398b5ec19043cf6005e06ba2d60f807d34d4ced378ae' + + 'cef2b1f75f6ad52cdd674d944e48d484be2e5f799510f244d089eb3570a674b2585' + + '0616f12641e7e3e38e36fba1eefbed32d7a4809a4b5b1e557582303ab419bc128a1' + + '813857157985f075d5d89e6867b7864dac0369b2513', 'hex'), + 'sha3-384, no salt': Buffer.from( + '1d1399da211efc709b2cea90ff65e7c49162d943cadb59c78186889f7645e5d08f7' + + '490de3f7b65ee5664c140dd61334182ddf45bcdc844845e4d60c917bf00eb1321e7' + + '46cd7fce971af5ceea60b272219ccda2328b89a11b228cd42bdcc4c7eb40f0b6333' + + '5f7496931baf36c0d2497045687ad27bb156c20f7fdae3baa38d57e35918f328bdd' + + '2de7e6b23d6c676a18342a082f7ea019021903f103ccb4a6fddb2d88c30a1284764' + + 'b68c04bfe452c3adc6c10066a915231b7b404727eb6201b4921eb96d9407de2b963' + + '3879ceb71d759d9828d7b4d062f6ef100757d8328187caf57dfb859d1555345207c' + + '1cce7905c3564c08fec78867a53d5a2cf84810e1ffa', 'hex'), + 'sha3-512, no salt': Buffer.from( + 'd2430dc87abeaa7d13f7cec8510f1a296e1c608f44b1696829c59a99e8eefe9b2ee' + + '6ee8ad6fdc93c24fcba2f04d1da195924b6209717e1992c10ed9f4783478765fe34' + + '3e761203bff9d326bb6dc2061b0a7554c8ce0814b29249136c20c8e30054df0c6bc' + + '656509a82845149368896690e32ff5dd32ef01543686f01d6a69bb438b049e66a8b' + + 'df485a13edcd7dc482da4cc57d0b740aca3e56f0da247794e600afd27b22b6da13b' + + 'cc15dd2059b525f8cb6bcd07540aa843f0ae51d4b0eea27045485914b908bdd01d0' + + 'a9d42379f9f7180f4ad162ff73df5fed0200eb02ad01473975d54a77c15a9c61a3c' + + 'b5e27de5d1eecc363d45506f7123a5ddd115c5e4c9e', 'hex'), + 'sha3-256, salted': Buffer.from( + '59cb9cce6ae838eb20d38d6af4acb9b866b0753bb7df9e441037d788512c03279e8' + + '3d9a9cf5c0921fe1c0b6e8e895a8c0ad24a18b123f809b34ef2a3a1f05974030320' + + '435692ef5d378cef4368c3658c098a25371dfaf1c0b6910f653a4ec15f2c08956c1' + + '405136c2aba7f25a808fa7dbf57a4cb2978bd91af710b27ee239d955c8cac7a76ae' + + '9085cefeda2a585a99cc948f064b5da66a9c4aa4f3f767ac905a9f314b47038e05c' + + '3608fbb7e67a278e4f009a62c3cd3fdf43692e759d9361be1217999a76a69d4d119' + + 'f8791a90e207e46b3f6125721f56fd819292d06a3cdae2c62c9a1dc0d964a06036c' + + '8c18661cc6c873532a3536ab51e1ce210926db299e2', 'hex'), + 'sha3-384, salted': Buffer.from( + '8d1f9297c8169f27f0c58827dba991d862de58c1155f612ad2995d2bf862d051c4a' + + '91b48571849b0412384382e5b77990de6a3c84010046b35c4a504f175a3479483d9' + + '5c58f86bb96d53a27e59d6f67fddaae295ce90610f5086acc711557c2c85aac32d3' + + '24199cff2367ae44e1d91307a98c8cbfb085a8bce6b1c20714711bc15b0eddb7881' + + '823227d4be477ffdad8093663a6a1fc62eb39c49c2c3a821c2b202cf7904b49ca92' + + '3c83819602bb13931577354a80f99309030044935b1cd41f0513160e661db1959fb' + + '1ec15f087f3d288e875d54cbf070ec860b0aeecc951ea65e97cd5460750d4b7de52' + + '22cb9e7466b1f506ecf6a81fc399dfd8334160f9084', 'hex'), + 'sha3-512, salted': Buffer.from( + '7b6d7be418c5d37cc8070698b8b03d818ecd8b673d047d34921913f6d59c69cb496' + + '172d6118207d9ff92b8e1246acf0e03a845d935a70f8a82c3d5d6db6a1a0e337269' + + '4b904372413dcbaa7ac5486bc8ccaf70d7e9470be82b928a90017e272cf9761ed26' + + 'c160fe874a2675a4fb2acad72c50fbfffdd70b5a6f2919553d7ea1829934670f8de' + + 'f2a5c2816404b1aa153323c92c58400622f184b9b0463fa48d6b27091f68c287e3f' + + '6d9ab9eb451711a5d984c547f3d56f14a686a89ddf36c47ce25092b8c6530904de9' + + '5df7fc602fe9394315f1b1847aae304cb5ad71e2cb78acfbc997a87a9d62a6898bb' + + '6d84a81bb89b50186265f4be171a93d837a4bf777c8', 'hex') } const vectors = [ @@ -142,6 +252,54 @@ module.exports = function() { hash: 'SHA-512', plaintext, signature: signatures['sha-512, salted'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSA-PSS', saltLength: 0 }, + hash: 'SHA3-256', + plaintext, + signature: signatures['sha3-256, no salt'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSA-PSS', saltLength: 0 }, + hash: 'SHA3-384', + plaintext, + signature: signatures['sha3-384, no salt'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSA-PSS', saltLength: 0 }, + hash: 'SHA3-512', + plaintext, + signature: signatures['sha3-512, no salt'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSA-PSS', saltLength: 32 }, + hash: 'SHA3-256', + plaintext, + signature: signatures['sha3-256, salted'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSA-PSS', saltLength: 48 }, + hash: 'SHA3-384', + plaintext, + signature: signatures['sha3-384, salted'] + }, + { + publicKeyBuffer: spki, + privateKeyBuffer: pkcs8, + algorithm: { name: 'RSA-PSS', saltLength: 64 }, + hash: 'SHA3-512', + plaintext, + signature: signatures['sha3-512, salted'] } ]; diff --git a/test/fixtures/webcrypto/supports-sha3.mjs b/test/fixtures/webcrypto/supports-sha3.mjs new file mode 100644 index 0000000000..077c6a6c40 --- /dev/null +++ b/test/fixtures/webcrypto/supports-sha3.mjs @@ -0,0 +1,88 @@ +const { subtle } = globalThis.crypto; + +const RSA_KEY_GEN = { + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]) +}; + +const [ECDH, X448, X25519] = await Promise.all([ + subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, false, ['deriveBits', 'deriveKey']), + subtle.generateKey('X448', false, ['deriveBits', 'deriveKey']), + subtle.generateKey('X25519', false, ['deriveBits', 'deriveKey']), +]); + +export const vectors = { + 'digest': [ + [true, 'SHA3-256'], + [true, 'SHA3-384'], + [true, 'SHA3-512'], + ], + 'generateKey': [ + [true, { name: 'HMAC', hash: 'SHA3-256' }], + [true, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [false, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [true, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [true, { name: 'RSA-PSS', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [true, { name: 'RSA-OAEP', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [true, { name: 'HMAC', hash: 'SHA3-256' }], + [true, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [false, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [false, { name: 'HMAC', hash: 'SHA3-256', length: 0 }], + ], + 'deriveKey': [ + [true, + { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, + { name: 'AES-CBC', length: 128 }], + [true, + { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, + { name: 'HMAC', hash: 'SHA3-256' }], + [false, + { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, + 'HKDF'], + [true, + { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, + { name: 'AES-CBC', length: 128 }], + [true, + { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, + { name: 'HMAC', hash: 'SHA3-256' }], + [false, + { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, + 'HKDF'], + [true, + { name: 'X25519', public: X25519.publicKey }, + { name: 'HMAC', hash: 'SHA3-256' }], + [true, + { name: 'X448', public: X448.publicKey }, + { name: 'HMAC', hash: 'SHA3-256' }], + [true, + { name: 'ECDH', public: ECDH.publicKey }, + { name: 'HMAC', hash: 'SHA3-256' }], + ], + 'deriveBits': [ + [true, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 8], + [true, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 0], + [false, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, null], + [false, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 7], + + [true, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 8], + [true, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 0], + [false, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 0 }, 8], + [false, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, null], + [false, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 7], + ], + 'importKey': [ + [true, { name: 'HMAC', hash: 'SHA3-256' }], + [true, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [false, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [true, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [true, { name: 'RSA-PSS', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [true, { name: 'RSA-OAEP', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [true, { name: 'HMAC', hash: 'SHA3-256' }], + [true, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [false, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [false, { name: 'HMAC', hash: 'SHA3-256', length: 0 }], + ], + 'get key length': [ + [false, { name: 'HMAC', hash: 'SHA3-256' }], + ], +}; diff --git a/test/parallel/test-webcrypto-derivebits-hkdf.js b/test/parallel/test-webcrypto-derivebits-hkdf.js index f687e81a57..e5804a44e6 100644 --- a/test/parallel/test-webcrypto-derivebits-hkdf.js +++ b/test/parallel/test-webcrypto-derivebits-hkdf.js @@ -25,6 +25,9 @@ const kDerivedKeyTypes = [ ['HMAC', 256, 'SHA-256', 'sign', 'verify'], ['HMAC', 256, 'SHA-384', 'sign', 'verify'], ['HMAC', 256, 'SHA-512', 'sign', 'verify'], + ['HMAC', 256, 'SHA3-256', 'sign', 'verify'], + ['HMAC', 256, 'SHA3-384', 'sign', 'verify'], + ['HMAC', 256, 'SHA3-512', 'sign', 'verify'], ]; const kDerivedKeys = { @@ -70,7 +73,19 @@ const kDerivations = { 'b127e92631c1c051482d6690941772b4', empty: '9e4b719033742101e90f1ad61e2ff3b4' + '256863667296d74389f1f02af2c4e6a6' - } + }, + 'SHA3-256': { + normal: '386b0693d7a58c4ddf01b49bfbbd2fa87c6f911991543995170ba20ed28df599', + empty: 'd029bc828b6c6c8bb16ce3d25f5058f19c7d2517745e11c5d65c6d242e82e47f', + }, + 'SHA3-384': { + normal: '8c3b72e659bad40bcd14bdc1f7c3836059d24253795ab046a272973fd0456508', + empty: '3211ff4c676f761494c1ca2683d2d4662fe1d770ae5c58ebf6af6acb181c7d71', + }, + 'SHA3-512': { + normal: '5588c5c70cb3dd2f95323da2e9d5f299ca99c301d920a499330c449d21c645cd', + empty: '2c944b916c2751a71a1b5e57fcb487939c624335683995770b9f7cc7cbbb21f0', + }, }, empty: { 'SHA-384': { @@ -96,7 +111,19 @@ const kDerivations = { '0acea6f165476eb83460b9353ed41dfe', empty: 'c8e12774135305c9147f2cc4766e5ead' + '25d8f457b9a1953d52677361ced558fb' - } + }, + 'SHA3-256': { + normal: '9befc557f5baf4075b5fb38c014b41b92ab7534150baf64201069e8807d0e83d', + empty: '54d1fa1aa7cad99dab0622b772170e775c103756183bac36a228fd817a98a3f6', + }, + 'SHA3-384': { + normal: '46b54c015e368677edf7ac16963bccd9d2ba8246eef0e8beb04d8d188774b91b', + empty: '46eb0b2649bb0f605d70e4818ffc8176ee1be9782396e69fb4d0fd7cfe902b55', + }, + 'SHA3-512': { + normal: 'aa4375c82b5d7a3cac88a0423250b3882f140c253e98e8e7a0f6055b0908e4c2', + empty: '6613003f98602ddb53ac35f5aa256c9f5279d50ee65bb08fdf2ecf65cc5df27f', + }, } }, long: { @@ -124,7 +151,19 @@ const kDerivations = { '50b3dd9a29f30606e2cad199bec14d13', empty: 'e579d1f9e7f08e6f990ffcfcce1ed201' + 'c5e37e62cdf606f0ba4aca80427fbc44' - } + }, + 'SHA3-256': { + normal: '24f38fd1905554b7cbf8395cc3976292d11ce24a0b3131da0fd4b109832d27e3', + empty: '33d0a5151c0f52e4bb7fb67cf7a17063127624dc3e685903f49ebb07872084d1', + }, + 'SHA3-384': { + normal: '15777581a1ea81ad0baac8a97d954df4142f7260d9e8351aa7f6ef6de2d04632', + empty: 'ada4da4e28dc971633a8760b265b3019db57baf17e7bf7e13cf78b1a676f6d44', + }, + 'SHA3-512': { + normal: '621e4602b07fcba55ed6b976a8bef513b0f7c4ad0c546e0f852993051d887408', + empty: 'f1292af65b05c86cf7146b739bc65785c707450316f3207ee54a3f596a7d0f7b', + }, }, empty: { 'SHA-384': { @@ -150,7 +189,19 @@ const kDerivations = { '851cc5baadb42cad024b6290fe213436', empty: 'b4f7e7557674d501cbfbc0148ad800c0' + '750189fe295a2aca5e1bf4122c85edf9' - } + }, + 'SHA3-256': { + normal: 'fe32459f7339dd2e8df6c6fc874ed9e81e3b7aad669edad9b71196f53ed95b12', + empty: '04519be1eb94079c91306cc5b21946b3de6a78ad35ec83d4f4a37bafbda678d7', + }, + 'SHA3-384': { + normal: 'a474e8289cb4a0511e90b87eaf9ec29cadd74d4c1f2ee1fb8cb5f7d08f91a379', + empty: '726c8c4b39083a7d5755604d3a67e9aa6139db00c08028ac9e69f7fb1525bf1d', + }, + 'SHA3-512': { + normal: 'c7a7f5004d1d595c6896498c169642ac24b946e13296ff53e12b534962a88675', + empty: '7b543480b5696932551abb3100d72e05c18f57fbb63aa44fe020bef1eec3555c', + }, } }, }; @@ -294,7 +345,7 @@ async function testDeriveBitsBadHash( subtle.deriveBits( { ...algorithm, - hash: hash.substring(0, 3) + hash.substring(4) + hash: hash.replace('-', '') }, baseKeys[size], 256), { message: /Unrecognized algorithm name/, name: 'NotSupportedError', @@ -430,7 +481,7 @@ async function testDeriveKeyBadHash( subtle.deriveKey( { ...algorithm, - hash: hash.substring(0, 3) + hash.substring(4) + hash: hash.replace('-', '') }, baseKeys[size], keyType, diff --git a/test/parallel/test-webcrypto-derivekey.js b/test/parallel/test-webcrypto-derivekey.js index 90f7683947..3ee1dcf52f 100644 --- a/test/parallel/test-webcrypto-derivekey.js +++ b/test/parallel/test-webcrypto-derivekey.js @@ -73,10 +73,20 @@ const { KeyObject } = require('crypto'); } const kTests = [ + ['hello', 'there', 'my friend', 'SHA-1', + '365ca5d3f42d050c74302e420c83975327950f1913a151eecd00526bf52614a0'], ['hello', 'there', 'my friend', 'SHA-256', '14d93b0ccd99d4f2cbd9fbfe9c830b5b8a43e3e45e32941ef21bdeb0fa87b6b6'], ['hello', 'there', 'my friend', 'SHA-384', 'e36cf2cf943d8f3a88adb80f478745c336ac811b1a86d03a7d10eb0b6b52295c'], + ['hello', 'there', 'my friend', 'SHA-512', + '1e42d43fcacba361716f65853bd5f3c479f679612f0180eab3c51ed6c9d2b47d'], + ['hello', 'there', 'my friend', 'SHA3-256', + '2a49a3b6fb219117af9e251c6c65f16600cbca13bd0be6e70d96b0b9fa4cf3fd'], + ['hello', 'there', 'my friend', 'SHA3-384', + '0437bb59b95f2db2c7684c0b439028cb0fdd6f0f5d03b9f489066a87ae147221'], + ['hello', 'there', 'my friend', 'SHA3-512', + '3bbc469d38214371921e52c6f147e96cb7eb370421a81f53dea8b4851dfb8bce'], ]; const tests = Promise.all(kTests.map((args) => test(...args))); @@ -109,10 +119,20 @@ const { KeyObject } = require('crypto'); } const kTests = [ - ['hello', 'there', 10, 'SHA-256', - 'f72d1cf4853fffbd16a42751765d11f8dc7939498ee7b7ce7678b4cb16fad880'], + ['hello', 'there', 5, 'SHA-1', + 'f8f65a5fd92c9b74916083a7e9b0001c46bc89e2a14c48014cf1e0e1dbabf635'], + ['hello', 'there', 5, 'SHA-256', + '2e575eae24267db32106c7dba01615e5417557e8c5cf33ba15a311cb0c2907ee'], ['hello', 'there', 5, 'SHA-384', '201509b012c9cd2fbe7ea938f0c509b36ecb140f38bf9130e96923f55f46756d'], + ['hello', 'there', 5, 'SHA-512', + '2e8d981741f98193e0af9c79870af0e985089341221edad9a130d297eae1984b'], + ['hello', 'there', 5, 'SHA3-256', + '0aed29b61b3ca3978aea34a9793276574ea997b69e8d03727438199f90571649'], + ['hello', 'there', 5, 'SHA3-384', + '7aa4a274aa19b4623c5d3091c4b06355de85ff6f25e53a83e3126cbb86ae68df'], + ['hello', 'there', 5, 'SHA3-512', + '4d909c47a81c625f866d1f9406248e6bc3c7ea89225fbccf1f08820254c9ef56'], ]; const tests = Promise.all(kTests.map((args) => test(...args))); @@ -128,26 +148,36 @@ const { KeyObject } = require('crypto'); [{ name: 'HMAC', hash: 'SHA-1' }, 'sign', 512], [{ name: 'HMAC', hash: 'SHA-256' }, 'sign', 512], // Not long enough secret generated by ECDH - // [{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 1024], - // [{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024], + [{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 1024], + [{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024], + [{ name: 'HMAC', hash: 'SHA3-256' }, 'sign', 1088], + [{ name: 'HMAC', hash: 'SHA3-384' }, 'sign', 832], + [{ name: 'HMAC', hash: 'SHA3-512' }, 'sign', 576], ]; (async () => { const keyPair = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-521' }, false, ['deriveKey']); for (const [derivedKeyAlgorithm, usage, expected] of vectors) { - const derived = await subtle.deriveKey( + const [result] = await Promise.allSettled([subtle.deriveKey( { name: 'ECDH', public: keyPair.publicKey }, keyPair.privateKey, derivedKeyAlgorithm, false, - [usage]); + [usage])]); - if (derived.algorithm.name === 'HMAC') { - assert.strictEqual(derived.algorithm.length, expected); + if (expected > 528) { + assert.strictEqual(result.status, 'rejected'); + assert.match(result.reason.message, /derived bit length is too small/); } else { - // KDFs cannot be exportable and do not indicate their length - const secretKey = KeyObject.from(derived); - assert.strictEqual(secretKey.symmetricKeySize, expected / 8); + assert.strictEqual(result.status, 'fulfilled'); + const derived = result.value; + if (derived.algorithm.name === 'HMAC') { + assert.strictEqual(derived.algorithm.length, expected); + } else { + // KDFs cannot be exportable and do not indicate their length + const secretKey = KeyObject.from(derived); + assert.strictEqual(secretKey.symmetricKeySize, expected / 8); + } } } })().then(common.mustCall()); @@ -159,6 +189,9 @@ const { KeyObject } = require('crypto'); [{ name: 'HMAC', hash: 'SHA-256' }, 'sign', 512], [{ name: 'HMAC', hash: 'SHA-384' }, 'sign', 1024], [{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024], + [{ name: 'HMAC', hash: 'SHA3-256' }, 'sign', 1088], + [{ name: 'HMAC', hash: 'SHA3-384' }, 'sign', 832], + [{ name: 'HMAC', hash: 'SHA3-512' }, 'sign', 576], ]; (async () => { diff --git a/test/parallel/test-webcrypto-digest.js b/test/parallel/test-webcrypto-digest.js index 87902842de..debfca16cc 100644 --- a/test/parallel/test-webcrypto-digest.js +++ b/test/parallel/test-webcrypto-digest.js @@ -15,6 +15,9 @@ const kTests = [ ['SHA-256', ['sha256'], 256], ['SHA-384', ['sha384'], 384], ['SHA-512', ['sha512'], 512], + ['SHA3-256', ['sha3-256'], 256], + ['SHA3-384', ['sha3-384'], 384], + ['SHA3-512', ['sha3-512'], 512], [{ name: 'cSHAKE128', length: 256 }, ['shake128', { outputLength: 256 >> 3 }], 256], [{ name: 'cSHAKE256', length: 512 }, ['shake256', { outputLength: 512 >> 3 }], 512], ]; @@ -163,6 +166,40 @@ const kDigestedData = { 'd5290933492f9d17411926a613dd0611668c2ac999e8' + 'c011aabaa9004323425fbad75b0f58ee6e777a94' }, + 'sha3-256': { + empty: 'a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a', + short: '3059af7aa33b517084e8ad7bbc4fb208a44c28ef32b4698d103dd540e4f91aa1', + medium: '1fa7cd1da74cd8046417508c8314e74a9a4a9d38f9f18e6cb215b8c891a0a80e', + long: 'b2cfc61e0386cdaef5e10a2be189891f5ef52a7624bfcd8edc893acc64fec600' + }, + 'sha3-384': { + empty: '0c63a75b845e4f7d01107d852e4c2485c51a50aaaa9' + + '4fc61995e71bbee983a2ac3713831264adb47fb6bd1' + + 'e058d5f004', + short: '54b8f0e4cf4974de740098f66b3024479b01631315a' + + '6773606c33eadc32556a6e778e08f0225ae79265aec' + + '666cb2390b', + medium: '437b7d8b68b250b5c1739ea4cc86db2033879dfb18' + + 'de292c9c50d9c193a4c79a08a6cae3f4e483c2795e' + + 'a5d1ef7e69d2', + long: '3b39c4c97ad87613305d0ccc987181713e2d5e84b1f9' + + '760011bcce0c297499005bdce8a3d2409b5ad0164f32' + + 'bb8778d0' + }, + 'sha3-512': { + empty: 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe' + + '25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9' + + '402c3ac558f500199d95b6d3e301758586281dcd26', + short: '2dd2e07a62e6ad0498ba84f313c4d4024cb46001f78' + + 'f75db336b0d4d8bd2a9ec152c4ad20878735d82ba08' + + '72ecf59608ef3ced2b2a8669427e7da31e362333d8', + medium: 'e640a21909536640369e9b0a48931c5cb2efcbc91f' + + 'ecf247306bc96a0e4ca33307cb8e1b9af367946dd01' + + 'c243f3907508d04f1692a3161df1f898de8ee25febe', + long: 'bd262cecf565c338032de5ba0138f0aacfe7dde83d27' + + '2d0d37d952829ed25de1a1342d98659ef7d2fa4aca7c' + + 'e2b1aa0784d8fc1dcbf81bcec7a7431a3da36bf7' + } }; async function testDigest(size, alg) { diff --git a/test/parallel/test-webcrypto-encrypt-decrypt.js b/test/parallel/test-webcrypto-encrypt-decrypt.js index 5d4ecc02c7..ab46de7a16 100644 --- a/test/parallel/test-webcrypto-encrypt-decrypt.js +++ b/test/parallel/test-webcrypto-encrypt-decrypt.js @@ -11,7 +11,7 @@ const { subtle } = globalThis.crypto; // This is only a partial test. The WebCrypto Web Platform Tests // will provide much greater coverage. -// Test Encrypt/Decrypt RSA-OAEP +// Test Encrypt/Decrypt RSA-OAEP w/ SHA-2 { const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); @@ -56,6 +56,51 @@ const { subtle } = globalThis.crypto; test().then(common.mustCall()); } +// Test Encrypt/Decrypt RSA-OAEP w/ SHA-3 +{ + const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); + + async function test() { + const ec = new TextEncoder(); + const { publicKey, privateKey } = await subtle.generateKey({ + name: 'RSA-OAEP', + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA3-384', + }, true, ['encrypt', 'decrypt']); + + const ciphertext = await subtle.encrypt({ + name: 'RSA-OAEP', + label: ec.encode('a label') + }, publicKey, buf); + + const plaintext = await subtle.decrypt({ + name: 'RSA-OAEP', + label: ec.encode('a label') + }, privateKey, ciphertext); + + assert.strictEqual( + Buffer.from(plaintext).toString('hex'), + Buffer.from(buf).toString('hex')); + + await assert.rejects(() => subtle.encrypt({ + name: 'RSA-OAEP', + }, privateKey, buf), { + name: 'InvalidAccessError', + message: 'The requested operation is not valid for the provided key' + }); + + await assert.rejects(() => subtle.decrypt({ + name: 'RSA-OAEP', + }, publicKey, ciphertext), { + name: 'InvalidAccessError', + message: 'The requested operation is not valid for the provided key' + }); + } + + test().then(common.mustCall()); +} + // Test Encrypt/Decrypt AES-CTR { const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); diff --git a/test/parallel/test-webcrypto-export-import-ec.js b/test/parallel/test-webcrypto-export-import-ec.js index 57f1b2831e..46a7e9153f 100644 --- a/test/parallel/test-webcrypto-export-import-ec.js +++ b/test/parallel/test-webcrypto-export-import-ec.js @@ -423,14 +423,14 @@ async function testImportRaw({ name, publicUsages }, namedCurve) { subtle.importKey( 'spki', rsaPublic.export({ format: 'der', type: 'spki' }), - { name, hash: 'SHA-256', namedCurve: 'P-256' }, + { name, namedCurve: 'P-256' }, true, publicUsages), { message: /Invalid key type/ }, ).then(common.mustCall()); assert.rejects( subtle.importKey( 'pkcs8', rsaPrivate.export({ format: 'der', type: 'pkcs8' }), - { name, hash: 'SHA-256', namedCurve: 'P-256' }, + { name, namedCurve: 'P-256' }, true, privateUsages), { message: /Invalid key type/ }, ).then(common.mustCall()); } @@ -491,7 +491,7 @@ async function testImportRaw({ name, publicUsages }, namedCurve) { subtle.importKey( 'pkcs8', pkcs8, - { name, hash: 'SHA-256', namedCurve }, + { name, namedCurve }, true, privateUsages), { name: 'DataError', message: /Invalid keyData/ }, ).then(common.mustCall()); } diff --git a/test/parallel/test-webcrypto-export-import-rsa.js b/test/parallel/test-webcrypto-export-import-rsa.js index f1bdaeed4d..f726579d49 100644 --- a/test/parallel/test-webcrypto-export-import-rsa.js +++ b/test/parallel/test-webcrypto-export-import-rsa.js @@ -17,6 +17,9 @@ const hashes = [ 'SHA-256', 'SHA-384', 'SHA-512', + 'SHA3-256', + 'SHA3-384', + 'SHA3-512', ]; const keyData = { @@ -387,13 +390,13 @@ async function testImportJwk( let alg; switch (name) { case 'RSA-PSS': - alg = `PS${hash === 'SHA-1' ? 1 : hash.substring(4)}`; + alg = hash.startsWith('SHA-') ? `PS${hash === 'SHA-1' ? 1 : hash.substring(4)}` : undefined; break; case 'RSA-OAEP': - alg = `RSA-OAEP${hash === 'SHA-1' ? '' : hash.substring(3)}`; + alg = hash.startsWith('SHA-') ? `RSA-OAEP${hash === 'SHA-1' ? '' : hash.substring(3)}` : undefined; break; case 'RSASSA-PKCS1-v1_5': - alg = `RS${hash === 'SHA-1' ? 1 : hash.substring(4)}`; + alg = hash.startsWith('SHA-') ? `RS${hash === 'SHA-1' ? 1 : hash.substring(4)}` : undefined; break; } @@ -497,7 +500,7 @@ async function testImportJwk( { message: 'Invalid JWK "use" Parameter' }); } - { + if (alg) { await assert.rejects( subtle.importKey( 'jwk', @@ -516,7 +519,7 @@ async function testImportJwk( { message: 'JWK "alg" does not match the requested algorithm' }); } - { + if (!hash.startsWith('SHA3-')) { let invalidAlgHash = name === 'RSA-OAEP' ? name : name === 'RSA-PSS' ? 'PS' : 'RS'; switch (name) { case 'RSA-OAEP': @@ -547,7 +550,7 @@ async function testImportJwk( { message: 'JWK "alg" does not match the requested algorithm' }); } - { + if (!hash.startsWith('SHA3-')) { const invalidAlgType = name === 'RSA-PSS' ? `RS${hash.substring(4)}` : `PS${hash.substring(4)}`; await assert.rejects( subtle.importKey( diff --git a/test/parallel/test-webcrypto-export-import.js b/test/parallel/test-webcrypto-export-import.js index bd0cd056d4..2108972186 100644 --- a/test/parallel/test-webcrypto-export-import.js +++ b/test/parallel/test-webcrypto-export-import.js @@ -1,12 +1,14 @@ 'use strict'; const common = require('../common'); +const fixtures = require('../common/fixtures'); if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const { subtle } = globalThis.crypto; +const { createPrivateKey, createPublicKey, createSecretKey } = require('crypto'); { async function test() { @@ -291,3 +293,41 @@ const { subtle } = globalThis.crypto; test().then(common.mustCall()); } + +// SHA-3 hashes and JWK "alg" +{ + const rsa = fixtures.readKey('rsa_private_2048.pem'); + const privateKey = createPrivateKey(rsa); + const publicKey = createPublicKey(privateKey); + + async function test(keyObject, algorithm, usages) { + const key = keyObject.toCryptoKey(algorithm, true, usages); + const jwk = await subtle.exportKey('jwk', key); + assert.strictEqual(jwk.alg, undefined); + } + + for (const hash of ['SHA3-256', 'SHA3-384', 'SHA3-512']) { + for (const name of ['RSA-OAEP', 'RSA-PSS', 'RSASSA-PKCS1-v1_5']) { + test(publicKey, { name, hash }, []).then(common.mustCall()); + test(privateKey, { name, hash }, [name === 'RSA-OAEP' ? 'unwrapKey' : 'sign']).then(common.mustCall()); + } + + test(createSecretKey(Buffer.alloc(32)), { name: 'HMAC', hash }, ['sign']); + } + + { + const jwk = createSecretKey(Buffer.alloc(16)).export({ format: 'jwk' }); + // This is rejected for SHA-2 but ignored for SHA-3 + // Otherwise, if the name attribute of hash is defined in another applicable specification: + // Perform any key import steps defined by other applicable specifications, passing format, + // jwk and hash and obtaining hash. + jwk.alg = 'HS3-256'; + + assert.rejects(subtle.importKey('jwk', jwk, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']), { + name: 'DataError', + message: 'JWK "alg" does not match the requested algorithm', + }).then(common.mustCall()); + + subtle.importKey('jwk', jwk, { name: 'HMAC', hash: 'SHA3-256' }, false, ['sign', 'verify']).then(common.mustCall()); + } +} diff --git a/test/parallel/test-webcrypto-keygen.js b/test/parallel/test-webcrypto-keygen.js index b9802d90d7..08882ea976 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -401,15 +401,15 @@ if (hasOpenSSL(3, 5)) { 'RSASSA-PKCS1-v1_5', 1024, Buffer.from([1, 0, 1]), - 'SHA-256', + 'SHA-1', ['sign'], ['verify'], ], [ 'RSA-PSS', - 2048, + 1024, Buffer.from([1, 0, 1]), - 'SHA-512', + 'SHA-256', ['sign'], ['verify'], ], @@ -417,7 +417,7 @@ if (hasOpenSSL(3, 5)) { 'RSA-OAEP', 1024, Buffer.from([3]), - 'SHA-384', + 'SHA3-256', ['decrypt', 'unwrapKey'], ['encrypt', 'wrapKey'], ], @@ -579,6 +579,9 @@ if (hasOpenSSL(3, 5)) { case 'SHA-256': length = 512; break; case 'SHA-384': length = 1024; break; case 'SHA-512': length = 1024; break; + case 'SHA3-256': length = 1088; break; + case 'SHA3-384': length = 832; break; + case 'SHA3-512': length = 576; break; } } @@ -608,6 +611,9 @@ if (hasOpenSSL(3, 5)) { [ undefined, 'SHA-256', ['sign', 'verify']], [ undefined, 'SHA-384', ['sign', 'verify']], [ undefined, 'SHA-512', ['sign', 'verify']], + [ undefined, 'SHA3-256', ['sign', 'verify']], + [ undefined, 'SHA3-384', ['sign', 'verify']], + [ undefined, 'SHA3-512', ['sign', 'verify']], [ 128, 'SHA-256', ['sign', 'verify']], [ 1024, 'SHA-512', ['sign', 'verify']], ]; diff --git a/test/parallel/test-webcrypto-sign-verify-rsa.js b/test/parallel/test-webcrypto-sign-verify-rsa.js index ef9f6e8bd4..d3e3126ea0 100644 --- a/test/parallel/test-webcrypto-sign-verify-rsa.js +++ b/test/parallel/test-webcrypto-sign-verify-rsa.js @@ -236,7 +236,15 @@ async function testSaltLength(keyLength, hash, hLen) { }); for (const keyLength of [1024, 2048]) { - for (const [hash, hLen] of [['SHA-1', 20], ['SHA-256', 32], ['SHA-384', 48], ['SHA-512', 64]]) { + for (const [hash, hLen] of [ + ['SHA-1', 20], + ['SHA-256', 32], + ['SHA-384', 48], + ['SHA-512', 64], + ['SHA3-256', 32], + ['SHA3-384', 48], + ['SHA3-512', 64], + ]) { variations.push(testSaltLength(keyLength, hash, hLen)); } } diff --git a/test/parallel/test-webcrypto-supports.mjs b/test/parallel/test-webcrypto-supports.mjs index f21a239dc0..918fe6a38d 100644 --- a/test/parallel/test-webcrypto-supports.mjs +++ b/test/parallel/test-webcrypto-supports.mjs @@ -10,6 +10,7 @@ const sources = [ import('../fixtures/webcrypto/supports-level-2.mjs'), import('../fixtures/webcrypto/supports-secure-curves.mjs'), import('../fixtures/webcrypto/supports-modern-algorithms.mjs'), + import('../fixtures/webcrypto/supports-sha3.mjs'), ]; const vectors = {};