diff --git a/WebCryptoAPI/derive_bits_keys/cfrg_curves.js b/WebCryptoAPI/derive_bits_keys/cfrg_curves.js new file mode 100644 index 00000000000000..25113bfe04a140 --- /dev/null +++ b/WebCryptoAPI/derive_bits_keys/cfrg_curves.js @@ -0,0 +1,128 @@ +async function defineCfrgTests(algorithmName, operation) { + const subtle = self.crypto.subtle; + const isDeriveBits = operation === "deriveBits"; + + kSmallOrderPoint[algorithmName].forEach(test => { + promise_test(async() => { + let privateKey; + let publicKey; + let derived; + let error; + + try { + privateKey = await subtle.importKey( + "pkcs8", + pkcs8[algorithmName], + {name: algorithmName}, + false, + ["deriveBits", "deriveKey"] + ); + publicKey = await subtle.importKey( + "spki", + test.vector, + {name: algorithmName}, + false, + [] + ); + derived = isDeriveBits + ? await subtle.deriveBits( + {name: algorithmName, public: publicKey}, + privateKey, + 8 * sizes[algorithmName] + ) + : await subtle.deriveKey( + {name: algorithmName, public: publicKey}, + privateKey, + {name: "HMAC", hash: "SHA-256", length: 256}, + true, + ["sign", "verify"] + ); + } catch (caught) { + error = caught; + } + + assert_not_equals(privateKey, undefined, "Private key should be valid."); + assert_not_equals(publicKey, undefined, "Public key should be valid."); + assert_not_equals(error, undefined, "Operation should fail."); + assert_equals( + error.name, + "OperationError", + "Should throw correct error, not " + error.name + ": " + error.message + "." + ); + assert_equals(derived, undefined, "Operation succeeded, but should not have."); + }, algorithmName + + (isDeriveBits ? " key derivation" : " deriveBits") + + " checks for all-zero value result with a key of order " + test.order); + }); + + if (!isDeriveBits) { + promise_test(async() => { + const key = await subtle.generateKey( + {name: algorithmName}, + true, + ["deriveKey", "deriveBits"] + ); + const derived = await subtle.deriveKey( + {name: algorithmName, public: key.publicKey}, + key.privateKey, + {name: "HMAC", hash: "SHA-256", length: 256}, + true, + ["sign", "verify"] + ); + assert_not_equals(derived, undefined, "Key derivation failed."); + }, "Key derivation using a " + algorithmName + " generated keys."); + } + + const noUsage = isDeriveBits ? ["deriveKey"] : ["deriveBits"]; + const [ + privateKey, + noUsagePrivateKey, + publicKey, + ecdhPublicKey, + ] = await Promise.all([ + subtle.importKey( + "pkcs8", + pkcs8[algorithmName], + {name: algorithmName}, + false, + ["deriveBits", "deriveKey"] + ), + subtle.importKey( + "pkcs8", + pkcs8[algorithmName], + {name: algorithmName}, + false, + noUsage + ), + subtle.importKey( + "spki", + spki[algorithmName], + {name: algorithmName}, + false, + [] + ), + subtle.importKey( + "spki", + ecSPKI, + {name: "ECDH", namedCurve: "P-256"}, + false, + [] + ), + ]); + + registerDeriveTests({ + operation, + algorithmName, + mixedCaseName: algorithmName.toLowerCase(), + size: sizes[algorithmName], + derivation: derivations[algorithmName], + privateKey, + publicKey, + noUsagePrivateKey, + invalidPublicKeys: [{ + name: algorithmName + " mismatched algorithms", + key: ecdhPublicKey, + }], + missingPublicLabel: algorithmName + " missing public property", + }); +} diff --git a/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js b/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js index 1406e8bf0a1928..c3826a295e622c 100644 --- a/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js +++ b/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js @@ -1,227 +1,7 @@ function define_tests_25519() { - return define_tests("X25519"); + return defineCfrgTests("X25519", "deriveBits"); } function define_tests_448() { - return define_tests("X448"); -} - -function define_tests(algorithmName) { - // May want to test prefixed implementations. - var subtle = self.crypto.subtle; - - // Verify the derive functions perform checks against the all-zero value results, - // ensuring small-order points are rejected. - // https://www.rfc-editor.org/rfc/rfc7748#section-6.1 - { - kSmallOrderPoint[algorithmName].forEach(function(test) { - promise_test(async() => { - let derived; - let privateKey; - let publicKey; - try { - privateKey = await subtle.importKey("pkcs8", pkcs8[algorithmName], - {name: algorithmName}, - false, ["deriveBits", "deriveKey"]); - publicKey = await subtle.importKey("spki", test.vector, - {name: algorithmName}, - false, []) - derived = await subtle.deriveBits({name: algorithmName, public: publicKey}, privateKey, 8 * sizes[algorithmName]); - } catch (err) { - assert_true(privateKey !== undefined, "Private key should be valid."); - assert_true(publicKey !== undefined, "Public key should be valid."); - assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message + "."); - } - assert_equals(derived, undefined, "Operation succeeded, but should not have."); - }, algorithmName + " key derivation checks for all-zero value result with a key of order " + test.order); - }); - } - - return importKeys(pkcs8, spki, sizes) - .then(function(results) { - publicKeys = results.publicKeys; - privateKeys = results.privateKeys; - noDeriveBitsKeys = results.noDeriveBitsKeys; - ecdhKeys = results.ecdhKeys; - - { - // Basic success case - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[algorithmName]), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, algorithmName + " good parameters"); - - // Case insensitivity check - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName.toLowerCase(), public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[algorithmName]), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, algorithmName + " mixed case parameters"); - - // Shorter than entire derivation per algorithm - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName] - 32) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[algorithmName], 8 * sizes[algorithmName] - 32), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, algorithmName + " short result"); - - // Non-multiple of 8 - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName] - 11) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[algorithmName], 8 * sizes[algorithmName] - 11), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, algorithmName + " non-multiple of 8 bits"); - - // Errors to test: - - // - missing public property TypeError - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName}, privateKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " missing public property"); - - // - Non CryptoKey public property TypeError - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: {message: "Not a CryptoKey"}}, privateKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " public property of algorithm is not a CryptoKey"); - - // - wrong algorithm - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: ecdhKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " mismatched algorithms"); - - // - No deriveBits usage in baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, noDeriveBitsKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " no deriveBits usage for base key"); - - // - Use public key for baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, publicKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " base key is not a private key"); - - // - Use private key for public property InvalidAccessError - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: privateKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " public property value is a private key"); - - // - Use secret key for public property InvalidAccessError - promise_test(function(test) { - return subtle.generateKey({name: "AES-CBC", length: 128}, true, ["encrypt", "decrypt"]) - .then(function(secretKey) { - return subtle.deriveBits({name: algorithmName, public: secretKey}, privateKeys[algorithmName], 8 * sizes[algorithmName]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }); - }, algorithmName + " public property value is a secret key"); - - // - Length greater than possible for particular curves OperationError - promise_test(function(test) { - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName] + 8) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with OperationError"); - }, function(err) { - assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " asking for too many bits"); - } - }); - - function importKeys(pkcs8, spki, sizes) { - var privateKeys = {}; - var publicKeys = {}; - var noDeriveBitsKeys = {}; - var ecdhPublicKeys = {}; - - var promises = []; - { - var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], - {name: algorithmName}, - false, ["deriveBits", "deriveKey"]) - .then(function(key) { - privateKeys[algorithmName] = key; - }, function (err) { - privateKeys[algorithmName] = null; - }); - promises.push(operation); - } - { - var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], - {name: algorithmName}, - false, ["deriveKey"]) - .then(function(key) { - noDeriveBitsKeys[algorithmName] = key; - }, function (err) { - noDeriveBitsKeys[algorithmName] = null; - }); - promises.push(operation); - } - { - var operation = subtle.importKey("spki", spki[algorithmName], - {name: algorithmName}, - false, []) - .then(function(key) { - publicKeys[algorithmName] = key; - }, function (err) { - publicKeys[algorithmName] = null; - }); - promises.push(operation); - } - { - var operation = subtle.importKey("spki", ecSPKI, - {name: "ECDH", namedCurve: "P-256"}, - false, []) - .then(function(key) { - ecdhPublicKeys[algorithmName] = key; - }); - } - return Promise.all(promises) - .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveBitsKeys: noDeriveBitsKeys, ecdhKeys: ecdhPublicKeys}}); - } - + return defineCfrgTests("X448", "deriveBits"); } diff --git a/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js b/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js index 5684d7624076c7..b425652088742b 100644 --- a/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js @@ -1,6 +1,8 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves // META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js +// META: script=derive.js +// META: script=cfrg_curves.js // META: script=cfrg_curves_bits.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js b/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js index 5e482ef0b9d804..cda5ba87fba056 100644 --- a/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js @@ -1,6 +1,8 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves // META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js +// META: script=derive.js +// META: script=cfrg_curves.js // META: script=cfrg_curves_bits.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js b/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js index cefc45ac692903..1989c55c903fe5 100644 --- a/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js +++ b/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js @@ -1,224 +1,7 @@ function define_tests_25519() { - return define_tests("X25519"); + return defineCfrgTests("X25519", "deriveKey"); } function define_tests_448() { - return define_tests("X448"); -} - -function define_tests(algorithmName) { - // May want to test prefixed implementations. - var subtle = self.crypto.subtle; - - // Verify the derive functions perform checks against the all-zero value results, - // ensuring small-order points are rejected. - // https://www.rfc-editor.org/rfc/rfc7748#section-6.1 - // TODO: The spec states that the check must be done on use, but there is discussion about doing it on import. - // https://github.com/WICG/webcrypto-secure-curves/pull/13 - { - kSmallOrderPoint[algorithmName].forEach(function(test) { - promise_test(async() => { - let derived; - let privateKey; - let publicKey; - try { - privateKey = await subtle.importKey("pkcs8", pkcs8[algorithmName], - {name: algorithmName}, - false, ["deriveBits", "deriveKey"]); - publicKey = await subtle.importKey("spki", test.vector, - {name: algorithmName}, - false, []) - derived = await subtle.deriveKey({name: algorithmName, public: publicKey}, privateKey, - {name: "HMAC", hash: "SHA-256", length: 256}, true, - ["sign", "verify"]); - } catch (err) { - assert_false(privateKey === undefined, "Private key should be valid."); - assert_false(publicKey === undefined, "Public key should be valid."); - assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message + "."); - } - assert_equals(derived, undefined, "Operation succeeded, but should not have."); - }, algorithmName + " deriveBits checks for all-zero value result with a key of order " + test.order); - }); - } - - // Ensure the keys generated by each algorithm are valid for key derivation. - { - promise_test(async() => { - let derived; - try { - let key = await subtle.generateKey({name: algorithmName}, true, ["deriveKey", "deriveBits"]); - derived = await subtle.deriveKey({name: algorithmName, public: key.publicKey}, key.privateKey, {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]); - } catch (err) { - assert_unreached("Threw an unexpected error: " + err.toString() + " -"); - } - assert_false (derived === undefined, "Key derivation failed."); - }, "Key derivation using a " + algorithmName + " generated keys."); - } - - return importKeys(pkcs8, spki, sizes) - .then(function(results) { - publicKeys = results.publicKeys; - privateKeys = results.privateKeys; - noDeriveKeyKeys = results.noDeriveKeyKeys; - ecdhKeys = results.ecdhKeys; - - { - // Basic success case - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_true(equalBuffers(exportedKey, derivations[algorithmName], 8 * exportedKey.length), "Derived correct key"); - }, function(err) { - assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); - }); - }, algorithmName + " good parameters"); - - // Case insensitivity check - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName.toLowerCase(), public: publicKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_true(equalBuffers(exportedKey, derivations[algorithmName], 8 * exportedKey.length), "Derived correct key"); - }, function(err) { - assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); - }); - }, algorithmName + " mixed case parameters"); - // Errors to test: - - // - missing public property TypeError - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " missing public property"); - - // - Non CryptoKey public property TypeError - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName, public: {message: "Not a CryptoKey"}}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " public property of algorithm is not a CryptoKey"); - - // - wrong algorithm - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName, public: ecdhKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " mismatched algorithms"); - - // - No deriveKey usage in baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName, public: publicKeys[algorithmName]}, noDeriveKeyKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " no deriveKey usage for base key"); - - // - Use public key for baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName, public: publicKeys[algorithmName]}, publicKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " base key is not a private key"); - - // - Use private key for public property InvalidAccessError - promise_test(function(test) { - return subtle.deriveKey({name: algorithmName, public: privateKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, algorithmName + " public property value is a private key"); - - // - Use secret key for public property InvalidAccessError - promise_test(function(test) { - return subtle.generateKey({name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(secretKey) { - return subtle.deriveKey({name: algorithmName, public: secretKey}, privateKeys[algorithmName], {name: "AES-CBC", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }); - }, algorithmName + " public property value is a secret key"); - } - }); - - function importKeys(pkcs8, spki, sizes) { - var privateKeys = {}; - var publicKeys = {}; - var noDeriveKeyKeys = {}; - var ecdhPublicKeys = {}; - - var promises = []; - { - var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], - {name: algorithmName}, - false, ["deriveBits", "deriveKey"]) - .then(function(key) { - privateKeys[algorithmName] = key; - }, function (err) { - privateKeys[algorithmName] = null; - }); - promises.push(operation); - } - { - var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], - {name: algorithmName}, - false, ["deriveBits"]) - .then(function(key) { - noDeriveKeyKeys[algorithmName] = key; - }, function (err) { - noDeriveKeyKeys[algorithmName] = null; - }); - promises.push(operation); - } - { - var operation = subtle.importKey("spki", spki[algorithmName], - {name: algorithmName}, - false, []) - .then(function(key) { - publicKeys[algorithmName] = key; - }, function (err) { - publicKeys[algorithmName] = null; - }); - promises.push(operation); - } - { - var operation = subtle.importKey("spki", ecSPKI, - {name: "ECDH", namedCurve: "P-256"}, - false, []) - .then(function(key) { - ecdhPublicKeys[algorithmName] = key; - }); - } - - return Promise.all(promises) - .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveKeyKeys: noDeriveKeyKeys, ecdhKeys: ecdhPublicKeys}}); - } - + return defineCfrgTests("X448", "deriveKey"); } diff --git a/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js b/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js index 8bcc201d4e95ec..683ae21bac9f98 100644 --- a/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js @@ -1,6 +1,8 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves // META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js +// META: script=derive.js +// META: script=cfrg_curves.js // META: script=cfrg_curves_keys.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js b/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js index 0ed3954ac200b5..38a5ce1db5b24e 100644 --- a/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js @@ -1,6 +1,8 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves // META: script=../util/helpers.js // META: script=cfrg_curves_bits_fixtures.js +// META: script=derive.js +// META: script=cfrg_curves.js // META: script=cfrg_curves_keys.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/derive.js b/WebCryptoAPI/derive_bits_keys/derive.js new file mode 100644 index 00000000000000..16c9ec6407bbac --- /dev/null +++ b/WebCryptoAPI/derive_bits_keys/derive.js @@ -0,0 +1,169 @@ +function registerDeriveTests(options) { + const { + operation, + algorithmName, + testName = algorithmName, + mixedCaseName, + size, + derivation, + privateKey, + publicKey, + noUsagePrivateKey, + invalidPublicKeys, + missingPublicLabel, + } = options; + const subtle = self.crypto.subtle; + const isDeriveBits = operation === "deriveBits"; + const derivedKeyAlgorithm = {name: "HMAC", hash: "SHA-256", length: 256}; + const derivedKeyUsages = ["sign", "verify"]; + + function derive(name, publicKey, baseKey, length = 8 * size, keyOptions = {}) { + const algorithm = {name, public: publicKey}; + if (isDeriveBits) { + return subtle.deriveBits(algorithm, baseKey, length); + } + + return subtle.deriveKey( + algorithm, + baseKey, + keyOptions.algorithm || derivedKeyAlgorithm, + true, + keyOptions.usages || derivedKeyUsages + ).then(key => subtle.exportKey("raw", key)); + } + + function assertDerived(result, length) { + if (isDeriveBits) { + assert_true(equalBuffers(result, derivation, length), "Derived correct bits"); + } else { + assert_array_equals( + new Uint8Array(result), + derivation.slice(0, 32), + "Derived correct key" + ); + } + } + + function successTest(name, algorithm, length = 8 * size) { + promise_test(() => { + return derive(algorithm, publicKey, privateKey, length).then( + result => assertDerived(result, length), + error => assert_unreached( + operation + " failed with error " + error.name + ": " + error.message + ) + ); + }, name); + } + + function failureTest(name, expectedError, deriveOperation) { + promise_test(() => { + return Promise.resolve().then(deriveOperation).then( + () => assert_unreached( + operation + " succeeded but should have failed with " + expectedError + ), + error => assert_equals( + error.name, + expectedError, + "Should throw correct error, not " + error.name + ": " + error.message + ) + ); + }, name); + } + + successTest(testName + " good parameters", algorithmName); + successTest(testName + " mixed case parameters", mixedCaseName); + + if (isDeriveBits) { + successTest(testName + " short result", algorithmName, 8 * size - 32); + successTest( + testName + " non-multiple of 8 bits", + algorithmName, + 8 * size - 11 + ); + } + + failureTest(missingPublicLabel, "TypeError", () => { + return subtle[operation]( + {name: algorithmName}, + privateKey, + ...(isDeriveBits + ? [8 * size] + : [derivedKeyAlgorithm, true, derivedKeyUsages]) + ); + }); + + failureTest( + testName + " public property of algorithm is not a CryptoKey", + "TypeError", + () => derive(algorithmName, {message: "Not a CryptoKey"}, privateKey) + ); + + invalidPublicKeys.forEach(test => { + failureTest( + test.name, + "InvalidAccessError", + () => derive(algorithmName, test.key, privateKey) + ); + }); + + failureTest( + testName + " no " + operation + " usage for base key", + "InvalidAccessError", + () => derive(algorithmName, publicKey, noUsagePrivateKey) + ); + + failureTest( + testName + " base key is not a private key", + "InvalidAccessError", + () => derive(algorithmName, publicKey, publicKey) + ); + + failureTest( + testName + " public property value is a private key", + "InvalidAccessError", + () => derive(algorithmName, privateKey, privateKey) + ); + + promise_test(async() => { + const secretKey = isDeriveBits + ? await subtle.generateKey( + {name: "AES-CBC", length: 128}, + true, + ["encrypt", "decrypt"] + ) + : await subtle.generateKey( + derivedKeyAlgorithm, + true, + derivedKeyUsages + ); + const keyOptions = isDeriveBits ? {} : { + algorithm: {name: "AES-CBC", length: 256}, + usages: ["sign", "verify"], + }; + + return derive( + algorithmName, + secretKey, + privateKey, + 8 * size, + keyOptions + ).then( + () => assert_unreached( + operation + " succeeded but should have failed with InvalidAccessError" + ), + error => assert_equals( + error.name, + "InvalidAccessError", + "Should throw correct error, not " + error.name + ": " + error.message + ) + ); + }, testName + " public property value is a secret key"); + + if (isDeriveBits) { + failureTest( + testName + " asking for too many bits", + "OperationError", + () => derive(algorithmName, publicKey, privateKey, 8 * size + 8) + ); + } +} diff --git a/WebCryptoAPI/derive_bits_keys/ecdh.js b/WebCryptoAPI/derive_bits_keys/ecdh.js new file mode 100644 index 00000000000000..99039f250c2c59 --- /dev/null +++ b/WebCryptoAPI/derive_bits_keys/ecdh.js @@ -0,0 +1,79 @@ +async function defineEcdhTests(operation) { + const subtle = self.crypto.subtle; + const fixtures = getEcdhTestFixtures(); + const curves = Object.keys(fixtures.sizes); + const keys = {}; + + await Promise.all(curves.map(async namedCurve => { + const algorithm = {name: "ECDH", namedCurve}; + const noUsage = operation === "deriveBits" ? ["deriveKey"] : ["deriveBits"]; + const [ + privateKey, + noUsagePrivateKey, + publicKey, + ecdsaKeyPair, + ] = await Promise.all([ + subtle.importKey( + "pkcs8", + fixtures.pkcs8[namedCurve], + algorithm, + false, + ["deriveBits", "deriveKey"] + ), + subtle.importKey( + "pkcs8", + fixtures.pkcs8[namedCurve], + algorithm, + false, + noUsage + ), + subtle.importKey( + "spki", + fixtures.spki[namedCurve], + algorithm, + false, + [] + ), + subtle.generateKey( + {name: "ECDSA", namedCurve}, + false, + ["sign", "verify"] + ), + ]); + + keys[namedCurve] = { + privateKey, + noUsagePrivateKey, + publicKey, + ecdsaKeyPair, + }; + })); + + curves.forEach(namedCurve => { + const otherCurve = namedCurve === "P-256" ? "P-384" : "P-256"; + const key = keys[namedCurve]; + registerDeriveTests({ + operation, + algorithmName: "ECDH", + testName: namedCurve, + mixedCaseName: "EcDh", + size: fixtures.sizes[namedCurve], + derivation: fixtures.derivations[namedCurve], + privateKey: key.privateKey, + publicKey: key.publicKey, + noUsagePrivateKey: key.noUsagePrivateKey, + invalidPublicKeys: [ + { + name: namedCurve + " mismatched curves", + key: keys[otherCurve].publicKey, + }, + { + name: namedCurve + + " public property of algorithm is not an ECDSA public key", + key: key.ecdsaKeyPair.publicKey, + }, + ], + missingPublicLabel: namedCurve + " missing public curve", + }); + }); +} diff --git a/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js b/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js index 58a0cecd5efed6..38058d6ce7231b 100644 --- a/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.js @@ -1,5 +1,8 @@ // META: title=WebCryptoAPI: deriveBits() Using ECDH // META: script=../util/helpers.js +// META: script=ecdh_fixtures.js +// META: script=derive.js +// META: script=ecdh.js // META: script=ecdh_bits.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/ecdh_bits.js b/WebCryptoAPI/derive_bits_keys/ecdh_bits.js index 8e79909020d398..bbe48b5e2859b5 100644 --- a/WebCryptoAPI/derive_bits_keys/ecdh_bits.js +++ b/WebCryptoAPI/derive_bits_keys/ecdh_bits.js @@ -1,233 +1,3 @@ - function define_tests() { - // May want to test prefixed implementations. - var subtle = self.crypto.subtle; - - var pkcs8 = { - "P-521": new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 1, 166, 126, 211, 33, 145, 90, 100, 170, 53, 155, 125, 100, 141, 220, 38, 24, 250, 142, 141, 24, 103, 232, 247, 24, 48, 177, 13, 37, 237, 40, 145, 250, 241, 47, 60, 126, 117, 66, 26, 46, 162, 100, 249, 169, 21, 50, 13, 39, 79, 225, 71, 7, 66, 185, 132, 233, 107, 152, 145, 32, 129, 250, 205, 71, 141, 161, 129, 137, 3, 129, 134, 0, 4, 0, 32, 157, 72, 63, 40, 102, 104, 129, 198, 100, 31, 58, 18, 111, 64, 15, 81, 228, 101, 17, 112, 254, 103, 140, 117, 232, 87, 18, 226, 134, 138, 220, 133, 8, 36, 153, 123, 235, 240, 188, 130, 180, 48, 40, 166, 210, 236, 23, 119, 202, 69, 39, 159, 114, 6, 163, 234, 139, 92, 210, 7, 63, 73, 62, 69, 0, 12, 181, 76, 58, 90, 202, 162, 104, 197, 103, 16, 66, 136, 120, 217, 139, 138, 251, 246, 138, 97, 33, 83, 99, 40, 70, 216, 7, 233, 38, 114, 105, 143, 27, 156, 97, 29, 231, 211, 142, 52, 205, 108, 115, 136, 144, 146, 197, 110, 82, 214, 128, 241, 223, 208, 146, 184, 122, 200, 239, 159, 243, 200, 251, 72]), - "P-256": new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 15, 247, 79, 232, 241, 202, 175, 97, 92, 206, 241, 29, 217, 53, 114, 87, 98, 217, 216, 65, 236, 186, 185, 94, 170, 38, 68, 123, 52, 100, 245, 113, 161, 68, 3, 66, 0, 4, 140, 96, 11, 44, 102, 25, 45, 97, 158, 39, 210, 37, 107, 59, 151, 118, 178, 141, 30, 5, 246, 13, 234, 189, 98, 174, 123, 154, 211, 157, 224, 217, 59, 4, 102, 109, 199, 119, 14, 126, 207, 13, 211, 203, 203, 211, 110, 221, 107, 94, 220, 153, 81, 7, 55, 161, 237, 104, 46, 205, 112, 244, 10, 47]), - "P-384": new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 248, 113, 165, 102, 101, 137, 193, 74, 87, 71, 38, 62, 248, 91, 49, 156, 192, 35, 219, 110, 53, 103, 108, 61, 120, 30, 239, 139, 5, 95, 207, 190, 134, 250, 13, 6, 208, 86, 181, 25, 95, 177, 50, 58, 248, 222, 37, 179, 161, 100, 3, 98, 0, 4, 241, 25, 101, 223, 125, 212, 89, 77, 4, 25, 197, 8, 100, 130, 163, 184, 38, 185, 121, 127, 155, 224, 189, 13, 16, 156, 158, 30, 153, 137, 193, 185, 169, 43, 143, 38, 159, 152, 225, 122, 209, 132, 186, 115, 193, 247, 151, 98, 175, 69, 175, 129, 65, 96, 38, 66, 218, 39, 26, 107, 176, 255, 235, 12, 180, 71, 143, 207, 112, 126, 102, 26, 166, 214, 205, 245, 21, 73, 200, 140, 63, 19, 11, 233, 232, 32, 31, 111, 106, 9, 244, 24, 90, 175, 149, 196]) - }; - - var spki = { - "P-521": new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 0, 238, 105, 249, 71, 21, 215, 1, 233, 226, 1, 19, 51, 212, 244, 249, 108, 186, 125, 145, 248, 139, 17, 43, 175, 117, 207, 9, 204, 31, 138, 202, 151, 97, 141, 169, 56, 152, 34, 210, 155, 111, 233, 153, 106, 97, 32, 62, 247, 82, 183, 113, 232, 149, 143, 196, 103, 123, 179, 119, 133, 101, 171, 96, 214, 237, 0, 222, 171, 103, 97, 137, 91, 147, 94, 58, 211, 37, 251, 133, 73, 229, 111, 19, 120, 106, 167, 63, 136, 162, 236, 254, 64, 147, 52, 115, 216, 174, 242, 64, 196, 223, 215, 213, 6, 242, 44, 221, 14, 85, 85, 143, 63, 191, 5, 235, 247, 239, 239, 122, 114, 215, 143, 70, 70, 155, 132, 72, 242, 110, 39, 18]), - "P-256": new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 154, 116, 32, 120, 126, 95, 77, 105, 211, 232, 34, 114, 115, 1, 109, 56, 224, 71, 129, 133, 223, 127, 238, 156, 142, 103, 60, 202, 211, 79, 126, 128, 254, 49, 141, 182, 221, 107, 119, 218, 99, 32, 165, 246, 151, 89, 9, 68, 23, 177, 52, 239, 138, 139, 116, 193, 101, 4, 57, 198, 115, 0, 90, 61]), - "P-384": new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 145, 130, 45, 194, 175, 89, 193, 143, 91, 103, 248, 13, 246, 26, 38, 3, 194, 168, 240, 179, 192, 175, 130, 45, 99, 194, 121, 112, 26, 130, 69, 96, 64, 68, 1, 221, 233, 165, 110, 229, 39, 87, 234, 139, 199, 72, 212, 200, 43, 83, 55, 180, 141, 123, 101, 88, 58, 61, 87, 36, 56, 136, 0, 54, 186, 198, 115, 15, 66, 202, 82, 120, 150, 107, 213, 242, 30, 134, 226, 29, 48, 197, 166, 208, 70, 62, 197, 19, 221, 80, 159, 252, 220, 175, 31, 245]) - }; - - var sizes = { - "P-521": 66, - "P-256": 32, - "P-384": 48 - }; - - var derivations = { - "P-521": new Uint8Array([0, 156, 43, 206, 87, 190, 128, 173, 171, 59, 7, 56, 91, 142, 89, 144, 235, 125, 111, 222, 189, 176, 27, 243, 83, 113, 164, 246, 7, 94, 157, 40, 138, 193, 42, 109, 254, 3, 170, 87, 67, 188, 129, 112, 157, 73, 168, 34, 148, 2, 25, 182, 75, 118, 138, 205, 82, 15, 161, 54, 142, 160, 175, 141, 71, 93]), - "P-256": new Uint8Array([14, 143, 60, 77, 177, 178, 162, 131, 115, 90, 0, 220, 87, 31, 26, 232, 151, 28, 227, 35, 250, 17, 131, 137, 203, 95, 65, 196, 59, 61, 181, 161]), - "P-384": new Uint8Array([224, 189, 107, 206, 10, 239, 140, 164, 136, 56, 166, 226, 252, 197, 126, 103, 185, 197, 232, 134, 12, 95, 11, 233, 218, 190, 197, 62, 69, 78, 24, 160, 161, 116, 196, 136, 136, 162, 100, 136, 17, 91, 45, 201, 241, 223, 165, 45]) - }; - - return importKeys(pkcs8, spki, sizes) - .then(function(results) { - publicKeys = results.publicKeys; - privateKeys = results.privateKeys; - ecdsaKeyPairs = results.ecdsaKeyPairs; - noDeriveBitsKeys = results.noDeriveBitsKeys; - - Object.keys(sizes).forEach(function(namedCurve) { - // Basic success case - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[namedCurve]), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, namedCurve + " good parameters"); - - // Case insensitivity check - promise_test(function(test) { - return subtle.deriveBits({name: "EcDh", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[namedCurve]), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, namedCurve + " mixed case parameters"); - - // Shorter than entire derivation per algorithm - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve] - 32) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[namedCurve], 8 * sizes[namedCurve] - 32), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, namedCurve + " short result"); - - // Non-multiple of 8 - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve] - 11) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[namedCurve], 8 * sizes[namedCurve] - 11), "Derived correct bits"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, namedCurve + " non-multiple of 8 bits"); - - // Errors to test: - - // - missing public property TypeError - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH"}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " missing public curve"); - - // - Non CryptoKey public property TypeError - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: {message: "Not a CryptoKey"}}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " public property of algorithm is not a CryptoKey"); - - // - wrong named curve - promise_test(function(test) { - publicKey = publicKeys["P-256"]; - if (namedCurve === "P-256") { - publicKey = publicKeys["P-384"]; - } - return subtle.deriveBits({name: "ECDH", public: publicKey}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " mismatched curves"); - - // - not ECDH public property InvalidAccessError - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: ecdsaKeyPairs[namedCurve].publicKey}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " public property of algorithm is not an ECDSA public key"); - - // - No deriveBits usage in baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, noDeriveBitsKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " no deriveBits usage for base key"); - - // - Use public key for baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, publicKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " base key is not a private key"); - - // - Use private key for public property InvalidAccessError - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: privateKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " public property value is a private key"); - - // - Use secret key for public property InvalidAccessError - promise_test(function(test) { - return subtle.generateKey({name: "AES-CBC", length: 128}, true, ["encrypt", "decrypt"]) - .then(function(secretKey) { - return subtle.deriveBits({name: "ECDH", public: secretKey}, privateKeys[namedCurve], 8 * sizes[namedCurve]) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }); - }, namedCurve + " public property value is a secret key"); - - // - Length greater than 256, 384, 521 for particular curves OperationError - promise_test(function(test) { - return subtle.deriveBits({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], 8 * sizes[namedCurve] + 8) - .then(function(derivation) { - assert_unreached("deriveBits succeeded but should have failed with OperationError"); - }, function(err) { - assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " asking for too many bits"); - }); - }); - - function importKeys(pkcs8, spki, sizes) { - var privateKeys = {}; - var publicKeys = {}; - var ecdsaKeyPairs = {}; - var noDeriveBitsKeys = {}; - - var promises = []; - Object.keys(pkcs8).forEach(function(namedCurve) { - var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], - {name: "ECDH", namedCurve: namedCurve}, - false, ["deriveBits", "deriveKey"]) - .then(function(key) { - privateKeys[namedCurve] = key; - }, function (err) { - privateKeys[namedCurve] = null; - }); - promises.push(operation); - }); - Object.keys(pkcs8).forEach(function(namedCurve) { - var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], - {name: "ECDH", namedCurve: namedCurve}, - false, ["deriveKey"]) - .then(function(key) { - noDeriveBitsKeys[namedCurve] = key; - }, function (err) { - noDeriveBitsKeys[namedCurve] = null; - }); - promises.push(operation); - }); - Object.keys(spki).forEach(function(namedCurve) { - var operation = subtle.importKey("spki", spki[namedCurve], - {name: "ECDH", namedCurve: namedCurve}, - false, []) - .then(function(key) { - publicKeys[namedCurve] = key; - }, function (err) { - publicKeys[namedCurve] = null; - }); - promises.push(operation); - }); - Object.keys(sizes).forEach(function(namedCurve) { - var operation = subtle.generateKey({name: "ECDSA", namedCurve: namedCurve}, false, ["sign", "verify"]) - .then(function(keyPair) { - ecdsaKeyPairs[namedCurve] = keyPair; - }, function (err) { - ecdsaKeyPairs[namedCurve] = null; - }); - promises.push(operation); - }); - - return Promise.all(promises) - .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, ecdsaKeyPairs: ecdsaKeyPairs, noDeriveBitsKeys: noDeriveBitsKeys}}); - } - + return defineEcdhTests("deriveBits"); } diff --git a/WebCryptoAPI/derive_bits_keys/ecdh_fixtures.js b/WebCryptoAPI/derive_bits_keys/ecdh_fixtures.js new file mode 100644 index 00000000000000..46539d548da74f --- /dev/null +++ b/WebCryptoAPI/derive_bits_keys/ecdh_fixtures.js @@ -0,0 +1,32 @@ +function getEcdhTestFixtures() { + var pkcs8 = { + "P-521": new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 1, 166, 126, 211, 33, 145, 90, 100, 170, 53, 155, 125, 100, 141, 220, 38, 24, 250, 142, 141, 24, 103, 232, 247, 24, 48, 177, 13, 37, 237, 40, 145, 250, 241, 47, 60, 126, 117, 66, 26, 46, 162, 100, 249, 169, 21, 50, 13, 39, 79, 225, 71, 7, 66, 185, 132, 233, 107, 152, 145, 32, 129, 250, 205, 71, 141, 161, 129, 137, 3, 129, 134, 0, 4, 0, 32, 157, 72, 63, 40, 102, 104, 129, 198, 100, 31, 58, 18, 111, 64, 15, 81, 228, 101, 17, 112, 254, 103, 140, 117, 232, 87, 18, 226, 134, 138, 220, 133, 8, 36, 153, 123, 235, 240, 188, 130, 180, 48, 40, 166, 210, 236, 23, 119, 202, 69, 39, 159, 114, 6, 163, 234, 139, 92, 210, 7, 63, 73, 62, 69, 0, 12, 181, 76, 58, 90, 202, 162, 104, 197, 103, 16, 66, 136, 120, 217, 139, 138, 251, 246, 138, 97, 33, 83, 99, 40, 70, 216, 7, 233, 38, 114, 105, 143, 27, 156, 97, 29, 231, 211, 142, 52, 205, 108, 115, 136, 144, 146, 197, 110, 82, 214, 128, 241, 223, 208, 146, 184, 122, 200, 239, 159, 243, 200, 251, 72]), + "P-256": new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 15, 247, 79, 232, 241, 202, 175, 97, 92, 206, 241, 29, 217, 53, 114, 87, 98, 217, 216, 65, 236, 186, 185, 94, 170, 38, 68, 123, 52, 100, 245, 113, 161, 68, 3, 66, 0, 4, 140, 96, 11, 44, 102, 25, 45, 97, 158, 39, 210, 37, 107, 59, 151, 118, 178, 141, 30, 5, 246, 13, 234, 189, 98, 174, 123, 154, 211, 157, 224, 217, 59, 4, 102, 109, 199, 119, 14, 126, 207, 13, 211, 203, 203, 211, 110, 221, 107, 94, 220, 153, 81, 7, 55, 161, 237, 104, 46, 205, 112, 244, 10, 47]), + "P-384": new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 248, 113, 165, 102, 101, 137, 193, 74, 87, 71, 38, 62, 248, 91, 49, 156, 192, 35, 219, 110, 53, 103, 108, 61, 120, 30, 239, 139, 5, 95, 207, 190, 134, 250, 13, 6, 208, 86, 181, 25, 95, 177, 50, 58, 248, 222, 37, 179, 161, 100, 3, 98, 0, 4, 241, 25, 101, 223, 125, 212, 89, 77, 4, 25, 197, 8, 100, 130, 163, 184, 38, 185, 121, 127, 155, 224, 189, 13, 16, 156, 158, 30, 153, 137, 193, 185, 169, 43, 143, 38, 159, 152, 225, 122, 209, 132, 186, 115, 193, 247, 151, 98, 175, 69, 175, 129, 65, 96, 38, 66, 218, 39, 26, 107, 176, 255, 235, 12, 180, 71, 143, 207, 112, 126, 102, 26, 166, 214, 205, 245, 21, 73, 200, 140, 63, 19, 11, 233, 232, 32, 31, 111, 106, 9, 244, 24, 90, 175, 149, 196]) + }; + + var spki = { + "P-521": new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 0, 238, 105, 249, 71, 21, 215, 1, 233, 226, 1, 19, 51, 212, 244, 249, 108, 186, 125, 145, 248, 139, 17, 43, 175, 117, 207, 9, 204, 31, 138, 202, 151, 97, 141, 169, 56, 152, 34, 210, 155, 111, 233, 153, 106, 97, 32, 62, 247, 82, 183, 113, 232, 149, 143, 196, 103, 123, 179, 119, 133, 101, 171, 96, 214, 237, 0, 222, 171, 103, 97, 137, 91, 147, 94, 58, 211, 37, 251, 133, 73, 229, 111, 19, 120, 106, 167, 63, 136, 162, 236, 254, 64, 147, 52, 115, 216, 174, 242, 64, 196, 223, 215, 213, 6, 242, 44, 221, 14, 85, 85, 143, 63, 191, 5, 235, 247, 239, 239, 122, 114, 215, 143, 70, 70, 155, 132, 72, 242, 110, 39, 18]), + "P-256": new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 154, 116, 32, 120, 126, 95, 77, 105, 211, 232, 34, 114, 115, 1, 109, 56, 224, 71, 129, 133, 223, 127, 238, 156, 142, 103, 60, 202, 211, 79, 126, 128, 254, 49, 141, 182, 221, 107, 119, 218, 99, 32, 165, 246, 151, 89, 9, 68, 23, 177, 52, 239, 138, 139, 116, 193, 101, 4, 57, 198, 115, 0, 90, 61]), + "P-384": new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 145, 130, 45, 194, 175, 89, 193, 143, 91, 103, 248, 13, 246, 26, 38, 3, 194, 168, 240, 179, 192, 175, 130, 45, 99, 194, 121, 112, 26, 130, 69, 96, 64, 68, 1, 221, 233, 165, 110, 229, 39, 87, 234, 139, 199, 72, 212, 200, 43, 83, 55, 180, 141, 123, 101, 88, 58, 61, 87, 36, 56, 136, 0, 54, 186, 198, 115, 15, 66, 202, 82, 120, 150, 107, 213, 242, 30, 134, 226, 29, 48, 197, 166, 208, 70, 62, 197, 19, 221, 80, 159, 252, 220, 175, 31, 245]) + }; + + var sizes = { + "P-521": 66, + "P-256": 32, + "P-384": 48 + }; + + var derivations = { + "P-521": new Uint8Array([0, 156, 43, 206, 87, 190, 128, 173, 171, 59, 7, 56, 91, 142, 89, 144, 235, 125, 111, 222, 189, 176, 27, 243, 83, 113, 164, 246, 7, 94, 157, 40, 138, 193, 42, 109, 254, 3, 170, 87, 67, 188, 129, 112, 157, 73, 168, 34, 148, 2, 25, 182, 75, 118, 138, 205, 82, 15, 161, 54, 142, 160, 175, 141, 71, 93]), + "P-256": new Uint8Array([14, 143, 60, 77, 177, 178, 162, 131, 115, 90, 0, 220, 87, 31, 26, 232, 151, 28, 227, 35, 250, 17, 131, 137, 203, 95, 65, 196, 59, 61, 181, 161]), + "P-384": new Uint8Array([224, 189, 107, 206, 10, 239, 140, 164, 136, 56, 166, 226, 252, 197, 126, 103, 185, 197, 232, 134, 12, 95, 11, 233, 218, 190, 197, 62, 69, 78, 24, 160, 161, 116, 196, 136, 136, 162, 100, 136, 17, 91, 45, 201, 241, 223, 165, 45]) + }; + + return { + pkcs8: pkcs8, + spki: spki, + sizes: sizes, + derivations: derivations, + }; +} diff --git a/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js b/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js index 6464dacfe3aa81..f9d0da921d52b1 100644 --- a/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/ecdh_keys.https.any.js @@ -1,5 +1,8 @@ // META: title=WebCryptoAPI: deriveKey() Using ECDH // META: script=../util/helpers.js +// META: script=ecdh_fixtures.js +// META: script=derive.js +// META: script=ecdh.js // META: script=ecdh_keys.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/ecdh_keys.js b/WebCryptoAPI/derive_bits_keys/ecdh_keys.js index 8c3d2aeb5a4976..c4ee495aa6ffe7 100644 --- a/WebCryptoAPI/derive_bits_keys/ecdh_keys.js +++ b/WebCryptoAPI/derive_bits_keys/ecdh_keys.js @@ -1,212 +1,3 @@ - function define_tests() { - // May want to test prefixed implementations. - var subtle = self.crypto.subtle; - - var pkcs8 = { - "P-521": new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 1, 166, 126, 211, 33, 145, 90, 100, 170, 53, 155, 125, 100, 141, 220, 38, 24, 250, 142, 141, 24, 103, 232, 247, 24, 48, 177, 13, 37, 237, 40, 145, 250, 241, 47, 60, 126, 117, 66, 26, 46, 162, 100, 249, 169, 21, 50, 13, 39, 79, 225, 71, 7, 66, 185, 132, 233, 107, 152, 145, 32, 129, 250, 205, 71, 141, 161, 129, 137, 3, 129, 134, 0, 4, 0, 32, 157, 72, 63, 40, 102, 104, 129, 198, 100, 31, 58, 18, 111, 64, 15, 81, 228, 101, 17, 112, 254, 103, 140, 117, 232, 87, 18, 226, 134, 138, 220, 133, 8, 36, 153, 123, 235, 240, 188, 130, 180, 48, 40, 166, 210, 236, 23, 119, 202, 69, 39, 159, 114, 6, 163, 234, 139, 92, 210, 7, 63, 73, 62, 69, 0, 12, 181, 76, 58, 90, 202, 162, 104, 197, 103, 16, 66, 136, 120, 217, 139, 138, 251, 246, 138, 97, 33, 83, 99, 40, 70, 216, 7, 233, 38, 114, 105, 143, 27, 156, 97, 29, 231, 211, 142, 52, 205, 108, 115, 136, 144, 146, 197, 110, 82, 214, 128, 241, 223, 208, 146, 184, 122, 200, 239, 159, 243, 200, 251, 72]), - "P-256": new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 15, 247, 79, 232, 241, 202, 175, 97, 92, 206, 241, 29, 217, 53, 114, 87, 98, 217, 216, 65, 236, 186, 185, 94, 170, 38, 68, 123, 52, 100, 245, 113, 161, 68, 3, 66, 0, 4, 140, 96, 11, 44, 102, 25, 45, 97, 158, 39, 210, 37, 107, 59, 151, 118, 178, 141, 30, 5, 246, 13, 234, 189, 98, 174, 123, 154, 211, 157, 224, 217, 59, 4, 102, 109, 199, 119, 14, 126, 207, 13, 211, 203, 203, 211, 110, 221, 107, 94, 220, 153, 81, 7, 55, 161, 237, 104, 46, 205, 112, 244, 10, 47]), - "P-384": new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 248, 113, 165, 102, 101, 137, 193, 74, 87, 71, 38, 62, 248, 91, 49, 156, 192, 35, 219, 110, 53, 103, 108, 61, 120, 30, 239, 139, 5, 95, 207, 190, 134, 250, 13, 6, 208, 86, 181, 25, 95, 177, 50, 58, 248, 222, 37, 179, 161, 100, 3, 98, 0, 4, 241, 25, 101, 223, 125, 212, 89, 77, 4, 25, 197, 8, 100, 130, 163, 184, 38, 185, 121, 127, 155, 224, 189, 13, 16, 156, 158, 30, 153, 137, 193, 185, 169, 43, 143, 38, 159, 152, 225, 122, 209, 132, 186, 115, 193, 247, 151, 98, 175, 69, 175, 129, 65, 96, 38, 66, 218, 39, 26, 107, 176, 255, 235, 12, 180, 71, 143, 207, 112, 126, 102, 26, 166, 214, 205, 245, 21, 73, 200, 140, 63, 19, 11, 233, 232, 32, 31, 111, 106, 9, 244, 24, 90, 175, 149, 196]) - }; - - var spki = { - "P-521": new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 0, 238, 105, 249, 71, 21, 215, 1, 233, 226, 1, 19, 51, 212, 244, 249, 108, 186, 125, 145, 248, 139, 17, 43, 175, 117, 207, 9, 204, 31, 138, 202, 151, 97, 141, 169, 56, 152, 34, 210, 155, 111, 233, 153, 106, 97, 32, 62, 247, 82, 183, 113, 232, 149, 143, 196, 103, 123, 179, 119, 133, 101, 171, 96, 214, 237, 0, 222, 171, 103, 97, 137, 91, 147, 94, 58, 211, 37, 251, 133, 73, 229, 111, 19, 120, 106, 167, 63, 136, 162, 236, 254, 64, 147, 52, 115, 216, 174, 242, 64, 196, 223, 215, 213, 6, 242, 44, 221, 14, 85, 85, 143, 63, 191, 5, 235, 247, 239, 239, 122, 114, 215, 143, 70, 70, 155, 132, 72, 242, 110, 39, 18]), - "P-256": new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 154, 116, 32, 120, 126, 95, 77, 105, 211, 232, 34, 114, 115, 1, 109, 56, 224, 71, 129, 133, 223, 127, 238, 156, 142, 103, 60, 202, 211, 79, 126, 128, 254, 49, 141, 182, 221, 107, 119, 218, 99, 32, 165, 246, 151, 89, 9, 68, 23, 177, 52, 239, 138, 139, 116, 193, 101, 4, 57, 198, 115, 0, 90, 61]), - "P-384": new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 145, 130, 45, 194, 175, 89, 193, 143, 91, 103, 248, 13, 246, 26, 38, 3, 194, 168, 240, 179, 192, 175, 130, 45, 99, 194, 121, 112, 26, 130, 69, 96, 64, 68, 1, 221, 233, 165, 110, 229, 39, 87, 234, 139, 199, 72, 212, 200, 43, 83, 55, 180, 141, 123, 101, 88, 58, 61, 87, 36, 56, 136, 0, 54, 186, 198, 115, 15, 66, 202, 82, 120, 150, 107, 213, 242, 30, 134, 226, 29, 48, 197, 166, 208, 70, 62, 197, 19, 221, 80, 159, 252, 220, 175, 31, 245]) - }; - - var sizes = { - "P-521": 66, - "P-256": 32, - "P-384": 48 - }; - - var derivations = { - "P-521": new Uint8Array([0, 156, 43, 206, 87, 190, 128, 173, 171, 59, 7, 56, 91, 142, 89, 144, 235, 125, 111, 222, 189, 176, 27, 243, 83, 113, 164, 246, 7, 94, 157, 40, 138, 193, 42, 109, 254, 3, 170, 87, 67, 188, 129, 112, 157, 73, 168, 34, 148, 2, 25, 182, 75, 118, 138, 205, 82, 15, 161, 54, 142, 160, 175, 141, 71, 93]), - "P-256": new Uint8Array([14, 143, 60, 77, 177, 178, 162, 131, 115, 90, 0, 220, 87, 31, 26, 232, 151, 28, 227, 35, 250, 17, 131, 137, 203, 95, 65, 196, 59, 61, 181, 161]), - "P-384": new Uint8Array([224, 189, 107, 206, 10, 239, 140, 164, 136, 56, 166, 226, 252, 197, 126, 103, 185, 197, 232, 134, 12, 95, 11, 233, 218, 190, 197, 62, 69, 78, 24, 160, 161, 116, 196, 136, 136, 162, 100, 136, 17, 91, 45, 201, 241, 223, 165, 45]) - }; - - return importKeys(pkcs8, spki, sizes) - .then(function(results) { - publicKeys = results.publicKeys; - privateKeys = results.privateKeys; - ecdsaKeyPairs = results.ecdsaKeyPairs; - noDeriveKeyKeys = results.noDeriveKeyKeys; - - Object.keys(sizes).forEach(function(namedCurve) { - // Basic success case - promise_test(function(test) { - return subtle.deriveKey({name: "ECDH", public: publicKeys[namedCurve]}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_true(equalBuffers(exportedKey, derivations[namedCurve], 8 * exportedKey.length), "Derived correct key"); - }, function(err) { - assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); - }); - }, namedCurve + " good parameters"); - - // Case insensitivity check - promise_test(function(test) { - return subtle.deriveKey({name: "EcDh", public: publicKeys[namedCurve]}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_true(equalBuffers(exportedKey, derivations[namedCurve], 8 * exportedKey.length), "Derived correct key"); - }, function(err) { - assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); - }); - }, namedCurve + " mixed case parameters"); - // Errors to test: - - // - missing public property TypeError - promise_test(function(test) { - return subtle.deriveKey({name: "ECDH"}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " missing public curve"); - - // - Non CryptoKey public property TypeError - promise_test(function(test) { - return subtle.deriveKey({name: "ECDH", public: {message: "Not a CryptoKey"}}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with TypeError"); - }, function(err) { - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " public property of algorithm is not a CryptoKey"); - - // - wrong named curve - promise_test(function(test) { - publicKey = publicKeys["P-256"]; - if (namedCurve === "P-256") { - publicKey = publicKeys["P-384"]; - } - return subtle.deriveKey({name: "ECDH", public: publicKey}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " mismatched curves"); - - // - not ECDH public property InvalidAccessError - promise_test(function(test) { - return subtle.deriveKey({name: "ECDH", public: ecdsaKeyPairs[namedCurve].publicKey}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " public property of algorithm is not an ECDSA public key"); - - // - No deriveKey usage in baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveKey({name: "ECDH", public: publicKeys[namedCurve]}, noDeriveKeyKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " no deriveKey usage for base key"); - - // - Use public key for baseKey InvalidAccessError - promise_test(function(test) { - return subtle.deriveKey({name: "ECDH", public: publicKeys[namedCurve]}, publicKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " base key is not a private key"); - - // - Use private key for public property InvalidAccessError - promise_test(function(test) { - return subtle.deriveKey({name: "ECDH", public: privateKeys[namedCurve]}, privateKeys[namedCurve], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, namedCurve + " public property value is a private key"); - - // - Use secret key for public property InvalidAccessError - promise_test(function(test) { - return subtle.generateKey({name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) - .then(function(secretKey) { - return subtle.deriveKey({name: "ECDH", public: secretKey}, privateKeys[namedCurve], {name: "AES-CBC", length: 256}, true, ["sign", "verify"]) - .then(function(key) {return crypto.subtle.exportKey("raw", key);}) - .then(function(exportedKey) { - assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }); - }, namedCurve + " public property value is a secret key"); - }); - }); - - function importKeys(pkcs8, spki, sizes) { - var privateKeys = {}; - var publicKeys = {}; - var ecdsaKeyPairs = {}; - var noDeriveKeyKeys = {}; - - var promises = []; - Object.keys(pkcs8).forEach(function(namedCurve) { - var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], - {name: "ECDH", namedCurve: namedCurve}, - false, ["deriveBits", "deriveKey"]) - .then(function(key) { - privateKeys[namedCurve] = key; - }, function (err) { - privateKeys[namedCurve] = null; - }); - promises.push(operation); - }); - Object.keys(pkcs8).forEach(function(namedCurve) { - var operation = subtle.importKey("pkcs8", pkcs8[namedCurve], - {name: "ECDH", namedCurve: namedCurve}, - false, ["deriveBits"]) - .then(function(key) { - noDeriveKeyKeys[namedCurve] = key; - }, function (err) { - noDeriveKeyKeys[namedCurve] = null; - }); - promises.push(operation); - }); - Object.keys(spki).forEach(function(namedCurve) { - var operation = subtle.importKey("spki", spki[namedCurve], - {name: "ECDH", namedCurve: namedCurve}, - false, []) - .then(function(key) { - publicKeys[namedCurve] = key; - }, function (err) { - publicKeys[namedCurve] = null; - }); - promises.push(operation); - }); - Object.keys(sizes).forEach(function(namedCurve) { - var operation = subtle.generateKey({name: "ECDSA", namedCurve: namedCurve}, false, ["sign", "verify"]) - .then(function(keyPair) { - ecdsaKeyPairs[namedCurve] = keyPair; - }, function (err) { - ecdsaKeyPairs[namedCurve] = null; - }); - promises.push(operation); - }); - - return Promise.all(promises) - .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, ecdsaKeyPairs: ecdsaKeyPairs, noDeriveKeyKeys: noDeriveKeyKeys}}); - } - + return defineEcdhTests("deriveKey"); } diff --git a/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js b/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js index 3879ddb14b903a..b283f2ba7920e6 100644 --- a/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/hkdf.https.any.js @@ -6,6 +6,7 @@ // META: script=../util/helpers.js // META: script=/common/subset-tests.js // META: script=hkdf_vectors.js +// META: script=kdf.js // META: script=hkdf.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/hkdf.js b/WebCryptoAPI/derive_bits_keys/hkdf.js index 08e8c0c8974617..a090169836e573 100644 --- a/WebCryptoAPI/derive_bits_keys/hkdf.js +++ b/WebCryptoAPI/derive_bits_keys/hkdf.js @@ -1,278 +1,63 @@ - function define_tests() { - // May want to test prefixed implementations. - var subtle = self.crypto.subtle; - - // hkdf2_vectors sets up test data with the correct derivations for each - // test case. - var testData = getTestData(); - var derivedKeys = testData.derivedKeys; - var salts = testData.salts; - var derivations = testData.derivations; - var infos = testData.infos; - - // What kinds of keys can be created with deriveKey? The following: - var derivedKeyTypes = testData.derivedKeyTypes; - - return setUpBaseKeys(derivedKeys) - .then(function(allKeys) { - // We get several kinds of base keys. Normal ones that can be used for - // derivation operations, ones that lack the deriveBits usage, ones - // that lack the deriveKeys usage, and one key that is for the wrong - // algorithm (not HKDF in this case). - var baseKeys = allKeys.baseKeys; - var noBits = allKeys.noBits; - var noKey = allKeys.noKey; - var wrongKey = allKeys.wrongKey; - - // Test each combination of derivedKey size, salt size, hash function, - // and number of iterations. The derivations object is structured in - // that way, so navigate it to run tests and compare with correct results. - Object.keys(derivations).forEach(function(derivedKeySize) { - Object.keys(derivations[derivedKeySize]).forEach(function(saltSize) { - Object.keys(derivations[derivedKeySize][saltSize]).forEach(function(hashName) { - Object.keys(derivations[derivedKeySize][saltSize][hashName]).forEach(function(infoSize) { - var testName = derivedKeySize + " derivedKey, " + saltSize + " salt, " + hashName + ", with " + infoSize + " info"; - var algorithm = {name: "HKDF", salt: salts[saltSize], info: infos[infoSize], hash: hashName}; - - // Check for correct deriveBits result - subsetTest(promise_test, function(test) { - return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 256) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[derivedKeySize][saltSize][hashName][infoSize]), "Derived correct key"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, testName); - - // 0 length - subsetTest(promise_test, function(test) { - return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 0) - .then(function(derivation) { - assert_equals(derivation.byteLength, 0, "Derived correctly empty key"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); - }); - }, testName + " with 0 length"); - - // Check for correct deriveKey results for every kind of - // key that can be created by the deriveKeys operation. - derivedKeyTypes.forEach(function(derivedKeyType) { - var testName = "Derived key of type "; - Object.keys(derivedKeyType.algorithm).forEach(function(prop) { - testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; - }); - testName += " using " + derivedKeySize + " derivedKey, " + saltSize + " salt, " + hashName + ", with " + infoSize + " info"; - - // Test the particular key derivation. - subsetTest(promise_test, function(test) { - return subtle.deriveKey(algorithm, baseKeys[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - // Need to export the key to see that the correct bits were set. - return subtle.exportKey("raw", key) - .then(function(buffer) { - assert_true(equalBuffers(buffer, derivations[derivedKeySize][saltSize][hashName][infoSize].slice(0, derivedKeyType.algorithm.length/8)), "Exported key matches correct value"); + return runKdfTests({ + name: "HKDF", + getBaseKeyData: function(testData) { + return testData.derivedKeys; + }, + registerTests: function(context) { + var subtle = context.subtle; + var testData = context.testData; + var derivations = testData.derivations; + var salts = testData.salts; + var infos = testData.infos; + + Object.keys(derivations).forEach(function(derivedKeySize) { + Object.keys(derivations[derivedKeySize]).forEach(function(saltSize) { + Object.keys(derivations[derivedKeySize][saltSize]).forEach(function(hashName) { + Object.keys(derivations[derivedKeySize][saltSize][hashName]).forEach(function(infoSize) { + var testName = derivedKeySize + " derivedKey, " + saltSize + " salt, " + hashName + ", with " + infoSize + " info"; + var testCase = { + name: testName, + keyName: derivedKeySize, + hash: hashName, + algorithm: {name: "HKDF", salt: salts[saltSize], info: infos[infoSize], hash: hashName}, + expected: derivations[derivedKeySize][saltSize][hashName][infoSize] + }; + + context.registerCase(testCase, function() { + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "HKDF", info: infos[infoSize], hash: hashName}, context.keys.baseKeys[derivedKeySize], 0) + .then(function(derivation) { + assert_equals(derivation.byteLength, 0, "Derived even with missing salt"); }, function(err) { - assert_unreached("Exporting derived key failed with error " + err.name + ": " + err.message); + assert_equals(err.name, "TypeError", "deriveBits missing salt correctly threw OperationError: " + err.message); }); - }, function(err) { - assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); - - }); - }, testName); - - // Test various error conditions for deriveKey: + }, testName + " with missing salt"); - // - illegal name for hash algorithm (NotSupportedError) - var badHash = hashName.substring(0, 3) + hashName.substring(4); - subsetTest(promise_test, function(test) { - var badAlgorithm = {name: "HKDF", salt: salts[saltSize], hash: badHash, info: algorithm.info}; - return subtle.deriveKey(badAlgorithm, baseKeys[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - assert_unreached("bad hash name should have thrown an NotSupportedError"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "deriveKey with bad hash name correctly threw NotSupportedError: " + err.message); - }); - }, testName + " with bad hash name " + badHash); - - // - baseKey usages missing "deriveKey" (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveKey(algorithm, noKey[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - assert_unreached("missing deriveKey usage should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveKey with missing deriveKey usage correctly threw InvalidAccessError: " + err.message); - }); - }, testName + " with missing deriveKey usage"); - - // - baseKey algorithm does not match HKDF (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveKey(algorithm, wrongKey, derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveKey with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); - }); - }, testName + " with wrong (ECDH) key"); - - }); - - // Test various error conditions for deriveBits below: - - // missing salt (TypeError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "HKDF", info: infos[infoSize], hash: hashName}, baseKeys[derivedKeySize], 0) - .then(function(derivation) { - assert_equals(derivation.byteLength, 0, "Derived even with missing salt"); - }, function(err) { - assert_equals(err.name, "TypeError", "deriveBits missing salt correctly threw OperationError: " + err.message); - }); - }, testName + " with missing salt"); - - // missing info (TypeError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "HKDF", salt: salts[saltSize], hash: hashName}, baseKeys[derivedKeySize], 0) - .then(function(derivation) { - assert_equals(derivation.byteLength, 0, "Derived even with missing info"); - }, function(err) { - assert_equals(err.name, "TypeError", "deriveBits missing info correctly threw OperationError: " + err.message); - }); - }, testName + " with missing info"); - - // length not multiple of 8 (OperationError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 44) - .then(function(derivation) { - assert_unreached("non-multiple of 8 length should have thrown an OperationError"); - }, function(err) { - assert_equals(err.name, "OperationError", "deriveBits with non-multiple of 8 length correctly threw OperationError: " + err.message); - }); - }, testName + " with non-multiple of 8 length"); - - // - illegal name for hash algorithm (NotSupportedError) - var badHash = hashName.substring(0, 3) + hashName.substring(4); - subsetTest(promise_test, function(test) { - var badAlgorithm = {name: "HKDF", salt: salts[saltSize], hash: badHash, info: algorithm.info}; - return subtle.deriveBits(badAlgorithm, baseKeys[derivedKeySize], 256) - .then(function(derivation) { - assert_unreached("bad hash name should have thrown an NotSupportedError"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "deriveBits with bad hash name correctly threw NotSupportedError: " + err.message); - }); - }, testName + " with bad hash name " + badHash); - - // - baseKey usages missing "deriveBits" (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits(algorithm, noBits[derivedKeySize], 256) - .then(function(derivation) { - assert_unreached("missing deriveBits usage should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveBits with missing deriveBits usage correctly threw InvalidAccessError: " + err.message); - }); - }, testName + " with missing deriveBits usage"); - - // - baseKey algorithm does not match HKDF (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits(algorithm, wrongKey, 256) - .then(function(derivation) { - assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveBits with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); + subsetTest(promise_test, function(test) { + return subtle.deriveBits({name: "HKDF", salt: salts[saltSize], hash: hashName}, context.keys.baseKeys[derivedKeySize], 0) + .then(function(derivation) { + assert_equals(derivation.byteLength, 0, "Derived even with missing info"); + }, function(err) { + assert_equals(err.name, "TypeError", "deriveBits missing info correctly threw OperationError: " + err.message); + }); + }, testName + " with missing info"); }); - }, testName + " with wrong (ECDH) key"); - }); - }); - - // - legal algorithm name but not digest one (e.g., PBKDF2) (NotSupportedError) - var nonDigestHash = "PBKDF2"; - Object.keys(infos).forEach(function(infoSize) { - var testName = derivedKeySize + " derivedKey, " + saltSize + " salt, " + nonDigestHash + ", with " + infoSize + " info"; - var algorithm = {name: "HKDF", salt: salts[saltSize], hash: nonDigestHash}; - if (infoSize !== "missing") { - algorithm.info = infos[infoSize]; - } - - subsetTest(promise_test, function(test) { - return subtle.deriveBits(algorithm, baseKeys[derivedKeySize], 256) - .then(function(derivation) { - assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "deriveBits with non-digest algorithm correctly threw NotSupportedError: " + err.message); }); - }, testName + " with non-digest algorithm " + nonDigestHash); + }); - derivedKeyTypes.forEach(function(derivedKeyType) { - var testName = "Derived key of type "; - Object.keys(derivedKeyType.algorithm).forEach(function(prop) { - testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + var nonDigestHash = "PBKDF2"; + Object.keys(infos).forEach(function(infoSize) { + var testName = derivedKeySize + " derivedKey, " + saltSize + " salt, " + nonDigestHash + ", with " + infoSize + " info"; + context.registerNonDigestCase({ + name: testName, + keyName: derivedKeySize, + hash: nonDigestHash, + algorithm: {name: "HKDF", salt: salts[saltSize], hash: nonDigestHash, info: infos[infoSize]} }); - testName += " using " + derivedKeySize + " derivedKey, " + saltSize + " salt, " + nonDigestHash + ", with " + infoSize + " info"; - - subsetTest(promise_test, function(test) { - return subtle.deriveKey(algorithm, baseKeys[derivedKeySize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(derivation) { - assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "derivekey with non-digest algorithm correctly threw NotSupportedError: " + err.message); - }); - }, testName); }); - }); - }); - }); + } }); - - // Deriving bits and keys requires starting with a base key, which is created - // by importing a derivedKey. setUpBaseKeys returns a promise that yields the - // necessary base keys. - function setUpBaseKeys(derivedKeys) { - var promises = []; - - var baseKeys = {}; - var noBits = {}; - var noKey = {}; - var wrongKey = null; - - Object.keys(derivedKeys).forEach(function(derivedKeySize) { - var promise = subtle.importKey("raw", derivedKeys[derivedKeySize], {name: "HKDF"}, false, ["deriveKey", "deriveBits"]) - .then(function(baseKey) { - baseKeys[derivedKeySize] = baseKey; - }, function(err) { - baseKeys[derivedKeySize] = null; - }); - promises.push(promise); - - promise = subtle.importKey("raw", derivedKeys[derivedKeySize], {name: "HKDF"}, false, ["deriveBits"]) - .then(function(baseKey) { - noKey[derivedKeySize] = baseKey; - }, function(err) { - noKey[derivedKeySize] = null; - }); - promises.push(promise); - - promise = subtle.importKey("raw", derivedKeys[derivedKeySize], {name: "HKDF"}, false, ["deriveKey"]) - .then(function(baseKey) { - noBits[derivedKeySize] = baseKey; - }, function(err) { - noBits[derivedKeySize] = null; - }); - promises.push(promise); - }); - - var promise = subtle.generateKey({name: "ECDH", namedCurve: "P-256"}, false, ["deriveKey", "deriveBits"]) - .then(function(baseKey) { - wrongKey = baseKey.privateKey; - }, function(err) { - wrongKey = null; - }); - promises.push(promise); - - - return Promise.all(promises).then(function() { - return {baseKeys: baseKeys, noBits: noBits, noKey: noKey, wrongKey: wrongKey}; - }); - } - } diff --git a/WebCryptoAPI/derive_bits_keys/kdf.js b/WebCryptoAPI/derive_bits_keys/kdf.js new file mode 100644 index 00000000000000..ecbb3b4148f4a0 --- /dev/null +++ b/WebCryptoAPI/derive_bits_keys/kdf.js @@ -0,0 +1,209 @@ +function runKdfTests(options) { + var subtle = self.crypto.subtle; + var testData = getTestData(); + var derivedKeyTypes = testData.derivedKeyTypes; + + return setUpBaseKeys(options.getBaseKeyData(testData)) + .then(function(allKeys) { + function derivedKeyTestName(derivedKeyType, caseName) { + var testName = "Derived key of type "; + Object.keys(derivedKeyType.algorithm).forEach(function(prop) { + testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + }); + return testName + " using " + caseName; + } + + function withHash(algorithm, hash) { + return Object.assign({}, algorithm, {hash: hash}); + } + + function registerCase(testCase, registerAdditionalBitsTests) { + var algorithm = testCase.algorithm; + var baseKey = allKeys.baseKeys[testCase.keyName]; + var badHash = testCase.hash.substring(0, 3) + testCase.hash.substring(4); + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKey, 256) + .then(function(derivation) { + assert_true(equalBuffers(derivation, testCase.expected), "Derived correct key"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, testCase.name); + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKey, 0) + .then(function(derivation) { + assert_equals(derivation.byteLength, 0, "Derived correctly empty key"); + }, function(err) { + assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + }); + }, testCase.name + " with 0 length"); + + derivedKeyTypes.forEach(function(derivedKeyType) { + var testName = derivedKeyTestName(derivedKeyType, testCase.name); + + subsetTest(promise_test, function(test) { + return subtle.deriveKey(algorithm, baseKey, derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + return subtle.exportKey("raw", key) + .then(function(buffer) { + assert_true(equalBuffers(buffer, testCase.expected.slice(0, derivedKeyType.algorithm.length/8)), "Exported key matches correct value"); + }, function(err) { + assert_unreached("Exporting derived key failed with error " + err.name + ": " + err.message); + }); + }, function(err) { + assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); + }); + }, testName); + + subsetTest(promise_test, function(test) { + return subtle.deriveKey(withHash(algorithm, badHash), baseKey, derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("bad hash name should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveKey with bad hash name correctly threw NotSupportedError: " + err.message); + }); + }, testName + " with bad hash name " + badHash); + + subsetTest(promise_test, function(test) { + return subtle.deriveKey(algorithm, allKeys.noKey[testCase.keyName], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("missing deriveKey usage should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveKey with missing deriveKey usage correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with missing deriveKey usage"); + + subsetTest(promise_test, function(test) { + return subtle.deriveKey(algorithm, allKeys.wrongKey, derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(key) { + assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveKey with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); + }); + }, testName + " with wrong (ECDH) key"); + }); + + if (registerAdditionalBitsTests !== undefined) { + registerAdditionalBitsTests(); + } + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, baseKey, 44) + .then(function(derivation) { + assert_unreached("non-multiple of 8 length should have thrown an OperationError"); + }, function(err) { + assert_equals(err.name, "OperationError", "deriveBits with non-multiple of 8 length correctly threw OperationError: " + err.message); + }); + }, testCase.name + " with non-multiple of 8 length"); + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(withHash(algorithm, badHash), baseKey, 256) + .then(function(derivation) { + assert_unreached("bad hash name should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveBits with bad hash name correctly threw NotSupportedError: " + err.message); + }); + }, testCase.name + " with bad hash name " + badHash); + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, allKeys.noBits[testCase.keyName], 256) + .then(function(derivation) { + assert_unreached("missing deriveBits usage should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveBits with missing deriveBits usage correctly threw InvalidAccessError: " + err.message); + }); + }, testCase.name + " with missing deriveBits usage"); + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(algorithm, allKeys.wrongKey, 256) + .then(function(derivation) { + assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "deriveBits with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); + }); + }, testCase.name + " with wrong (ECDH) key"); + } + + function registerNonDigestCase(testCase) { + var baseKey = allKeys.baseKeys[testCase.keyName]; + + subsetTest(promise_test, function(test) { + return subtle.deriveBits(testCase.algorithm, baseKey, 256) + .then(function(derivation) { + assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "deriveBits with non-digest algorithm correctly threw NotSupportedError: " + err.message); + }); + }, testCase.name + " with non-digest algorithm " + testCase.hash); + + derivedKeyTypes.forEach(function(derivedKeyType) { + subsetTest(promise_test, function(test) { + return subtle.deriveKey(testCase.algorithm, baseKey, derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(derivation) { + assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); + }, function(err) { + assert_equals(err.name, "NotSupportedError", "derivekey with non-digest algorithm correctly threw NotSupportedError: " + err.message); + }); + }, derivedKeyTestName(derivedKeyType, testCase.name)); + }); + } + + options.registerTests({ + subtle: subtle, + testData: testData, + derivedKeyTypes: derivedKeyTypes, + keys: allKeys, + registerCase: registerCase, + registerNonDigestCase: registerNonDigestCase, + derivedKeyTestName: derivedKeyTestName + }); + }); + + function setUpBaseKeys(baseKeyData) { + var promises = []; + var baseKeys = {}; + var noBits = {}; + var noKey = {}; + var wrongKey = null; + + Object.keys(baseKeyData).forEach(function(keyName) { + var promise = subtle.importKey("raw", baseKeyData[keyName], {name: options.name}, false, ["deriveKey", "deriveBits"]) + .then(function(baseKey) { + baseKeys[keyName] = baseKey; + }, function(err) { + baseKeys[keyName] = null; + }); + promises.push(promise); + + promise = subtle.importKey("raw", baseKeyData[keyName], {name: options.name}, false, ["deriveBits"]) + .then(function(baseKey) { + noKey[keyName] = baseKey; + }, function(err) { + noKey[keyName] = null; + }); + promises.push(promise); + + promise = subtle.importKey("raw", baseKeyData[keyName], {name: options.name}, false, ["deriveKey"]) + .then(function(baseKey) { + noBits[keyName] = baseKey; + }, function(err) { + noBits[keyName] = null; + }); + promises.push(promise); + }); + + var promise = subtle.generateKey({name: "ECDH", namedCurve: "P-256"}, false, ["deriveKey", "deriveBits"]) + .then(function(baseKey) { + wrongKey = baseKey.privateKey; + }, function(err) { + wrongKey = null; + }); + promises.push(promise); + + return Promise.all(promises).then(function() { + return {baseKeys: baseKeys, noBits: noBits, noKey: noKey, wrongKey: wrongKey}; + }); + } +} diff --git a/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.js b/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.js index cc2ed9b9cef872..8d1299358575a2 100644 --- a/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.js +++ b/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.js @@ -12,6 +12,7 @@ // META: script=../util/helpers.js // META: script=/common/subset-tests.js // META: script=pbkdf2_vectors.js +// META: script=kdf.js // META: script=pbkdf2.js // Define subtests from a `promise_test` to ensure the harness does not diff --git a/WebCryptoAPI/derive_bits_keys/pbkdf2.js b/WebCryptoAPI/derive_bits_keys/pbkdf2.js index 4d5b0137a387c8..57c19ae3f01480 100644 --- a/WebCryptoAPI/derive_bits_keys/pbkdf2.js +++ b/WebCryptoAPI/derive_bits_keys/pbkdf2.js @@ -1,274 +1,64 @@ function define_tests() { - // May want to test prefixed implementations. - var subtle = self.crypto.subtle; - - // pbkdf2_vectors sets up test data with the correct derivations for each - // test case. - var testData = getTestData(); - var passwords = testData.passwords; - var salts = testData.salts; - var derivations = testData.derivations; - - // What kinds of keys can be created with deriveKey? The following: - var derivedKeyTypes = testData.derivedKeyTypes; - - return setUpBaseKeys(passwords) - .then(function(allKeys) { - // We get several kinds of base keys. Normal ones that can be used for - // derivation operations, ones that lack the deriveBits usage, ones - // that lack the deriveKeys usage, and one key that is for the wrong - // algorithm (not PBKDF2 in this case). - var baseKeys = allKeys.baseKeys; - var noBits = allKeys.noBits; - var noKey = allKeys.noKey; - var wrongKey = allKeys.wrongKey; - - // Test each combination of password size, salt size, hash function, - // and number of iterations. The derivations object is structured in - // that way, so navigate it to run tests and compare with correct results. - Object.keys(derivations).forEach(function(passwordSize) { - Object.keys(derivations[passwordSize]).forEach(function(saltSize) { - Object.keys(derivations[passwordSize][saltSize]).forEach(function(hashName) { - Object.keys(derivations[passwordSize][saltSize][hashName]).forEach(function(iterations) { - var testName = passwordSize + " password, " + saltSize + " salt, " + hashName + ", with " + iterations + " iterations"; - - // Check for correct deriveBits result - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], 256) - .then(function(derivation) { - assert_true(equalBuffers(derivation, derivations[passwordSize][saltSize][hashName][iterations]), "Derived correct key"); - }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + return runKdfTests({ + name: "PBKDF2", + getBaseKeyData: function(testData) { + return testData.passwords; + }, + registerTests: function(context) { + var subtle = context.subtle; + var testData = context.testData; + var derivations = testData.derivations; + var salts = testData.salts; + + Object.keys(derivations).forEach(function(passwordSize) { + Object.keys(derivations[passwordSize]).forEach(function(saltSize) { + Object.keys(derivations[passwordSize][saltSize]).forEach(function(hashName) { + Object.keys(derivations[passwordSize][saltSize][hashName]).forEach(function(iterations) { + var testName = passwordSize + " password, " + saltSize + " salt, " + hashName + ", with " + iterations + " iterations"; + context.registerCase({ + name: testName, + keyName: passwordSize, + hash: hashName, + algorithm: {name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, + expected: derivations[passwordSize][saltSize][hashName][iterations] }); - }, testName); + }); - // 0 length + var zeroIterationName = passwordSize + " password, " + saltSize + " salt, " + hashName + ", with 0 iterations"; + var zeroIterationAlgorithm = {name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: 0}; subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], 0) + return subtle.deriveBits(zeroIterationAlgorithm, context.keys.baseKeys[passwordSize], 256) .then(function(derivation) { - assert_true(equalBuffers(derivation.byteLength, 0, "Derived correctly empty key")); + assert_unreached("0 iterations should have thrown an error"); }, function(err) { - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); + assert_equals(err.name, "OperationError", "deriveBits with 0 iterations correctly threw OperationError: " + err.message); }); - }, testName + " with 0 length"); + }, zeroIterationName); - // Check for correct deriveKey results for every kind of - // key that can be created by the deriveKeys operation. - derivedKeyTypes.forEach(function(derivedKeyType) { - var testName = "Derived key of type "; - Object.keys(derivedKeyType.algorithm).forEach(function(prop) { - testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; - }); - testName += " using " + passwordSize + " password, " + saltSize + " salt, " + hashName + ", with " + iterations + " iterations"; - - // Test the particular key derivation. - subsetTest(promise_test, function(test) { - return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - // Need to export the key to see that the correct bits were set. - return subtle.exportKey("raw", key) - .then(function(buffer) { - assert_true(equalBuffers(buffer, derivations[passwordSize][saltSize][hashName][iterations].slice(0, derivedKeyType.algorithm.length/8)), "Exported key matches correct value"); - }, function(err) { - assert_unreached("Exporting derived key failed with error " + err.name + ": " + err.message); - }); - }, function(err) { - assert_unreached("deriveKey failed with error " + err.name + ": " + err.message); - - }); - }, testName); - - // Test various error conditions for deriveKey: - - // - illegal name for hash algorithm (NotSupportedError) - var badHash = hashName.substring(0, 3) + hashName.substring(4); + context.derivedKeyTypes.forEach(function(derivedKeyType) { subsetTest(promise_test, function(test) { - return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: badHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - assert_unreached("bad hash name should have thrown an NotSupportedError"); + return subtle.deriveKey(zeroIterationAlgorithm, context.keys.baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) + .then(function(derivation) { + assert_unreached("0 iterations should have thrown an error"); }, function(err) { - assert_equals(err.name, "NotSupportedError", "deriveKey with bad hash name correctly threw NotSupportedError: " + err.message); + assert_equals(err.name, "OperationError", "derivekey with 0 iterations correctly threw OperationError: " + err.message); }); - }, testName + " with bad hash name " + badHash); - - // - baseKey usages missing "deriveKey" (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, noKey[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - assert_unreached("missing deriveKey usage should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveKey with missing deriveKey usage correctly threw InvalidAccessError: " + err.message); - }); - }, testName + " with missing deriveKey usage"); - - // - baseKey algorithm does not match PBKDF2 (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, wrongKey, derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(key) { - assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveKey with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); - }); - }, testName + " with wrong (ECDH) key"); - + }, context.derivedKeyTestName(derivedKeyType, zeroIterationName)); }); - - // length not multiple of 8 (OperationError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, baseKeys[passwordSize], 44) - .then(function(derivation) { - assert_unreached("non-multiple of 8 length should have thrown an OperationError"); - }, function(err) { - assert_equals(err.name, "OperationError", "deriveBits with non-multiple of 8 length correctly threw OperationError: " + err.message); - }); - }, testName + " with non-multiple of 8 length"); - - // - illegal name for hash algorithm (NotSupportedError) - var badHash = hashName.substring(0, 3) + hashName.substring(4); - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: badHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], 256) - .then(function(derivation) { - assert_unreached("bad hash name should have thrown an NotSupportedError"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "deriveBits with bad hash name correctly threw NotSupportedError: " + err.message); - }); - }, testName + " with bad hash name " + badHash); - - // - baseKey usages missing "deriveBits" (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, noBits[passwordSize], 256) - .then(function(derivation) { - assert_unreached("missing deriveBits usage should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveBits with missing deriveBits usage correctly threw InvalidAccessError: " + err.message); - }); - }, testName + " with missing deriveBits usage"); - - // - baseKey algorithm does not match PBKDF2 (InvalidAccessError) - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: parseInt(iterations)}, wrongKey, 256) - .then(function(derivation) { - assert_unreached("wrong (ECDH) key should have thrown an InvalidAccessError"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "deriveBits with wrong (ECDH) key correctly threw InvalidAccessError: " + err.message); - }); - }, testName + " with wrong (ECDH) key"); - }); - - // Check that 0 iterations throws proper error - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: 0}, baseKeys[passwordSize], 256) - .then(function(derivation) { - assert_unreached("0 iterations should have thrown an error"); - }, function(err) { - assert_equals(err.name, "OperationError", "deriveBits with 0 iterations correctly threw OperationError: " + err.message); - }); - }, passwordSize + " password, " + saltSize + " salt, " + hashName + ", with 0 iterations"); - - derivedKeyTypes.forEach(function(derivedKeyType) { - var testName = "Derived key of type "; - Object.keys(derivedKeyType.algorithm).forEach(function(prop) { - testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; - }); - testName += " using " + passwordSize + " password, " + saltSize + " salt, " + hashName + ", with 0 iterations"; - - subsetTest(promise_test, function(test) { - return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: hashName, iterations: 0}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(derivation) { - assert_unreached("0 iterations should have thrown an error"); - }, function(err) { - assert_equals(err.name, "OperationError", "derivekey with 0 iterations correctly threw OperationError: " + err.message); - }); - }, testName); }); - }); - - // - legal algorithm name but not digest one (e.g., PBKDF2) (NotSupportedError) - var nonDigestHash = "PBKDF2"; - [1, 1000, 100000].forEach(function(iterations) { - var testName = passwordSize + " password, " + saltSize + " salt, " + nonDigestHash + ", with " + iterations + " iterations"; - - subsetTest(promise_test, function(test) { - return subtle.deriveBits({name: "PBKDF2", salt: salts[saltSize], hash: nonDigestHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], 256) - .then(function(derivation) { - assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "deriveBits with non-digest algorithm correctly threw NotSupportedError: " + err.message); - }); - }, testName + " with non-digest algorithm " + nonDigestHash); - derivedKeyTypes.forEach(function(derivedKeyType) { - var testName = "Derived key of type "; - Object.keys(derivedKeyType.algorithm).forEach(function(prop) { - testName += prop + ": " + derivedKeyType.algorithm[prop] + " "; + var nonDigestHash = "PBKDF2"; + [1, 1000, 100000].forEach(function(iterations) { + var testName = passwordSize + " password, " + saltSize + " salt, " + nonDigestHash + ", with " + iterations + " iterations"; + context.registerNonDigestCase({ + name: testName, + keyName: passwordSize, + hash: nonDigestHash, + algorithm: {name: "PBKDF2", salt: salts[saltSize], hash: nonDigestHash, iterations: parseInt(iterations)} }); - testName += " using " + passwordSize + " password, " + saltSize + " salt, " + nonDigestHash + ", with " + iterations + " iterations"; - - subsetTest(promise_test, function(test) { - return subtle.deriveKey({name: "PBKDF2", salt: salts[saltSize], hash: nonDigestHash, iterations: parseInt(iterations)}, baseKeys[passwordSize], derivedKeyType.algorithm, true, derivedKeyType.usages) - .then(function(derivation) { - assert_unreached("non-digest algorithm should have thrown an NotSupportedError"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "derivekey with non-digest algorithm correctly threw NotSupportedError: " + err.message); - }); - }, testName); }); - }); - }); - }); + } }); - - // Deriving bits and keys requires starting with a base key, which is created - // by importing a password. setUpBaseKeys returns a promise that yields the - // necessary base keys. - function setUpBaseKeys(passwords) { - var promises = []; - - var baseKeys = {}; - var noBits = {}; - var noKey = {}; - var wrongKey = null; - - Object.keys(passwords).forEach(function(passwordSize) { - var promise = subtle.importKey("raw", passwords[passwordSize], {name: "PBKDF2"}, false, ["deriveKey", "deriveBits"]) - .then(function(baseKey) { - baseKeys[passwordSize] = baseKey; - }, function(err) { - baseKeys[passwordSize] = null; - }); - promises.push(promise); - - promise = subtle.importKey("raw", passwords[passwordSize], {name: "PBKDF2"}, false, ["deriveBits"]) - .then(function(baseKey) { - noKey[passwordSize] = baseKey; - }, function(err) { - noKey[passwordSize] = null; - }); - promises.push(promise); - - promise = subtle.importKey("raw", passwords[passwordSize], {name: "PBKDF2"}, false, ["deriveKey"]) - .then(function(baseKey) { - noBits[passwordSize] = baseKey; - }, function(err) { - noBits[passwordSize] = null; - }); - promises.push(promise); - }); - - var promise = subtle.generateKey({name: "ECDH", namedCurve: "P-256"}, false, ["deriveKey", "deriveBits"]) - .then(function(baseKey) { - wrongKey = baseKey.privateKey; - }, function(err) { - wrongKey = null; - }); - promises.push(promise); - - - return Promise.all(promises).then(function() { - return {baseKeys: baseKeys, noBits: noBits, noKey: noKey, wrongKey: wrongKey}; - }); - } - } diff --git a/WebCryptoAPI/digest/cshake.tentative.https.any.js b/WebCryptoAPI/digest/cshake.tentative.https.any.js index 81793666294c23..1bf78f58115410 100644 --- a/WebCryptoAPI/digest/cshake.tentative.https.any.js +++ b/WebCryptoAPI/digest/cshake.tentative.https.any.js @@ -1,23 +1,12 @@ // META: title=WebCryptoAPI: digest() cSHAKE algorithms // META: script=../util/helpers.js +// META: script=digest_test_data.js +// META: script=digest.js // META: timeout=long var subtle = crypto.subtle; // Change to test prefixed implementations -var sourceData = { - empty: new Uint8Array(0), - short: new Uint8Array([ - 21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255, - ]), - medium: new Uint8Array([ - 182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, - 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, - 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, - 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, - 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, - 171, 172, 161, 147, - ]), -}; +var sourceData = getDigestSourceData(false); // Test different output lengths for cSHAKE var digestLengths = [0, 256, 384, 512]; @@ -158,91 +147,19 @@ var digestedData = { }; // Test cSHAKE digest algorithms with variable output lengths -Object.keys(digestedData).forEach(function (alg) { - digestLengths.forEach(function (length) { - Object.keys(sourceData).forEach(function (size) { - promise_test(function (test) { - return crypto.subtle - .digest({ name: alg, outputLength: length }, sourceData[size]) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][length][size]), - 'digest matches expected' - ); - }); - }, alg + ' with ' + length + ' bit output and ' + size + ' source data'); - - if (sourceData[size].length > 0) { - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - // Alter the buffer before calling digest - buffer[0] = ~buffer[0]; - return crypto.subtle - .digest({ - get name() { - // Alter the buffer back while calling digest - buffer[0] = sourceData[size][0]; - return alg; - }, - outputLength: length - }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][length][size]), - 'digest matches expected' - ); - }); - }, alg + ' with ' + length + ' bit output and ' + size + ' source data and altered buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - var promise = crypto.subtle - .digest({ name: alg, outputLength: length }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][length][size]), - 'digest matches expected' - ); - }); - // Alter the buffer after calling digest - buffer[0] = ~buffer[0]; - return promise; - }, alg + ' with ' + length + ' bit output and ' + size + ' source data and altered buffer after call'); - - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - return crypto.subtle - .digest({ - get name() { - // Transfer the buffer while calling digest - buffer.buffer.transfer(); - return alg; - }, - outputLength: length - }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][length].empty), - 'digest on transferred buffer should match result for empty buffer' - ); - }); - }, alg + ' with ' + length + ' bit output and ' + size + ' source data and transferred buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - var promise = crypto.subtle - .digest({ name: alg, outputLength: length }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][length][size]), - 'digest matches expected' - ); - }); - // Transfer the buffer after calling digest - buffer.buffer.transfer(); - return promise; - }, alg + ' with ' + length + ' bit output and ' + size + ' source data and transferred buffer after call'); - } +runDigestTests(subtle, sourceData, function (size) { + var vectors = []; + Object.keys(digestedData).forEach(function (alg) { + digestLengths.forEach(function (length) { + vectors.push({ + algorithm: {name: alg, outputLength: length}, + expected: digestedData[alg][length][size], + emptyExpected: digestedData[alg][length].empty, + label: alg + ' with ' + length + ' bit output and ' + + size + ' source data', + mutations: true, + }); }); }); + return vectors; }); diff --git a/WebCryptoAPI/digest/digest.https.any.js b/WebCryptoAPI/digest/digest.https.any.js index 38ce85ec06cfc3..26711b2880d947 100644 --- a/WebCryptoAPI/digest/digest.https.any.js +++ b/WebCryptoAPI/digest/digest.https.any.js @@ -1,19 +1,12 @@ // META: title=WebCryptoAPI: digest() // META: script=../util/helpers.js +// META: script=digest_test_data.js +// META: script=digest.js // META: timeout=long var subtle = crypto.subtle; // Change to test prefixed implementations - var sourceData = { - empty: new Uint8Array(0), - short: new Uint8Array([21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255]), - medium: new Uint8Array([182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, 171, 172, 161, 147]) - }; - - sourceData.long = new Uint8Array(1024 * sourceData.medium.byteLength); - for (var i=0; i<1024; i++) { - sourceData.long.set(sourceData.medium, i * sourceData.medium.byteLength); - } + var sourceData = getDigestSourceData(true); var digestedData = { "sha-1": { @@ -43,105 +36,36 @@ } // Try every combination of hash with source data size. Variations tested are - // hash name in upper, lower, or mixed case, and upper-case version with the - // source buffer altered after call. - Object.keys(sourceData).forEach(function(size) { - Object.keys(digestedData).forEach(function(alg) { + // hash name in upper, lower, or mixed case, plus buffer mutation and transfer. + runDigestTests(subtle, sourceData, function (size) { + var vectors = []; + Object.keys(digestedData).forEach(function (alg) { var upCase = alg.toUpperCase(); var downCase = alg.toLowerCase(); - var mixedCase = upCase.substr(0, 1) + downCase.substr(1); - - promise_test(function(test) { - var promise = subtle.digest({name: upCase}, sourceData[size]) - .then(function(result) { - assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); - }, function(err) { - assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); - }); - - return promise; - }, upCase + " with " + size + " source data"); - - promise_test(function(test) { - var promise = subtle.digest({name: downCase}, sourceData[size]) - .then(function(result) { - assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); - }, function(err) { - assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); - }); - - return promise; - }, downCase + " with " + size + " source data"); - - promise_test(function(test) { - var promise = subtle.digest({name: mixedCase}, sourceData[size]) - .then(function(result) { - assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); - }, function(err) { - assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); - }); - - return promise; - }, mixedCase + " with " + size + " source data"); - - if (sourceData[size].length > 0) { - promise_test(function(test) { - var copiedBuffer = copyBuffer(sourceData[size]); - copiedBuffer[0] = 255 - copiedBuffer[0]; - var promise = subtle.digest({ - get name() { - copiedBuffer[0] = sourceData[size][0]; - return upCase; - } - }, copiedBuffer) - .then(function(result) { - assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); - }, function(err) { - assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); - }); - return promise; - }, upCase + " with " + size + " source data and altered buffer during call"); - - promise_test(function(test) { - var copiedBuffer = copyBuffer(sourceData[size]); - var promise = subtle.digest({name: upCase}, copiedBuffer) - .then(function(result) { - assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); - }, function(err) { - assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); - }); - - copiedBuffer[0] = 255 - copiedBuffer[0]; - return promise; - }, upCase + " with " + size + " source data and altered buffer after call"); - - promise_test(function(test) { - var copiedBuffer = copyBuffer(sourceData[size]); - copiedBuffer.buffer.transfer(); - return subtle.digest({name: upCase}, copiedBuffer) - .then(function(result) { - assert_true(equalBuffers(result, digestedData[alg].empty), "digest() on transferred buffer should yield result for empty buffer for " + alg + ":" + size); - }, function(err) { - assert_unreached("digest() threw an error for transferred buffer for " + alg + ":" + size + ": " + err.message); - }); - }, upCase + " with " + size + " source data and transferred buffer during call"); - - promise_test(function(test) { - var copiedBuffer = copyBuffer(sourceData[size]); - var promise = subtle.digest({name: upCase}, copiedBuffer) - .then(function(result) { - assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size); - }, function(err) { - assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message); - }); - - copiedBuffer.buffer.transfer(); - return promise; - }, upCase + " with " + size + " source data and transferred buffer after call"); - } + var mixedCase = upCase.slice(0, 1) + downCase.slice(1); + var expected = digestedData[alg][size]; + + vectors.push({ + algorithm: {name: upCase}, + expected: expected, + emptyExpected: digestedData[alg].empty, + label: upCase + " with " + size + " source data", + mutations: true, + transferBeforeCall: true, + }); + vectors.push({ + algorithm: {name: downCase}, + expected: expected, + label: downCase + " with " + size + " source data", + }); + vectors.push({ + algorithm: {name: mixedCase}, + expected: expected, + label: mixedCase + " with " + size + " source data", + }); }); + return vectors; }); - // Call digest() with bad algorithm names to get an error var badNames = ["AES-GCM", "RSA-OAEP", "PBKDF2", "AES-KW"]; Object.keys(sourceData).forEach(function(size) { diff --git a/WebCryptoAPI/digest/digest.js b/WebCryptoAPI/digest/digest.js new file mode 100644 index 00000000000000..9ef9c69a180b88 --- /dev/null +++ b/WebCryptoAPI/digest/digest.js @@ -0,0 +1,92 @@ +function runDigestTests(subtle, sourceData, getVectors) { + function algorithmName(algorithm) { + return typeof algorithm === 'string' ? algorithm : algorithm.name; + } + + function withNameGetter(algorithm, getter) { + var result = typeof algorithm === 'string' ? {} : { ...algorithm }; + Object.defineProperty(result, 'name', { + enumerable: true, + get: getter, + }); + return result; + } + + Object.keys(sourceData).forEach(function (size) { + getVectors(size).forEach(function (vector) { + promise_test(function () { + return subtle.digest(vector.algorithm, sourceData[size]) + .then(function (result) { + assert_true( + equalBuffers(result, vector.expected), + 'digest matches expected' + ); + }); + }, vector.label); + + if (!vector.mutations || sourceData[size].length === 0) { + return; + } + + promise_test(function () { + var buffer = new Uint8Array(sourceData[size]); + buffer[0] = ~buffer[0]; + var algorithm = withNameGetter(vector.algorithm, function () { + buffer[0] = sourceData[size][0]; + return algorithmName(vector.algorithm); + }); + return subtle.digest(algorithm, buffer).then(function (result) { + assert_true( + equalBuffers(result, vector.expected), + 'digest matches expected' + ); + }); + }, vector.label + ' and altered buffer during call'); + + promise_test(function () { + var buffer = new Uint8Array(sourceData[size]); + var promise = subtle.digest(vector.algorithm, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, vector.expected), + 'digest matches expected' + ); + }); + buffer[0] = ~buffer[0]; + return promise; + }, vector.label + ' and altered buffer after call'); + + promise_test(function () { + var buffer = new Uint8Array(sourceData[size]); + var algorithm = vector.transferBeforeCall + ? vector.algorithm + : withNameGetter(vector.algorithm, function () { + buffer.buffer.transfer(); + return algorithmName(vector.algorithm); + }); + if (vector.transferBeforeCall) { + buffer.buffer.transfer(); + } + return subtle.digest(algorithm, buffer).then(function (result) { + assert_true( + equalBuffers(result, vector.emptyExpected), + 'digest on transferred buffer should match result for empty buffer' + ); + }); + }, vector.label + ' and transferred buffer during call'); + + promise_test(function () { + var buffer = new Uint8Array(sourceData[size]); + var promise = subtle.digest(vector.algorithm, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, vector.expected), + 'digest matches expected' + ); + }); + buffer.buffer.transfer(); + return promise; + }, vector.label + ' and transferred buffer after call'); + }); + }); +} diff --git a/WebCryptoAPI/digest/digest_test_data.js b/WebCryptoAPI/digest/digest_test_data.js new file mode 100644 index 00000000000000..f088e02a087021 --- /dev/null +++ b/WebCryptoAPI/digest/digest_test_data.js @@ -0,0 +1,25 @@ +function getDigestSourceData(includeLong) { + var sourceData = { + empty: new Uint8Array(0), + short: new Uint8Array([ + 21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255, + ]), + medium: new Uint8Array([ + 182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, + 140, 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, + 178, 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, + 107, 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, + 200, 7, 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, + 134, 37, 171, 172, 161, 147, + ]), + }; + + if (includeLong) { + sourceData.long = new Uint8Array(1024 * sourceData.medium.byteLength); + for (var i = 0; i < 1024; i++) { + sourceData.long.set(sourceData.medium, i * sourceData.medium.byteLength); + } + } + + return sourceData; +} diff --git a/WebCryptoAPI/digest/kangarootwelve.tentative.https.any.js b/WebCryptoAPI/digest/kangarootwelve.tentative.https.any.js index 9f800b7937876a..0e38eb0542ad5f 100644 --- a/WebCryptoAPI/digest/kangarootwelve.tentative.https.any.js +++ b/WebCryptoAPI/digest/kangarootwelve.tentative.https.any.js @@ -1,24 +1,10 @@ // META: title=WebCryptoAPI: digest() KangarooTwelve algorithms // META: script=../util/helpers.js +// META: script=xof_digest.js // META: timeout=long var subtle = crypto.subtle; // Change to test prefixed implementations -// Generates a Uint8Array of length n by repeating the pattern 00 01 02 .. F9 FA. -function ptn(n) { - var buf = new Uint8Array(n); - for (var i = 0; i < n; i++) - buf[i] = i % 251; - return buf; -} - -function hexToBytes(hex) { - var bytes = new Uint8Array(hex.length / 2); - for (var i = 0; i < hex.length; i += 2) - bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); - return bytes; -} - // RFC 9861 Section 5 test vectors // [input, outputLengthBits, expected hex(, customization)] var kt128Vectors = [ @@ -182,143 +168,21 @@ var largeOutputTests = [ '2752f3ccd855288efee5fcbb8b563069'], ]; -largeOutputTests.forEach(function (entry) { - var alg = entry[0]; - var outputLength = entry[1]; - var lastN = entry[2]; - var expected = entry[3]; - - promise_test(function (test) { - return subtle - .digest({ name: alg, outputLength: outputLength }, new Uint8Array(0)) - .then(function (result) { - var full = new Uint8Array(result); - var last = full.slice(full.length - lastN); - assert_true( - equalBuffers(last.buffer, hexToBytes(expected)), - 'last ' + lastN + ' bytes of digest match expected' - ); - }); - }, alg + ' with ' + outputLength + ' bit output, verify last ' + lastN + ' bytes'); -}); - -function customizationEqual(emptyDataVector, customization) { - return equalBuffers(customization ?? new Uint8Array(0), emptyDataVector[3] ?? new Uint8Array(0)); -} - -function outputLengthLessOrEqual(emptyDataVector, outputLength) { - return outputLength <= emptyDataVector[1]; -} - -var allVectors = { - KT128: kt128Vectors, - KT256: kt256Vectors, -}; - -Object.keys(allVectors).forEach(function (alg) { - var emptyDataVector = allVectors[alg][0]; - allVectors[alg].forEach(function (vector, i) { - var input = vector[0]; - var outputLength = vector[1]; - var expected = vector[2]; - var customization = vector[3]; - - var algorithmParams = { name: alg, outputLength: outputLength }; - if (customization !== undefined) - algorithmParams.customization = customization; - - var label = alg + ' vector #' + (i + 1) + - ' (' + outputLength + ' bit output, ' + input.length + ' byte input' + - (customization !== undefined ? ', C=' + customization.length + ' bytes' : '') + ')'; - - promise_test(function (test) { - return subtle - .digest(algorithmParams, input) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - }, label); - - if (input.length > 0) { - promise_test(function (test) { - var buffer = new Uint8Array(input); - // Alter the buffer before calling digest - buffer[0] = ~buffer[0]; - return subtle - .digest({ - get name() { - // Alter the buffer back while calling digest - buffer[0] = input[0]; - return alg; - }, - outputLength: outputLength, - customization: customization, - }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - }, label + ' and altered buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(input); - var promise = subtle - .digest(algorithmParams, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - // Alter the buffer after calling digest - buffer[0] = ~buffer[0]; - return promise; - }, label + ' and altered buffer after call'); - - promise_test(function (test) { - var buffer = new Uint8Array(input); - return subtle - .digest({ - get name() { - // Transfer the buffer while calling digest - buffer.buffer.transfer(); - return alg; - }, - outputLength: outputLength, - customization: customization, - }, buffer) - .then(function (result) { - if (customizationEqual(emptyDataVector, customization) && outputLengthLessOrEqual(emptyDataVector, outputLength)) { - assert_true( - equalBuffers(result, Uint8Array.fromHex(emptyDataVector[2]).subarray(0, outputLength / 8)), - 'digest on transferred buffer should match result for empty buffer' - ); - } else { - assert_equals(result.byteLength, outputLength / 8, - 'digest on transferred buffer should have correct output length'); - } - }); - }, label + ' and transferred buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(input); - var promise = subtle - .digest(algorithmParams, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - // Transfer the buffer after calling digest - buffer.buffer.transfer(); - return promise; - }, label + ' and transferred buffer after call'); - } - }); +runXofDigestTests(subtle, { + vectors: { + KT128: kt128Vectors, + KT256: kt256Vectors, + }, + largeOutputTests: largeOutputTests, + parameterName: 'customization', + formatParameter: function (customization) { + return customization !== undefined ? + ', C=' + customization.length + ' bytes' : ''; + }, + parameterEquals: function (emptyDataVector, customization) { + return equalBuffers( + customization ?? new Uint8Array(0), + emptyDataVector[3] ?? new Uint8Array(0) + ); + }, }); diff --git a/WebCryptoAPI/digest/sha3.tentative.https.any.js b/WebCryptoAPI/digest/sha3.tentative.https.any.js index f9f38eadc2c39a..a6cafbb639f860 100644 --- a/WebCryptoAPI/digest/sha3.tentative.https.any.js +++ b/WebCryptoAPI/digest/sha3.tentative.https.any.js @@ -1,28 +1,12 @@ // META: title=WebCryptoAPI: digest() SHA-3 algorithms // META: script=../util/helpers.js +// META: script=digest_test_data.js +// META: script=digest.js // META: timeout=long var subtle = crypto.subtle; // Change to test prefixed implementations -var sourceData = { - empty: new Uint8Array(0), - short: new Uint8Array([ - 21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255, - ]), - medium: new Uint8Array([ - 182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, - 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, - 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, - 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, - 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, - 171, 172, 161, 147, - ]), -}; - -sourceData.long = new Uint8Array(1024 * sourceData.medium.byteLength); -for (var i = 0; i < 1024; i++) { - sourceData.long.set(sourceData.medium, i * sourceData.medium.byteLength); -} +var sourceData = getDigestSourceData(true); var digestedData = { 'SHA3-256': { @@ -97,83 +81,14 @@ var digestedData = { }; // Test SHA-3 digest algorithms -Object.keys(sourceData).forEach(function (size) { - Object.keys(digestedData).forEach(function (alg) { - promise_test(function (test) { - return crypto.subtle - .digest(alg, sourceData[size]) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][size]), - 'digest matches expected' - ); - }); - }, alg + ' with ' + size + ' source data'); - - if (sourceData[size].length > 0) { - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - // Alter the buffer before calling digest - buffer[0] = ~buffer[0]; - return crypto.subtle - .digest({ - get name() { - // Alter the buffer back while calling digest - buffer[0] = sourceData[size][0]; - return alg; - } - }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][size]), - 'digest matches expected' - ); - }); - }, alg + ' with ' + size + ' source data and altered buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - var promise = crypto.subtle.digest(alg, buffer).then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][size]), - 'digest matches expected' - ); - }); - // Alter the buffer after calling digest - buffer[0] = ~buffer[0]; - return promise; - }, alg + ' with ' + size + ' source data and altered buffer after call'); - - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - return crypto.subtle - .digest({ - get name() { - // Transfer the buffer while calling digest - buffer.buffer.transfer(); - return alg; - } - }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg].empty), - 'digest on transferred buffer should match result for empty buffer' - ); - }); - }, alg + ' with ' + size + ' source data and transferred buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(sourceData[size]); - var promise = crypto.subtle.digest(alg, buffer).then(function (result) { - assert_true( - equalBuffers(result, digestedData[alg][size]), - 'digest matches expected' - ); - }); - // Transfer the buffer after calling digest - buffer.buffer.transfer(); - return promise; - }, alg + ' with ' + size + ' source data and transferred buffer after call'); - } +runDigestTests(subtle, sourceData, function (size) { + return Object.keys(digestedData).map(function (alg) { + return { + algorithm: alg, + expected: digestedData[alg][size], + emptyExpected: digestedData[alg].empty, + label: alg + ' with ' + size + ' source data', + mutations: true, + }; }); }); diff --git a/WebCryptoAPI/digest/turboshake.tentative.https.any.js b/WebCryptoAPI/digest/turboshake.tentative.https.any.js index 243931cd119802..356e6987956cb7 100644 --- a/WebCryptoAPI/digest/turboshake.tentative.https.any.js +++ b/WebCryptoAPI/digest/turboshake.tentative.https.any.js @@ -1,24 +1,10 @@ // META: title=WebCryptoAPI: digest() TurboSHAKE algorithms // META: script=../util/helpers.js +// META: script=xof_digest.js // META: timeout=long var subtle = crypto.subtle; // Change to test prefixed implementations -// Generates a Uint8Array of length n by repeating the pattern 00 01 02 .. F9 FA. -function ptn(n) { - var buf = new Uint8Array(n); - for (var i = 0; i < n; i++) - buf[i] = i % 251; - return buf; -} - -function hexToBytes(hex) { - var bytes = new Uint8Array(hex.length / 2); - for (var i = 0; i < hex.length; i += 2) - bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); - return bytes; -} - // RFC 9861 Section 5 test vectors // [input, outputLengthBits, expected hex(, domainSeparation)] var turboSHAKE128Vectors = [ @@ -155,143 +141,18 @@ var largeOutputTests = [ '207265dccf2f43534e9c61ba0c9d1d75'], ]; -largeOutputTests.forEach(function (entry) { - var alg = entry[0]; - var outputLength = entry[1]; - var lastN = entry[2]; - var expected = entry[3]; - - promise_test(function (test) { - return subtle - .digest({ name: alg, outputLength: outputLength }, new Uint8Array(0)) - .then(function (result) { - var full = new Uint8Array(result); - var last = full.slice(full.length - lastN); - assert_true( - equalBuffers(last.buffer, hexToBytes(expected)), - 'last ' + lastN + ' bytes of digest match expected' - ); - }); - }, alg + ' with ' + outputLength + ' bit output, verify last ' + lastN + ' bytes'); -}); - -function domainSeparationEqual(emptyDataVector, domainSeparation) { - return (domainSeparation ?? 0x1f) === (emptyDataVector[3] ?? 0x1f); -} - -function outputLengthLessOrEqual(emptyDataVector, outputLength) { - return outputLength <= emptyDataVector[1]; -} - -var allVectors = { - TurboSHAKE128: turboSHAKE128Vectors, - TurboSHAKE256: turboSHAKE256Vectors, -}; - -Object.keys(allVectors).forEach(function (alg) { - var emptyDataVector = allVectors[alg][0]; - allVectors[alg].forEach(function (vector, i) { - var input = vector[0]; - var outputLength = vector[1]; - var expected = vector[2]; - var domainSeparation = vector[3]; - - var algorithmParams = { name: alg, outputLength: outputLength }; - if (domainSeparation !== undefined) - algorithmParams.domainSeparation = domainSeparation; - - var label = alg + ' vector #' + (i + 1) + - ' (' + outputLength + ' bit output, ' + input.length + ' byte input' + - (domainSeparation !== undefined ? ', D=0x' + domainSeparation.toString(16) : '') + ')'; - - promise_test(function (test) { - return subtle - .digest(algorithmParams, input) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - }, label); - - if (input.length > 0) { - promise_test(function (test) { - var buffer = new Uint8Array(input); - // Alter the buffer before calling digest - buffer[0] = ~buffer[0]; - return subtle - .digest({ - get name() { - // Alter the buffer back while calling digest - buffer[0] = input[0]; - return alg; - }, - outputLength: outputLength, - domainSeparation: domainSeparation, - }, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - }, label + ' and altered buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(input); - var promise = subtle - .digest(algorithmParams, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - // Alter the buffer after calling digest - buffer[0] = ~buffer[0]; - return promise; - }, label + ' and altered buffer after call'); - - promise_test(function (test) { - var buffer = new Uint8Array(input); - return subtle - .digest({ - get name() { - // Transfer the buffer while calling digest - buffer.buffer.transfer(); - return alg; - }, - outputLength: outputLength, - domainSeparation: domainSeparation, - }, buffer) - .then(function (result) { - if (domainSeparationEqual(emptyDataVector, domainSeparation) && outputLengthLessOrEqual(emptyDataVector, outputLength)) { - assert_true( - equalBuffers(result, Uint8Array.fromHex(emptyDataVector[2]).subarray(0, outputLength / 8)), - 'digest on transferred buffer should match result for empty buffer' - ); - } else { - assert_equals(result.byteLength, outputLength / 8, - 'digest on transferred buffer should have correct output length'); - } - }); - }, label + ' and transferred buffer during call'); - - promise_test(function (test) { - var buffer = new Uint8Array(input); - var promise = subtle - .digest(algorithmParams, buffer) - .then(function (result) { - assert_true( - equalBuffers(result, hexToBytes(expected)), - 'digest matches expected' - ); - }); - // Transfer the buffer after calling digest - buffer.buffer.transfer(); - return promise; - }, label + ' and transferred buffer after call'); - } - }); +runXofDigestTests(subtle, { + vectors: { + TurboSHAKE128: turboSHAKE128Vectors, + TurboSHAKE256: turboSHAKE256Vectors, + }, + largeOutputTests: largeOutputTests, + parameterName: 'domainSeparation', + formatParameter: function (domainSeparation) { + return domainSeparation !== undefined ? + ', D=0x' + domainSeparation.toString(16) : ''; + }, + parameterEquals: function (emptyDataVector, domainSeparation) { + return (domainSeparation ?? 0x1f) === (emptyDataVector[3] ?? 0x1f); + }, }); diff --git a/WebCryptoAPI/digest/xof_digest.js b/WebCryptoAPI/digest/xof_digest.js new file mode 100644 index 00000000000000..f5ef5846b79609 --- /dev/null +++ b/WebCryptoAPI/digest/xof_digest.js @@ -0,0 +1,146 @@ +// Generates a Uint8Array of length n by repeating the pattern 00 01 02 .. F9 FA. +function ptn(n) { + var buf = new Uint8Array(n); + for (var i = 0; i < n; i++) + buf[i] = i % 251; + return buf; +} + +function runXofDigestTests(subtle, options) { + options.largeOutputTests.forEach(function (entry) { + var alg = entry[0]; + var outputLength = entry[1]; + var lastN = entry[2]; + var expected = entry[3]; + + promise_test(function (test) { + return subtle + .digest({ name: alg, outputLength: outputLength }, new Uint8Array(0)) + .then(function (result) { + var full = new Uint8Array(result); + var last = full.slice(full.length - lastN); + assert_true( + equalBuffers(last.buffer, hexStringToUint8Array(expected)), + 'last ' + lastN + ' bytes of digest match expected' + ); + }); + }, alg + ' with ' + outputLength + ' bit output, verify last ' + lastN + ' bytes'); + }); + + Object.keys(options.vectors).forEach(function (alg) { + var emptyDataVector = options.vectors[alg][0]; + options.vectors[alg].forEach(function (vector, i) { + var input = vector[0]; + var outputLength = vector[1]; + var expected = vector[2]; + var parameter = vector[3]; + + var algorithmParams = { name: alg, outputLength: outputLength }; + if (parameter !== undefined) + algorithmParams[options.parameterName] = parameter; + + var label = alg + ' vector #' + (i + 1) + + ' (' + outputLength + ' bit output, ' + input.length + ' byte input' + + options.formatParameter(parameter) + ')'; + + promise_test(function (test) { + return subtle + .digest(algorithmParams, input) + .then(function (result) { + assert_true( + equalBuffers(result, hexStringToUint8Array(expected)), + 'digest matches expected' + ); + }); + }, label); + + if (input.length > 0) { + promise_test(function (test) { + var buffer = new Uint8Array(input); + // Alter the buffer before calling digest + buffer[0] = ~buffer[0]; + var duringCallParams = { + get name() { + // Alter the buffer back while calling digest + buffer[0] = input[0]; + return alg; + }, + outputLength: outputLength, + }; + duringCallParams[options.parameterName] = parameter; + return subtle + .digest(duringCallParams, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexStringToUint8Array(expected)), + 'digest matches expected' + ); + }); + }, label + ' and altered buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + var promise = subtle + .digest(algorithmParams, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexStringToUint8Array(expected)), + 'digest matches expected' + ); + }); + // Alter the buffer after calling digest + buffer[0] = ~buffer[0]; + return promise; + }, label + ' and altered buffer after call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + var duringCallParams = { + get name() { + // Transfer the buffer while calling digest + buffer.buffer.transfer(); + return alg; + }, + outputLength: outputLength, + }; + duringCallParams[options.parameterName] = parameter; + return subtle + .digest(duringCallParams, buffer) + .then(function (result) { + if ( + options.parameterEquals(emptyDataVector, parameter) && + outputLength <= emptyDataVector[1] + ) { + assert_true( + equalBuffers( + result, + hexStringToUint8Array(emptyDataVector[2]) + .subarray(0, outputLength / 8) + ), + 'digest on transferred buffer should match result for empty buffer' + ); + } else { + assert_equals(result.byteLength, outputLength / 8, + 'digest on transferred buffer should have correct output length'); + } + }); + }, label + ' and transferred buffer during call'); + + promise_test(function (test) { + var buffer = new Uint8Array(input); + var promise = subtle + .digest(algorithmParams, buffer) + .then(function (result) { + assert_true( + equalBuffers(result, hexStringToUint8Array(expected)), + 'digest matches expected' + ); + }); + // Transfer the buffer after calling digest + buffer.buffer.transfer(); + return promise; + }, label + ' and transferred buffer after call'); + } + }); + }); +} diff --git a/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js b/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js index 5a669753cd2701..ffb78f7e534860 100644 --- a/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js +++ b/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js @@ -27,11 +27,11 @@ function define_bits_tests() { 'encapsulateBits should return an object' ); assert_true( - encapsulatedBits.hasOwnProperty('sharedKey'), + Object.hasOwn(encapsulatedBits, 'sharedKey'), 'Result should have sharedKey property' ); assert_true( - encapsulatedBits.hasOwnProperty('ciphertext'), + Object.hasOwn(encapsulatedBits, 'ciphertext'), 'Result should have ciphertext property' ); assert_true( diff --git a/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js b/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js index 0a45c1fc4e9f6f..a482eafbb61021 100644 --- a/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js +++ b/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js @@ -61,11 +61,11 @@ function define_key_tests() { 'encapsulateKey should return an object' ); assert_true( - encapsulatedKey.hasOwnProperty('sharedKey'), + Object.hasOwn(encapsulatedKey, 'sharedKey'), 'Result should have sharedKey property' ); assert_true( - encapsulatedKey.hasOwnProperty('ciphertext'), + Object.hasOwn(encapsulatedKey, 'ciphertext'), 'Result should have ciphertext property' ); assert_true( diff --git a/WebCryptoAPI/encrypt_decrypt/aes.js b/WebCryptoAPI/encrypt_decrypt/aes.js index 879a6efe257e49..9caecf695cf7e7 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes.js +++ b/WebCryptoAPI/encrypt_decrypt/aes.js @@ -458,9 +458,7 @@ function run_test() { }); promise_test(function() { - return Promise.all(all_promises) - .then(function() {done();}) - .catch(function() {done();}) + return Promise.all(all_promises).finally(done); }, "setup"); // A test vector has all needed fields for encryption, EXCEPT that the @@ -470,9 +468,7 @@ function run_test() { // Returns a Promise that yields an updated vector on success. function importVectorKey(vector, usages) { if (vector.key !== null) { - return new Promise(function(resolve, reject) { - resolve(vector); - }); + return Promise.resolve(vector); } else { return subtle.importKey(vector.algorithm.name.toUpperCase() === "AES-OCB" ? "raw-secret" : "raw", vector.keyBuffer, {name: vector.algorithm.name}, false, usages) .then(function(key) { diff --git a/WebCryptoAPI/encrypt_decrypt/aes_cbc.https.any.js b/WebCryptoAPI/encrypt_decrypt/aes_cbc.https.any.js index ec09aae5a954a7..9dcbfbdeccbf8f 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_cbc.https.any.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_cbc.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: encrypt() Using AES-CBC // META: script=../util/helpers.js +// META: script=aes_common_fixtures.js // META: script=aes_cbc_vectors.js // META: script=aes.js // META: timeout=long diff --git a/WebCryptoAPI/encrypt_decrypt/aes_cbc_vectors.js b/WebCryptoAPI/encrypt_decrypt/aes_cbc_vectors.js index 96445a96325a55..28ef75fece62a4 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_cbc_vectors.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_cbc_vectors.js @@ -12,59 +12,9 @@ // plaintext - the text to encrypt // result - the expected result (usually just ciphertext, sometimes with added authentication) function getTestVectors() { - // Before we can really start, we need to fill a bunch of buffers with data - var plaintext = new Uint8Array([84, 104, 105, 115, 32, 115, - 112, 101, 99, 105, 102, 105, 99, 97, 116, 105, 111, 110, - 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, - 74, 97, 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80, - 73, 32, 102, 111, 114, 32, 112, 101, 114, 102, 111, 114, - 109, 105, 110, 103, 32, 98, 97, 115, 105, 99, 32, 99, 114, - 121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32, - 111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105, - 110, 32, 119, 101, 98, 32, 97, 112, 112, 108, 105, 99, 97, - 116, 105, 111, 110, 115, 44, 32, 115, 117, 99, 104, 32, 97, - 115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, 115, - 105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110, - 101, 114, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, - 118, 101, 114, 105, 102, 105, 99, 97, 116, 105, 111, 110, - 44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, 112, - 116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99, - 114, 121, 112, 116, 105, 111, 110, 46, 32, 65, 100, 100, - 105, 116, 105, 111, 110, 97, 108, 108, 121, 44, 32, 105, - 116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, - 110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112, - 108, 105, 99, 97, 116, 105, 111, 110, 115, 32, 116, 111, - 32, 103, 101, 110, 101, 114, 97, 116, 101, 32, 97, 110, - 100, 47, 111, 114, 32, 109, 97, 110, 97, 103, 101, 32, 116, - 104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97, - 116, 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115, - 115, 97, 114, 121, 32, 116, 111, 32, 112, 101, 114, 102, - 111, 114, 109, 32, 116, 104, 101, 115, 101, 32, 111, 112, - 101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115, - 101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32, - 65, 80, 73, 32, 114, 97, 110, 103, 101, 32, 102, 114, 111, - 109, 32, 117, 115, 101, 114, 32, 111, 114, 32, 115, 101, - 114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, 110, - 116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111, - 99, 117, 109, 101, 110, 116, 32, 111, 114, 32, 99, 111, - 100, 101, 32, 115, 105, 103, 110, 105, 110, 103, 44, 32, - 97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, 102, - 105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32, - 97, 110, 100, 32, 105, 110, 116, 101, 103, 114, 105, 116, - 121, 32, 111, 102, 32, 99, 111, 109, 109, 117, 110, 105, - 99, 97, 116, 105, 111, 110, 115, 46]); - - // We want some random key bytes of various sizes. - // These were randomly generated from a script. - var keyBytes = { - 128: new Uint8Array([222, 192, 212, 252, 191, 60, 71, - 65, 200, 146, 218, 189, 28, 212, 192, 78]), - 192: new Uint8Array([208, 238, 131, 65, 63, 68, 196, 63, 186, 208, - 61, 207, 166, 18, 99, 152, 29, 109, 221, 95, 240, 30, 28, 246]), - 256: new Uint8Array([103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236, - 233, 204, 58, 249, 16, 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116, - 216, 0, 11, 191, 48]) - } + var commonFixtures = getAesCommonFixtures(); + var plaintext = commonFixtures.plaintext; + var keyBytes = commonFixtures.keyBytes; // AES-CBC needs a 16 byte (128 bit) IV. var iv = new Uint8Array([85, 170, 248, 155, 168, 148, 19, 213, 78, 167, 39, diff --git a/WebCryptoAPI/encrypt_decrypt/aes_common_fixtures.js b/WebCryptoAPI/encrypt_decrypt/aes_common_fixtures.js new file mode 100644 index 00000000000000..d8c6d1666ccaeb --- /dev/null +++ b/WebCryptoAPI/encrypt_decrypt/aes_common_fixtures.js @@ -0,0 +1,57 @@ +function getAesCommonFixtures() { + var plaintext = new Uint8Array([ + 84, 104, 105, 115, 32, 115, 112, 101, 99, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, 74, 97, + 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80, 73, 32, 102, 111, 114, 32, + 112, 101, 114, 102, 111, 114, 109, 105, 110, 103, 32, 98, 97, 115, 105, 99, + 32, 99, 114, 121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32, 111, + 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105, 110, 32, 119, 101, 98, + 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 115, 44, 32, 115, + 117, 99, 104, 32, 97, 115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, + 115, 105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110, 101, 114, 97, + 116, 105, 111, 110, 32, 97, 110, 100, 32, 118, 101, 114, 105, 102, 105, 99, + 97, 116, 105, 111, 110, 44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, + 112, 116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99, 114, 121, 112, + 116, 105, 111, 110, 46, 32, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, + 108, 121, 44, 32, 105, 116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, + 32, 97, 110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112, 108, 105, + 99, 97, 116, 105, 111, 110, 115, 32, 116, 111, 32, 103, 101, 110, 101, 114, + 97, 116, 101, 32, 97, 110, 100, 47, 111, 114, 32, 109, 97, 110, 97, 103, + 101, 32, 116, 104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97, 116, + 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115, 115, 97, 114, 121, 32, + 116, 111, 32, 112, 101, 114, 102, 111, 114, 109, 32, 116, 104, 101, 115, + 101, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115, + 101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32, 65, 80, 73, 32, + 114, 97, 110, 103, 101, 32, 102, 114, 111, 109, 32, 117, 115, 101, 114, 32, + 111, 114, 32, 115, 101, 114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, + 110, 116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111, 99, 117, 109, + 101, 110, 116, 32, 111, 114, 32, 99, 111, 100, 101, 32, 115, 105, 103, 110, + 105, 110, 103, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, + 102, 105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32, 97, 110, 100, + 32, 105, 110, 116, 101, 103, 114, 105, 116, 121, 32, 111, 102, 32, 99, 111, + 109, 109, 117, 110, 105, 99, 97, 116, 105, 111, 110, 115, 46, + ]); + + var keyBytes = { + 128: new Uint8Array([ + 222, 192, 212, 252, 191, 60, 71, 65, 200, 146, 218, 189, 28, 212, 192, 78, + ]), + 192: new Uint8Array([ + 208, 238, 131, 65, 63, 68, 196, 63, 186, 208, 61, 207, 166, 18, 99, 152, + 29, 109, 221, 95, 240, 30, 28, 246, + ]), + 256: new Uint8Array([ + 103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236, 233, 204, 58, 249, 16, + 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116, 216, 0, 11, 191, 48, + ]), + }; + + var additionalData = new Uint8Array([ + 84, 104, 101, 114, 101, 32, 97, 114, 101, 32, 55, 32, 102, 117, 114, 116, + 104, 101, 114, 32, 101, 100, 105, 116, 111, 114, 105, 97, 108, 32, 110, 111, + 116, 101, 115, 32, 105, 110, 32, 116, 104, 101, 32, 100, 111, 99, 117, 109, + 101, 110, 116, 46, + ]); + + return { plaintext, keyBytes, additionalData }; +} diff --git a/WebCryptoAPI/encrypt_decrypt/aes_ctr.https.any.js b/WebCryptoAPI/encrypt_decrypt/aes_ctr.https.any.js index f9d85bb6c93b77..cbda32f354321f 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_ctr.https.any.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_ctr.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: encrypt() Using AES-CTR // META: script=../util/helpers.js +// META: script=aes_common_fixtures.js // META: script=aes_ctr_vectors.js // META: script=aes.js // META: timeout=long diff --git a/WebCryptoAPI/encrypt_decrypt/aes_ctr_vectors.js b/WebCryptoAPI/encrypt_decrypt/aes_ctr_vectors.js index 201dff83ce9cac..89a19fa5fcbe5e 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_ctr_vectors.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_ctr_vectors.js @@ -12,59 +12,9 @@ // plaintext - the text to encrypt // result - the expected result (usually just ciphertext, sometimes with added authentication) function getTestVectors() { - // Before we can really start, we need to fill a bunch of buffers with data - var plaintext = new Uint8Array([84, 104, 105, 115, 32, 115, - 112, 101, 99, 105, 102, 105, 99, 97, 116, 105, 111, 110, - 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, - 74, 97, 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80, - 73, 32, 102, 111, 114, 32, 112, 101, 114, 102, 111, 114, - 109, 105, 110, 103, 32, 98, 97, 115, 105, 99, 32, 99, 114, - 121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32, - 111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105, - 110, 32, 119, 101, 98, 32, 97, 112, 112, 108, 105, 99, 97, - 116, 105, 111, 110, 115, 44, 32, 115, 117, 99, 104, 32, 97, - 115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, 115, - 105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110, - 101, 114, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, - 118, 101, 114, 105, 102, 105, 99, 97, 116, 105, 111, 110, - 44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, 112, - 116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99, - 114, 121, 112, 116, 105, 111, 110, 46, 32, 65, 100, 100, - 105, 116, 105, 111, 110, 97, 108, 108, 121, 44, 32, 105, - 116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, - 110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112, - 108, 105, 99, 97, 116, 105, 111, 110, 115, 32, 116, 111, - 32, 103, 101, 110, 101, 114, 97, 116, 101, 32, 97, 110, - 100, 47, 111, 114, 32, 109, 97, 110, 97, 103, 101, 32, 116, - 104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97, - 116, 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115, - 115, 97, 114, 121, 32, 116, 111, 32, 112, 101, 114, 102, - 111, 114, 109, 32, 116, 104, 101, 115, 101, 32, 111, 112, - 101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115, - 101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32, - 65, 80, 73, 32, 114, 97, 110, 103, 101, 32, 102, 114, 111, - 109, 32, 117, 115, 101, 114, 32, 111, 114, 32, 115, 101, - 114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, 110, - 116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111, - 99, 117, 109, 101, 110, 116, 32, 111, 114, 32, 99, 111, - 100, 101, 32, 115, 105, 103, 110, 105, 110, 103, 44, 32, - 97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, 102, - 105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32, - 97, 110, 100, 32, 105, 110, 116, 101, 103, 114, 105, 116, - 121, 32, 111, 102, 32, 99, 111, 109, 109, 117, 110, 105, - 99, 97, 116, 105, 111, 110, 115, 46]); - - // We want some random key bytes of various sizes. - // These were randomly generated from a script. - var keyBytes = { - 128: new Uint8Array([222, 192, 212, 252, 191, 60, 71, - 65, 200, 146, 218, 189, 28, 212, 192, 78]), - 192: new Uint8Array([208, 238, 131, 65, 63, 68, 196, 63, 186, 208, - 61, 207, 166, 18, 99, 152, 29, 109, 221, 95, 240, 30, 28, 246]), - 256: new Uint8Array([103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236, - 233, 204, 58, 249, 16, 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116, - 216, 0, 11, 191, 48]) - } + var commonFixtures = getAesCommonFixtures(); + var plaintext = commonFixtures.plaintext; + var keyBytes = commonFixtures.keyBytes; // AES-CTR needs a 16 byte (128 bit) counter. var counter = new Uint8Array([85, 170, 248, 155, 168, 148, 19, 213, 78, 167, 39, diff --git a/WebCryptoAPI/encrypt_decrypt/aes_gcm.https.any.js b/WebCryptoAPI/encrypt_decrypt/aes_gcm.https.any.js index b3e6b5f0d2c1ff..295351fc319d65 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_gcm.https.any.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_gcm.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: encrypt() Using AES-GCM w/ 96-bit iv // META: script=../util/helpers.js +// META: script=aes_common_fixtures.js // META: script=aes_gcm_96_iv_fixtures.js // META: script=aes_gcm_vectors.js // META: script=aes.js diff --git a/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv.https.any.js b/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv.https.any.js index 196a8ea94fb1c4..a46f4c79b891a5 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv.https.any.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: encrypt() Using AES-GCM w/ 256-bit iv // META: script=../util/helpers.js +// META: script=aes_common_fixtures.js // META: script=aes_gcm_256_iv_fixtures.js // META: script=aes_gcm_vectors.js // META: script=aes.js diff --git a/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv_fixtures.js b/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv_fixtures.js index 9cdbbbb79075c0..a081b8e864831c 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv_fixtures.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_gcm_256_iv_fixtures.js @@ -1,53 +1,7 @@ function getFixtures() { - // Before we can really start, we need to fill a bunch of buffers with data - var plaintext = new Uint8Array([ - 84, 104, 105, 115, 32, 115, 112, 101, 99, 105, 102, 105, 99, 97, 116, 105, - 111, 110, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, 74, 97, - 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80, 73, 32, 102, 111, 114, 32, - 112, 101, 114, 102, 111, 114, 109, 105, 110, 103, 32, 98, 97, 115, 105, 99, - 32, 99, 114, 121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32, 111, - 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105, 110, 32, 119, 101, 98, - 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 115, 44, 32, 115, - 117, 99, 104, 32, 97, 115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, - 115, 105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110, 101, 114, 97, - 116, 105, 111, 110, 32, 97, 110, 100, 32, 118, 101, 114, 105, 102, 105, 99, - 97, 116, 105, 111, 110, 44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, - 112, 116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99, 114, 121, 112, - 116, 105, 111, 110, 46, 32, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, - 108, 121, 44, 32, 105, 116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, - 32, 97, 110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112, 108, 105, - 99, 97, 116, 105, 111, 110, 115, 32, 116, 111, 32, 103, 101, 110, 101, 114, - 97, 116, 101, 32, 97, 110, 100, 47, 111, 114, 32, 109, 97, 110, 97, 103, - 101, 32, 116, 104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97, 116, - 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115, 115, 97, 114, 121, 32, - 116, 111, 32, 112, 101, 114, 102, 111, 114, 109, 32, 116, 104, 101, 115, - 101, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115, - 101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32, 65, 80, 73, 32, - 114, 97, 110, 103, 101, 32, 102, 114, 111, 109, 32, 117, 115, 101, 114, 32, - 111, 114, 32, 115, 101, 114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, - 110, 116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111, 99, 117, 109, - 101, 110, 116, 32, 111, 114, 32, 99, 111, 100, 101, 32, 115, 105, 103, 110, - 105, 110, 103, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, - 102, 105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32, 97, 110, 100, - 32, 105, 110, 116, 101, 103, 114, 105, 116, 121, 32, 111, 102, 32, 99, 111, - 109, 109, 117, 110, 105, 99, 97, 116, 105, 111, 110, 115, 46, - ]); - - // We want some random key bytes of various sizes. - // These were randomly generated from a script. - var keyBytes = { - 128: new Uint8Array([ - 222, 192, 212, 252, 191, 60, 71, 65, 200, 146, 218, 189, 28, 212, 192, 78, - ]), - 192: new Uint8Array([ - 208, 238, 131, 65, 63, 68, 196, 63, 186, 208, 61, 207, 166, 18, 99, 152, - 29, 109, 221, 95, 240, 30, 28, 246, - ]), - 256: new Uint8Array([ - 103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236, 233, 204, 58, 249, 16, - 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116, 216, 0, 11, 191, 48, - ]), - }; + var commonFixtures = getAesCommonFixtures(); + var plaintext = commonFixtures.plaintext; + var keyBytes = commonFixtures.keyBytes; // AES-GCM needs an IV of no more than 2^64 - 1 bytes. Arbitrary 32 bytes is okay then. var iv = new Uint8Array([ @@ -55,15 +9,7 @@ function getFixtures() { 33, 117, 56, 94, 248, 173, 234, 194, 200, 115, 53, 235, 146, 141, 212, ]); - // Authenticated encryption via AES-GCM requires additional data that - // will be checked. We use the ASCII encoded Editorial Note - // following the Abstract of the Web Cryptography API recommendation. - var additionalData = new Uint8Array([ - 84, 104, 101, 114, 101, 32, 97, 114, 101, 32, 55, 32, 102, 117, 114, 116, - 104, 101, 114, 32, 101, 100, 105, 116, 111, 114, 105, 97, 108, 32, 110, 111, - 116, 101, 115, 32, 105, 110, 32, 116, 104, 101, 32, 100, 111, 99, 117, 109, - 101, 110, 116, 46, - ]); + var additionalData = commonFixtures.additionalData; // The length of the tag defaults to 16 bytes (128 bit). var tag = { diff --git a/WebCryptoAPI/encrypt_decrypt/aes_gcm_96_iv_fixtures.js b/WebCryptoAPI/encrypt_decrypt/aes_gcm_96_iv_fixtures.js index bb00e2d7dd92cb..e120b58d8dc493 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_gcm_96_iv_fixtures.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_gcm_96_iv_fixtures.js @@ -1,68 +1,14 @@ function getFixtures() { - // Before we can really start, we need to fill a bunch of buffers with data - var plaintext = new Uint8Array([ - 84, 104, 105, 115, 32, 115, 112, 101, 99, 105, 102, 105, 99, 97, 116, 105, - 111, 110, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, 74, 97, - 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80, 73, 32, 102, 111, 114, 32, - 112, 101, 114, 102, 111, 114, 109, 105, 110, 103, 32, 98, 97, 115, 105, 99, - 32, 99, 114, 121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32, 111, - 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105, 110, 32, 119, 101, 98, - 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 115, 44, 32, 115, - 117, 99, 104, 32, 97, 115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, - 115, 105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110, 101, 114, 97, - 116, 105, 111, 110, 32, 97, 110, 100, 32, 118, 101, 114, 105, 102, 105, 99, - 97, 116, 105, 111, 110, 44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, - 112, 116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99, 114, 121, 112, - 116, 105, 111, 110, 46, 32, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, - 108, 121, 44, 32, 105, 116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, - 32, 97, 110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112, 108, 105, - 99, 97, 116, 105, 111, 110, 115, 32, 116, 111, 32, 103, 101, 110, 101, 114, - 97, 116, 101, 32, 97, 110, 100, 47, 111, 114, 32, 109, 97, 110, 97, 103, - 101, 32, 116, 104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97, 116, - 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115, 115, 97, 114, 121, 32, - 116, 111, 32, 112, 101, 114, 102, 111, 114, 109, 32, 116, 104, 101, 115, - 101, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115, - 101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32, 65, 80, 73, 32, - 114, 97, 110, 103, 101, 32, 102, 114, 111, 109, 32, 117, 115, 101, 114, 32, - 111, 114, 32, 115, 101, 114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, - 110, 116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111, 99, 117, 109, - 101, 110, 116, 32, 111, 114, 32, 99, 111, 100, 101, 32, 115, 105, 103, 110, - 105, 110, 103, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, - 102, 105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32, 97, 110, 100, - 32, 105, 110, 116, 101, 103, 114, 105, 116, 121, 32, 111, 102, 32, 99, 111, - 109, 109, 117, 110, 105, 99, 97, 116, 105, 111, 110, 115, 46, - ]); - - // We want some random key bytes of various sizes. - // These were randomly generated from a script. - var keyBytes = { - 128: new Uint8Array([ - 222, 192, 212, 252, 191, 60, 71, 65, 200, 146, 218, 189, 28, 212, 192, 78, - ]), - 192: new Uint8Array([ - 208, 238, 131, 65, 63, 68, 196, 63, 186, 208, 61, 207, 166, 18, 99, 152, - 29, 109, 221, 95, 240, 30, 28, 246, - ]), - 256: new Uint8Array([ - 103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236, 233, 204, 58, 249, 16, - 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116, 216, 0, 11, 191, 48, - ]), - }; + var commonFixtures = getAesCommonFixtures(); + var plaintext = commonFixtures.plaintext; + var keyBytes = commonFixtures.keyBytes; // AES-GCM specification recommends that the IV should be 96 bits long. var iv = new Uint8Array([ 58, 146, 115, 42, 166, 234, 57, 191, 57, 134, 224, 199, ]); - // Authenticated encryption via AES-GCM requires additional data that - // will be checked. We use the ASCII encoded Editorial Note - // following the Abstract of the Web Cryptography API recommendation. - var additionalData = new Uint8Array([ - 84, 104, 101, 114, 101, 32, 97, 114, 101, 32, 55, 32, 102, 117, 114, 116, - 104, 101, 114, 32, 101, 100, 105, 116, 111, 114, 105, 97, 108, 32, 110, 111, - 116, 101, 115, 32, 105, 110, 32, 116, 104, 101, 32, 100, 111, 99, 117, 109, - 101, 110, 116, 46, - ]); + var additionalData = commonFixtures.additionalData; // The length of the tag defaults to 16 bytes (128 bit). var tag = { diff --git a/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js b/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js index cca34e9e54e70a..e6a6246074c186 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: encrypt() Using AES-OCB w/ 120-bit iv // META: script=../util/helpers.js +// META: script=aes_common_fixtures.js // META: script=aes_ocb_fixtures.js // META: script=aes_ocb_vectors.js // META: script=aes.js diff --git a/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js b/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js index a5795195f163ce..3e0c014c3e1c07 100644 --- a/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js +++ b/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js @@ -1,64 +1,13 @@ function getFixtures() { - // Before we can really start, we need to fill a bunch of buffers with data - var plaintext = new Uint8Array([ - 84, 104, 105, 115, 32, 115, 112, 101, 99, 105, 102, 105, 99, 97, 116, 105, - 111, 110, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, 74, 97, - 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80, 73, 32, 102, 111, 114, 32, - 112, 101, 114, 102, 111, 114, 109, 105, 110, 103, 32, 98, 97, 115, 105, 99, - 32, 99, 114, 121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32, 111, - 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105, 110, 32, 119, 101, 98, - 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 115, 44, 32, 115, - 117, 99, 104, 32, 97, 115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, - 115, 105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110, 101, 114, 97, - 116, 105, 111, 110, 32, 97, 110, 100, 32, 118, 101, 114, 105, 102, 105, 99, - 97, 116, 105, 111, 110, 44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, - 112, 116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99, 114, 121, 112, - 116, 105, 111, 110, 46, 32, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, - 108, 121, 44, 32, 105, 116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, - 32, 97, 110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112, 108, 105, - 99, 97, 116, 105, 111, 110, 115, 32, 116, 111, 32, 103, 101, 110, 101, 114, - 97, 116, 101, 32, 97, 110, 100, 47, 111, 114, 32, 109, 97, 110, 97, 103, - 101, 32, 116, 104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97, 116, - 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115, 115, 97, 114, 121, 32, - 116, 111, 32, 112, 101, 114, 102, 111, 114, 109, 32, 116, 104, 101, 115, - 101, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115, - 101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32, 65, 80, 73, 32, - 114, 97, 110, 103, 101, 32, 102, 114, 111, 109, 32, 117, 115, 101, 114, 32, - 111, 114, 32, 115, 101, 114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, - 110, 116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111, 99, 117, 109, - 101, 110, 116, 32, 111, 114, 32, 99, 111, 100, 101, 32, 115, 105, 103, 110, - 105, 110, 103, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, - 102, 105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32, 97, 110, 100, - 32, 105, 110, 116, 101, 103, 114, 105, 116, 121, 32, 111, 102, 32, 99, 111, - 109, 109, 117, 110, 105, 99, 97, 116, 105, 111, 110, 115, 46, - ]); - - // We want some random key bytes of various sizes. - // These were randomly generated from a script. - var keyBytes = { - 128: new Uint8Array([ - 222, 192, 212, 252, 191, 60, 71, 65, 200, 146, 218, 189, 28, 212, 192, 78, - ]), - 192: new Uint8Array([ - 208, 238, 131, 65, 63, 68, 196, 63, 186, 208, 61, 207, 166, 18, 99, 152, - 29, 109, 221, 95, 240, 30, 28, 246, - ]), - 256: new Uint8Array([ - 103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236, 233, 204, 58, 249, 16, - 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116, 216, 0, 11, 191, 48, - ]), - }; + var commonFixtures = getAesCommonFixtures(); + var plaintext = commonFixtures.plaintext; + var keyBytes = commonFixtures.keyBytes; var iv = new Uint8Array([ 58, 146, 115, 42, 166, 234, 57, 191, 57, 134, 224, 199, 108, 116, 46, ]); - var additionalData = new Uint8Array([ - 84, 104, 101, 114, 101, 32, 97, 114, 101, 32, 55, 32, 102, 117, 114, 116, - 104, 101, 114, 32, 101, 100, 105, 116, 111, 114, 105, 97, 108, 32, 110, 111, - 116, 101, 115, 32, 105, 110, 32, 116, 104, 101, 32, 100, 111, 99, 117, 109, - 101, 110, 116, 46, - ]); + var additionalData = commonFixtures.additionalData; var ciphertext = { 128: { diff --git a/WebCryptoAPI/encrypt_decrypt/rsa.js b/WebCryptoAPI/encrypt_decrypt/rsa.js index 071c086b3c4dfa..951ffd56e58165 100644 --- a/WebCryptoAPI/encrypt_decrypt/rsa.js +++ b/WebCryptoAPI/encrypt_decrypt/rsa.js @@ -23,7 +23,7 @@ function run_test() { promise_test(function(test) { return subtle.decrypt(vector.algorithm, vector.privateKey, vector.ciphertext) .then(function(plaintext) { - assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works")); + assert_true(equalBuffers(plaintext, vector.plaintext), "Decryption works"); }, function(err) { assert_unreached("Decryption should not throw error " + vector.name + ": '" + err.message + "'"); }); @@ -60,7 +60,7 @@ function run_test() { } }, vector.privateKey, ciphertext) .then(function(plaintext) { - assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works")); + assert_true(equalBuffers(plaintext, vector.plaintext), "Decryption works"); }, function(err) { assert_unreached("Decryption should not throw error " + vector.name + ": '" + err.message + "'"); }); @@ -91,7 +91,7 @@ function run_test() { var ciphertext = copyBuffer(vector.ciphertext); var operation = subtle.decrypt(vector.algorithm, vector.privateKey, ciphertext) .then(function(plaintext) { - assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works")); + assert_true(equalBuffers(plaintext, vector.plaintext), "Decryption works"); }, function(err) { assert_unreached("Decryption should not throw error " + vector.name + ": '" + err.message + "'"); }); @@ -160,7 +160,7 @@ function run_test() { var ciphertext = copyBuffer(vector.ciphertext); var operation = subtle.decrypt(vector.algorithm, vector.privateKey, ciphertext) .then(function(plaintext) { - assert_true(equalBuffers(plaintext, vector.plaintext, "Decryption works")); + assert_true(equalBuffers(plaintext, vector.plaintext), "Decryption works"); }, function(err) { assert_unreached("Decryption should not throw error " + vector.name + ": '" + err.message + "'"); }); @@ -538,9 +538,7 @@ function run_test() { }); promise_test(function() { - return Promise.all(all_promises) - .then(function() {done();}) - .catch(function() {done();}) + return Promise.all(all_promises).finally(done); }, "setup"); // A test vector has all needed fields for encryption, EXCEPT that the @@ -552,9 +550,7 @@ function run_test() { var publicPromise, privatePromise; if (vector.publicKey !== null) { - publicPromise = new Promise(function(resolve, reject) { - resolve(vector); - }); + publicPromise = Promise.resolve(vector); } else { publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, publicKeyUsages) .then(function(key) { @@ -564,9 +560,7 @@ function run_test() { } if (vector.privateKey !== null) { - privatePromise = new Promise(function(resolve, reject) { - resolve(vector); - }); + privatePromise = Promise.resolve(vector); } else { privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, privateKeyUsages) .then(function(key) { diff --git a/WebCryptoAPI/encrypt_decrypt/rsa_oaep.https.any.js b/WebCryptoAPI/encrypt_decrypt/rsa_oaep.https.any.js index 3550f5eec28793..42511415f15725 100644 --- a/WebCryptoAPI/encrypt_decrypt/rsa_oaep.https.any.js +++ b/WebCryptoAPI/encrypt_decrypt/rsa_oaep.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: encrypt() Using RSA-OAEP // META: script=../util/helpers.js +// META: script=../util/rsa_key_fixtures.js // META: script=rsa_vectors.js // META: script=rsa.js // META: timeout=long diff --git a/WebCryptoAPI/encrypt_decrypt/rsa_vectors.js b/WebCryptoAPI/encrypt_decrypt/rsa_vectors.js index fcc732eddc1d63..ca99953524e4ff 100644 --- a/WebCryptoAPI/encrypt_decrypt/rsa_vectors.js +++ b/WebCryptoAPI/encrypt_decrypt/rsa_vectors.js @@ -18,8 +18,9 @@ // plaintext - the text to encrypt // result - the expected result (usually just ciphertext, sometimes with added authentication) function getTestVectors() { - var pkcs8 = new Uint8Array([48, 130, 4, 191, 2, 1, 0, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 4, 169, 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 211, 87, 96, 146, 230, 41, 87, 54, 69, 68, 231, 228, 35, 59, 123, 219, 41, 61, 178, 8, 81, 34, 196, 121, 50, 133, 70, 249, 240, 247, 18, 246, 87, 196, 177, 120, 104, 201, 48, 144, 140, 197, 148, 247, 237, 0, 192, 20, 66, 193, 175, 4, 194, 246, 120, 164, 139, 162, 200, 15, 209, 113, 62, 48, 181, 172, 80, 120, 122, 195, 81, 101, 137, 241, 113, 150, 127, 99, 134, 173, 163, 73, 0, 166, 187, 4, 238, 206, 164, 43, 240, 67, 206, 217, 160, 249, 77, 12, 192, 158, 145, 155, 157, 113, 102, 192, 138, 182, 206, 32, 70, 64, 174, 164, 196, 146, 13, 182, 216, 110, 185, 22, 208, 220, 192, 244, 52, 26, 16, 56, 4, 41, 231, 225, 3, 33, 68, 234, 148, 157, 232, 246, 192, 204, 191, 149, 250, 142, 146, 141, 112, 216, 163, 140, 225, 104, 219, 69, 246, 241, 52, 102, 61, 111, 101, 111, 92, 234, 188, 114, 93, 168, 192, 42, 171, 234, 170, 19, 172, 54, 167, 92, 192, 186, 225, 53, 223, 49, 20, 182, 101, 137, 199, 237, 60, 182, 21, 89, 174, 90, 56, 79, 22, 43, 250, 128, 219, 228, 97, 127, 134, 195, 241, 208, 16, 201, 79, 226, 201, 191, 1, 154, 110, 99, 179, 239, 192, 40, 212, 60, 238, 97, 28, 133, 236, 38, 60, 144, 108, 70, 55, 114, 198, 145, 27, 25, 238, 192, 150, 202, 118, 236, 94, 49, 225, 227, 2, 3, 1, 0, 1, 2, 130, 1, 1, 0, 139, 55, 92, 203, 135, 200, 37, 197, 255, 61, 83, 208, 9, 145, 110, 150, 65, 5, 126, 24, 82, 114, 39, 160, 122, 178, 38, 190, 16, 136, 129, 58, 59, 56, 187, 123, 72, 243, 119, 5, 81, 101, 250, 42, 147, 57, 210, 77, 198, 103, 213, 197, 186, 52, 39, 230, 164, 129, 23, 110, 172, 21, 255, 212, 144, 104, 49, 30, 28, 40, 59, 159, 58, 142, 12, 184, 9, 180, 99, 12, 80, 170, 143, 62, 69, 166, 11, 53, 158, 25, 191, 140, 187, 94, 202, 214, 78, 118, 31, 16, 149, 116, 63, 243, 106, 175, 92, 240, 236, 185, 127, 237, 173, 221, 166, 11, 91, 243, 93, 129, 26, 117, 184, 34, 35, 12, 250, 160, 25, 47, 173, 64, 84, 126, 39, 84, 72, 170, 51, 22, 191, 142, 43, 76, 224, 133, 79, 199, 112, 139, 83, 123, 162, 45, 19, 33, 11, 9, 174, 195, 122, 39, 89, 239, 192, 130, 161, 83, 27, 35, 169, 23, 48, 3, 125, 222, 78, 242, 107, 95, 150, 239, 220, 195, 159, 211, 76, 52, 90, 213, 28, 187, 228, 79, 229, 139, 138, 59, 78, 201, 151, 134, 108, 8, 109, 255, 27, 136, 49, 239, 10, 31, 234, 38, 60, 247, 218, 205, 3, 192, 76, 188, 194, 178, 121, 229, 127, 165, 185, 83, 153, 107, 251, 29, 214, 136, 23, 175, 127, 180, 44, 222, 247, 165, 41, 74, 87, 250, 194, 184, 173, 115, 159, 27, 2, 153, 2, 129, 129, 0, 251, 248, 51, 194, 198, 49, 201, 112, 36, 12, 142, 116, 133, 240, 106, 62, 162, 168, 72, 34, 81, 26, 134, 39, 221, 70, 78, 248, 175, 175, 113, 72, 209, 164, 37, 182, 184, 101, 125, 221, 82, 70, 131, 43, 142, 83, 48, 32, 197, 187, 181, 104, 133, 90, 106, 236, 62, 66, 33, 215, 147, 241, 220, 91, 47, 37, 132, 226, 65, 94, 72, 233, 162, 189, 41, 43, 19, 64, 49, 249, 156, 142, 180, 47, 192, 188, 208, 68, 155, 242, 44, 230, 222, 201, 112, 20, 239, 229, 172, 147, 235, 232, 53, 135, 118, 86, 37, 44, 187, 177, 108, 65, 91, 103, 177, 132, 210, 40, 69, 104, 162, 119, 213, 147, 53, 88, 92, 253, 2, 129, 129, 0, 214, 184, 206, 39, 199, 41, 93, 93, 22, 252, 53, 112, 237, 100, 200, 218, 147, 3, 250, 210, 148, 136, 193, 166, 94, 154, 215, 17, 249, 3, 112, 24, 125, 187, 253, 129, 49, 109, 105, 100, 139, 200, 140, 197, 200, 53, 81, 175, 255, 69, 222, 186, 207, 182, 17, 5, 247, 9, 228, 195, 8, 9, 185, 0, 49, 235, 214, 134, 36, 68, 150, 198, 246, 158, 105, 46, 189, 200, 20, 246, 66, 57, 244, 173, 21, 117, 110, 203, 120, 197, 165, 176, 153, 49, 219, 24, 48, 119, 197, 70, 163, 140, 76, 116, 56, 137, 173, 61, 62, 208, 121, 181, 98, 46, 208, 18, 15, 160, 225, 249, 59, 89, 61, 183, 216, 82, 224, 95, 2, 129, 128, 56, 135, 75, 157, 131, 247, 129, 120, 206, 45, 158, 252, 23, 92, 131, 137, 127, 214, 127, 48, 107, 191, 166, 159, 100, 238, 52, 35, 104, 206, 212, 124, 128, 195, 241, 206, 23, 122, 117, 141, 100, 186, 251, 12, 151, 134, 164, 66, 133, 250, 1, 205, 236, 53, 7, 205, 238, 125, 201, 183, 226, 178, 29, 60, 187, 204, 16, 14, 238, 153, 103, 132, 59, 5, 115, 41, 253, 204, 166, 41, 152, 237, 15, 17, 179, 140, 232, 176, 171, 199, 222, 57, 1, 124, 113, 207, 208, 174, 87, 84, 108, 85, 145, 68, 205, 208, 175, 208, 100, 95, 126, 168, 255, 7, 185, 116, 209, 237, 68, 253, 31, 142, 0, 245, 96, 191, 109, 69, 2, 129, 129, 0, 133, 41, 239, 144, 115, 207, 143, 123, 95, 249, 226, 26, 186, 223, 58, 65, 115, 211, 144, 6, 112, 223, 175, 89, 66, 106, 188, 223, 4, 147, 193, 61, 47, 29, 27, 70, 184, 36, 166, 172, 24, 148, 179, 217, 37, 37, 12, 24, 30, 52, 114, 193, 96, 120, 5, 110, 177, 154, 141, 40, 247, 31, 48, 128, 146, 117, 52, 129, 212, 148, 68, 253, 247, 140, 158, 166, 194, 68, 7, 220, 1, 142, 119, 211, 175, 239, 56, 91, 47, 247, 67, 158, 150, 35, 121, 65, 51, 45, 212, 70, 206, 190, 255, 219, 68, 4, 254, 79, 113, 89, 81, 97, 208, 22, 64, 44, 51, 77, 15, 87, 198, 26, 190, 79, 249, 244, 203, 249, 2, 129, 129, 0, 135, 216, 119, 8, 212, 103, 99, 228, 204, 190, 178, 209, 233, 113, 46, 91, 240, 33, 109, 112, 222, 148, 32, 165, 178, 6, 155, 116, 89, 185, 159, 93, 159, 127, 47, 173, 124, 215, 154, 174, 230, 122, 127, 154, 52, 67, 126, 60, 121, 168, 74, 240, 205, 141, 233, 223, 242, 104, 235, 12, 71, 147, 245, 1, 249, 136, 213, 64, 246, 211, 71, 92, 32, 121, 184, 34, 122, 35, 217, 104, 222, 196, 227, 198, 101, 3, 24, 113, 147, 69, 150, 48, 71, 43, 253, 182, 186, 29, 231, 134, 199, 151, 250, 111, 78, 166, 90, 42, 132, 25, 38, 47, 41, 103, 136, 86, 203, 115, 201, 189, 75, 200, 155, 94, 4, 27, 34, 119]); - var spki = new Uint8Array([48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 211, 87, 96, 146, 230, 41, 87, 54, 69, 68, 231, 228, 35, 59, 123, 219, 41, 61, 178, 8, 81, 34, 196, 121, 50, 133, 70, 249, 240, 247, 18, 246, 87, 196, 177, 120, 104, 201, 48, 144, 140, 197, 148, 247, 237, 0, 192, 20, 66, 193, 175, 4, 194, 246, 120, 164, 139, 162, 200, 15, 209, 113, 62, 48, 181, 172, 80, 120, 122, 195, 81, 101, 137, 241, 113, 150, 127, 99, 134, 173, 163, 73, 0, 166, 187, 4, 238, 206, 164, 43, 240, 67, 206, 217, 160, 249, 77, 12, 192, 158, 145, 155, 157, 113, 102, 192, 138, 182, 206, 32, 70, 64, 174, 164, 196, 146, 13, 182, 216, 110, 185, 22, 208, 220, 192, 244, 52, 26, 16, 56, 4, 41, 231, 225, 3, 33, 68, 234, 148, 157, 232, 246, 192, 204, 191, 149, 250, 142, 146, 141, 112, 216, 163, 140, 225, 104, 219, 69, 246, 241, 52, 102, 61, 111, 101, 111, 92, 234, 188, 114, 93, 168, 192, 42, 171, 234, 170, 19, 172, 54, 167, 92, 192, 186, 225, 53, 223, 49, 20, 182, 101, 137, 199, 237, 60, 182, 21, 89, 174, 90, 56, 79, 22, 43, 250, 128, 219, 228, 97, 127, 134, 195, 241, 208, 16, 201, 79, 226, 201, 191, 1, 154, 110, 99, 179, 239, 192, 40, 212, 60, 238, 97, 28, 133, 236, 38, 60, 144, 108, 70, 55, 114, 198, 145, 27, 25, 238, 192, 150, 202, 118, 236, 94, 49, 225, 227, 2, 3, 1, 0, 1]); + var keyFixtures = getRsaKeyFixtures(); + var pkcs8 = keyFixtures.pkcs8; + var spki = keyFixtures.spki; // Can optionally provide a label for encryption. We use the ASCII-encoded // abstract from the candidate recommendation. diff --git a/WebCryptoAPI/generateKey/algorithm_registry.js b/WebCryptoAPI/generateKey/algorithm_registry.js new file mode 100644 index 00000000000000..2c7493dfffd674 --- /dev/null +++ b/WebCryptoAPI/generateKey/algorithm_registry.js @@ -0,0 +1,36 @@ +// Generated by WebCryptoAPI/tools/generate.py. Do not edit directly. +const generateKeyTestVectors = [ + {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "AES-OCB", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "ChaCha20-Poly1305", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, + {name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "RSA-PSS", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "RSA-OAEP", resultType: "CryptoKeyPair", usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: ["decrypt", "unwrapKey"]}, + {name: "ECDSA", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, + {name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-44", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-65", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-87", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-KEM-512", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, + {name: "ML-KEM-768", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, + {name: "ML-KEM-1024", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, + {name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, + {name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, + {name: "KMAC128", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, + {name: "KMAC256", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, +]; + +function getGenerateKeyTestVectors(algorithmNames) { + if (algorithmNames && !Array.isArray(algorithmNames)) { + algorithmNames = [algorithmNames]; + } + + return generateKeyTestVectors.filter( + vector => !algorithmNames || algorithmNames.includes(vector.name)); +} diff --git a/WebCryptoAPI/generateKey/failures.js b/WebCryptoAPI/generateKey/failures.js index a3258ae0dd7788..2a618ce4ab25e9 100644 --- a/WebCryptoAPI/generateKey/failures.js +++ b/WebCryptoAPI/generateKey/failures.js @@ -1,8 +1,6 @@ function run_test(algorithmNames) { var subtle = crypto.subtle; // Change to test prefixed implementations - setup({explicit_timeout: true}); - // These tests check that generateKey throws an error, and that // the error is of the right type, for a wide set of incorrect parameters. // @@ -21,42 +19,7 @@ function run_test(algorithmNames) { // helper functions that generate all possible test parameters for // different situations. - var allTestVectors = [ // Parameters that should work for generateKey - {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-OCB", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "ChaCha20-Poly1305", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, - {name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "RSA-PSS", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "RSA-OAEP", resultType: "CryptoKeyPair", usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: ["decrypt", "unwrapKey"]}, - {name: "ECDSA", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, - {name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-DSA-44", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-DSA-65", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-DSA-87", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-KEM-512", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, - {name: "ML-KEM-768", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, - {name: "ML-KEM-1024", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, - {name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, - {name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, - {name: "KMAC128", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, - {name: "KMAC256", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, - ]; - - var testVectors = []; - if (algorithmNames && !Array.isArray(algorithmNames)) { - algorithmNames = [algorithmNames]; - }; - allTestVectors.forEach(function(vector) { - if (!algorithmNames || algorithmNames.includes(vector.name)) { - testVectors.push(vector); - } - }); + var testVectors = getGenerateKeyTestVectors(algorithmNames); function parameterString(algorithm, extractable, usages) { @@ -117,16 +80,15 @@ function run_test(algorithmNames) { } - // Don't create an exhaustive list of all invalid usages, - // because there would usually be nearly 2**8 of them, - // way too many to test. Instead, create every singleton + // Don't create an exhaustive list of all invalid usages because + // there would be too many to test. Instead, create every singleton // of an illegal usage, and "poison" every valid usage // with an illegal one. function invalidUsages(validUsages, mandatoryUsages) { var results = []; var illegalUsages = []; - ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey", "deriveKey", "deriveBits"].forEach(function(usage) { + allKeyUsages.forEach(function(usage) { if (!validUsages.includes(usage)) { illegalUsages.push(usage); } diff --git a/WebCryptoAPI/generateKey/failures_AES-CBC.https.any.js b/WebCryptoAPI/generateKey/failures_AES-CBC.https.any.js index 38bed1cc702819..5febdbb94926f7 100644 --- a/WebCryptoAPI/generateKey/failures_AES-CBC.https.any.js +++ b/WebCryptoAPI/generateKey/failures_AES-CBC.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["AES-CBC"]); diff --git a/WebCryptoAPI/generateKey/failures_AES-CTR.https.any.js b/WebCryptoAPI/generateKey/failures_AES-CTR.https.any.js index 0e7940775fe0f5..0eb6664f5d00d8 100644 --- a/WebCryptoAPI/generateKey/failures_AES-CTR.https.any.js +++ b/WebCryptoAPI/generateKey/failures_AES-CTR.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["AES-CTR"]); diff --git a/WebCryptoAPI/generateKey/failures_AES-GCM.https.any.js b/WebCryptoAPI/generateKey/failures_AES-GCM.https.any.js index a394c8b629c579..3d13b78903fdf9 100644 --- a/WebCryptoAPI/generateKey/failures_AES-GCM.https.any.js +++ b/WebCryptoAPI/generateKey/failures_AES-GCM.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["AES-GCM"]); diff --git a/WebCryptoAPI/generateKey/failures_AES-KW.https.any.js b/WebCryptoAPI/generateKey/failures_AES-KW.https.any.js index 40c199b29a5c6e..138565e59ac190 100644 --- a/WebCryptoAPI/generateKey/failures_AES-KW.https.any.js +++ b/WebCryptoAPI/generateKey/failures_AES-KW.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["AES-KW"]); diff --git a/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js b/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js index d4a2cd868ff51a..ef7c8c38e537f9 100644 --- a/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["AES-OCB"]); diff --git a/WebCryptoAPI/generateKey/failures_ECDH.https.any.js b/WebCryptoAPI/generateKey/failures_ECDH.https.any.js index e522254d743aa4..f61d27e995c467 100644 --- a/WebCryptoAPI/generateKey/failures_ECDH.https.any.js +++ b/WebCryptoAPI/generateKey/failures_ECDH.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["ECDH"]); diff --git a/WebCryptoAPI/generateKey/failures_ECDSA.https.any.js b/WebCryptoAPI/generateKey/failures_ECDSA.https.any.js index e19974ff488cc0..e49b5e675b3f9b 100644 --- a/WebCryptoAPI/generateKey/failures_ECDSA.https.any.js +++ b/WebCryptoAPI/generateKey/failures_ECDSA.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["ECDSA"]); diff --git a/WebCryptoAPI/generateKey/failures_Ed25519.https.any.js b/WebCryptoAPI/generateKey/failures_Ed25519.https.any.js index 8f18fb1efe0950..7505e97bf2e1e6 100644 --- a/WebCryptoAPI/generateKey/failures_Ed25519.https.any.js +++ b/WebCryptoAPI/generateKey/failures_Ed25519.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["Ed25519"]); diff --git a/WebCryptoAPI/generateKey/failures_Ed448.tentative.https.any.js b/WebCryptoAPI/generateKey/failures_Ed448.tentative.https.any.js index b25dcd14909410..6ee388e40f761a 100644 --- a/WebCryptoAPI/generateKey/failures_Ed448.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/failures_Ed448.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["Ed448"]); diff --git a/WebCryptoAPI/generateKey/failures_HMAC.https.any.js b/WebCryptoAPI/generateKey/failures_HMAC.https.any.js index 43ce1c026fc74e..e3097cd46cdc59 100644 --- a/WebCryptoAPI/generateKey/failures_HMAC.https.any.js +++ b/WebCryptoAPI/generateKey/failures_HMAC.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["HMAC"]); diff --git a/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js b/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js index 91e20bc6148fa3..d41636dea79746 100644 --- a/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["ML-DSA-44", "ML-DSA-65", "ML-DSA-87"]); diff --git a/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js b/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js index 9cd347d00f815c..0ece96944e7ba8 100644 --- a/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"]); diff --git a/WebCryptoAPI/generateKey/failures_RSA-OAEP.https.any.js b/WebCryptoAPI/generateKey/failures_RSA-OAEP.https.any.js index 1d2bca96b18c7e..a4eb4e6cbc825e 100644 --- a/WebCryptoAPI/generateKey/failures_RSA-OAEP.https.any.js +++ b/WebCryptoAPI/generateKey/failures_RSA-OAEP.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["RSA-OAEP"]); diff --git a/WebCryptoAPI/generateKey/failures_RSA-PSS.https.any.js b/WebCryptoAPI/generateKey/failures_RSA-PSS.https.any.js index 562f66697c9f63..62ac442ebe2b11 100644 --- a/WebCryptoAPI/generateKey/failures_RSA-PSS.https.any.js +++ b/WebCryptoAPI/generateKey/failures_RSA-PSS.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["RSA-PSS"]); diff --git a/WebCryptoAPI/generateKey/failures_RSASSA-PKCS1-v1_5.https.any.js b/WebCryptoAPI/generateKey/failures_RSASSA-PKCS1-v1_5.https.any.js index fb19308de6f7a2..f06e3402799a59 100644 --- a/WebCryptoAPI/generateKey/failures_RSASSA-PKCS1-v1_5.https.any.js +++ b/WebCryptoAPI/generateKey/failures_RSASSA-PKCS1-v1_5.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["RSASSA-PKCS1-v1_5"]); diff --git a/WebCryptoAPI/generateKey/failures_X25519.https.any.js b/WebCryptoAPI/generateKey/failures_X25519.https.any.js index 2662d8697a9a6f..6735e85151e65c 100644 --- a/WebCryptoAPI/generateKey/failures_X25519.https.any.js +++ b/WebCryptoAPI/generateKey/failures_X25519.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["X25519"]); diff --git a/WebCryptoAPI/generateKey/failures_X448.tentative.https.any.js b/WebCryptoAPI/generateKey/failures_X448.tentative.https.any.js index 455e260d1fe920..26e12b9725900f 100644 --- a/WebCryptoAPI/generateKey/failures_X448.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/failures_X448.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["X448"]); diff --git a/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js b/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js index c9a278cdfc2b18..6ec0593a14b97e 100644 --- a/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["ChaCha20-Poly1305"]); diff --git a/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js b/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js index f906038c7d3f4a..889c17e9c23b63 100644 --- a/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCryptoAPI: generateKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=algorithm_registry.js // META: script=failures.js run_test(["KMAC128", "KMAC256"]); diff --git a/WebCryptoAPI/generateKey/successes.js b/WebCryptoAPI/generateKey/successes.js index c72384b7b93bf4..5006cd35ad9c0f 100644 --- a/WebCryptoAPI/generateKey/successes.js +++ b/WebCryptoAPI/generateKey/successes.js @@ -2,8 +2,6 @@ function run_test(algorithmNames, slowTest) { var subtle = crypto.subtle; // Change to test prefixed implementations - setup({explicit_timeout: true}); - // These tests check that generateKey successfully creates keys // when provided any of a wide set of correct parameters // and that they can be exported afterwards. @@ -17,42 +15,7 @@ function run_test(algorithmNames, slowTest) { // helper functions that generate all possible test parameters for // different situations. - var allTestVectors = [ // Parameters that should work for generateKey - {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-OCB", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "ChaCha20-Poly1305", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []}, - {name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, - {name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "RSA-PSS", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "RSA-OAEP", resultType: "CryptoKeyPair", usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: ["decrypt", "unwrapKey"]}, - {name: "ECDSA", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, - {name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-DSA-44", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-DSA-65", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-DSA-87", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, - {name: "ML-KEM-512", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, - {name: "ML-KEM-768", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, - {name: "ML-KEM-1024", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, - {name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, - {name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, - {name: "KMAC128", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, - {name: "KMAC256", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, - ]; - - var testVectors = []; - if (algorithmNames && !Array.isArray(algorithmNames)) { - algorithmNames = [algorithmNames]; - }; - allTestVectors.forEach(function(vector) { - if (!algorithmNames || algorithmNames.includes(vector.name)) { - testVectors.push(vector); - } - }); + var testVectors = getGenerateKeyTestVectors(algorithmNames); function parameterString(algorithm, extractable, usages) { var result = "(" + @@ -93,6 +56,7 @@ function run_test(algorithmNames, slowTest) { ]; if (extractable) promises.push(subtle.exportKey('raw-seed', result.privateKey)); + await Promise.all(promises); } else if (resultType === "CryptoKeyPair") { const promises = [ subtle.exportKey('jwk', result.publicKey), diff --git a/WebCryptoAPI/generateKey/successes_AES-CBC.https.any.js b/WebCryptoAPI/generateKey/successes_AES-CBC.https.any.js index 80f92c2cb7d7a6..b2e1b2971a9174 100644 --- a/WebCryptoAPI/generateKey/successes_AES-CBC.https.any.js +++ b/WebCryptoAPI/generateKey/successes_AES-CBC.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["AES-CBC"]); diff --git a/WebCryptoAPI/generateKey/successes_AES-CTR.https.any.js b/WebCryptoAPI/generateKey/successes_AES-CTR.https.any.js index 243a104b606dc8..bec9e22f3205d8 100644 --- a/WebCryptoAPI/generateKey/successes_AES-CTR.https.any.js +++ b/WebCryptoAPI/generateKey/successes_AES-CTR.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["AES-CTR"]); diff --git a/WebCryptoAPI/generateKey/successes_AES-GCM.https.any.js b/WebCryptoAPI/generateKey/successes_AES-GCM.https.any.js index f0f947c8160f90..df6e694c1e12b7 100644 --- a/WebCryptoAPI/generateKey/successes_AES-GCM.https.any.js +++ b/WebCryptoAPI/generateKey/successes_AES-GCM.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["AES-GCM"]); diff --git a/WebCryptoAPI/generateKey/successes_AES-KW.https.any.js b/WebCryptoAPI/generateKey/successes_AES-KW.https.any.js index dbc040fdc5cb4f..e55b24745c260d 100644 --- a/WebCryptoAPI/generateKey/successes_AES-KW.https.any.js +++ b/WebCryptoAPI/generateKey/successes_AES-KW.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["AES-KW"]); diff --git a/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js b/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js index b43abc4edb41c4..c87f875f4b1e07 100644 --- a/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["AES-OCB"]); diff --git a/WebCryptoAPI/generateKey/successes_ECDH.https.any.js b/WebCryptoAPI/generateKey/successes_ECDH.https.any.js index e9dee526149da6..9ec44a350605e4 100644 --- a/WebCryptoAPI/generateKey/successes_ECDH.https.any.js +++ b/WebCryptoAPI/generateKey/successes_ECDH.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["ECDH"]); diff --git a/WebCryptoAPI/generateKey/successes_ECDSA.https.any.js b/WebCryptoAPI/generateKey/successes_ECDSA.https.any.js index a022f31fe9d119..9b0f40aa9a9b3a 100644 --- a/WebCryptoAPI/generateKey/successes_ECDSA.https.any.js +++ b/WebCryptoAPI/generateKey/successes_ECDSA.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["ECDSA"]); diff --git a/WebCryptoAPI/generateKey/successes_Ed25519.https.any.js b/WebCryptoAPI/generateKey/successes_Ed25519.https.any.js index 6b3bc460f60f2f..8ecbbd23553c3c 100644 --- a/WebCryptoAPI/generateKey/successes_Ed25519.https.any.js +++ b/WebCryptoAPI/generateKey/successes_Ed25519.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["Ed25519"]); diff --git a/WebCryptoAPI/generateKey/successes_Ed448.tentative.https.any.js b/WebCryptoAPI/generateKey/successes_Ed448.tentative.https.any.js index 8e37f57b244b58..d017170ca1ad1f 100644 --- a/WebCryptoAPI/generateKey/successes_Ed448.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/successes_Ed448.tentative.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["Ed448"]); diff --git a/WebCryptoAPI/generateKey/successes_HMAC.https.any.js b/WebCryptoAPI/generateKey/successes_HMAC.https.any.js index 18e0b271226ff6..59fab83b08b84c 100644 --- a/WebCryptoAPI/generateKey/successes_HMAC.https.any.js +++ b/WebCryptoAPI/generateKey/successes_HMAC.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["HMAC"]); diff --git a/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js b/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js index 15d52f2a5059f5..6c81b193167c32 100644 --- a/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["ML-DSA-44", "ML-DSA-65", "ML-DSA-87"]); diff --git a/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js b/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js index 68a0d97b975537..f41b5c34cdb535 100644 --- a/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"]); diff --git a/WebCryptoAPI/generateKey/successes_RSA-OAEP.https.any.js b/WebCryptoAPI/generateKey/successes_RSA-OAEP.https.any.js index d933fd981d4a33..f7c550df22224c 100644 --- a/WebCryptoAPI/generateKey/successes_RSA-OAEP.https.any.js +++ b/WebCryptoAPI/generateKey/successes_RSA-OAEP.https.any.js @@ -18,5 +18,6 @@ // META: variant=?151-last // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["RSA-OAEP"]); diff --git a/WebCryptoAPI/generateKey/successes_RSA-PSS.https.any.js b/WebCryptoAPI/generateKey/successes_RSA-PSS.https.any.js index cb43e3de3de364..d1a9ec33ac231f 100644 --- a/WebCryptoAPI/generateKey/successes_RSA-PSS.https.any.js +++ b/WebCryptoAPI/generateKey/successes_RSA-PSS.https.any.js @@ -6,5 +6,6 @@ // META: variant=?31-last // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["RSA-PSS"]); diff --git a/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-v1_5.https.any.js b/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-v1_5.https.any.js index b8db5972284d1a..6db5a3703fe7d5 100644 --- a/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-v1_5.https.any.js +++ b/WebCryptoAPI/generateKey/successes_RSASSA-PKCS1-v1_5.https.any.js @@ -6,5 +6,6 @@ // META: variant=?31-last // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["RSASSA-PKCS1-v1_5"]); diff --git a/WebCryptoAPI/generateKey/successes_X25519.https.any.js b/WebCryptoAPI/generateKey/successes_X25519.https.any.js index 0e87cf50108e69..5acd5b5a1c2bcd 100644 --- a/WebCryptoAPI/generateKey/successes_X25519.https.any.js +++ b/WebCryptoAPI/generateKey/successes_X25519.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["X25519"]); diff --git a/WebCryptoAPI/generateKey/successes_X448.tentative.https.any.js b/WebCryptoAPI/generateKey/successes_X448.tentative.https.any.js index e7dbe32696d8fe..f1475c16bbd2be 100644 --- a/WebCryptoAPI/generateKey/successes_X448.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/successes_X448.tentative.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["X448"]); diff --git a/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js b/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js index a1cef25c2f24fb..2f3efebb6bc2ed 100644 --- a/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["ChaCha20-Poly1305"]); diff --git a/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js b/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js index 9f881f92bc17cc..8276fa9058c478 100644 --- a/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js +++ b/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js @@ -2,5 +2,6 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=/common/subset-tests.js +// META: script=algorithm_registry.js // META: script=successes.js run_test(["KMAC128", "KMAC256"]); diff --git a/WebCryptoAPI/getRandomValues.any.js b/WebCryptoAPI/getRandomValues.any.js index aecd38efd60bac..8fd18a81deff39 100644 --- a/WebCryptoAPI/getRandomValues.any.js +++ b/WebCryptoAPI/getRandomValues.any.js @@ -66,7 +66,7 @@ for (const array of arrays) { }, "Large length: " + array); test(function() { - assert_true(self.crypto.getRandomValues(new ctor(0)).length == 0) + assert_true(self.crypto.getRandomValues(new ctor(0)).length === 0) }, "Null arrays: " + array); test(function() { diff --git a/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js b/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js index 5ce13d858d6fff..02f745d71c2862 100644 --- a/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js +++ b/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js @@ -1,8 +1,9 @@ // META: title=WebCryptoAPI: importKey() for ML-DSA keys // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/mldsa_key_fixtures.js // META: script=ML-DSA_importKey_fixtures.js -// META: script=ML-DSA_importKey.js +// META: script=ml_importKey.js runTests("ML-DSA-44"); runTests("ML-DSA-65"); diff --git a/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js b/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js index ef1f5a1f51a944..abccc10c63fb07 100644 --- a/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js +++ b/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js @@ -1,99 +1,11 @@ +var mldsaKeyFixtures = getMldsaKeyFixtures(); + var keyData = { 'ML-DSA-44': { privateUsages: ['sign'], publicUsages: ['verify'], - pkcs8: new Uint8Array([ - 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 4, 34, - 128, 32, 153, 21, 95, 99, 48, 150, 218, 124, 190, 8, 122, 137, 72, 184, - 79, 118, 123, 16, 249, 1, 200, 35, 194, 64, 177, 221, 43, 200, 112, 5, - 201, 62, - ]), - spki: new Uint8Array([ - 48, 130, 5, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 3, 130, 5, - 33, 0, 85, 152, 213, 68, 198, 20, 177, 84, 200, 188, 33, 104, 36, 161, - 193, 127, 226, 151, 48, 107, 122, 191, 89, 86, 188, 3, 245, 199, 18, 79, - 168, 192, 218, 218, 223, 227, 84, 133, 41, 187, 9, 183, 14, 222, 155, 137, - 84, 111, 138, 97, 234, 152, 52, 15, 163, 47, 227, 218, 19, 20, 229, 93, - 99, 252, 155, 213, 30, 241, 158, 211, 213, 191, 155, 73, 211, 145, 59, - 194, 75, 140, 3, 161, 149, 139, 48, 172, 155, 172, 120, 234, 142, 79, 78, - 116, 215, 184, 50, 182, 162, 192, 93, 221, 179, 216, 70, 186, 92, 93, 51, - 190, 61, 173, 105, 206, 9, 208, 52, 54, 208, 252, 115, 176, 146, 118, 23, - 0, 5, 41, 151, 121, 241, 246, 193, 206, 212, 160, 181, 7, 99, 220, 78, 96, - 123, 142, 35, 107, 37, 218, 138, 139, 228, 207, 166, 132, 87, 36, 116, - 251, 174, 10, 41, 196, 171, 26, 212, 90, 213, 223, 141, 87, 232, 59, 46, - 173, 16, 247, 173, 4, 219, 165, 234, 8, 217, 233, 163, 13, 10, 160, 22, - 87, 232, 2, 9, 92, 177, 35, 67, 55, 104, 51, 204, 231, 81, 209, 62, 31, - 117, 56, 141, 78, 109, 148, 118, 191, 93, 193, 59, 30, 88, 237, 19, 169, - 14, 11, 150, 102, 215, 144, 69, 246, 32, 159, 110, 49, 75, 78, 225, 121, - 184, 206, 234, 126, 171, 164, 43, 237, 244, 63, 83, 70, 136, 213, 244, - 121, 184, 34, 201, 249, 95, 64, 165, 99, 14, 195, 231, 18, 121, 20, 156, - 80, 231, 133, 197, 0, 94, 195, 22, 251, 255, 174, 213, 103, 75, 88, 58, - 138, 66, 37, 85, 162, 15, 242, 29, 49, 147, 191, 163, 170, 109, 195, 22, - 63, 197, 149, 117, 100, 36, 81, 115, 203, 126, 62, 86, 103, 193, 182, 69, - 238, 233, 162, 62, 248, 132, 158, 212, 208, 187, 127, 212, 198, 169, 245, - 26, 153, 28, 207, 85, 65, 145, 200, 23, 196, 38, 64, 49, 54, 233, 185, 72, - 156, 86, 230, 127, 152, 108, 184, 240, 109, 8, 103, 228, 206, 142, 73, 74, - 214, 52, 182, 203, 82, 201, 175, 188, 111, 42, 232, 8, 177, 131, 47, 237, - 92, 120, 210, 124, 48, 185, 215, 137, 36, 70, 162, 164, 119, 0, 155, 20, - 57, 33, 27, 220, 77, 254, 233, 190, 106, 135, 21, 194, 57, 238, 95, 162, - 78, 164, 33, 210, 215, 43, 100, 96, 232, 87, 19, 43, 65, 240, 183, 17, - 131, 247, 97, 241, 7, 111, 159, 40, 252, 45, 228, 76, 71, 46, 85, 181, 54, - 41, 135, 162, 144, 227, 128, 121, 173, 207, 119, 54, 19, 197, 23, 231, - 176, 125, 190, 32, 76, 60, 34, 24, 160, 42, 73, 190, 124, 99, 5, 9, 214, - 6, 220, 177, 206, 79, 222, 10, 142, 250, 63, 179, 67, 21, 159, 57, 126, - 239, 28, 238, 240, 107, 79, 185, 174, 232, 168, 146, 128, 229, 119, 19, - 21, 33, 239, 193, 42, 178, 152, 124, 24, 203, 131, 193, 93, 162, 2, 208, - 231, 20, 203, 232, 47, 54, 114, 255, 236, 97, 99, 156, 15, 160, 75, 60, - 111, 59, 35, 25, 230, 43, 91, 170, 161, 74, 70, 179, 180, 251, 71, 197, - 240, 104, 42, 39, 202, 206, 12, 115, 249, 138, 55, 252, 216, 61, 185, 121, - 76, 137, 172, 166, 88, 92, 130, 18, 52, 67, 13, 187, 49, 147, 212, 77, 74, - 56, 59, 123, 99, 205, 36, 137, 96, 111, 148, 121, 157, 2, 83, 246, 86, - 156, 152, 98, 172, 77, 244, 214, 225, 184, 240, 121, 144, 56, 213, 161, - 43, 67, 4, 161, 104, 202, 91, 134, 247, 108, 24, 46, 187, 63, 216, 50, - 125, 120, 17, 216, 22, 228, 156, 253, 7, 180, 15, 130, 180, 72, 71, 169, - 3, 236, 247, 11, 170, 32, 76, 236, 225, 133, 250, 20, 235, 200, 143, 89, - 25, 158, 49, 158, 164, 213, 221, 81, 120, 241, 150, 210, 19, 79, 165, 24, - 35, 170, 182, 242, 255, 143, 171, 148, 140, 41, 207, 186, 98, 224, 16, - 152, 224, 38, 110, 175, 169, 111, 132, 201, 178, 114, 25, 196, 50, 149, - 158, 193, 180, 101, 183, 92, 109, 131, 102, 119, 123, 78, 107, 223, 4, 1, - 206, 140, 130, 237, 205, 36, 18, 180, 197, 154, 26, 236, 140, 173, 230, - 101, 35, 189, 121, 104, 21, 75, 81, 224, 186, 212, 81, 107, 66, 244, 235, - 64, 90, 206, 39, 44, 43, 162, 187, 63, 229, 217, 154, 185, 157, 24, 125, - 252, 91, 136, 59, 47, 182, 200, 73, 19, 137, 132, 81, 16, 234, 227, 210, - 32, 16, 160, 188, 250, 27, 190, 164, 53, 244, 219, 199, 177, 146, 117, 50, - 99, 72, 235, 37, 154, 72, 51, 203, 61, 39, 230, 34, 132, 117, 217, 167, - 201, 42, 17, 76, 72, 103, 172, 93, 169, 29, 76, 88, 178, 226, 32, 53, 190, - 60, 210, 132, 113, 198, 26, 70, 179, 47, 34, 184, 88, 178, 208, 1, 196, - 89, 136, 167, 33, 38, 9, 255, 89, 202, 27, 93, 229, 100, 192, 24, 234, - 200, 186, 125, 231, 212, 188, 11, 29, 51, 189, 70, 147, 176, 231, 81, 16, - 114, 152, 159, 21, 124, 185, 208, 50, 74, 211, 113, 207, 35, 54, 173, 205, - 133, 52, 167, 199, 87, 158, 120, 33, 204, 163, 146, 233, 21, 61, 28, 102, - 48, 232, 184, 15, 219, 238, 240, 215, 222, 239, 3, 110, 180, 95, 103, 147, - 236, 10, 57, 195, 159, 231, 50, 92, 145, 165, 44, 204, 121, 187, 9, 210, - 80, 86, 251, 169, 132, 236, 248, 23, 207, 222, 227, 13, 53, 1, 88, 69, - 105, 13, 238, 202, 251, 194, 245, 14, 38, 1, 245, 157, 212, 162, 182, 217, - 230, 115, 139, 175, 219, 199, 74, 124, 186, 158, 3, 220, 87, 220, 177, 85, - 13, 58, 168, 223, 6, 238, 156, 80, 121, 44, 166, 176, 0, 48, 98, 70, 93, - 78, 50, 192, 16, 186, 2, 233, 105, 105, 120, 195, 17, 100, 141, 214, 158, - 144, 63, 4, 88, 190, 101, 209, 55, 119, 46, 128, 117, 225, 121, 204, 195, - 19, 61, 170, 116, 251, 225, 230, 28, 27, 249, 84, 195, 224, 190, 60, 212, - 83, 3, 148, 204, 4, 103, 50, 233, 175, 207, 47, 51, 216, 79, 251, 150, 81, - 171, 7, 145, 55, 188, 187, 217, 200, 155, 246, 85, 42, 123, 18, 112, 192, - 116, 163, 40, 187, 132, 192, 210, 188, 106, 117, 217, 185, 183, 202, 33, - 11, 205, 10, 61, 52, 15, 66, 131, 121, 112, 26, 96, 166, 241, 1, 68, 206, - 80, 92, 132, 83, 89, 126, 135, 157, 4, 202, 16, 5, 131, 112, 62, 56, 234, - 176, 213, 119, 205, 203, 17, 106, 156, 117, 251, 135, 21, 73, 219, 238, 3, - 88, 21, 71, 136, 118, 0, 7, 106, 151, 200, 221, 179, 206, 50, 198, 27, - 118, 181, 27, 85, 35, 248, 44, 57, 15, 221, 97, 121, 4, 167, 111, 182, - 207, 195, 52, 134, 195, 128, 173, 111, 98, 152, 29, 138, 197, 175, 171, - 247, 194, 20, 134, 209, 232, 94, 17, 203, 139, 30, 237, 187, 243, 16, 180, - 43, 105, 236, 66, 175, 170, 139, 24, 99, 28, 225, 141, 96, 250, 119, 0, - 111, 212, 34, 217, 42, 134, 88, 78, 76, 126, 169, 168, 59, 154, 93, 54, - 43, 161, 29, 111, 124, 59, 225, 52, 86, 147, 38, 151, 161, 36, 119, 204, - 164, 121, 46, 186, 65, 84, 70, 38, 15, 203, 48, 168, 235, 231, 30, 55, 95, - 36, 10, 20, 166, 109, 8, 18, 109, 251, 213, 82, 142, 240, 49, 249, 180, - 78, 69, - ]), + pkcs8: mldsaKeyFixtures.pkcs8['ML-DSA-44'], + spki: mldsaKeyFixtures.spki['ML-DSA-44'], 'raw-public': hexStringToUint8Array( '5598d544c614b154c8bc216824a1c17fe297306b7abf5956bc03f5c7124fa8c0dadadfe3548529bb09b70ede9b89546f8a61ea98340fa32fe3da1314e55d63fc9bd51ef19ed3d5bf9b49d3913bc24b8c03a1958b30ac9bac78ea8e4f4e74d7b832b6a2c05dddb3d846ba5c5d33be3dad69ce09d03436d0fc73b09276170005299779f1f6c1ced4a0b50763dc4e607b8e236b25da8a8be4cfa684572474fbae0a29c4ab1ad45ad5df8d57e83b2ead10f7ad04dba5ea08d9e9a30d0aa01657e802095cb12343376833cce751d13e1f75388d4e6d9476bf5dc13b1e58ed13a90e0b9666d79045f6209f6e314b4ee179b8ceea7eaba42bedf43f534688d5f479b822c9f95f40a5630ec3e71279149c50e785c5005ec316fbffaed5674b583a8a422555a20ff21d3193bfa3aa6dc3163fc5957564245173cb7e3e5667c1b645eee9a23ef8849ed4d0bb7fd4c6a9f51a991ccf554191c817c426403136e9b9489c56e67f986cb8f06d0867e4ce8e494ad634b6cb52c9afbc6f2ae808b1832fed5c78d27c30b9d7892446a2a477009b1439211bdc4dfee9be6a8715c239ee5fa24ea421d2d72b6460e857132b41f0b71183f761f1076f9f28fc2de44c472e55b5362987a290e38079adcf773613c517e7b07dbe204c3c2218a02a49be7c630509d606dcb1ce4fde0a8efa3fb343159f397eef1ceef06b4fb9aee8a89280e577131521efc12ab2987c18cb83c15da202d0e714cbe82f3672ffec61639c0fa04b3c6f3b2319e62b5baaa14a46b3b4fb47c5f0682a27cace0c73f98a37fcd83db9794c89aca6585c821234430dbb3193d44d4a383b7b63cd2489606f94799d0253f6569c9862ac4df4d6e1b8f0799038d5a12b4304a168ca5b86f76c182ebb3fd8327d7811d816e49cfd07b40f82b44847a903ecf70baa204cece185fa14ebc88f59199e319ea4d5dd5178f196d2134fa51823aab6f2ff8fab948c29cfba62e01098e0266eafa96f84c9b27219c432959ec1b465b75c6d8366777b4e6bdf0401ce8c82edcd2412b4c59a1aec8cade66523bd7968154b51e0bad4516b42f4eb405ace272c2ba2bb3fe5d99ab99d187dfc5b883b2fb6c8491389845110eae3d22010a0bcfa1bbea435f4dbc7b19275326348eb259a4833cb3d27e6228475d9a7c92a114c4867ac5da91d4c58b2e22035be3cd28471c61a46b32f22b858b2d001c45988a7212609ff59ca1b5de564c018eac8ba7de7d4bc0b1d33bd4693b0e7511072989f157cb9d0324ad371cf2336adcd8534a7c7579e7821cca392e9153d1c6630e8b80fdbeef0d7deef036eb45f6793ec0a39c39fe7325c91a52ccc79bb09d25056fba984ecf817cfdee30d35015845690deecafbc2f50e2601f59dd4a2b6d9e6738bafdbc74a7cba9e03dc57dcb1550d3aa8df06ee9c50792ca6b0003062465d4e32c010ba02e9696978c311648dd69e903f0458be65d137772e8075e179ccc3133daa74fbe1e61c1bf954c3e0be3cd4530394cc046732e9afcf2f33d84ffb9651ab079137bcbbd9c89bf6552a7b1270c074a328bb84c0d2bc6a75d9b9b7ca210bcd0a3d340f428379701a60a6f10144ce505c8453597e879d04ca100583703e38eab0d577cdcb116a9c75fb871549dbee03581547887600076a97c8ddb3ce32c61b76b51b5523f82c390fdd617904a76fb6cfc33486c380ad6f62981d8ac5afabf7c21486d1e85e11cb8b1eedbbf310b42b69ec42afaa8b18631ce18d60fa77006fd422d92a86584e4c7ea9a83b9a5d362ba11d6f7c3be13456932697a12477cca4792eba415446260fcb30a8ebe71e375f240a14a66d08126dfbd5528ef031f9b44e45' ), @@ -111,138 +23,8 @@ var keyData = { 'ML-DSA-65': { privateUsages: ['sign'], publicUsages: ['verify'], - pkcs8: new Uint8Array([ - 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 4, 34, - 128, 32, 132, 164, 137, 75, 123, 70, 164, 178, 3, 156, 206, 16, 195, 26, - 133, 186, 176, 195, 102, 48, 254, 35, 29, 66, 103, 17, 67, 152, 38, 7, - 130, 139, - ]), - spki: new Uint8Array([ - 48, 130, 7, 178, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 3, 130, - 7, 161, 0, 216, 177, 233, 60, 151, 24, 246, 66, 175, 161, 192, 118, 9, - 177, 87, 232, 5, 216, 49, 254, 251, 160, 51, 216, 250, 171, 229, 104, 149, - 117, 135, 107, 5, 239, 244, 167, 83, 57, 49, 153, 29, 135, 108, 138, 117, - 236, 120, 65, 89, 65, 17, 201, 127, 147, 246, 103, 238, 204, 25, 83, 240, - 29, 173, 127, 140, 1, 88, 40, 43, 134, 51, 19, 125, 131, 224, 50, 167, 82, - 20, 217, 215, 162, 41, 95, 215, 56, 130, 226, 177, 216, 20, 169, 133, 85, - 140, 9, 105, 172, 54, 121, 0, 87, 202, 18, 93, 96, 147, 103, 127, 164, 63, - 197, 97, 49, 230, 125, 53, 80, 64, 20, 239, 29, 90, 118, 102, 221, 177, 6, - 220, 220, 170, 107, 107, 18, 138, 125, 138, 70, 66, 60, 185, 232, 209, 4, - 100, 17, 118, 24, 181, 110, 241, 50, 250, 138, 209, 19, 84, 220, 61, 96, - 80, 128, 81, 101, 160, 9, 5, 53, 33, 112, 60, 59, 195, 79, 115, 190, 101, - 93, 56, 171, 146, 51, 82, 233, 66, 225, 226, 211, 72, 58, 9, 74, 222, 185, - 175, 211, 156, 164, 68, 188, 119, 46, 14, 64, 160, 13, 207, 60, 81, 68, - 108, 148, 59, 88, 88, 92, 88, 171, 249, 204, 160, 137, 222, 234, 168, 233, - 3, 86, 224, 174, 105, 224, 1, 177, 184, 230, 236, 30, 85, 249, 56, 105, - 211, 50, 83, 168, 139, 28, 175, 181, 22, 89, 166, 215, 152, 218, 184, 111, - 65, 24, 82, 71, 185, 100, 172, 66, 178, 6, 215, 164, 252, 56, 40, 198, - 207, 152, 110, 186, 207, 39, 235, 179, 38, 215, 88, 105, 109, 177, 130, - 91, 5, 223, 164, 78, 241, 176, 125, 197, 94, 100, 40, 214, 251, 239, 253, - 88, 154, 14, 75, 254, 94, 210, 86, 244, 51, 95, 168, 139, 213, 73, 87, - 151, 209, 150, 126, 88, 69, 251, 116, 157, 122, 96, 212, 206, 42, 218, 38, - 85, 184, 50, 246, 188, 35, 72, 60, 226, 155, 246, 86, 209, 110, 133, 161, - 129, 126, 80, 154, 238, 64, 64, 170, 156, 177, 225, 52, 87, 42, 88, 154, - 174, 246, 30, 84, 143, 221, 51, 27, 65, 60, 40, 22, 120, 42, 145, 34, 82, - 235, 79, 20, 215, 211, 231, 151, 108, 119, 53, 116, 190, 13, 139, 199, - 189, 84, 54, 186, 222, 90, 116, 253, 227, 207, 104, 209, 118, 42, 144, 94, - 22, 219, 198, 211, 216, 171, 75, 245, 61, 240, 157, 108, 81, 19, 238, 39, - 120, 210, 242, 63, 126, 6, 15, 18, 97, 232, 207, 184, 84, 239, 72, 115, - 90, 95, 112, 78, 45, 201, 13, 102, 208, 151, 146, 253, 153, 177, 115, 14, - 194, 184, 107, 118, 120, 63, 105, 89, 144, 60, 242, 80, 106, 32, 11, 204, - 170, 165, 221, 182, 31, 187, 159, 216, 118, 218, 207, 182, 107, 136, 211, - 162, 231, 196, 128, 83, 251, 192, 189, 149, 1, 245, 36, 146, 159, 11, 116, - 30, 191, 141, 182, 157, 227, 91, 88, 72, 224, 55, 195, 96, 245, 135, 249, - 142, 16, 229, 237, 27, 60, 2, 91, 138, 82, 197, 210, 40, 8, 123, 172, 202, - 207, 119, 199, 190, 102, 40, 141, 174, 93, 211, 219, 134, 105, 26, 103, - 100, 102, 62, 130, 224, 135, 173, 82, 224, 200, 213, 76, 211, 38, 181, 16, - 97, 99, 75, 14, 42, 162, 223, 237, 141, 1, 29, 140, 191, 146, 49, 236, - 179, 88, 202, 220, 124, 239, 231, 131, 101, 134, 111, 28, 54, 151, 172, - 67, 167, 113, 96, 204, 63, 76, 169, 95, 14, 175, 149, 189, 173, 39, 177, - 102, 23, 158, 102, 236, 224, 70, 203, 190, 132, 230, 136, 3, 28, 201, 131, - 148, 164, 219, 181, 208, 26, 239, 111, 86, 35, 102, 133, 114, 113, 180, - 184, 82, 180, 106, 124, 248, 126, 87, 177, 165, 176, 204, 128, 141, 179, - 141, 34, 119, 160, 57, 206, 168, 95, 197, 110, 79, 60, 48, 170, 125, 206, - 147, 137, 156, 85, 46, 7, 193, 228, 150, 22, 46, 147, 51, 153, 157, 248, - 151, 253, 114, 58, 126, 38, 127, 19, 225, 99, 183, 235, 175, 90, 166, 8, - 233, 141, 10, 85, 232, 147, 7, 20, 137, 240, 84, 231, 86, 134, 50, 212, - 201, 6, 253, 18, 150, 114, 160, 140, 2, 254, 189, 152, 14, 68, 110, 50, - 134, 199, 73, 237, 56, 116, 110, 135, 36, 40, 14, 167, 50, 71, 81, 9, 178, - 54, 182, 247, 64, 32, 204, 116, 92, 131, 40, 30, 246, 188, 236, 182, 187, - 132, 239, 124, 136, 238, 146, 137, 247, 87, 52, 15, 78, 108, 135, 178, - 101, 70, 199, 193, 192, 144, 196, 106, 186, 141, 42, 101, 214, 196, 67, - 175, 38, 8, 189, 148, 166, 253, 221, 144, 119, 81, 1, 232, 175, 81, 237, - 13, 188, 220, 230, 47, 115, 184, 179, 0, 51, 118, 39, 22, 114, 232, 88, - 15, 121, 216, 130, 107, 173, 108, 175, 225, 113, 40, 223, 185, 6, 244, - 227, 73, 38, 64, 84, 10, 200, 53, 81, 179, 217, 106, 172, 59, 161, 70, - 180, 70, 48, 56, 46, 233, 133, 245, 57, 120, 154, 167, 49, 109, 188, 152, - 245, 181, 1, 159, 247, 44, 167, 152, 6, 191, 246, 38, 120, 141, 57, 241, - 168, 60, 38, 6, 82, 248, 87, 85, 0, 10, 22, 19, 44, 178, 63, 38, 78, 1, - 210, 166, 140, 3, 199, 112, 135, 155, 36, 13, 204, 124, 47, 5, 190, 103, - 91, 205, 147, 248, 115, 177, 196, 180, 234, 85, 35, 24, 182, 16, 207, 107, - 167, 10, 54, 193, 146, 71, 95, 45, 109, 184, 43, 101, 155, 184, 55, 171, - 196, 136, 89, 227, 84, 183, 31, 0, 137, 230, 146, 250, 6, 27, 225, 241, - 11, 95, 124, 248, 133, 171, 149, 67, 73, 19, 110, 104, 173, 86, 6, 246, - 195, 196, 200, 175, 53, 18, 198, 223, 140, 85, 208, 253, 204, 220, 255, - 232, 88, 238, 20, 97, 24, 52, 13, 3, 179, 62, 151, 101, 67, 33, 79, 253, - 157, 253, 233, 197, 109, 130, 78, 11, 165, 214, 200, 41, 157, 63, 46, 175, - 251, 246, 225, 227, 199, 92, 107, 216, 58, 124, 226, 202, 153, 92, 31, - 250, 182, 92, 99, 0, 110, 18, 78, 228, 166, 190, 67, 88, 245, 155, 139, - 82, 152, 39, 204, 74, 140, 95, 82, 82, 160, 147, 144, 33, 0, 242, 200, 22, - 102, 160, 233, 102, 224, 42, 205, 240, 56, 95, 197, 226, 175, 235, 240, - 125, 10, 51, 12, 246, 150, 234, 173, 95, 132, 173, 174, 1, 161, 23, 39, - 52, 168, 87, 54, 4, 66, 201, 34, 155, 82, 133, 170, 76, 52, 226, 109, 163, - 19, 34, 184, 226, 39, 20, 75, 72, 201, 70, 188, 71, 182, 230, 6, 19, 255, - 8, 145, 193, 63, 81, 150, 24, 72, 89, 168, 74, 98, 173, 133, 67, 227, 44, - 252, 252, 227, 192, 125, 20, 227, 144, 24, 31, 48, 67, 67, 48, 94, 163, - 52, 219, 163, 225, 214, 214, 109, 211, 122, 213, 198, 90, 204, 40, 97, - 211, 121, 17, 28, 132, 246, 110, 230, 51, 197, 42, 162, 143, 199, 158, - 215, 210, 133, 60, 65, 127, 1, 153, 193, 22, 171, 250, 114, 204, 246, 255, - 126, 25, 96, 44, 164, 102, 172, 211, 23, 245, 122, 48, 221, 249, 138, 148, - 134, 206, 135, 246, 42, 235, 198, 89, 189, 45, 125, 204, 69, 193, 48, 29, - 144, 125, 224, 127, 66, 1, 134, 141, 224, 211, 193, 141, 69, 128, 75, 167, - 244, 160, 120, 54, 191, 214, 29, 40, 249, 15, 46, 68, 141, 91, 242, 91, - 80, 252, 109, 122, 154, 64, 153, 56, 65, 254, 106, 18, 4, 172, 171, 136, - 80, 98, 79, 133, 255, 4, 100, 191, 144, 171, 219, 46, 132, 181, 130, 228, - 107, 68, 32, 123, 201, 17, 67, 35, 144, 180, 160, 30, 125, 9, 55, 184, - 172, 0, 159, 250, 232, 83, 168, 162, 102, 158, 121, 208, 177, 116, 163, - 160, 80, 241, 46, 156, 58, 203, 240, 67, 176, 244, 170, 160, 115, 122, - 141, 154, 101, 218, 178, 119, 130, 195, 32, 207, 51, 149, 98, 51, 219, 57, - 121, 216, 156, 101, 218, 184, 220, 204, 41, 181, 149, 63, 80, 194, 11, - 143, 164, 219, 23, 123, 141, 119, 43, 94, 78, 175, 89, 165, 48, 167, 44, - 45, 219, 197, 15, 202, 118, 116, 245, 151, 218, 14, 199, 96, 27, 102, 206, - 198, 123, 222, 178, 210, 20, 200, 38, 25, 124, 58, 102, 92, 197, 107, 51, - 5, 236, 125, 173, 198, 113, 144, 108, 177, 22, 104, 223, 165, 39, 9, 84, - 87, 124, 80, 153, 8, 212, 76, 2, 28, 12, 90, 212, 129, 148, 212, 229, 63, - 29, 200, 113, 171, 154, 107, 189, 202, 22, 147, 7, 32, 253, 70, 37, 224, - 98, 199, 129, 21, 54, 49, 52, 124, 84, 40, 190, 194, 108, 73, 26, 15, 124, - 87, 87, 198, 217, 122, 127, 82, 167, 131, 59, 8, 172, 49, 162, 61, 64, 79, - 196, 205, 65, 110, 75, 130, 128, 197, 182, 251, 110, 141, 197, 184, 166, - 244, 246, 217, 20, 105, 85, 42, 80, 251, 77, 59, 204, 247, 179, 218, 181, - 124, 209, 4, 28, 118, 234, 145, 237, 140, 106, 54, 88, 82, 28, 235, 68, - 221, 109, 139, 11, 166, 182, 63, 142, 194, 255, 213, 219, 116, 158, 31, - 224, 119, 126, 232, 160, 144, 1, 177, 92, 219, 162, 49, 181, 116, 163, - 104, 245, 193, 188, 26, 172, 15, 190, 135, 207, 106, 246, 13, 132, 76, - 189, 160, 25, 123, 26, 20, 48, 203, 59, 209, 69, 235, 103, 253, 160, 108, - 83, 206, 70, 98, 0, 2, 57, 162, 202, 63, 45, 89, 173, 201, 254, 254, 253, - 143, 21, 77, 131, 184, 234, 37, 68, 206, 69, 186, 179, 145, 147, 135, 42, - 137, 152, 253, 213, 240, 13, 122, 161, 218, 186, 180, 213, 162, 150, 231, - 63, 112, 182, 233, 86, 12, 225, 195, 133, 37, 28, 22, 147, 201, 200, 197, - 115, 3, 138, 194, 86, 79, 247, 27, 241, 149, 128, 197, 8, 11, 134, 53, - 118, 175, 248, 253, 114, 91, 31, 192, 253, 209, 111, 31, 228, 244, 184, - 179, 146, 145, 167, 137, 155, 184, 218, 38, 62, 187, 22, 181, 193, 93, 16, - 9, 195, 42, 198, 225, 100, 144, 148, 223, 184, 40, 117, 32, 131, 94, 93, - 83, 88, 125, 95, 220, 20, 206, 7, 228, 78, 54, 238, 178, 196, 38, 245, 95, - 8, 235, 106, 17, 175, 142, 193, 60, 179, 53, 244, 92, 147, 244, 218, 95, - 127, 251, 128, 42, 105, 82, 243, 224, 213, 25, 91, 151, 22, 201, 18, 25, - 230, 165, 85, 25, 249, 170, 160, 171, 210, 209, 32, 154, 124, 245, 60, 30, - 255, 138, 154, 29, 85, 156, 232, 177, 78, 14, 137, 52, 215, 247, 26, 211, - 115, 72, 20, 133, 232, 1, 151, 251, 63, 45, 120, 69, 49, 209, 130, 255, 2, - 218, 21, 251, 16, 86, 30, 62, 136, 92, 149, 60, 6, 125, 129, 145, 235, - 102, 190, 144, 248, 1, 53, 135, 21, 158, 44, 158, 230, 246, 172, 249, 161, - 105, 204, 49, 60, 70, 63, 127, 163, 231, 175, 174, 234, 147, 185, 62, 5, - 244, 156, 4, 31, 39, 156, 176, 154, 251, 166, 143, 212, 43, 30, 97, 50, - 37, 176, 155, 77, 149, 102, - ]), + pkcs8: mldsaKeyFixtures.pkcs8['ML-DSA-65'], + spki: mldsaKeyFixtures.spki['ML-DSA-65'], 'raw-public': hexStringToUint8Array( 'd8b1e93c9718f642afa1c07609b157e805d831fefba033d8faabe5689575876b05eff4a7533931991d876c8a75ec7841594111c97f93f667eecc1953f01dad7f8c0158282b8633137d83e032a75214d9d7a2295fd73882e2b1d814a985558c0969ac36790057ca125d6093677fa43fc56131e67d35504014ef1d5a7666ddb106dcdcaa6b6b128a7d8a46423cb9e8d10464117618b56ef132fa8ad11354dc3d6050805165a009053521703c3bc34f73be655d38ab923352e942e1e2d3483a094adeb9afd39ca444bc772e0e40a00dcf3c51446c943b58585c58abf9cca089deeaa8e90356e0ae69e001b1b8e6ec1e55f93869d33253a88b1cafb51659a6d798dab86f41185247b964ac42b206d7a4fc3828c6cf986ebacf27ebb326d758696db1825b05dfa44ef1b07dc55e6428d6fbeffd589a0e4bfe5ed256f4335fa88bd5495797d1967e5845fb749d7a60d4ce2ada2655b832f6bc23483ce29bf656d16e85a1817e509aee4040aa9cb1e134572a589aaef61e548fdd331b413c2816782a912252eb4f14d7d3e7976c773574be0d8bc7bd5436bade5a74fde3cf68d1762a905e16dbc6d3d8ab4bf53df09d6c5113ee2778d2f23f7e060f1261e8cfb854ef48735a5f704e2dc90d66d09792fd99b1730ec2b86b76783f6959903cf2506a200bccaaa5ddb61fbb9fd876dacfb66b88d3a2e7c48053fbc0bd9501f524929f0b741ebf8db69de35b5848e037c360f587f98e10e5ed1b3c025b8a52c5d228087baccacf77c7be66288dae5dd3db86691a6764663e82e087ad52e0c8d54cd326b51061634b0e2aa2dfed8d011d8cbf9231ecb358cadc7cefe78365866f1c3697ac43a77160cc3f4ca95f0eaf95bdad27b166179e66ece046cbbe84e688031cc98394a4dbb5d01aef6f562366857271b4b852b46a7cf87e57b1a5b0cc808db38d2277a039cea85fc56e4f3c30aa7dce93899c552e07c1e496162e9333999df897fd723a7e267f13e163b7ebaf5aa608e98d0a55e893071489f054e7568632d4c906fd129672a08c02febd980e446e3286c749ed38746e8724280ea732475109b236b6f74020cc745c83281ef6bcecb6bb84ef7c88ee9289f757340f4e6c87b26546c7c1c090c46aba8d2a65d6c443af2608bd94a6fddd90775101e8af51ed0dbcdce62f73b8b3003376271672e8580f79d8826bad6cafe17128dfb906f4e3492640540ac83551b3d96aac3ba146b44630382ee985f539789aa7316dbc98f5b5019ff72ca79806bff626788d39f1a83c260652f85755000a16132cb23f264e01d2a68c03c770879b240dcc7c2f05be675bcd93f873b1c4b4ea552318b610cf6ba70a36c192475f2d6db82b659bb837abc48859e354b71f0089e692fa061be1f10b5f7cf885ab954349136e68ad5606f6c3c4c8af3512c6df8c55d0fdccdcffe858ee146118340d03b33e976543214ffd9dfde9c56d824e0ba5d6c8299d3f2eaffbf6e1e3c75c6bd83a7ce2ca995c1ffab65c63006e124ee4a6be4358f59b8b529827cc4a8c5f5252a093902100f2c81666a0e966e02acdf0385fc5e2afebf07d0a330cf696eaad5f84adae01a1172734a857360442c9229b5285aa4c34e26da31322b8e227144b48c946bc47b6e60613ff0891c13f5196184859a84a62ad8543e32cfcfce3c07d14e390181f304343305ea334dba3e1d6d66dd37ad5c65acc2861d379111c84f66ee633c52aa28fc79ed7d2853c417f0199c116abfa72ccf6ff7e19602ca466acd317f57a30ddf98a9486ce87f62aebc659bd2d7dcc45c1301d907de07f4201868de0d3c18d45804ba7f4a07836bfd61d28f90f2e448d5bf25b50fc6d7a9a40993841fe6a1204acab8850624f85ff0464bf90abdb2e84b582e46b44207bc911432390b4a01e7d0937b8ac009ffae853a8a2669e79d0b174a3a050f12e9c3acbf043b0f4aaa0737a8d9a65dab27782c320cf33956233db3979d89c65dab8dccc29b5953f50c20b8fa4db177b8d772b5e4eaf59a530a72c2ddbc50fca7674f597da0ec7601b66cec67bdeb2d214c826197c3a665cc56b3305ec7dadc671906cb11668dfa5270954577c509908d44c021c0c5ad48194d4e53f1dc871ab9a6bbdca16930720fd4625e062c781153631347c5428bec26c491a0f7c5757c6d97a7f52a7833b08ac31a23d404fc4cd416e4b8280c5b6fb6e8dc5b8a6f4f6d91469552a50fb4d3bccf7b3dab57cd1041c76ea91ed8c6a3658521ceb44dd6d8b0ba6b63f8ec2ffd5db749e1fe0777ee8a09001b15cdba231b574a368f5c1bc1aac0fbe87cf6af60d844cbda0197b1a1430cb3bd145eb67fda06c53ce4662000239a2ca3f2d59adc9fefefd8f154d83b8ea2544ce45bab39193872a8998fdd5f00d7aa1dabab4d5a296e73f70b6e9560ce1c385251c1693c9c8c573038ac2564ff71bf19580c5080b863576aff8fd725b1fc0fdd16f1fe4f4b8b39291a7899bb8da263ebb16b5c15d1009c32ac6e1649094dfb8287520835e5d53587d5fdc14ce07e44e36eeb2c426f55f08eb6a11af8ec13cb335f45c93f4da5f7ffb802a6952f3e0d5195b9716c91219e6a55519f9aaa0abd2d1209a7cf53c1eff8a9a1d559ce8b14e0e8934d7f71ad373481485e80197fb3f2d784531d182ff02da15fb10561e3e885c953c067d8191eb66be90f8013587159e2c9ee6f6acf9a169cc313c463f7fa3e7afaeea93b93e05f49c041f279cb09afba68fd42b1e613225b09b4d9566' ), @@ -260,178 +42,8 @@ var keyData = { 'ML-DSA-87': { privateUsages: ['sign'], publicUsages: ['verify'], - pkcs8: new Uint8Array([ - 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 4, 34, - 128, 32, 161, 80, 109, 145, 76, 109, 101, 140, 117, 39, 228, 51, 151, 221, - 109, 76, 37, 246, 164, 121, 116, 51, 90, 76, 208, 59, 254, 105, 131, 68, - 18, 81, - ]), - spki: new Uint8Array([ - 48, 130, 10, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 3, 130, - 10, 33, 0, 146, 184, 67, 40, 172, 27, 204, 27, 135, 22, 109, 223, 127, 23, - 97, 130, 198, 228, 199, 62, 178, 21, 173, 20, 88, 180, 205, 168, 17, 164, - 135, 92, 85, 146, 76, 194, 152, 80, 239, 157, 33, 21, 239, 182, 176, 254, - 124, 80, 135, 138, 87, 169, 103, 99, 87, 5, 91, 161, 239, 59, 18, 246, - 148, 20, 32, 60, 117, 245, 182, 156, 196, 230, 82, 117, 228, 211, 81, 45, - 115, 217, 23, 95, 138, 95, 103, 124, 32, 89, 187, 48, 251, 103, 81, 234, - 76, 4, 57, 197, 71, 48, 125, 169, 195, 147, 183, 142, 166, 8, 147, 7, 77, - 240, 111, 44, 168, 23, 89, 107, 95, 220, 75, 202, 44, 25, 244, 200, 160, - 0, 174, 111, 107, 204, 22, 36, 122, 191, 101, 33, 52, 252, 14, 47, 25, - 109, 135, 48, 131, 253, 195, 237, 60, 86, 14, 119, 85, 28, 182, 139, 136, - 191, 59, 187, 90, 126, 207, 168, 238, 184, 83, 77, 254, 208, 21, 57, 104, - 188, 228, 134, 82, 249, 190, 249, 163, 120, 111, 68, 225, 210, 131, 29, - 151, 153, 146, 71, 163, 104, 225, 194, 33, 64, 213, 92, 145, 253, 42, 32, - 233, 95, 224, 72, 184, 119, 192, 113, 253, 177, 153, 246, 240, 49, 103, - 170, 229, 82, 69, 186, 36, 252, 29, 124, 255, 25, 148, 5, 160, 159, 105, - 157, 185, 25, 158, 122, 145, 30, 245, 51, 205, 62, 56, 154, 23, 52, 0, - 225, 177, 105, 195, 131, 177, 151, 197, 114, 110, 128, 227, 127, 176, 28, - 252, 217, 56, 61, 136, 148, 190, 124, 108, 129, 62, 243, 235, 37, 70, 228, - 233, 10, 67, 124, 120, 58, 164, 83, 57, 80, 39, 204, 98, 28, 199, 136, 75, - 12, 51, 255, 24, 130, 127, 19, 239, 160, 94, 137, 75, 15, 82, 158, 252, - 163, 43, 236, 193, 234, 27, 74, 69, 14, 179, 171, 10, 169, 27, 138, 172, - 213, 189, 222, 167, 110, 24, 11, 118, 151, 223, 94, 154, 125, 9, 21, 137, - 70, 128, 51, 102, 52, 105, 104, 157, 54, 186, 75, 217, 226, 169, 71, 125, - 177, 253, 218, 85, 236, 242, 25, 215, 147, 181, 104, 242, 82, 75, 50, 165, - 49, 102, 128, 82, 237, 170, 134, 162, 196, 56, 247, 199, 138, 102, 118, - 37, 66, 114, 165, 177, 156, 251, 39, 199, 12, 167, 246, 169, 150, 108, 91, - 192, 42, 68, 192, 244, 255, 107, 18, 191, 7, 73, 19, 174, 28, 116, 66, - 131, 96, 173, 60, 131, 190, 249, 219, 246, 71, 182, 124, 183, 129, 101, - 109, 95, 180, 78, 17, 140, 182, 62, 80, 195, 184, 253, 176, 169, 153, 1, - 29, 83, 39, 252, 150, 41, 219, 176, 48, 151, 108, 60, 255, 239, 0, 85, - 101, 193, 110, 204, 12, 254, 22, 136, 15, 154, 217, 88, 13, 28, 252, 232, - 48, 32, 33, 41, 221, 103, 227, 228, 177, 54, 175, 195, 106, 174, 140, 54, - 128, 108, 214, 228, 215, 118, 226, 206, 171, 21, 155, 162, 152, 135, 203, - 16, 170, 130, 100, 173, 155, 243, 80, 40, 98, 157, 248, 7, 101, 88, 199, - 218, 224, 141, 82, 238, 121, 92, 82, 97, 49, 31, 155, 61, 63, 84, 227, 90, - 143, 164, 59, 216, 101, 19, 35, 134, 2, 20, 18, 197, 97, 215, 169, 85, - 220, 75, 254, 91, 125, 144, 43, 65, 128, 29, 66, 77, 184, 172, 89, 123, - 203, 231, 254, 59, 18, 249, 204, 249, 220, 153, 84, 166, 63, 23, 108, 120, - 145, 216, 67, 223, 123, 248, 15, 253, 63, 191, 126, 84, 95, 98, 141, 66, - 200, 129, 194, 174, 30, 80, 48, 75, 113, 14, 102, 101, 218, 249, 14, 203, - 24, 6, 11, 89, 99, 56, 49, 17, 148, 160, 242, 101, 191, 102, 227, 115, 33, - 107, 71, 235, 6, 141, 68, 161, 162, 165, 227, 159, 82, 253, 54, 157, 214, - 255, 141, 151, 154, 134, 150, 93, 141, 97, 158, 244, 180, 135, 42, 10, 3, - 148, 9, 152, 149, 20, 18, 237, 253, 180, 136, 165, 13, 80, 195, 220, 43, - 3, 178, 10, 127, 144, 2, 207, 209, 246, 40, 110, 38, 133, 9, 22, 180, 11, - 223, 116, 236, 205, 186, 25, 183, 155, 165, 77, 206, 101, 255, 106, 223, - 70, 10, 22, 176, 119, 142, 163, 197, 178, 251, 216, 112, 237, 63, 201, 77, - 219, 196, 2, 176, 48, 15, 207, 91, 74, 236, 21, 8, 205, 126, 77, 28, 13, - 26, 28, 202, 250, 100, 79, 134, 209, 193, 78, 202, 58, 248, 124, 215, 64, - 143, 244, 17, 23, 163, 162, 241, 249, 49, 210, 168, 203, 213, 135, 77, 14, - 29, 35, 193, 234, 58, 12, 106, 165, 163, 251, 192, 115, 251, 7, 198, 189, - 93, 207, 178, 246, 50, 189, 185, 51, 45, 84, 140, 194, 34, 46, 92, 90, - 136, 81, 81, 53, 52, 253, 128, 247, 131, 243, 21, 207, 245, 141, 49, 178, - 213, 214, 211, 8, 17, 234, 133, 225, 104, 197, 186, 224, 117, 1, 173, 104, - 17, 177, 161, 223, 71, 195, 159, 194, 45, 177, 116, 26, 187, 193, 161, - 213, 179, 158, 8, 122, 186, 122, 191, 158, 5, 12, 178, 235, 78, 132, 78, - 189, 16, 86, 110, 73, 51, 129, 255, 242, 110, 63, 6, 53, 209, 110, 132, - 236, 43, 239, 192, 221, 138, 1, 128, 176, 0, 113, 85, 119, 201, 36, 188, - 202, 9, 223, 98, 196, 42, 130, 158, 149, 200, 150, 202, 132, 118, 153, 97, - 54, 195, 154, 15, 45, 246, 129, 144, 255, 231, 75, 25, 56, 47, 178, 98, - 10, 106, 84, 56, 113, 161, 227, 37, 246, 1, 245, 129, 173, 70, 186, 11, - 28, 125, 198, 243, 225, 113, 130, 5, 138, 52, 251, 194, 152, 105, 48, 214, - 13, 246, 228, 75, 236, 194, 223, 177, 64, 150, 97, 167, 20, 27, 74, 76, - 166, 199, 239, 91, 240, 8, 22, 54, 41, 63, 35, 112, 255, 251, 88, 252, - 147, 173, 185, 43, 98, 83, 155, 230, 176, 55, 161, 8, 83, 15, 110, 151, - 241, 110, 168, 203, 190, 198, 218, 152, 144, 150, 58, 123, 11, 123, 250, - 104, 113, 198, 93, 1, 152, 51, 172, 140, 246, 115, 113, 229, 218, 166, - 200, 35, 123, 16, 133, 169, 191, 59, 103, 12, 114, 15, 60, 37, 4, 92, 208, - 54, 31, 79, 56, 225, 6, 11, 74, 107, 79, 225, 239, 16, 73, 249, 234, 197, - 129, 230, 97, 39, 115, 49, 96, 141, 41, 242, 225, 177, 214, 18, 103, 34, - 229, 37, 176, 241, 99, 82, 227, 195, 77, 32, 64, 4, 120, 49, 199, 209, - 139, 2, 4, 222, 233, 45, 151, 141, 142, 252, 41, 124, 231, 13, 144, 63, - 212, 252, 145, 34, 142, 232, 152, 84, 135, 87, 175, 46, 53, 139, 60, 168, - 135, 167, 101, 253, 127, 152, 138, 154, 31, 231, 198, 77, 89, 182, 9, 54, - 103, 119, 100, 218, 245, 44, 191, 74, 30, 152, 84, 22, 62, 159, 131, 163, - 223, 3, 51, 194, 241, 49, 9, 213, 43, 214, 201, 75, 158, 198, 22, 203, - 209, 190, 199, 189, 75, 4, 6, 72, 60, 241, 113, 171, 30, 42, 143, 73, 51, - 72, 206, 110, 175, 203, 195, 199, 15, 155, 208, 166, 121, 26, 132, 59, 44, - 72, 155, 7, 48, 122, 132, 224, 142, 3, 7, 21, 207, 11, 30, 112, 18, 149, - 146, 127, 41, 104, 197, 169, 86, 213, 108, 253, 111, 160, 5, 11, 202, 172, - 233, 32, 5, 52, 92, 124, 152, 162, 11, 88, 28, 166, 248, 141, 251, 38, - 161, 53, 49, 136, 246, 183, 85, 9, 165, 115, 108, 18, 208, 218, 129, 165, - 163, 131, 34, 32, 94, 226, 121, 93, 24, 87, 226, 105, 25, 242, 128, 198, - 78, 26, 237, 21, 92, 33, 121, 8, 119, 131, 140, 193, 14, 60, 139, 130, 19, - 65, 96, 50, 5, 249, 12, 27, 51, 23, 195, 89, 255, 47, 23, 109, 62, 202, - 190, 5, 131, 92, 91, 39, 27, 209, 132, 146, 95, 98, 66, 26, 230, 186, 236, - 186, 162, 149, 81, 143, 221, 21, 79, 171, 236, 21, 161, 19, 135, 10, 213, - 168, 200, 135, 19, 221, 177, 207, 106, 214, 194, 124, 220, 53, 45, 176, - 245, 178, 189, 49, 242, 22, 230, 154, 241, 146, 230, 187, 180, 244, 158, - 145, 197, 225, 51, 150, 140, 26, 175, 78, 142, 243, 232, 221, 137, 205, - 130, 178, 54, 216, 136, 118, 212, 33, 90, 206, 18, 224, 158, 44, 23, 144, - 204, 24, 184, 48, 81, 233, 124, 20, 222, 77, 119, 144, 22, 145, 241, 19, - 206, 135, 252, 164, 114, 84, 37, 175, 107, 67, 243, 183, 137, 213, 53, - 236, 41, 73, 50, 34, 146, 218, 204, 68, 235, 158, 150, 139, 133, 75, 248, - 157, 7, 0, 53, 68, 44, 156, 110, 56, 197, 209, 201, 0, 155, 225, 85, 35, - 169, 193, 231, 36, 31, 142, 101, 168, 29, 192, 31, 128, 81, 191, 253, 184, - 153, 226, 214, 1, 27, 6, 0, 192, 36, 101, 72, 105, 150, 226, 3, 21, 12, - 127, 72, 250, 223, 240, 136, 249, 157, 129, 247, 91, 178, 157, 208, 86, - 146, 23, 176, 150, 35, 211, 155, 22, 207, 119, 168, 167, 122, 180, 183, - 106, 97, 138, 87, 96, 34, 141, 110, 145, 231, 226, 35, 115, 232, 129, 54, - 186, 128, 190, 238, 37, 169, 194, 37, 24, 237, 211, 164, 111, 54, 88, 245, - 125, 67, 78, 194, 11, 194, 235, 217, 87, 203, 14, 220, 189, 107, 68, 94, - 139, 66, 230, 5, 54, 64, 28, 246, 143, 75, 127, 239, 243, 20, 251, 189, - 246, 246, 151, 90, 219, 227, 242, 223, 205, 40, 124, 245, 4, 189, 72, 39, - 145, 110, 96, 120, 164, 27, 117, 146, 177, 30, 76, 173, 106, 130, 228, - 192, 189, 59, 167, 30, 127, 178, 164, 5, 133, 80, 199, 207, 216, 189, 156, - 93, 222, 150, 129, 81, 193, 180, 38, 59, 8, 214, 210, 95, 150, 182, 175, - 148, 43, 153, 169, 66, 62, 135, 140, 159, 89, 195, 253, 3, 132, 180, 164, - 244, 243, 232, 71, 196, 200, 158, 194, 114, 115, 193, 88, 161, 185, 235, - 247, 14, 126, 225, 176, 111, 17, 79, 77, 245, 80, 229, 174, 6, 180, 156, - 217, 85, 174, 201, 255, 237, 85, 83, 53, 188, 153, 98, 91, 193, 21, 211, - 49, 145, 196, 252, 52, 66, 226, 131, 203, 214, 130, 237, 194, 208, 174, - 102, 133, 220, 235, 222, 79, 232, 36, 21, 161, 248, 51, 185, 164, 156, 95, - 121, 65, 57, 233, 183, 29, 199, 105, 104, 12, 90, 195, 186, 81, 199, 176, - 1, 87, 16, 226, 192, 206, 185, 197, 46, 34, 75, 174, 153, 238, 15, 50, 87, - 226, 96, 26, 197, 202, 73, 235, 19, 140, 9, 79, 12, 52, 83, 76, 85, 146, - 234, 24, 151, 179, 178, 118, 58, 162, 223, 103, 69, 244, 231, 135, 167, - 204, 117, 166, 60, 237, 82, 63, 11, 4, 207, 10, 146, 54, 126, 191, 79, - 133, 60, 128, 34, 136, 170, 23, 84, 81, 38, 94, 9, 130, 245, 100, 115, - 209, 34, 228, 158, 101, 216, 135, 208, 207, 191, 169, 115, 252, 144, 139, - 226, 252, 6, 44, 221, 134, 170, 87, 11, 46, 124, 58, 219, 179, 238, 6, 98, - 216, 18, 174, 42, 12, 97, 126, 85, 245, 81, 220, 232, 135, 114, 21, 125, - 135, 225, 182, 245, 228, 223, 242, 62, 158, 35, 76, 6, 110, 25, 184, 206, - 124, 237, 54, 252, 199, 44, 78, 89, 0, 135, 44, 176, 57, 168, 36, 221, - 173, 77, 214, 209, 60, 1, 202, 238, 237, 61, 90, 47, 114, 230, 92, 238, - 235, 18, 151, 220, 243, 225, 163, 159, 139, 189, 253, 62, 225, 182, 202, - 59, 7, 83, 99, 129, 118, 175, 37, 246, 85, 119, 251, 246, 69, 180, 247, - 37, 24, 194, 89, 158, 97, 230, 247, 254, 145, 102, 89, 77, 68, 245, 3, - 103, 83, 28, 45, 168, 30, 189, 151, 112, 120, 215, 84, 90, 198, 85, 85, - 129, 55, 127, 124, 28, 137, 229, 139, 54, 88, 229, 105, 81, 212, 83, 28, - 107, 250, 82, 164, 43, 24, 15, 57, 206, 156, 19, 145, 95, 57, 169, 8, 128, - 211, 29, 213, 195, 148, 27, 73, 186, 221, 242, 11, 167, 78, 246, 133, 18, - 118, 67, 236, 59, 19, 112, 254, 93, 168, 157, 118, 0, 107, 248, 57, 149, - 67, 222, 123, 225, 207, 251, 69, 218, 56, 110, 162, 19, 25, 209, 209, 213, - 200, 158, 70, 9, 100, 208, 77, 48, 255, 151, 200, 0, 68, 230, 70, 120, - 209, 29, 86, 225, 188, 189, 226, 101, 42, 176, 32, 147, 121, 72, 151, 130, - 217, 13, 66, 148, 84, 129, 215, 249, 164, 174, 187, 80, 85, 185, 245, 108, - 169, 119, 59, 178, 144, 229, 63, 194, 132, 250, 131, 82, 161, 125, 126, - 255, 252, 220, 204, 104, 231, 201, 136, 246, 116, 43, 88, 233, 0, 43, 128, - 214, 40, 59, 81, 147, 139, 132, 69, 24, 233, 21, 14, 91, 230, 241, 19, - 138, 163, 55, 13, 221, 47, 64, 140, 248, 6, 38, 164, 16, 219, 63, 33, 180, - 71, 151, 0, 234, 103, 58, 213, 222, 163, 95, 132, 1, 178, 146, 66, 124, - 242, 223, 102, 129, 192, 214, 194, 117, 162, 252, 246, 143, 42, 70, 139, - 97, 168, 64, 141, 190, 115, 126, 93, 175, 59, 49, 9, 184, 88, 201, 100, - 182, 142, 145, 244, 72, 128, 203, 49, 196, 5, 5, 18, 46, 34, 87, 171, 132, - 158, 128, 75, 194, 8, 242, 52, 156, 229, 245, 56, 245, 88, 14, 195, 110, - 166, 51, 158, 245, 195, 120, 17, 166, 66, 100, 212, 188, 243, 2, 236, 90, - 8, 16, 35, 151, 122, 175, 115, 168, 186, 191, 60, 71, 23, 81, 217, 79, - 203, 239, 61, 146, 247, 168, 112, 83, 102, 146, 222, 178, 45, 247, 63, 23, - 181, 3, 136, 208, 62, 154, 203, 35, 250, 238, 61, 98, 207, 90, 169, 175, - 36, 227, 9, 182, 78, 226, 99, 89, 67, 105, 185, 35, 242, 162, 54, 99, 60, - 148, 14, 118, 1, 26, 120, 62, 82, 62, 222, 34, 99, 58, 174, 145, 199, 190, - 21, 182, 117, 238, 13, 170, 29, 67, 149, 44, 90, 94, 181, 125, 182, 186, - 82, 55, 105, 253, 29, 212, 67, 134, 204, 227, 94, 255, 127, 72, 157, 140, - 142, 224, 77, 149, 29, 170, 45, 163, 214, 209, 46, 28, 125, 177, 111, 2, - 92, 121, 252, 166, 204, 227, 173, 51, 60, 162, 243, 202, 207, 103, 30, - 153, 182, 116, 182, 130, 98, 59, 25, 141, 239, 49, 224, 176, 27, 237, 218, - 76, 68, 189, 108, 185, 136, 255, 105, 150, 11, 153, 44, 248, 139, 199, - 178, 235, 85, 115, 121, 144, 87, 221, 50, 222, 238, 16, 20, 51, 190, 93, - 248, 228, 84, 228, 115, 31, 229, 227, 137, 180, 44, 115, 224, 119, 129, - 181, 134, 224, 144, 186, 123, 208, 118, 96, 101, 177, 191, 232, 171, 6, - 17, 247, 187, 173, 84, 70, 249, 19, 191, 116, 172, 126, 131, 216, 123, - 225, 151, 55, 205, 177, 93, 139, 117, - ]), + pkcs8: mldsaKeyFixtures.pkcs8['ML-DSA-87'], + spki: mldsaKeyFixtures.spki['ML-DSA-87'], 'raw-public': hexStringToUint8Array( '92b84328ac1bcc1b87166ddf7f176182c6e4c73eb215ad1458b4cda811a4875c55924cc29850ef9d2115efb6b0fe7c50878a57a9676357055ba1ef3b12f69414203c75f5b69cc4e65275e4d3512d73d9175f8a5f677c2059bb30fb6751ea4c0439c547307da9c393b78ea60893074df06f2ca817596b5fdc4bca2c19f4c8a000ae6f6bcc16247abf652134fc0e2f196d873083fdc3ed3c560e77551cb68b88bf3bbb5a7ecfa8eeb8534dfed0153968bce48652f9bef9a3786f44e1d2831d97999247a368e1c22140d55c91fd2a20e95fe048b877c071fdb199f6f03167aae55245ba24fc1d7cff199405a09f699db9199e7a911ef533cd3e389a173400e1b169c383b197c5726e80e37fb01cfcd9383d8894be7c6c813ef3eb2546e4e90a437c783aa453395027cc621cc7884b0c33ff18827f13efa05e894b0f529efca32becc1ea1b4a450eb3ab0aa91b8aacd5bddea76e180b7697df5e9a7d091589468033663469689d36ba4bd9e2a9477db1fdda55ecf219d793b568f2524b32a531668052edaa86a2c438f7c78a6676254272a5b19cfb27c70ca7f6a9966c5bc02a44c0f4ff6b12bf074913ae1c74428360ad3c83bef9dbf647b67cb781656d5fb44e118cb63e50c3b8fdb0a999011d5327fc9629dbb030976c3cffef005565c16ecc0cfe16880f9ad9580d1cfce830202129dd67e3e4b136afc36aae8c36806cd6e4d776e2ceab159ba29887cb10aa8264ad9bf35028629df8076558c7dae08d52ee795c5261311f9b3d3f54e35a8fa43bd865132386021412c561d7a955dc4bfe5b7d902b41801d424db8ac597bcbe7fe3b12f9ccf9dc9954a63f176c7891d843df7bf80ffd3fbf7e545f628d42c881c2ae1e50304b710e6665daf90ecb18060b596338311194a0f265bf66e373216b47eb068d44a1a2a5e39f52fd369dd6ff8d979a86965d8d619ef4b4872a0a03940998951412edfdb488a50d50c3dc2b03b20a7f9002cfd1f6286e26850916b40bdf74eccdba19b79ba54dce65ff6adf460a16b0778ea3c5b2fbd870ed3fc94ddbc402b0300fcf5b4aec1508cd7e4d1c0d1a1ccafa644f86d1c14eca3af87cd7408ff41117a3a2f1f931d2a8cbd5874d0e1d23c1ea3a0c6aa5a3fbc073fb07c6bd5dcfb2f632bdb9332d548cc2222e5c5a8851513534fd80f783f315cff58d31b2d5d6d30811ea85e168c5bae07501ad6811b1a1df47c39fc22db1741abbc1a1d5b39e087aba7abf9e050cb2eb4e844ebd10566e493381fff26e3f0635d16e84ec2befc0dd8a0180b000715577c924bcca09df62c42a829e95c896ca8476996136c39a0f2df68190ffe74b19382fb2620a6a543871a1e325f601f581ad46ba0b1c7dc6f3e17182058a34fbc2986930d60df6e44becc2dfb1409661a7141b4a4ca6c7ef5bf0081636293f2370fffb58fc93adb92b62539be6b037a108530f6e97f16ea8cbbec6da9890963a7b0b7bfa6871c65d019833ac8cf67371e5daa6c8237b1085a9bf3b670c720f3c25045cd0361f4f38e1060b4a6b4fe1ef1049f9eac581e661277331608d29f2e1b1d6126722e525b0f16352e3c34d2040047831c7d18b0204dee92d978d8efc297ce70d903fd4fc91228ee898548757af2e358b3ca887a765fd7f988a9a1fe7c64d59b60936677764daf52cbf4a1e9854163e9f83a3df0333c2f13109d52bd6c94b9ec616cbd1bec7bd4b0406483cf171ab1e2a8f493348ce6eafcbc3c70f9bd0a6791a843b2c489b07307a84e08e030715cf0b1e701295927f2968c5a956d56cfd6fa0050bcaace92005345c7c98a20b581ca6f88dfb26a1353188f6b75509a5736c12d0da81a5a38322205ee2795d1857e26919f280c64e1aed155c21790877838cc10e3c8b821341603205f90c1b3317c359ff2f176d3ecabe05835c5b271bd184925f62421ae6baecbaa295518fdd154fabec15a113870ad5a8c88713ddb1cf6ad6c27cdc352db0f5b2bd31f216e69af192e6bbb4f49e91c5e133968c1aaf4e8ef3e8dd89cd82b236d88876d4215ace12e09e2c1790cc18b83051e97c14de4d77901691f113ce87fca4725425af6b43f3b789d535ec2949322292dacc44eb9e968b854bf89d070035442c9c6e38c5d1c9009be15523a9c1e7241f8e65a81dc01f8051bffdb899e2d6011b0600c02465486996e203150c7f48fadff088f99d81f75bb29dd0569217b09623d39b16cf77a8a77ab4b76a618a5760228d6e91e7e22373e88136ba80beee25a9c22518edd3a46f3658f57d434ec20bc2ebd957cb0edcbd6b445e8b42e60536401cf68f4b7feff314fbbdf6f6975adbe3f2dfcd287cf504bd4827916e6078a41b7592b11e4cad6a82e4c0bd3ba71e7fb2a4058550c7cfd8bd9c5dde968151c1b4263b08d6d25f96b6af942b99a9423e878c9f59c3fd0384b4a4f4f3e847c4c89ec27273c158a1b9ebf70e7ee1b06f114f4df550e5ae06b49cd955aec9ffed555335bc99625bc115d33191c4fc3442e283cbd682edc2d0ae6685dcebde4fe82415a1f833b9a49c5f794139e9b71dc769680c5ac3ba51c7b0015710e2c0ceb9c52e224bae99ee0f3257e2601ac5ca49eb138c094f0c34534c5592ea1897b3b2763aa2df6745f4e787a7cc75a63ced523f0b04cf0a92367ebf4f853c802288aa175451265e0982f56473d122e49e65d887d0cfbfa973fc908be2fc062cdd86aa570b2e7c3adbb3ee0662d812ae2a0c617e55f551dce88772157d87e1b6f5e4dff23e9e234c066e19b8ce7ced36fcc72c4e5900872cb039a824ddad4dd6d13c01caeeed3d5a2f72e65ceeeb1297dcf3e1a39f8bbdfd3ee1b6ca3b0753638176af25f65577fbf645b4f72518c2599e61e6f7fe9166594d44f50367531c2da81ebd977078d7545ac6555581377f7c1c89e58b3658e56951d4531c6bfa52a42b180f39ce9c13915f39a90880d31dd5c3941b49baddf20ba74ef685127643ec3b1370fe5da89d76006bf8399543de7be1cffb45da386ea21319d1d1d5c89e460964d04d30ff97c80044e64678d11d56e1bcbde2652ab0209379489782d90d42945481d7f9a4aebb5055b9f56ca9773bb290e53fc284fa8352a17d7efffcdccc68e7c988f6742b58e9002b80d6283b51938b844518e9150e5be6f1138aa3370ddd2f408cf80626a410db3f21b4479700ea673ad5dea35f8401b292427cf2df6681c0d6c275a2fcf68f2a468b61a8408dbe737e5daf3b3109b858c964b68e91f44880cb31c40505122e2257ab849e804bc208f2349ce5f538f5580ec36ea6339ef5c37811a64264d4bcf302ec5a081023977aaf73a8babf3c471751d94fcbef3d92f7a870536692deb22df73f17b50388d03e9acb23faee3d62cf5aa9af24e309b64ee263594369b923f2a236633c940e76011a783e523ede22633aae91c7be15b675ee0daa1d43952c5a5eb57db6ba523769fd1dd44386cce35eff7f489d8c8ee04d951daa2da3d6d12e1c7db16f025c79fca6cce3ad333ca2f3cacf671e99b674b682623b198def31e0b01bedda4c44bd6cb988ff69960b992cf88bc7b2eb5573799057dd32deee101433be5df8e454e4731fe5e389b42c73e07781b586e090ba7bd0766065b1bfe8ab0611f7bbad5446f913bf74ac7e83d87be19737cdb15d8b75' ), diff --git a/WebCryptoAPI/import_export/ML-KEM_importKey.js b/WebCryptoAPI/import_export/ML-KEM_importKey.js deleted file mode 100644 index d9257ac6982505..00000000000000 --- a/WebCryptoAPI/import_export/ML-KEM_importKey.js +++ /dev/null @@ -1,130 +0,0 @@ -var subtle = crypto.subtle; - -function runTests(algorithmName) { - var algorithm = { name: algorithmName }; - var data = keyData[algorithmName]; - var jwkData = { - jwk: { kty: data.jwk.kty, alg: data.jwk.alg, pub: data.jwk.pub }, - }; - - [true, false].forEach(function (extractable) { - // Test public keys first - allValidUsages(data.publicUsages, true).forEach(function (usages) { - ['spki', 'jwk', 'raw-public'].forEach(function (format) { - if (format === 'jwk') { - // Not all fields used for public keys - testFormat( - format, - algorithm, - jwkData, - algorithmName, - usages, - extractable - ); - } else { - testFormat( - format, - algorithm, - data, - algorithmName, - usages, - extractable - ); - } - }); - }); - - // Next, test private keys - allValidUsages(data.privateUsages).forEach(function (usages) { - ['pkcs8', 'jwk', 'raw-seed'].forEach(function (format) { - testFormat(format, algorithm, data, algorithmName, usages, extractable); - }); - }); - }); -} - -// Test importKey with a given key format and other parameters. If -// extrable is true, export the key and verify that it matches the input. -function testFormat(format, algorithm, keyData, keySize, usages, extractable) { - [algorithm, algorithm.name].forEach((alg) => { - promise_test(function (test) { - return subtle - .importKey(format, keyData[format], alg, extractable, usages) - .then( - function (key) { - assert_equals( - key.constructor, - CryptoKey, - 'Imported a CryptoKey object' - ); - assert_goodCryptoKey( - key, - algorithm, - extractable, - usages, - format === 'pkcs8' || - format === 'raw-seed' || - (format === 'jwk' && keyData[format].priv) - ? 'private' - : 'public' - ); - if (!extractable) { - return; - } - - return subtle.exportKey(format, key).then( - function (result) { - if (format !== 'jwk') { - assert_true( - equalBuffers(keyData[format], result), - 'Round trip works' - ); - } else { - assert_true( - equalJwk(keyData[format], result), - 'Round trip works' - ); - } - }, - function (err) { - assert_unreached( - 'Threw an unexpected error: ' + err.toString() - ); - } - ); - }, - function (err) { - assert_unreached('Threw an unexpected error: ' + err.toString()); - } - ); - }, 'Good parameters: ' + - keySize.toString() + - ' bits ' + - parameterString(format, keyData[format], alg, extractable, usages)); - }); -} - -// Helper methods follow: - -// Convert method parameters to a string to uniquely name each test -function parameterString(format, data, algorithm, extractable, usages) { - if ('byteLength' in data) { - data = 'buffer(' + data.byteLength.toString() + ')'; - } else { - data = 'object(' + Object.keys(data).join(', ') + ')'; - } - var result = - '(' + - objectToString(format) + - ', ' + - objectToString(data) + - ', ' + - objectToString(algorithm) + - ', ' + - objectToString(extractable) + - ', ' + - objectToString(usages) + - ')'; - - return result; -} diff --git a/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js b/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js index 8b459c17e2d329..11d80c76bc552e 100644 --- a/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js +++ b/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js @@ -2,7 +2,7 @@ // META: timeout=long // META: script=../util/helpers.js // META: script=ML-KEM_importKey_fixtures.js -// META: script=ML-KEM_importKey.js +// META: script=ml_importKey.js runTests("ML-KEM-512"); runTests("ML-KEM-768"); diff --git a/WebCryptoAPI/import_export/ec_importKey.https.any.js b/WebCryptoAPI/import_export/ec_importKey.https.any.js index 3b78bab4e74132..473fab2887e78c 100644 --- a/WebCryptoAPI/import_export/ec_importKey.https.any.js +++ b/WebCryptoAPI/import_export/ec_importKey.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for EC keys // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/ec_key_fixtures.js // Test importKey and exportKey for EC algorithms. Only "happy paths" are // currently tested - those where the operation should succeed. @@ -9,56 +10,7 @@ var curves = ['P-256', 'P-384', 'P-521']; - var keyData = { - "P-521": { - spki: new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), - spki_compressed: new Uint8Array([48, 88, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 68, 0, 3, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63]), - raw: new Uint8Array([4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), - raw_compressed: new Uint8Array([3, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63]), - pkcs8: new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 0, 244, 8, 117, 131, 104, 186, 147, 15, 48, 247, 106, 224, 84, 254, 92, 210, 206, 127, 218, 44, 159, 118, 166, 212, 54, 207, 117, 214, 108, 68, 11, 254, 99, 49, 199, 193, 114, 161, 36, 120, 25, 60, 130, 81, 72, 123, 201, 18, 99, 250, 80, 33, 127, 133, 255, 99, 111, 89, 205, 84, 110, 58, 180, 131, 180, 161, 129, 137, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), - pkcs8_private_only: new Uint8Array([48, 96, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 73, 48, 71, 2, 1, 1, 4, 66, 0, 244, 8, 117, 131, 104, 186, 147, 15, 48, 247, 106, 224, 84, 254, 92, 210, 206, 127, 218, 44, 159, 118, 166, 212, 54, 207, 117, 214, 108, 68, 11, 254, 99, 49, 199, 193, 114, 161, 36, 120, 25, 60, 130, 81, 72, 123, 201, 18, 99, 250, 80, 33, 127, 133, 255, 99, 111, 89, 205, 84, 110, 58, 180, 131, 180]), - jwk: { - kty: "EC", - crv: "P-521", - x: "AVb0efjfHiCn_8BM5CDD4VSuJRmWvuQvA0uE1Bt0PzTkXzEbgTqc3sjNpZu7vTHUYLMpJSHnwbci5WZ8A9svrnU_", - y: "AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0WXtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7", - d: "APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHwXKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0" - } - }, - - "P-256": { - spki: new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), - spki_compressed: new Uint8Array([48, 57, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 34, 0, 2, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209]), - raw: new Uint8Array([4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), - raw_compressed: new Uint8Array([2, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209]), - pkcs8: new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 19, 211, 58, 45, 90, 191, 156, 249, 235, 178, 31, 248, 96, 212, 174, 254, 110, 86, 231, 119, 144, 244, 222, 233, 180, 8, 132, 235, 211, 53, 68, 234, 161, 68, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), - pkcs8_private_only: new Uint8Array([48, 65, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 39, 48, 37, 2, 1, 1, 4, 32, 19, 211, 58, 45, 90, 191, 156, 249, 235, 178, 31, 248, 96, 212, 174, 254, 110, 86, 231, 119, 144, 244, 222, 233, 180, 8, 132, 235, 211, 53, 68, 234]), - jwk: { - kty: "EC", - crv: "P-256", - x: "0hCwpvnZ8BKGgFi0P6T0cQGFQ7ugDJJQ35JXwqyuXdE", - y: "zgN1UtSBRQzjm00QlXAbF1v6s0uObAmeGPHBmDWDYeg", - d: "E9M6LVq_nPnrsh_4YNSu_m5W53eQ9N7ptAiE69M1ROo" - } - }, - - "P-384": { - spki: new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), - spki_compressed: new Uint8Array([48, 70, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 50, 0, 2, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53]), - raw: new Uint8Array([4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), - raw_compressed: new Uint8Array([2, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53]), - pkcs8: new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 69, 55, 181, 153, 7, 132, 211, 194, 210, 46, 150, 168, 249, 47, 161, 170, 73, 46, 232, 115, 229, 118, 164, 21, 130, 225, 68, 24, 60, 152, 136, 209, 14, 107, 158, 180, 206, 212, 178, 204, 64, 18, 228, 172, 94, 168, 64, 115, 161, 100, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), - pkcs8_private_only: new Uint8Array([48, 78, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 55, 48, 53, 2, 1, 1, 4, 48, 69, 55, 181, 153, 7, 132, 211, 194, 210, 46, 150, 168, 249, 47, 161, 170, 73, 46, 232, 115, 229, 118, 164, 21, 130, 225, 68, 24, 60, 152, 136, 209, 14, 107, 158, 180, 206, 212, 178, 204, 64, 18, 228, 172, 94, 168, 64, 115]), - jwk: { - kty: "EC", - crv: "P-384", - x: "IZwU1mYXs27G2IVrOFtzp000T9iude8EZDXdpU47RL1fvevR0I3Wni19wdwhjLQ1", - y: "vSgTjMd4M3qEL2vWGyQOdCSfJGZ8KlgQp2v8KOAzX4imUB3sAZdtqFr7AIactqzo", - d: "RTe1mQeE08LSLpao-S-hqkku6HPldqQVguFEGDyYiNEOa560ztSyzEAS5KxeqEBz" - } - }, - - }; + var keyData = ecKeyData; // combinations to test var testVectors = [ diff --git a/WebCryptoAPI/import_export/ec_importKey_failures_ECDH.https.any.js b/WebCryptoAPI/import_export/ec_importKey_failures_ECDH.https.any.js index 423d399f19def4..260e49791a51ea 100644 --- a/WebCryptoAPI/import_export/ec_importKey_failures_ECDH.https.any.js +++ b/WebCryptoAPI/import_export/ec_importKey_failures_ECDH.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/ec_key_fixtures.js // META: script=ec_importKey_failures_fixtures.js // META: script=importKey_failures.js diff --git a/WebCryptoAPI/import_export/ec_importKey_failures_ECDSA.https.any.js b/WebCryptoAPI/import_export/ec_importKey_failures_ECDSA.https.any.js index 527940798a42a5..96116d5462df7c 100644 --- a/WebCryptoAPI/import_export/ec_importKey_failures_ECDSA.https.any.js +++ b/WebCryptoAPI/import_export/ec_importKey_failures_ECDSA.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/ec_key_fixtures.js // META: script=ec_importKey_failures_fixtures.js // META: script=importKey_failures.js diff --git a/WebCryptoAPI/import_export/ec_importKey_failures_fixtures.js b/WebCryptoAPI/import_export/ec_importKey_failures_fixtures.js index dc0e11d551a922..a37a72cb28d542 100644 --- a/WebCryptoAPI/import_export/ec_importKey_failures_fixtures.js +++ b/WebCryptoAPI/import_export/ec_importKey_failures_fixtures.js @@ -1,17 +1,41 @@ -// Setup: define the correct behaviors that should be sought, and create -// helper functions that generate all possible test parameters for -// different situations. +function ecPrivateJwk(namedCurve) { + return Object.assign({}, ecKeyData[namedCurve].jwk); +} + function getValidKeyData(algorithm) { - return validKeyData[algorithm.namedCurve]; + var key = ecKeyData[algorithm.namedCurve]; + return [ + {format: "spki", data: key.spki}, + {format: "raw", data: key.raw}, + {format: "pkcs8", data: key.pkcs8}, + {format: "jwk", data: ecPrivateJwk(algorithm.namedCurve)} + ]; } function getBadKeyLengthData(algorithm) { - return badKeyLengthData[algorithm.namedCurve]; + var key = ecKeyData[algorithm.namedCurve]; + var jwk = ecPrivateJwk(algorithm.namedCurve); + jwk.x = jwk.x.slice(0, -1); + return [ + {format: "spki", data: key.spki.slice(0, -1)}, + {format: "raw", data: key.raw.slice(0, -1)}, + {format: "pkcs8", data: key.pkcs8.slice(0, -1)}, + {format: "jwk", data: jwk} + ]; } function getMissingJWKFieldKeyData(algorithm) { - // The curve doesn't affect when testing for missing JWK fields. - return missingJWKFieldKeyData["P-521"]; + var missingX = ecPrivateJwk("P-521"); + var missingKty = ecPrivateJwk("P-521"); + var missingCrv = ecPrivateJwk("P-521"); + delete missingX.x; + delete missingKty.kty; + delete missingCrv.crv; + return [ + {param: "x", data: missingX}, + {param: "kty", data: missingKty}, + {param: "crv", data: missingCrv} + ]; } function getMismatchedJWKKeyData(algorithm) { @@ -20,206 +44,15 @@ function getMismatchedJWKKeyData(algorithm) { } function getMismatchedKtyField(algorithm) { - return mismatchedKtyField[algorithm.namedCurve]; + return "OKP"; } function getMismatchedCrvField(algorithm) { - return mismatchedCrvField[algorithm.namedCurve]; -} - -var validKeyData = { - "P-521": [ - { - format: "spki", - data: new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), - }, - { - format: "raw", - data: new Uint8Array([4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), - }, - { - format:"pkcs8", - data: new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 0, 244, 8, 117, 131, 104, 186, 147, 15, 48, 247, 106, 224, 84, 254, 92, 210, 206, 127, 218, 44, 159, 118, 166, 212, 54, 207, 117, 214, 108, 68, 11, 254, 99, 49, 199, 193, 114, 161, 36, 120, 25, 60, 130, 81, 72, 123, 201, 18, 99, 250, 80, 33, 127, 133, 255, 99, 111, 89, 205, 84, 110, 58, 180, 131, 180, 161, 129, 137, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56, 251]), - }, - { - format: "jwk", - data: { - kty: "EC", - crv: "P-521", - x: "AVb0efjfHiCn_8BM5CDD4VSuJRmWvuQvA0uE1Bt0PzTkXzEbgTqc3sjNpZu7vTHUYLMpJSHnwbci5WZ8A9svrnU_", - y: "AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0WXtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7", - d: "APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHwXKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0" - } - } - ], - "P-256": [ - { - format: "spki", - data: new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), - }, - { - format: "raw", - data: new Uint8Array([4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 19, 211, 58, 45, 90, 191, 156, 249, 235, 178, 31, 248, 96, 212, 174, 254, 110, 86, 231, 119, 144, 244, 222, 233, 180, 8, 132, 235, 211, 53, 68, 234, 161, 68, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97, 232]), - }, - { - format: "jwk", - data: { - kty: "EC", - crv: "P-256", - x: "0hCwpvnZ8BKGgFi0P6T0cQGFQ7ugDJJQ35JXwqyuXdE", - y: "zgN1UtSBRQzjm00QlXAbF1v6s0uObAmeGPHBmDWDYeg", - d: "E9M6LVq_nPnrsh_4YNSu_m5W53eQ9N7ptAiE69M1ROo" - } - }, - ], - "P-384": [ - { - format: "spki", - data: new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), - }, - { - format: "raw", - data: new Uint8Array([4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 69, 55, 181, 153, 7, 132, 211, 194, 210, 46, 150, 168, 249, 47, 161, 170, 73, 46, 232, 115, 229, 118, 164, 21, 130, 225, 68, 24, 60, 152, 136, 209, 14, 107, 158, 180, 206, 212, 178, 204, 64, 18, 228, 172, 94, 168, 64, 115, 161, 100, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172, 232]), - }, - { - format: "jwk", - data: { - kty: "EC", - crv: "P-384", - x: "IZwU1mYXs27G2IVrOFtzp000T9iude8EZDXdpU47RL1fvevR0I3Wni19wdwhjLQ1", - y: "vSgTjMd4M3qEL2vWGyQOdCSfJGZ8KlgQp2v8KOAzX4imUB3sAZdtqFr7AIactqzo", - d: "RTe1mQeE08LSLpao-S-hqkku6HPldqQVguFEGDyYiNEOa560ztSyzEAS5KxeqEBz" - } - } - ] -}; - -// Removed just the last byte. -var badKeyLengthData = { - "P-521": [ - { - format: "spki", - data: new Uint8Array([48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56]), - }, - { - format: "raw", - data: new Uint8Array([4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56]), - }, - { - format:"pkcs8", - data: new Uint8Array([48, 129, 238, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 35, 4, 129, 214, 48, 129, 211, 2, 1, 1, 4, 66, 0, 244, 8, 117, 131, 104, 186, 147, 15, 48, 247, 106, 224, 84, 254, 92, 210, 206, 127, 218, 44, 159, 118, 166, 212, 54, 207, 117, 214, 108, 68, 11, 254, 99, 49, 199, 193, 114, 161, 36, 120, 25, 60, 130, 81, 72, 123, 201, 18, 99, 250, 80, 33, 127, 133, 255, 99, 111, 89, 205, 84, 110, 58, 180, 131, 180, 161, 129, 137, 3, 129, 134, 0, 4, 1, 86, 244, 121, 248, 223, 30, 32, 167, 255, 192, 76, 228, 32, 195, 225, 84, 174, 37, 25, 150, 190, 228, 47, 3, 75, 132, 212, 27, 116, 63, 52, 228, 95, 49, 27, 129, 58, 156, 222, 200, 205, 165, 155, 187, 189, 49, 212, 96, 179, 41, 37, 33, 231, 193, 183, 34, 229, 102, 124, 3, 219, 47, 174, 117, 63, 1, 80, 23, 54, 207, 226, 71, 57, 67, 32, 216, 228, 175, 194, 253, 57, 181, 169, 51, 16, 97, 184, 30, 34, 65, 40, 43, 158, 23, 137, 24, 34, 181, 183, 158, 5, 47, 69, 151, 181, 150, 67, 253, 57, 55, 156, 81, 189, 81, 37, 196, 244, 139, 195, 240, 37, 206, 60, 211, 105, 83, 40, 108, 203, 56]), - }, - { - format: "jwk", - data: { - kty: "EC", - crv: "P-521", - x: "AVb0efjfHiCn_8BM5CDD4VSuJRmWvuQvA0uE1Bt0PzTkXzEbgTqc3sjNpZu7vTHUYLMpJSHnwbci5WZ8A9svrnU", - y: "AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0WXtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7", - d: "APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHwXKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0" - } - } - ], - "P-256": [ - { - format: "spki", - data: new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97]), - }, - { - format: "raw", - data: new Uint8Array([4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 19, 211, 58, 45, 90, 191, 156, 249, 235, 178, 31, 248, 96, 212, 174, 254, 110, 86, 231, 119, 144, 244, 222, 233, 180, 8, 132, 235, 211, 53, 68, 234, 161, 68, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244, 113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93, 209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27, 23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97]), - }, - { - format: "jwk", - data: { - kty: "EC", - crv: "P-256", - x: "0hCwpvnZ8BKGgFi0P6T0cQGFQ7ugDJJQ35JXwqyuXd", - y: "zgN1UtSBRQzjm00QlXAbF1v6s0uObAmeGPHBmDWDYeg", - d: "E9M6LVq_nPnrsh_4YNSu_m5W53eQ9N7ptAiE69M1ROo" - } - }, - ], - "P-384": [ - { - format: "spki", - data: new Uint8Array([48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172]), - }, - { - format: "raw", - data: new Uint8Array([4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 69, 55, 181, 153, 7, 132, 211, 194, 210, 46, 150, 168, 249, 47, 161, 170, 73, 46, 232, 115, 229, 118, 164, 21, 130, 225, 68, 24, 60, 152, 136, 209, 14, 107, 158, 180, 206, 212, 178, 204, 64, 18, 228, 172, 94, 168, 64, 115, 161, 100, 3, 98, 0, 4, 33, 156, 20, 214, 102, 23, 179, 110, 198, 216, 133, 107, 56, 91, 115, 167, 77, 52, 79, 216, 174, 117, 239, 4, 100, 53, 221, 165, 78, 59, 68, 189, 95, 189, 235, 209, 208, 141, 214, 158, 45, 125, 193, 220, 33, 140, 180, 53, 189, 40, 19, 140, 199, 120, 51, 122, 132, 47, 107, 214, 27, 36, 14, 116, 36, 159, 36, 102, 124, 42, 88, 16, 167, 107, 252, 40, 224, 51, 95, 136, 166, 80, 29, 236, 1, 151, 109, 168, 90, 251, 0, 134, 156, 182, 172]), - }, - { - format: "jwk", - data: { - kty: "EC", - crv: "P-384", - x: "IZwU1mYXs27G2IVrOFtzp000T9iude8EZDXdpU47RL1fvevR0I3Wni19wdwhjLQ", - y: "vSgTjMd4M3qEL2vWGyQOdCSfJGZ8KlgQp2v8KOAzX4imUB3sAZdtqFr7AIactqzo", - d: "RTe1mQeE08LSLpao-S-hqkku6HPldqQVguFEGDyYiNEOa560ztSyzEAS5KxeqEBz" - } - } - ] -}; - -var missingJWKFieldKeyData = { - "P-521": [ - { - param: "x", - data: { - kty: "EC", - crv: "P-521", - y: "AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0WXtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7", - d: "APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHwXKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0" - } - }, - { - param: "kty", - data: { - crv: "P-521", - x: "AVb0efjfHiCn_8BM5CDD4VSuJRmWvuQvA0uE1Bt0PzTkXzEbgTqc3sjNpZu7vTHUYLMpJSHnwbci5WZ8A9svrnU_", - y: "AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0WXtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7", - d: "APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHwXKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0" - } - }, - { - param: "crv", - data: { - kty: "EC", - x: "AVb0efjfHiCn_8BM5CDD4VSuJRmWvuQvA0uE1Bt0PzTkXzEbgTqc3sjNpZu7vTHUYLMpJSHnwbci5WZ8A9svrnU_", - y: "AVAXNs_iRzlDINjkr8L9ObWpMxBhuB4iQSgrnheJGCK1t54FL0WXtZZD_Tk3nFG9USXE9IvD8CXOPNNpUyhsyzj7", - d: "APQIdYNoupMPMPdq4FT-XNLOf9osn3am1DbPddZsRAv-YzHHwXKhJHgZPIJRSHvJEmP6UCF_hf9jb1nNVG46tIO0" - } - } - ] -}; - -// The 'kty' field doesn't match the key algorithm. -var mismatchedKtyField = { - "P-521": "OKP", - "P-256": "OKP", - "P-384": "OKP", + return mismatchedEcCurves[algorithm.namedCurve]; } -// The 'kty' field doesn't match the key algorithm. -var mismatchedCrvField = { +var mismatchedEcCurves = { "P-521": "P-256", "P-256": "P-384", - "P-384": "P-521", -} + "P-384": "P-521" +}; diff --git a/WebCryptoAPI/import_export/importKey_failures.js b/WebCryptoAPI/import_export/importKey_failures.js index f45da96cf6b01c..7581614f0dcb43 100644 --- a/WebCryptoAPI/import_export/importKey_failures.js +++ b/WebCryptoAPI/import_export/importKey_failures.js @@ -1,8 +1,6 @@ function run_test(algorithmNames) { var subtle = crypto.subtle; // Change to test prefixed implementations - setup({explicit_timeout: true}); - // These tests check that importKey and exportKey throw an error, and that // the error is of the right type, for a wide set of incorrect parameters. @@ -79,16 +77,15 @@ function run_test(algorithmNames) { }, testTag + ": importKey" + parameterString(format, algorithm, extractable, usages, keyData)); } - // Don't create an exhaustive list of all invalid usages, - // because there would usually be nearly 2**8 of them, - // way too many to test. Instead, create every singleton + // Don't create an exhaustive list of all invalid usages because + // there would be too many to test. Instead, create every singleton // of an illegal usage, and "poison" every valid usage // with an illegal one. function invalidUsages(validUsages, mandatoryUsages) { var results = []; var illegalUsages = []; - ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey", "deriveKey", "deriveBits"].forEach(function(usage) { + allKeyUsages.forEach(function(usage) { if (!validUsages.includes(usage)) { illegalUsages.push(usage); } diff --git a/WebCryptoAPI/import_export/ML-DSA_importKey.js b/WebCryptoAPI/import_export/ml_importKey.js similarity index 98% rename from WebCryptoAPI/import_export/ML-DSA_importKey.js rename to WebCryptoAPI/import_export/ml_importKey.js index d9257ac6982505..a33c3a85b912e4 100644 --- a/WebCryptoAPI/import_export/ML-DSA_importKey.js +++ b/WebCryptoAPI/import_export/ml_importKey.js @@ -1,5 +1,6 @@ var subtle = crypto.subtle; +// Shared ML-DSA and ML-KEM import/export tests. function runTests(algorithmName) { var algorithm = { name: algorithmName }; var data = keyData[algorithmName]; diff --git a/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js b/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js index 49656489d425dd..b6b3786519512e 100644 --- a/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for OKP keys // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_fixtures.js // META: script=okp_importKey.js diff --git a/WebCryptoAPI/import_export/okp_importKey_Ed448.tentative.https.any.js b/WebCryptoAPI/import_export/okp_importKey_Ed448.tentative.https.any.js index 5bb7460c1fbc93..8498ce4ef8f350 100644 --- a/WebCryptoAPI/import_export/okp_importKey_Ed448.tentative.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_Ed448.tentative.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for OKP keys // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_fixtures.js // META: script=okp_importKey.js diff --git a/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js b/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js index de1431d6cc2467..5d629c082730ee 100644 --- a/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for OKP keys // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_fixtures.js // META: script=okp_importKey.js diff --git a/WebCryptoAPI/import_export/okp_importKey_X448.tentative.https.any.js b/WebCryptoAPI/import_export/okp_importKey_X448.tentative.https.any.js index f8552be3c826dc..09361ed9b8d6ff 100644 --- a/WebCryptoAPI/import_export/okp_importKey_X448.tentative.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_X448.tentative.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for OKP keys // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_fixtures.js // META: script=okp_importKey.js diff --git a/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js b/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js index e07b796df83d19..0b541d77016f20 100644 --- a/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_failures_fixtures.js // META: script=importKey_failures.js diff --git a/WebCryptoAPI/import_export/okp_importKey_failures_Ed448.tentative.https.any.js b/WebCryptoAPI/import_export/okp_importKey_failures_Ed448.tentative.https.any.js index 8ff3de5c79d3ab..726d5c1e377234 100644 --- a/WebCryptoAPI/import_export/okp_importKey_failures_Ed448.tentative.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_failures_Ed448.tentative.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_failures_fixtures.js // META: script=importKey_failures.js diff --git a/WebCryptoAPI/import_export/okp_importKey_failures_X25519.https.any.js b/WebCryptoAPI/import_export/okp_importKey_failures_X25519.https.any.js index a0116bee888512..d4c9c105bc3ba4 100644 --- a/WebCryptoAPI/import_export/okp_importKey_failures_X25519.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_failures_X25519.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_failures_fixtures.js // META: script=importKey_failures.js diff --git a/WebCryptoAPI/import_export/okp_importKey_failures_X448.tentative.https.any.js b/WebCryptoAPI/import_export/okp_importKey_failures_X448.tentative.https.any.js index eccce68fac731c..2b575d7ab4d740 100644 --- a/WebCryptoAPI/import_export/okp_importKey_failures_X448.tentative.https.any.js +++ b/WebCryptoAPI/import_export/okp_importKey_failures_X448.tentative.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: importKey() for Failures // META: timeout=long // META: script=../util/helpers.js +// META: script=../util/okp_key_fixtures.js // META: script=okp_importKey_failures_fixtures.js // META: script=importKey_failures.js diff --git a/WebCryptoAPI/import_export/okp_importKey_failures_fixtures.js b/WebCryptoAPI/import_export/okp_importKey_failures_fixtures.js index 6a7f583e0165c5..01c65d60d44d57 100644 --- a/WebCryptoAPI/import_export/okp_importKey_failures_fixtures.js +++ b/WebCryptoAPI/import_export/okp_importKey_failures_fixtures.js @@ -1,438 +1,85 @@ -// Setup: define the correct behaviors that should be sought, and create -// helper functions that generate all possible test parameters for -// different situations. +function algorithmName(algorithm) { + return algorithm.name || algorithm; +} + +function privateJwk(name) { + return Object.assign({}, okpKeyData[name].jwk); +} + +function publicJwk(name) { + var jwk = privateJwk(name); + delete jwk.d; + return jwk; +} + function getValidKeyData(algorithm) { - return validKeyData[algorithm.name || algorithm]; + var name = algorithmName(algorithm); + var key = okpKeyData[name]; + return [ + {format: "spki", data: key.spki}, + {format: "pkcs8", data: key.pkcs8}, + {format: "raw", data: key.raw}, + {format: "jwk", data: privateJwk(name)}, + {format: "jwk", data: publicJwk(name)} + ]; } function getBadKeyLengthData(algorithm) { - return badKeyLengthData[algorithm.name || algorithm]; + var name = algorithmName(algorithm); + var key = okpKeyData[name]; + var badPrivateJwk = privateJwk(name); + var badPublicJwk = publicJwk(name); + badPrivateJwk.d = badPrivateJwk.d.slice(0, -1); + badPublicJwk.x = badPublicJwk.x.slice(0, -1); + return [ + {format: "spki", data: key.spki.slice(0, -1)}, + {format: "pkcs8", data: key.pkcs8.slice(0, -1)}, + {format: "raw", data: key.raw.slice(0, -1)}, + {format: "jwk", data: badPrivateJwk}, + {format: "jwk", data: badPublicJwk} + ]; } function getMissingJWKFieldKeyData(algorithm) { - return missingJWKFieldKeyData[algorithm.name || algorithm]; + var name = algorithmName(algorithm); + var missingX = privateJwk(name); + var missingKty = privateJwk(name); + var missingCrv = name === "Ed448" ? privateJwk(name) : publicJwk(name); + delete missingX.x; + delete missingKty.kty; + delete missingCrv.crv; + return [ + {param: "x", data: missingX}, + {param: "kty", data: missingKty}, + {param: "crv", data: missingCrv} + ]; } function getMismatchedJWKKeyData(algorithm) { - return mismatchedJWKKeyData[algorithm.name || algorithm]; + var name = algorithmName(algorithm); + var jwk = privateJwk(name); + jwk.x = mismatchedPublicKeys[name]; + return [jwk]; } function getMismatchedKtyField(algorithm) { - return mismatchedKtyField[algorithm.name || algorithm]; + return "EC"; } function getMismatchedCrvField(algorithm) { - return mismatchedCrvField[algorithm.name || algorithm]; + return mismatchedCurves[algorithmName(algorithm)]; } -var validKeyData = { - "Ed25519": [ - { - format: "spki", - data: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0, 216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61, 204]) - }, - { - format: "pkcs8", - data: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 243, 200, 244, 196, 141, 248, 120, 20, 110, 140, 211, 191, 109, 244, 229, 14, 56, 155, 167, 7, 78, 21, 194, 53, 45, 205, 93, 48, 141, 76, 168, 31]) - }, - { - format: "raw", - data: new Uint8Array([216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61, 204]) - }, - { - format: "jwk", - data: { - crv: "Ed25519", - d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", - x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", - kty: "OKP" - }, - }, - { - format: "jwk", - data: { - crv: "Ed25519", - x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", - kty: "OKP" - }, - } - ], - "Ed448": [ - { - format: "spki", - data: new Uint8Array([48, 67, 48, 5, 6, 3, 43, 101, 113, 3, 58, 0, 171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90, 128]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 71, 2, 1, 0, 48, 5, 6, 3, 43, 101, 113, 4, 59, 4, 57, 14, 255, 3, 69, 140, 40, 224, 23, 156, 82, 29, 227, 18, 201, 105, 183, 131, 67, 72, 236, 171, 153, 26, 96, 227, 178, 233, 167, 158, 76, 217, 228, 128, 239, 41, 23, 18, 210, 200, 61, 4, 114, 114, 213, 201, 244, 40, 102, 79, 105, 109, 38, 112, 69, 143, 29, 46]), - }, - { - format: "raw", - data: new Uint8Array([171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90, 128]), - }, - { - format: "jwk", - data: { - crv: "Ed448", - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", - kty: "OKP" - }, - }, - { - format: "jwk", - data: { - crv: "Ed448", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", - kty: "OKP" - }, - }, - ], - "X25519": [ - { - format: "spki", - data: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32, 200, 131, 142, 118, 208, 87, 223, 183, 216, 201, 90, 105, 225, 56, 22, 10, 221, 99, 115, 253, 113, 164, 210, 118, 187, 86, 227, 168, 27, 100, 255, 97]), - }, - { - format: "raw", - data: new Uint8Array([28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - }, - { - format: "jwk", - data: { - crv: "X25519", - d: "yIOOdtBX37fYyVpp4TgWCt1jc_1xpNJ2u1bjqBtk_2E", - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lwY", - kty: "OKP" - }, - }, - { - format: "jwk", - data: { - crv: "X25519", - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lwY", - kty: "OKP" - }, - }, - ], - "X448": [ - { - format: "spki", - data: new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 70, 2, 1, 0, 48, 5, 6, 3, 43, 101, 111, 4, 58, 4, 56, 88, 199, 210, 154, 62, 181, 25, 178, 157, 0, 207, 177, 145, 187, 100, 252, 109, 138, 66, 216, 241, 113, 118, 39, 43, 137, 242, 39, 45, 24, 25, 41, 92, 101, 37, 192, 130, 150, 113, 176, 82, 239, 7, 39, 83, 15, 24, 142, 49, 208, 204, 83, 191, 38, 146, 158]), - }, - { - format: "raw", - data: new Uint8Array([182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]), - }, - { - format: "jwk", - data: { - crv: "X448", - d: "WMfSmj61GbKdAM-xkbtk_G2KQtjxcXYnK4nyJy0YGSlcZSXAgpZxsFLvBydTDxiOMdDMU78mkp4", - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm8", - kty: "OKP" - }, - }, - { - format: "jwk", - data: { - crv: "X448", - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm8", - kty: "OKP" - }, - }, - ], -}; - -// Removed just the last byte. -var badKeyLengthData = { - "Ed25519": [ - { - format: "spki", - data: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0, 216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61]) - }, - { - format: "pkcs8", - data: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 243, 200, 244, 196, 141, 248, 120, 20, 110, 140, 211, 191, 109, 244, 229, 14, 56, 155, 167, 7, 78, 21, 194, 53, 45, 205, 93, 48, 141, 76, 168]) - }, - { - format: "raw", - data: new Uint8Array([216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61]) - }, - { - format: "jwk", - data: { - crv: "Ed25519", - d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB", - x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", - kty: "OKP" - } - }, - { - format: "jwk", - data: { - crv: "Ed25519", - x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPc", - kty: "OKP" - } - } - ], - "Ed448": [ - { - format: "spki", - data: new Uint8Array([48, 67, 48, 5, 6, 3, 43, 101, 113, 3, 58, 0, 171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 71, 2, 1, 0, 48, 5, 6, 3, 43, 101, 113, 4, 59, 4, 57, 14, 255, 3, 69, 140, 40, 224, 23, 156, 82, 29, 227, 18, 201, 105, 183, 131, 67, 72, 236, 171, 153, 26, 96, 227, 178, 233, 167, 158, 76, 217, 228, 128, 239, 41, 23, 18, 210, 200, 61, 4, 114, 114, 213, 201, 244, 40, 102, 79, 105, 109, 38, 112, 69, 143, 29]), - }, - { - format: "raw", - data: new Uint8Array([171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90]), - }, - { - format: "jwk", - data: { - crv: "Ed448", - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", - kty: "OKP" - }, - }, - { - format: "jwk", - data: { - crv: "Ed448", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalq", - kty: "OKP" - }, - }, - ], - "X25519": [ - { - format: "spki", - data: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32, 200, 131, 142, 118, 208, 87, 223, 183, 216, 201, 90, 105, 225, 56, 22, 10, 221, 99, 115, 253, 113, 164, 210, 118, 187, 86, 227, 168, 27, 100, 255]), - }, - { - format: "raw", - data: new Uint8Array([28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151]), - }, - { - format: "jwk", - data: { - crv: "X25519", - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lw", - kty: "OKP" - } - }, - { - format: "jwk", - data: { - crv: "X25519", - d: "yIOOdtBX37fYyVpp4TgWCt1jc_1xpNJ2u1bjqBtk_2", - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lwY", - kty: "OKP" - }, - }, - ], - "X448": [ - { - format: "spki", - data: new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206]), - }, - { - format: "pkcs8", - data: new Uint8Array([48, 70, 2, 1, 0, 48, 5, 6, 3, 43, 101, 111, 4, 58, 4, 56, 88, 199, 210, 154, 62, 181, 25, 178, 157, 0, 207, 177, 145, 187, 100, 252, 109, 138, 66, 216, 241, 113, 118, 39, 43, 137, 242, 39, 45, 24, 25, 41, 92, 101, 37, 192, 130, 150, 113, 176, 82, 239, 7, 39, 83, 15, 24, 142, 49, 208, 204, 83, 191, 38, 146]), - }, - { - format: "raw", - data: new Uint8Array([182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206]), - }, - { - format: "jwk", - data: { - crv: "X448", - d: "WMfSmj61GbKdAM-xkbtk_G2KQtjxcXYnK4nyJy0YGSlcZSXAgpZxsFLvBydTDxiOMdDMU78mkp", - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm8", - kty: "OKP" - }, - }, - { - format: "jwk", - data: { - crv: "X448", - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm", - kty: "OKP" - }, - }, - ], +var mismatchedPublicKeys = { + "Ed25519": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", + "Ed448": "X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq_oJWGA", + "X25519": "hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo", + "X448": "mwj3zDG34+Z9ItWuoSEHSic70rg94Jxj+qc9LCLF2bvINmRyQdlT1AxbEtqIEg1TF3+A5TLEH6A" }; -var missingJWKFieldKeyData = { - "Ed25519": [ - { - param: "x", - data: { - crv: "Ed25519", - d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", - kty: "OKP" - }, - }, - { - param: "kty", - data: { - crv: "Ed25519", - x: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", - d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", - }, - }, - { - param: "crv", - data: { - x: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", - kty: "OKP" - }, - } - ], - "Ed448": [ - { - param: "x", - data: { - crv: "Ed448", - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", - kty: "OKP" - } - }, - { - param: "kty", - data: { - crv: "Ed448", - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", - } - }, - { - param: "crv", - data: { - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", - kty: "OKP" - } - } - ], - "X25519": [ - { - param: "x", - data: { - crv: "X25519", - d: "yIOOdtBX37fYyVpp4TgWCt1jc_1xpNJ2u1bjqBtk_2E", - kty: "OKP" - }, - }, - { - param: "kty", - data: { - crv: "X25519", - d: "yIOOdtBX37fYyVpp4TgWCt1jc_1xpNJ2u1bjqBtk_2E", - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lwY", - }, - }, - { - param: "crv", - data: { - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lwY", - kty: "OKP" - }, - } - ], - "X448": [ - { - param: "x", - data: { - crv: "X448", - d: "WMfSmj61GbKdAM-xkbtk_G2KQtjxcXYnK4nyJy0YGSlcZSXAgpZxsFLvBydTDxiOMdDMU78mkp4", - kty: "OKP" - } - }, - { - param: "kty", - data: { - crv: "X448", - d: "WMfSmj61GbKdAM-xkbtk_G2KQtjxcXYnK4nyJy0YGSlcZSXAgpZxsFLvBydTDxiOMdDMU78mkp4", - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm8", - } - }, - { - param: "crv", - data: { - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm8", - kty: "OKP" - } - } - ], -}; - -// The public key doesn't match the private key. -var mismatchedJWKKeyData = { - "Ed25519": [ - { - crv: "Ed25519", - d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", - x: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", - kty: "OKP" - }, - ], - "Ed448": [ - { - crv: "Ed448", - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", - x: "X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq_oJWGA", - kty: "OKP" - }, - ], - "X25519": [ - { - crv: "X25519", - d: "yIOOdtBX37fYyVpp4TgWCt1jc_1xpNJ2u1bjqBtk_2E", - x: "hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo", - kty: "OKP" - }, - ], - "X448": [ - { - - crv: "X448", - kty: "OKP", - d: "WMfSmj61GbKdAM-xkbtk_G2KQtjxcXYnK4nyJy0YGSlcZSXAgpZxsFLvBydTDxiOMdDMU78mkp4", - x: "mwj3zDG34+Z9ItWuoSEHSic70rg94Jxj+qc9LCLF2bvINmRyQdlT1AxbEtqIEg1TF3+A5TLEH6A", - }, - ], -} - -// The 'kty' field doesn't match the key algorithm. -var mismatchedKtyField = { - "Ed25519": "EC", - "X25519": "EC", - "Ed448": "EC", - "X448": "EC", -} - -// The 'kty' field doesn't match the key algorithm. -var mismatchedCrvField = { +var mismatchedCurves = { "Ed25519": "X25519", "X25519": "Ed25519", "Ed448": "X448", - "X448": "Ed448", -} + "X448": "Ed448" +}; diff --git a/WebCryptoAPI/import_export/okp_importKey_fixtures.js b/WebCryptoAPI/import_export/okp_importKey_fixtures.js index 58b41d52601eb9..5fe0f05c42b42f 100644 --- a/WebCryptoAPI/import_export/okp_importKey_fixtures.js +++ b/WebCryptoAPI/import_export/okp_importKey_fixtures.js @@ -1,58 +1 @@ -var keyData = { - "Ed25519": { - privateUsages: ["sign"], - publicUsages: ["verify"], - spki: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0, 216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61, 204]), - raw: new Uint8Array([216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61, 204]), - pkcs8: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 243, 200, 244, 196, 141, 248, 120, 20, 110, 140, 211, 191, 109, 244, 229, 14, 56, 155, 167, 7, 78, 21, 194, 53, 45, 205, 93, 48, 141, 76, 168, 31]), - jwk: { - crv: "Ed25519", - d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", - x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", - kty: "OKP" - } - }, - - "Ed448": { - privateUsages: ["sign"], - publicUsages: ["verify"], - spki: new Uint8Array([48, 67, 48, 5, 6, 3, 43, 101, 113, 3, 58, 0, 171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90, 128]), - raw: new Uint8Array([171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90, 128]), - pkcs8: new Uint8Array([48, 71, 2, 1, 0, 48, 5, 6, 3, 43, 101, 113, 4, 59, 4, 57, 14, 255, 3, 69, 140, 40, 224, 23, 156, 82, 29, 227, 18, 201, 105, 183, 131, 67, 72, 236, 171, 153, 26, 96, 227, 178, 233, 167, 158, 76, 217, 228, 128, 239, 41, 23, 18, 210, 200, 61, 4, 114, 114, 213, 201, 244, 40, 102, 79, 105, 109, 38, 112, 69, 143, 29, 46]), - jwk: { - crv: "Ed448", - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", - kty: "OKP" - } - }, - - "X25519": { - privateUsages: ["deriveKey", "deriveBits"], - publicUsages: [], - spki: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - raw: new Uint8Array([28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - pkcs8: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32, 200, 131, 142, 118, 208, 87, 223, 183, 216, 201, 90, 105, 225, 56, 22, 10, 221, 99, 115, 253, 113, 164, 210, 118, 187, 86, 227, 168, 27, 100, 255, 97]), - jwk: { - crv: "X25519", - d: "yIOOdtBX37fYyVpp4TgWCt1jc_1xpNJ2u1bjqBtk_2E", - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lwY", - kty: "OKP" - } - }, - - "X448": { - privateUsages: ["deriveKey", "deriveBits"], - publicUsages: [], - spki: new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]), - raw: new Uint8Array([182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]), - pkcs8: new Uint8Array([48, 70, 2, 1, 0, 48, 5, 6, 3, 43, 101, 111, 4, 58, 4, 56, 88, 199, 210, 154, 62, 181, 25, 178, 157, 0, 207, 177, 145, 187, 100, 252, 109, 138, 66, 216, 241, 113, 118, 39, 43, 137, 242, 39, 45, 24, 25, 41, 92, 101, 37, 192, 130, 150, 113, 176, 82, 239, 7, 39, 83, 15, 24, 142, 49, 208, 204, 83, 191, 38, 146, 158]), - jwk: { - crv: "X448", - d: "WMfSmj61GbKdAM-xkbtk_G2KQtjxcXYnK4nyJy0YGSlcZSXAgpZxsFLvBydTDxiOMdDMU78mkp4", - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm8", - kty: "OKP" - } - }, - -}; +var keyData = okpKeyData; diff --git a/WebCryptoAPI/sign_verify/ecdsa.https.any.js b/WebCryptoAPI/sign_verify/ecdsa.https.any.js index 3f1e2e5ea9d8a7..2af5e05048e444 100644 --- a/WebCryptoAPI/sign_verify/ecdsa.https.any.js +++ b/WebCryptoAPI/sign_verify/ecdsa.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: sign() and verify() Using ECDSA // META: script=../util/helpers.js // META: script=ecdsa_vectors.js +// META: script=signature.js // META: script=ecdsa.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/ecdsa.js b/WebCryptoAPI/sign_verify/ecdsa.js index cc13b1bd9c3cae..a1a744aaa8244b 100644 --- a/WebCryptoAPI/sign_verify/ecdsa.js +++ b/WebCryptoAPI/sign_verify/ecdsa.js @@ -1,658 +1,71 @@ - function run_test() { - setup({explicit_done: true}); - - var subtle = self.crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; - - // Source file [algorithm_name]_vectors.js provides the getTestVectors method - // for the algorithm that drives these tests. - var testVectors = getTestVectors(); - var invalidTestVectors = getInvalidTestVectors(); - - // Test verification first, because signing tests rely on that working - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - var algorithm = { - hash: vector.hashName, - get name() { - signature[0] = vector.signature[0]; - return vector.algorithmName; - } - }; - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with altered signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature[0] = 255 - signature[0]; - return operation; - }, vector.name + " verification with altered signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature after call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var algorithm = { - get name() { - signature.buffer.transfer(); - return vector.algorithmName; - }, - hash: vector.hashName - }; - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with transferred signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature.buffer.transfer(); - return operation; - }, vector.name + " verification with transferred signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature after call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - var algorithm = { - hash: vector.hashName, - get name() { - plaintext[0] = vector.plaintext[0]; - return vector.algorithmName; - } - }; - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with altered plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext[0] = 255 - plaintext[0]; - return operation; - }, vector.name + " with altered plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failed verification if plaintext is transferred during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var algorithm = { - get name() { - plaintext.buffer.transfer(); - return vector.algorithmName; - }, - hash: vector.hashName - }; - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with transferred plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is transferred after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext.buffer.transfer(); - return operation; - }, vector.name + " with transferred plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to using privateKey to verify. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - return subtle.verify(algorithm, vector.privateKey, vector.signature, vector.plaintext) - .then(function(plaintext) { - assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " using privateKey to verify"); - - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " using privateKey to verify"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to using publicKey to sign. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - return subtle.sign(algorithm, vector.publicKey, vector.plaintext) - .then(function(signature) { - assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " using publicKey to sign"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " using publicKey to sign"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to no "verify" usage. - testVectors.forEach(function(originalVector) { - var vector = Object.assign({}, originalVector); - - var promise = importVectorKeys(vector, [], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - return subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) - .then(function(plaintext) { - assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " no verify usage"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " no verify usage"); - }); - - all_promises.push(promise); - }); - - // Check for successful signing and verification. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - return subtle.sign(algorithm, vector.privateKey, vector.plaintext) - .then(function(signature) { - // Can we verify the signature? - return subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Round trip verification works"); - return signature; - }, function(err) { - assert_unreached("verify error for test " + vector.name + ": '" + err.message + "'"); - }); - }, function(err) { - assert_unreached("sign error for test " + vector.name + ": '" + err.message + "'"); - }); - }, vector.name + " round trip"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested signing or verifying - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " round trip"); - }); - - all_promises.push(promise); - }); - - // Test signing with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - return importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var operation = subtle.sign(algorithm, wrongKey, vector.plaintext) - .then(function(signature) { - assert_unreached("Signing should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " signing with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " signing with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Test verification with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - return importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - var operation = subtle.verify(algorithm, wrongKey, vector.signature, vector.plaintext) - .then(function(signature) { - assert_unreached("Verifying should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verifying with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verifying with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " verifying with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with wrong signature - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to altered signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to altered signature"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with wrong hash - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var hashName = "SHA-1"; - if (vector.hashName === "SHA-1") { - hashName = "SHA-256" + const subtle = self.crypto.subtle; + const normalize = vector => ({...vector, data: vector.plaintext}); + const testVectors = getTestVectors().map(normalize); + const invalidTestVectors = getInvalidTestVectors().map(normalize); + const algorithmIdentifier = vector => ({ + name: vector.algorithmName, + hash: vector.hashName, + }); + const importAlgorithm = vector => ({ + name: vector.algorithmName, + namedCurve: vector.namedCurve, + }); + + runSignatureTests({ + vectors: testVectors, + invalidVectors: invalidTestVectors, + algorithmIdentifier, + importAlgorithm, + dataLabel: "plaintext", + }); + + testVectors.forEach(function(vector) { + promise_test(async function() { + const key = await subtle.importKey( + vector.publicKeyFormat, + vector.publicKeyBuffer, + importAlgorithm(vector), + false, + ["verify"] + ); + const hash = vector.hashName === "SHA-1" ? "SHA-256" : "SHA-1"; + const isVerified = await subtle.verify( + {name: vector.algorithmName, hash}, + key, + vector.signature, + vector.data + ); + assert_false(isVerified, "Signature NOT verified"); + }, vector.name + " verification failure due to wrong hash"); + + promise_test(async function() { + const key = await subtle.importKey( + vector.publicKeyFormat, + vector.publicKeyBuffer, + importAlgorithm(vector), + false, + ["verify"] + ); + const hash = vector.hashName.substring(0, 3) + + vector.hashName.substring(4); + let error; + try { + await subtle.verify( + {name: vector.algorithmName, hash}, + key, + vector.signature, + vector.data + ); + } catch (caught) { + error = caught; } - var algorithm = {name: vector.algorithmName, hash: hashName}; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to wrong hash"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to wrong hash"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with bad hash name - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - // use the wrong name for the hash - var hashName = vector.hashName.substring(0, 3) + vector.hashName.substring(4); - var algorithm = {name: vector.algorithmName, hash: hashName}; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_unreached("Verification should throw an error"); - }, function(err) { - assert_equals(err.name, "NotSupportedError", "Correctly throws NotSupportedError for illegal hash name") - }); - - return operation; - }, vector.name + " verification failure due to bad hash name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to bad hash name"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with short (odd length) signature - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - var signature = vector.signature.slice(1); // Skip the first byte - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to shortened signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to shortened signature"); - }); - - all_promises.push(promise); - }); - - // Test verification fails with wrong plaintext - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to altered plaintext"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to altered plaintext"); - }); - - all_promises.push(promise); + assert_not_equals(error, undefined, "Verification should throw"); + assert_equals( + error.name, + "NotSupportedError", + "Correctly throws NotSupportedError for illegal hash name" + ); + }, vector.name + " verification failure due to bad hash name"); }); - - // Test invalid signatures - invalidTestVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - var algorithm = {name: vector.algorithmName, hash: vector.hashName}; - promise_test(function(test) { - var operation = subtle.verify(algorithm, vector.publicKey, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature unexpectedly verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification"); - }); - - all_promises.push(promise); - }); - - promise_test(function() { - return Promise.all(all_promises) - .then(function() {done();}) - .catch(function() {done();}) - }, "setup"); - - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. - // - // Returns a Promise that yields an updated vector on success. - function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) { - var publicPromise, privatePromise; - - if (vector.publicKey !== null) { - publicPromise = new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithmName, namedCurve: vector.namedCurve}, false, publicKeyUsages) - .then(function(key) { - vector.publicKey = key; - return vector; - }); // Returns a copy of the sourceBuffer it is sent. - } - - if (vector.privateKey !== null) { - privatePromise = new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithmName, namedCurve: vector.namedCurve}, false, privateKeyUsages) - .then(function(key) { - vector.privateKey = key; - return vector; - }); - } - - return Promise.all([publicPromise, privatePromise]); - } - - return; } diff --git a/WebCryptoAPI/sign_verify/eddsa.js b/WebCryptoAPI/sign_verify/eddsa.js index 77961566d9a602..a60ceda96a6c7e 100644 --- a/WebCryptoAPI/sign_verify/eddsa.js +++ b/WebCryptoAPI/sign_verify/eddsa.js @@ -1,337 +1,10 @@ - function run_test(algorithmName) { - var subtle = self.crypto.subtle; // Change to test prefixed implementations - - // Source file [algorithm_name]_vectors.js provides the getTestVectors method - // for the algorithm that drives these tests. - var testVectors = getTestVectors(algorithmName); - - testVectors.forEach(function(vector) { - var algorithm = {name: vector.algorithmName}; - - // Test verification first, because signing tests rely on that working - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Signature verified"); - }, vector.name + " verification"); - - // Test verification with an altered buffer during call - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - isVerified = await subtle.verify({ - get name() { - signature[0] = vector.signature[0]; - return vector.algorithmName; - } - }, key, signature, vector.data); - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Signature verified"); - }, vector.name + " verification with altered signature during call"); - - // Test verification with an altered buffer after call - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var signature = copyBuffer(vector.signature); - [isVerified] = await Promise.all([ - subtle.verify(algorithm, key, signature, vector.data), - signature[0] = 255 - signature[0] - ]); - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Signature verified"); - }, vector.name + " verification with altered signature after call"); - - // Test verification with a transferred buffer during call - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var signature = copyBuffer(vector.signature); - isVerified = await subtle.verify({ - get name() { - signature.buffer.transfer(); - return vector.algorithmName; - } - }, key, signature, vector.data); - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_false(isVerified, "Signature is NOT verified"); - }, vector.name + " verification with transferred signature during call"); - - // Test verification with a transferred buffer after call - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var signature = copyBuffer(vector.signature); - var operation = subtle.verify(algorithm, key, signature, vector.data); - signature.buffer.transfer(); - isVerified = await operation; - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Signature verified"); - }, vector.name + " verification with transferred signature after call"); - - // Check for successful verification even if data is altered during call. - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var data = copyBuffer(vector.data); - data[0] = 255 - data[0]; - isVerified = await subtle.verify({ - get name() { - data[0] = vector.data[0]; - return vector.algorithmName; - } - }, key, vector.signature, data); - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Signature verified"); - }, vector.name + " with altered data during call"); - - // Check for successful verification even if data is altered after call. - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var data = copyBuffer(vector.data); - [isVerified] = await Promise.all([ - subtle.verify(algorithm, key, vector.signature, data), - data[0] = 255 - data[0] - ]); - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Signature verified"); - }, vector.name + " with altered data after call"); - - // Check for failed verification if data is transferred during call. - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var data = copyBuffer(vector.data); - isVerified = await subtle.verify({ - get name() { - data.buffer.transfer(); - return vector.algorithmName; - } - }, key, vector.signature, data); - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_false(isVerified, "Signature is NOT verified"); - }, vector.name + " with transferred data during call"); - - // Check for successful verification even if data is transferred after call. - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - var data = copyBuffer(vector.data); - var operation = subtle.verify(algorithm, key, vector.signature, data); - data.buffer.transfer(); - isVerified = await operation; - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Signature verified"); - }, vector.name + " with transferred data after call"); - - // Check for failures due to using privateKey to verify. - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]); - isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) - assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name); - } catch (err) { - if (err instanceof AssertionError) - throw err; - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }; - assert_false(isVerified, "Signature verified"); - }, vector.name + " using privateKey to verify"); - - // Check for failures due to using publicKey to sign. - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - let signature = await subtle.sign(algorithm, key, vector.data); - assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name); - } catch (err) { - if (err instanceof AssertionError) - throw err; - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }; - }, vector.name + " using publicKey to sign"); - - // Check for failures due to no "verify" usage. - promise_test(async() => { - let isVerified = false; - let key; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, []); - isVerified = await subtle.verify(algorithm, key, vector.signature, vector.data) - assert_unreached("Should have thrown error for no verify usage in " + vector.name); - } catch (err) { - if (err instanceof AssertionError) - throw err; - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }; - assert_false(isVerified, "Signature verified"); - }, vector.name + " no verify usage"); - - // Check for successful signing and verification. - var algorithm = {name: vector.algorithmName}; - promise_test(async() => { - let isVerified = false; - let privateKey, publicKey; - let signature; - try { - privateKey = await subtle.importKey("pkcs8", vector.privateKeyBuffer, algorithm, false, ["sign"]); - publicKey = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - signature = await subtle.sign(algorithm, privateKey, vector.data); - isVerified = await subtle.verify(algorithm, publicKey, vector.signature, vector.data) - } catch (err) { - assert_false(publicKey === undefined || privateKey === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_false(signature === undefined, "sign error for test " + vector.name + ": '" + err.message + "'"); - assert_unreached("verify error for test " + vector.name + ": '" + err.message + "'"); - }; - assert_true(isVerified, "Round trip verification works"); - }, vector.name + " round trip"); - - // Test signing with the wrong algorithm - var algorithm = {name: vector.algorithmName}; - promise_test(async() => { - let wrongKey; - try { - wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) - let signature = await subtle.sign(algorithm, wrongKey, vector.data); - assert_unreached("Signing should not have succeeded for " + vector.name); - } catch (err) { - if (err instanceof AssertionError) - throw err; - assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }; - }, vector.name + " signing with wrong algorithm name"); - - // Test verification with the wrong algorithm - var algorithm = {name: vector.algorithmName}; - promise_test(async() => { - let wrongKey; - try { - wrongKey = await subtle.generateKey({name: "HMAC", hash: "SHA-1"}, false, ["sign", "verify"]) - let isVerified = await subtle.verify(algorithm, wrongKey, vector.signature, vector.data) - assert_unreached("Verifying should not have succeeded for " + vector.name); - } catch (err) { - if (err instanceof AssertionError) - throw err; - assert_false(wrongKey === undefined, "Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }; - }, vector.name + " verifying with wrong algorithm name"); - - // Test verification fails with wrong signature - var algorithm = {name: vector.algorithmName}; - promise_test(async() => { - let key; - let isVerified = true; - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - isVerified = await subtle.verify(algorithm, key, signature, vector.data) - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_false(isVerified, "Signature verified"); - }, vector.name + " verification failure due to altered signature"); - - // Test verification fails with short (odd length) signature - promise_test(async() => { - let key; - let isVerified = true; - var signature = vector.signature.slice(1); // Skip the first byte - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - isVerified = await subtle.verify(algorithm, key, signature, vector.data) - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_false(isVerified, "Signature verified"); - }, vector.name + " verification failure due to shortened signature"); - - // Test verification fails with wrong data - promise_test(async() => { - let key; - let isVerified = true; - var data = copyBuffer(vector.data); - data[0] = 255 - data[0]; - try { - key = await subtle.importKey("spki", vector.publicKeyBuffer, algorithm, false, ["verify"]); - isVerified = await subtle.verify(algorithm, key, vector.signature, data) - } catch (err) { - assert_false(key === undefined, "importKey failed for " + vector.name + ". Message: ''" + err.message + "''"); - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }; - assert_false(isVerified, "Signature verified"); - }, vector.name + " verification failure due to altered data"); - - // Test that generated keys are valid for signing and verifying. - promise_test(async() => { - let key = await subtle.generateKey(algorithm, false, ["sign", "verify"]); - let signature = await subtle.sign(algorithm, key.privateKey, vector.data); - let isVerified = await subtle.verify(algorithm, key.publicKey, signature, vector.data); - assert_true(isVerified, "Verificaton failed."); - }, "Sign and verify using generated " + vector.algorithmName + " keys."); + runSignatureTests({ + vectors: getTestVectors(algorithmName), + algorithmIdentifier(vector) { + return {name: vector.algorithmName}; + }, + katFirst: true, + generatedKeys: true, }); - - return; } diff --git a/WebCryptoAPI/sign_verify/eddsa_curve25519.https.any.js b/WebCryptoAPI/sign_verify/eddsa_curve25519.https.any.js index b012b64733ef9d..a4f32cbaeb7eb2 100644 --- a/WebCryptoAPI/sign_verify/eddsa_curve25519.https.any.js +++ b/WebCryptoAPI/sign_verify/eddsa_curve25519.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: sign() and verify() Using EdDSA // META: script=../util/helpers.js // META: script=eddsa_vectors.js +// META: script=signature.js // META: script=eddsa.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/eddsa_curve448.tentative.https.any.js b/WebCryptoAPI/sign_verify/eddsa_curve448.tentative.https.any.js index 281bb63ad659f7..8dd43dfeb17278 100644 --- a/WebCryptoAPI/sign_verify/eddsa_curve448.tentative.https.any.js +++ b/WebCryptoAPI/sign_verify/eddsa_curve448.tentative.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: sign() and verify() Using EdDSA // META: script=../util/helpers.js // META: script=eddsa_vectors.js +// META: script=signature.js // META: script=eddsa.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/hmac.https.any.js b/WebCryptoAPI/sign_verify/hmac.https.any.js index a6c88f80ed99ee..070611181e5827 100644 --- a/WebCryptoAPI/sign_verify/hmac.https.any.js +++ b/WebCryptoAPI/sign_verify/hmac.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: sign() and verify() Using HMAC // META: script=../util/helpers.js // META: script=hmac_vectors.js +// META: script=mac.js // META: script=hmac.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/hmac.js b/WebCryptoAPI/sign_verify/hmac.js index 929d9464e171cb..05b9cedfb94ca4 100644 --- a/WebCryptoAPI/sign_verify/hmac.js +++ b/WebCryptoAPI/sign_verify/hmac.js @@ -1,494 +1,11 @@ - function run_test() { - setup({explicit_done: true}); - - var subtle = self.crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; - - // Source file hmac_vectors.js provides the getTestVectors method - // for the algorithm that drives these tests. - var testVectors = getTestVectors(); - - // Test verification first, because signing tests rely on that working - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - var operation = subtle.verify({ - get name() { - signature[0] = vector.signature[0]; - return "HMAC"; - }, - hash: vector.hash - }, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature is not verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with altered signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature is not verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature[0] = 255 - signature[0]; - return operation; - }, vector.name + " verification with altered signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature after call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify({ - get name() { - signature.buffer.transfer(); - return "HMAC"; - }, - hash: vector.hash - }, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with transferred signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature is not verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature.buffer.transfer(); - return operation; - }, vector.name + " verification with transferred signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature after call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - var operation = subtle.verify({ - hash: vector.hash, - get name() { - plaintext[0] = vector.plaintext[0]; - return "HMAC"; - } - }, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with altered plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext[0] = 255 - plaintext[0]; - return operation; - }, vector.name + " with altered plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failed verification if plaintext is transferred during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify({ - get name() { - plaintext.buffer.transfer(); - return "HMAC"; - }, - hash: vector.hash - }, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with transferred plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is transferred after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext.buffer.transfer(); - return operation; - }, vector.name + " with transferred plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to no "verify" usage. - testVectors.forEach(function(originalVector) { - var vector = Object.assign({}, originalVector); - - var promise = importVectorKeys(vector, ["sign"]) - .then(function(vector) { - promise_test(function(test) { - return subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, vector.plaintext) - .then(function(plaintext) { - assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " no verify usage"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " no verify usage"); - }); - - all_promises.push(promise); - }); - - // Check for successful signing and verification. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vectors) { - promise_test(function(test) { - return subtle.sign({name: "HMAC", hash: vector.hash}, vector.key, vector.plaintext) - .then(function(signature) { - assert_true(equalBuffers(signature, vector.signature), "Signing did not give the expected output"); - // Can we get the verify the new signature? - return subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Round trip verifies"); - return signature; - }, function(err) { - assert_unreached("verify error for test " + vector.name + ": '" + err.message + "'"); - }); - }); - }, vector.name + " round trip"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested signing or verifying - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " round trip"); - }); - - all_promises.push(promise); - }); - - // Test signing with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - return importVectorKeys(vector, ["verify", "sign"]) - .then(function(vectors) { - promise_test(function(test) { - var operation = subtle.sign({name: "HMAC", hash: vector.hash}, wrongKey.privateKey, vector.plaintext) - .then(function(signature) { - assert_unreached("Signing should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " signing with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " signing with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Test verification with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - return importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, wrongKey.publicKey, vector.signature, vector.plaintext) - .then(function(signature) { - assert_unreached("Verifying should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verifying with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verifying with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " verifying with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Verification should fail if the plaintext is changed - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to wrong plaintext"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to wrong plaintext"); - }); - - all_promises.push(promise); - }); - - // Verification should fail if the signature is changed - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to wrong signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to wrong signature"); - }); - - all_promises.push(promise); - }); - - // Verification should fail if the signature is wrong length - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - var signature = vector.signature.slice(1); // Drop first byte - promise_test(function(test) { - var operation = subtle.verify({name: "HMAC", hash: vector.hash}, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to short signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to short signature"); - }); - - all_promises.push(promise); - }); - - - - promise_test(function() { - return Promise.all(all_promises) - .then(function() {done();}) - .catch(function() {done();}) - }, "setup"); - - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. - // - // Returns a Promise that yields an updated vector on success. - function importVectorKeys(vector, keyUsages) { - if (vector.key !== null) { - return new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - return subtle.importKey("raw", vector.keyBuffer, {name: "HMAC", hash: vector.hash}, false, keyUsages) - .then(function(key) { - vector.key = key; - return vector; - }); + runMacTests({ + importFormat: "raw", + importAlgorithm: function(vector) { + return {name: "HMAC", hash: vector.hash}; + }, + operationAlgorithm: function(vector) { + return {name: "HMAC", hash: vector.hash}; } - } - - return; + }); } diff --git a/WebCryptoAPI/sign_verify/kmac.js b/WebCryptoAPI/sign_verify/kmac.js index d9d82d150b3933..ac30a5559d8c00 100644 --- a/WebCryptoAPI/sign_verify/kmac.js +++ b/WebCryptoAPI/sign_verify/kmac.js @@ -1,586 +1,25 @@ function run_test() { - setup({explicit_done: true}); - - var subtle = self.crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; - - // Source file kmac_vectors.js provides the getTestVectors method - // for the algorithm that drives these tests. - var testVectors = getTestVectors(); - - // Test verification first, because signing tests rely on that working - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - var algorithmParams = { - outputLength: vector.outputLength, - get name() { - signature[0] = vector.signature[0]; - return vector.algorithm; - } - }; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature is not verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with altered signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature is not verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature[0] = 255 - signature[0]; - return operation; - }, vector.name + " verification with altered signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature after call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var algorithmParams = { - get name() { - signature.buffer.transfer(); - return vector.algorithm; - }, - outputLength: vector.outputLength - }; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with transferred signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature is not verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature.buffer.transfer(); - return operation; - }, vector.name + " verification with transferred signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature after call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - var algorithmParams = { - outputLength: vector.outputLength, - get name() { - plaintext[0] = vector.plaintext[0]; - return vector.algorithm; - } - }; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with altered plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext[0] = 255 - plaintext[0]; - return operation; - }, vector.name + " with altered plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failed verification if plaintext is transferred during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var algorithmParams = { - get name() { - plaintext.buffer.transfer(); - return vector.algorithm; - }, - outputLength: vector.outputLength - }; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with transferred plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is transferred after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext.buffer.transfer(); - return operation; - }, vector.name + " with transferred plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to no "verify" usage. - testVectors.forEach(function(originalVector) { - var vector = Object.assign({}, originalVector); - - var promise = importVectorKeys(vector, ["sign"]) - .then(function(vector) { - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - return subtle.verify(algorithmParams, vector.key, vector.signature, vector.plaintext) - .then(function(plaintext) { - assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " no verify usage"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " no verify usage"); - }); - - all_promises.push(promise); - }); - - // Check for successful signing and verification. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vectors) { - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - return subtle.sign(algorithmParams, vector.key, vector.plaintext) - .then(function(signature) { - assert_true(equalBuffers(signature, vector.signature), "Signing did not give the expected output"); - // Can we get the verify the new signature? - return subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Round trip verifies"); - return signature; - }, function(err) { - assert_unreached("verify error for test " + vector.name + ": '" + err.message + "'"); - }); - }); - }, vector.name + " round trip"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested signing or verifying - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " round trip"); - }); - - all_promises.push(promise); - }); - - // Test signing with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - return importVectorKeys(vector, ["verify", "sign"]) - .then(function(vectors) { - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.sign(algorithmParams, wrongKey.privateKey, vector.plaintext) - .then(function(signature) { - assert_unreached("Signing should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " signing with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " signing with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Test verification with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var promise = subtle.generateKey({name: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"]) - .then(function(wrongKey) { - return importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, wrongKey.publicKey, vector.signature, vector.plaintext) - .then(function(signature) { - assert_unreached("Verifying should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verifying with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verifying with wrong algorithm name"); - }); - }, function(err) { - promise_test(function(test) { - assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); - }, "generate wrong key step: " + vector.name + " verifying with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Verification should fail if the plaintext is changed - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to wrong plaintext"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to wrong plaintext"); - }); - - all_promises.push(promise); - }); - - // Verification should fail if the signature is changed - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to wrong signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to wrong signature"); - }); - - all_promises.push(promise); - }); - - // Verification should fail if the signature is wrong length - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - var signature = vector.signature.slice(1); // Drop first byte - promise_test(function(test) { - var algorithmParams = {name: vector.algorithm, outputLength: vector.outputLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to short signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to short signature"); - }); - - all_promises.push(promise); - }); - - // Test verification failure due to wrong length parameter - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify", "sign"]) - .then(function(vector) { - promise_test(function(test) { - var differentLength = vector.outputLength === 256 ? 512 : 256; - var algorithmParams = {name: vector.algorithm, outputLength: differentLength}; - if (vector.customization !== undefined) { - algorithmParams.customization = vector.customization; - } - var operation = subtle.verify(algorithmParams, vector.key, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified with wrong length"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure due to wrong length parameter"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure due to wrong length parameter"); - }); - - all_promises.push(promise); - }); - - promise_test(function() { - return Promise.all(all_promises) - .then(function() {done();}) - .catch(function() {done();}) - }, "setup"); - - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. - // - // Returns a Promise that yields an updated vector on success. - function importVectorKeys(vector, keyUsages) { - if (vector.key !== null) { - return new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - return subtle.importKey("raw-secret", vector.keyBuffer, {name: vector.algorithm}, false, keyUsages) - .then(function(key) { - vector.key = key; - return vector; - }); + function operationAlgorithm(vector) { + var algorithm = { + name: vector.algorithm, + outputLength: vector.outputLength + }; + if (vector.customization !== undefined) { + algorithm.customization = vector.customization; } + return algorithm; } - return; + runMacTests({ + importFormat: "raw-secret", + importAlgorithm: function(vector) { + return {name: vector.algorithm}; + }, + operationAlgorithm: operationAlgorithm, + wrongVerificationAlgorithm: function(vector) { + var algorithm = operationAlgorithm(vector); + algorithm.outputLength = vector.outputLength === 256 ? 512 : 256; + return algorithm; + } + }); } diff --git a/WebCryptoAPI/sign_verify/kmac.tentative.https.any.js b/WebCryptoAPI/sign_verify/kmac.tentative.https.any.js index 3d34c5752137a8..0a57ba7a3f8054 100644 --- a/WebCryptoAPI/sign_verify/kmac.tentative.https.any.js +++ b/WebCryptoAPI/sign_verify/kmac.tentative.https.any.js @@ -1,6 +1,7 @@ // META: title=WebCryptoAPI: sign() and verify() Using KMAC // META: script=../util/helpers.js // META: script=kmac_vectors.js +// META: script=mac.js // META: script=kmac.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/mac.js b/WebCryptoAPI/sign_verify/mac.js new file mode 100644 index 00000000000000..27787c91d8a2b5 --- /dev/null +++ b/WebCryptoAPI/sign_verify/mac.js @@ -0,0 +1,514 @@ + +function runMacTests(options) { + setup({explicit_done: true}); + + var subtle = self.crypto.subtle; // Change to test prefixed implementations + + // When are all these tests really done? When all the promises they use have resolved. + var all_promises = []; + + // The algorithm-specific vector source provides getTestVectors(). + var testVectors = getTestVectors(); + + function operationAlgorithm(vector, nameGetter) { + var algorithm = options.operationAlgorithm(vector); + if (nameGetter !== undefined) { + Object.defineProperty(algorithm, "name", { + enumerable: true, + get: nameGetter + }); + } + return algorithm; + } + + // Test verification first, because signing tests rely on that working + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var operation = subtle.verify(operationAlgorithm(vector), vector.key, vector.signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification"); + }); + + all_promises.push(promise); + }); + + // Test verification with an altered buffer during call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + var operation = subtle.verify(operationAlgorithm(vector, function() { + signature[0] = vector.signature[0]; + return options.operationAlgorithm(vector).name; + }), vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature is not verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification with altered signature during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); + }); + + all_promises.push(promise); + }); + + // Test verification with an altered buffer after call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + var operation = subtle.verify(operationAlgorithm(vector), vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature is not verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + signature[0] = 255 - signature[0]; + return operation; + }, vector.name + " verification with altered signature after call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with altered signature after call"); + }); + + all_promises.push(promise); + }); + + // Test verification with a transferred buffer during call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + var operation = subtle.verify(operationAlgorithm(vector, function() { + signature.buffer.transfer(); + return options.operationAlgorithm(vector).name; + }), vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature is NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification with transferred signature during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with transferred signature during call"); + }); + + all_promises.push(promise); + }); + + // Test verification with a transferred buffer after call + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var signature = copyBuffer(vector.signature); + var operation = subtle.verify(operationAlgorithm(vector), vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature is not verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + signature.buffer.transfer(); + return operation; + }, vector.name + " verification with transferred signature after call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification with transferred signature after call"); + }); + + all_promises.push(promise); + }); + + // Check for successful verification even if plaintext is altered during call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + var operation = subtle.verify(operationAlgorithm(vector, function() { + plaintext[0] = vector.plaintext[0]; + return options.operationAlgorithm(vector).name; + }), vector.key, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " with altered plaintext during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); + }); + + all_promises.push(promise); + }); + + // Check for successful verification even if plaintext is altered after call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + var operation = subtle.verify(operationAlgorithm(vector), vector.key, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + plaintext[0] = 255 - plaintext[0]; + return operation; + }, vector.name + " with altered plaintext after call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); + }); + + all_promises.push(promise); + }); + + // Check for failed verification if plaintext is transferred during call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + var operation = subtle.verify(operationAlgorithm(vector, function() { + plaintext.buffer.transfer(); + return options.operationAlgorithm(vector).name; + }), vector.key, vector.signature, plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature is NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " with transferred plaintext during call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with transferred plaintext during call"); + }); + + all_promises.push(promise); + }); + + // Check for successful verification even if plaintext is transferred after call. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var plaintext = copyBuffer(vector.plaintext); + var operation = subtle.verify(operationAlgorithm(vector), vector.key, vector.signature, plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Signature verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + plaintext.buffer.transfer(); + return operation; + }, vector.name + " with transferred plaintext after call"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " with transferred plaintext after call"); + }); + + all_promises.push(promise); + }); + + // Check for failures due to no "verify" usage. + testVectors.forEach(function(originalVector) { + var vector = Object.assign({}, originalVector); + + var promise = importVectorKeys(vector, ["sign"]) + .then(function(vector) { + promise_test(function(test) { + return subtle.verify(operationAlgorithm(vector), vector.key, vector.signature, vector.plaintext) + .then(function(plaintext) { + assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": '" + err.message + "'"); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); + }); + }, vector.name + " no verify usage"); + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " no verify usage"); + }); + + all_promises.push(promise); + }); + + // Check for successful signing and verification. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vectors) { + promise_test(function(test) { + return subtle.sign(operationAlgorithm(vector), vector.key, vector.plaintext) + .then(function(signature) { + assert_true(equalBuffers(signature, vector.signature), "Signing did not give the expected output"); + // Can we get the verify the new signature? + return subtle.verify(operationAlgorithm(vector), vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_true(is_verified, "Round trip verifies"); + return signature; + }, function(err) { + assert_unreached("verify error for test " + vector.name + ": '" + err.message + "'"); + }); + }); + }, vector.name + " round trip"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested signing or verifying + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " round trip"); + }); + + all_promises.push(promise); + }); + + // Test signing with the wrong algorithm + testVectors.forEach(function(vector) { + // Want to get the key for the wrong algorithm + var promise = subtle.generateKey({name: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"]) + .then(function(wrongKey) { + return importVectorKeys(vector, ["verify", "sign"]) + .then(function(vectors) { + promise_test(function(test) { + var operation = subtle.sign(operationAlgorithm(vector), wrongKey.privateKey, vector.plaintext) + .then(function(signature) { + assert_unreached("Signing should not have succeeded for " + vector.name); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }); + + return operation; + }, vector.name + " signing with wrong algorithm name"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); + }); + }, function(err) { + promise_test(function(test) { + assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); + }, "generate wrong key step: " + vector.name + " signing with wrong algorithm name"); + }); + + all_promises.push(promise); + }); + + // Test verification with the wrong algorithm + testVectors.forEach(function(vector) { + // Want to get the key for the wrong algorithm + var promise = subtle.generateKey({name: "ECDSA", namedCurve: "P-256", hash: "SHA-256"}, false, ["sign", "verify"]) + .then(function(wrongKey) { + return importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var operation = subtle.verify(operationAlgorithm(vector), wrongKey.publicKey, vector.signature, vector.plaintext) + .then(function(signature) { + assert_unreached("Verifying should not have succeeded for " + vector.name); + }, function(err) { + assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verifying with wrong algorithm name"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verifying with wrong algorithm name"); + }); + }, function(err) { + promise_test(function(test) { + assert_unreached("Generate wrong key for test " + vector.name + " failed: '" + err.message + "'"); + }, "generate wrong key step: " + vector.name + " verifying with wrong algorithm name"); + }); + + all_promises.push(promise); + }); + + // Verification should fail if the plaintext is changed + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + var plaintext = copyBuffer(vector.plaintext); + plaintext[0] = 255 - plaintext[0]; + promise_test(function(test) { + var operation = subtle.verify(operationAlgorithm(vector), vector.key, vector.signature, plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature is NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to wrong plaintext"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to wrong plaintext"); + }); + + all_promises.push(promise); + }); + + // Verification should fail if the signature is changed + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + promise_test(function(test) { + var operation = subtle.verify(operationAlgorithm(vector), vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature is NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to wrong signature"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to wrong signature"); + }); + + all_promises.push(promise); + }); + + // Verification should fail if the signature is wrong length + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + var signature = vector.signature.slice(1); // Drop first byte + promise_test(function(test) { + var operation = subtle.verify(operationAlgorithm(vector), vector.key, signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature is NOT verified"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to short signature"); + + }, function(err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to short signature"); + }); + + all_promises.push(promise); + }); + + if (options.wrongVerificationAlgorithm !== undefined) { + // Test verification failure due to algorithm-specific parameters. + testVectors.forEach(function(vector) { + var promise = importVectorKeys(vector, ["verify", "sign"]) + .then(function(vector) { + promise_test(function(test) { + var operation = subtle.verify(options.wrongVerificationAlgorithm(vector), vector.key, vector.signature, vector.plaintext) + .then(function(is_verified) { + assert_false(is_verified, "Signature is NOT verified with wrong length"); + }, function(err) { + assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); + }); + + return operation; + }, vector.name + " verification failure due to wrong length parameter"); + + }, function(err) { + promise_test(function(test) { + assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); + }, "importVectorKeys step: " + vector.name + " verification failure due to wrong length parameter"); + }); + + all_promises.push(promise); + }); + } + + + + promise_test(function() { + return Promise.all(all_promises).finally(done); + }, "setup"); + + // A test vector has all needed fields for signing and verifying, EXCEPT that the + // key field may be null. This function replaces that null with the Correct + // CryptoKey object. + // + // Returns a Promise that yields an updated vector on success. + function importVectorKeys(vector, keyUsages) { + if (vector.key !== null) { + return Promise.resolve(vector); + } else { + return subtle.importKey(options.importFormat, vector.keyBuffer, options.importAlgorithm(vector), false, keyUsages) + .then(function(key) { + vector.key = key; + return vector; + }); + } + } + + return; +} diff --git a/WebCryptoAPI/sign_verify/mldsa.js b/WebCryptoAPI/sign_verify/mldsa.js index 10879273c1c3f4..a2a4ef276043c4 100644 --- a/WebCryptoAPI/sign_verify/mldsa.js +++ b/WebCryptoAPI/sign_verify/mldsa.js @@ -1,1038 +1,10 @@ function run_test() { - setup({ explicit_done: true }); - - var subtle = self.crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; - - // Source file [algorithm_name]_vectors.js provides the getTestVectors method - // for the algorithm that drives these tests. - var testVectors = getTestVectors(); - var invalidTestVectors = getInvalidTestVectors(); - - // Test verification first, because signing tests rely on that working - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - var operation = subtle - .verify(algorithm, vector.publicKey, vector.signature, vector.data) - .then( - function (is_verified) { - assert_true(is_verified, 'Signature verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verification'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + vector.name + ' verification'); - } - ); - - all_promises.push(promise); + runSignatureTests({ + vectors: getTestVectors(), + invalidVectors: getInvalidTestVectors(), + algorithmIdentifier(vector) { + return vector.algorithmName; + }, + dataLabel: 'plaintext', }); - - // Test verification with an altered buffer during call - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - promise_test(function (test) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - var operation = subtle - .verify( - { - get name() { - signature[0] = vector.signature[0]; - return vector.algorithmName; - }, - }, - vector.publicKey, - signature, - vector.data - ) - .then( - function (is_verified) { - assert_true(is_verified, 'Signature verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verification with altered signature during call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verification with altered signature during call'); - } - ); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer after call - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - var signature = copyBuffer(vector.signature); - var operation = subtle - .verify(algorithm, vector.publicKey, signature, vector.data) - .then( - function (is_verified) { - assert_true(is_verified, 'Signature verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - signature[0] = 255 - signature[0]; - return operation; - }, vector.name + ' verification with altered signature after call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verification with altered signature after call'); - } - ); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer during call - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - promise_test(function (test) { - var signature = copyBuffer(vector.signature); - var operation = subtle - .verify( - { - get name() { - signature.buffer.transfer(); - return vector.algorithmName; - }, - }, - vector.publicKey, - signature, - vector.data - ) - .then( - function (is_verified) { - assert_false(is_verified, 'Signature is NOT verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verification with transferred signature during call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verification with transferred signature during call'); - } - ); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer after call - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - var signature = copyBuffer(vector.signature); - var operation = subtle - .verify(algorithm, vector.publicKey, signature, vector.data) - .then( - function (is_verified) { - assert_true(is_verified, 'Signature verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - signature.buffer.transfer(); - return operation; - }, vector.name + ' verification with transferred signature after call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verification with transferred signature after call'); - } - ); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered during call. - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - promise_test(function (test) { - var plaintext = copyBuffer(vector.data); - plaintext[0] = 255 - plaintext[0]; - var operation = subtle - .verify( - { - get name() { - plaintext[0] = vector.data[0]; - return vector.algorithmName; - }, - }, - vector.publicKey, - vector.signature, - plaintext - ) - .then( - function (is_verified) { - assert_true(is_verified, 'Signature verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' with altered plaintext during call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' with altered plaintext during call'); - } - ); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered after call. - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - var plaintext = copyBuffer(vector.data); - var operation = subtle - .verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then( - function (is_verified) { - assert_true(is_verified, 'Signature verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - plaintext[0] = 255 - plaintext[0]; - return operation; - }, vector.name + ' with altered plaintext after call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' with altered plaintext after call'); - } - ); - - all_promises.push(promise); - }); - - // Check for failed verification if plaintext is transferred during call. - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - promise_test(function (test) { - var plaintext = copyBuffer(vector.data); - var operation = subtle - .verify( - { - get name() { - plaintext.buffer.transfer(); - return vector.algorithmName; - }, - }, - vector.publicKey, - vector.signature, - plaintext - ) - .then( - function (is_verified) { - assert_false(is_verified, 'Signature is NOT verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' with transferred plaintext during call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' with transferred plaintext during call'); - } - ); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is transferred after call. - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - var plaintext = copyBuffer(vector.data); - var operation = subtle - .verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then( - function (is_verified) { - assert_true(is_verified, 'Signature verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - plaintext.buffer.transfer(); - return operation; - }, vector.name + ' with transferred plaintext after call'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' with transferred plaintext after call'); - } - ); - - all_promises.push(promise); - }); - - // Check for failures due to using privateKey to verify. - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - return subtle - .verify(algorithm, vector.privateKey, vector.signature, vector.data) - .then( - function (plaintext) { - assert_unreached( - 'Should have thrown error for using privateKey to verify in ' + - vector.name + - ': ' + - err.message + - "'" - ); - }, - function (err) { - assert_equals( - err.name, - 'InvalidAccessError', - "Should throw InvalidAccessError instead of '" + - err.message + - "'" - ); - } - ); - }, vector.name + ' using privateKey to verify'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' using privateKey to verify'); - } - ); - - all_promises.push(promise); - }); - - // Check for failures due to using publicKey to sign. - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - return subtle.sign(algorithm, vector.publicKey, vector.data).then( - function (signature) { - assert_unreached( - 'Should have thrown error for using publicKey to sign in ' + - vector.name + - ': ' + - err.message + - "'" - ); - }, - function (err) { - assert_equals( - err.name, - 'InvalidAccessError', - "Should throw InvalidAccessError instead of '" + - err.message + - "'" - ); - } - ); - }, vector.name + ' using publicKey to sign'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' using publicKey to sign'); - } - ); - - all_promises.push(promise); - }); - - // Check for failures due to no "verify" usage. - testVectors.forEach(function (originalVector) { - var vector = Object.assign({}, originalVector); - - var promise = importVectorKeys(vector, [], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - return subtle - .verify(algorithm, vector.publicKey, vector.signature, vector.data) - .then( - function (plaintext) { - assert_unreached( - 'Should have thrown error for no verify usage in ' + - vector.name + - ': ' + - err.message + - "'" - ); - }, - function (err) { - assert_equals( - err.name, - 'InvalidAccessError', - "Should throw InvalidAccessError instead of '" + - err.message + - "'" - ); - } - ); - }, vector.name + ' no verify usage'); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + vector.name + ' no verify usage'); - } - ); - - all_promises.push(promise); - }); - - // Check for successful signing and verification. - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - return subtle.sign(algorithm, vector.privateKey, vector.data).then( - function (signature) { - // Can we verify the signature? - return subtle - .verify(algorithm, vector.publicKey, signature, vector.data) - .then( - function (is_verified) { - assert_true(is_verified, 'Round trip verification works'); - return signature; - }, - function (err) { - assert_unreached( - 'verify error for test ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - }, - function (err) { - assert_unreached( - 'sign error for test ' + vector.name + ": '" + err.message + "'" - ); - } - ); - }, vector.name + ' round trip'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested signing or verifying - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + vector.name + ' round trip'); - } - ); - - all_promises.push(promise); - }); - - // Test signing with the wrong algorithm - testVectors.forEach(function (vector) { - // Want to get the key for the wrong algorithm - var promise = subtle - .generateKey({ name: 'HMAC', hash: 'SHA-1' }, false, ['sign', 'verify']) - .then( - function (wrongKey) { - var algorithm = vector.algorithmName; - return importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - promise_test(function (test) { - var operation = subtle - .sign(algorithm, wrongKey, vector.data) - .then( - function (signature) { - assert_unreached( - 'Signing should not have succeeded for ' + vector.name - ); - }, - function (err) { - assert_equals( - err.name, - 'InvalidAccessError', - "Should have thrown InvalidAccessError instead of '" + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' signing with wrong algorithm name'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' signing with wrong algorithm name'); - } - ); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'Generate wrong key for test ' + - vector.name + - " failed: '" + - err.message + - "'" - ); - }, 'generate wrong key step: ' + - vector.name + - ' signing with wrong algorithm name'); - } - ); - - all_promises.push(promise); - }); - - // Test verification with the wrong algorithm - testVectors.forEach(function (vector) { - // Want to get the key for the wrong algorithm - var promise = subtle - .generateKey({ name: 'HMAC', hash: 'SHA-1' }, false, ['sign', 'verify']) - .then( - function (wrongKey) { - return importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - var operation = subtle - .verify(algorithm, wrongKey, vector.signature, vector.data) - .then( - function (signature) { - assert_unreached( - 'Verifying should not have succeeded for ' + vector.name - ); - }, - function (err) { - assert_equals( - err.name, - 'InvalidAccessError', - "Should have thrown InvalidAccessError instead of '" + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verifying with wrong algorithm name'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verifying with wrong algorithm name'); - } - ); - }, - function (err) { - promise_test(function (test) { - assert_unreached( - 'Generate wrong key for test ' + - vector.name + - " failed: '" + - err.message + - "'" - ); - }, 'generate wrong key step: ' + - vector.name + - ' verifying with wrong algorithm name'); - } - ); - - all_promises.push(promise); - }); - - // Test verification fails with wrong signature - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - promise_test(function (test) { - var operation = subtle - .verify(algorithm, vector.publicKey, signature, vector.data) - .then( - function (is_verified) { - assert_false(is_verified, 'Signature NOT verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verification failure due to altered signature'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verification failure due to altered signature'); - } - ); - - all_promises.push(promise); - }); - - // Test verification fails with short (odd length) signature - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - var signature = vector.signature.slice(1); // Skip the first byte - promise_test(function (test) { - var operation = subtle - .verify(algorithm, vector.publicKey, signature, vector.data) - .then( - function (is_verified) { - assert_false(is_verified, 'Signature NOT verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verification failure due to shortened signature'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verification failure due to shortened signature'); - } - ); - - all_promises.push(promise); - }); - - // Test verification fails with wrong plaintext - testVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - var plaintext = copyBuffer(vector.data); - plaintext[0] = 255 - plaintext[0]; - promise_test(function (test) { - var operation = subtle - .verify(algorithm, vector.publicKey, vector.signature, plaintext) - .then( - function (is_verified) { - assert_false(is_verified, 'Signature NOT verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verification failure due to altered plaintext'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + - vector.name + - ' verification failure due to altered plaintext'); - } - ); - - all_promises.push(promise); - }); - - // Test invalid signatures - invalidTestVectors.forEach(function (vector) { - var promise = importVectorKeys(vector, ['verify'], ['sign']).then( - function (vectors) { - var algorithm = vector.algorithmName; - promise_test(function (test) { - var operation = subtle - .verify(algorithm, vector.publicKey, vector.signature, vector.data) - .then( - function (is_verified) { - assert_false(is_verified, 'Signature unexpectedly verified'); - }, - function (err) { - assert_unreached( - 'Verification should not throw error ' + - vector.name + - ': ' + - err.message + - "'" - ); - } - ); - - return operation; - }, vector.name + ' verification'); - }, - function (err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function (test) { - assert_unreached( - 'importVectorKeys failed for ' + - vector.name + - ". Message: ''" + - err.message + - "''" - ); - }, 'importVectorKeys step: ' + vector.name + ' verification'); - } - ); - - all_promises.push(promise); - }); - - promise_test(function () { - return Promise.all(all_promises) - .then(function () { - done(); - }) - .catch(function () { - done(); - }); - }, 'setup'); - - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. - // - // Returns a Promise that yields an updated vector on success. - function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) { - var publicPromise, privatePromise; - - if (vector.publicKey !== null) { - publicPromise = new Promise(function (resolve, reject) { - resolve(vector); - }); - } else { - publicPromise = subtle - .importKey( - vector.publicKeyFormat, - vector.publicKeyBuffer, - { name: vector.algorithmName }, - false, - publicKeyUsages - ) - .then(function (key) { - vector.publicKey = key; - return vector; - }); // Returns a copy of the sourceBuffer it is sent. - } - - if (vector.privateKey !== null) { - privatePromise = new Promise(function (resolve, reject) { - resolve(vector); - }); - } else { - privatePromise = subtle - .importKey( - vector.privateKeyFormat, - vector.privateKeyBuffer, - { name: vector.algorithmName }, - false, - privateKeyUsages - ) - .then(function (key) { - vector.privateKey = key; - return vector; - }); - } - - return Promise.all([publicPromise, privatePromise]); - } - - return; } diff --git a/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js b/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js index be336b3498462c..253cc85e258f67 100644 --- a/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js +++ b/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js @@ -1,6 +1,8 @@ // META: title=WebCryptoAPI: sign() and verify() Using ML-DSA // META: script=../util/helpers.js +// META: script=../util/mldsa_key_fixtures.js // META: script=mldsa_vectors.js +// META: script=signature.js // META: script=mldsa.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/mldsa_vectors.js b/WebCryptoAPI/sign_verify/mldsa_vectors.js index a035821b7e3593..021060a1f35bfe 100644 --- a/WebCryptoAPI/sign_verify/mldsa_vectors.js +++ b/WebCryptoAPI/sign_verify/mldsa_vectors.js @@ -1,393 +1,4 @@ -// PKCS#8 private keys for ML-DSA variants -var pkcs8 = { - 'ML-DSA-44': new Uint8Array([ - 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 4, 34, 128, - 32, 153, 21, 95, 99, 48, 150, 218, 124, 190, 8, 122, 137, 72, 184, 79, 118, - 123, 16, 249, 1, 200, 35, 194, 64, 177, 221, 43, 200, 112, 5, 201, 62, - ]), - 'ML-DSA-65': new Uint8Array([ - 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 4, 34, 128, - 32, 132, 164, 137, 75, 123, 70, 164, 178, 3, 156, 206, 16, 195, 26, 133, - 186, 176, 195, 102, 48, 254, 35, 29, 66, 103, 17, 67, 152, 38, 7, 130, 139, - ]), - 'ML-DSA-87': new Uint8Array([ - 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 4, 34, 128, - 32, 161, 80, 109, 145, 76, 109, 101, 140, 117, 39, 228, 51, 151, 221, 109, - 76, 37, 246, 164, 121, 116, 51, 90, 76, 208, 59, 254, 105, 131, 68, 18, 81, - ]), -}; - -// SPKI public keys for ML-DSA variants -var spki = { - 'ML-DSA-44': new Uint8Array([ - 48, 130, 5, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 3, 130, 5, - 33, 0, 85, 152, 213, 68, 198, 20, 177, 84, 200, 188, 33, 104, 36, 161, 193, - 127, 226, 151, 48, 107, 122, 191, 89, 86, 188, 3, 245, 199, 18, 79, 168, - 192, 218, 218, 223, 227, 84, 133, 41, 187, 9, 183, 14, 222, 155, 137, 84, - 111, 138, 97, 234, 152, 52, 15, 163, 47, 227, 218, 19, 20, 229, 93, 99, 252, - 155, 213, 30, 241, 158, 211, 213, 191, 155, 73, 211, 145, 59, 194, 75, 140, - 3, 161, 149, 139, 48, 172, 155, 172, 120, 234, 142, 79, 78, 116, 215, 184, - 50, 182, 162, 192, 93, 221, 179, 216, 70, 186, 92, 93, 51, 190, 61, 173, - 105, 206, 9, 208, 52, 54, 208, 252, 115, 176, 146, 118, 23, 0, 5, 41, 151, - 121, 241, 246, 193, 206, 212, 160, 181, 7, 99, 220, 78, 96, 123, 142, 35, - 107, 37, 218, 138, 139, 228, 207, 166, 132, 87, 36, 116, 251, 174, 10, 41, - 196, 171, 26, 212, 90, 213, 223, 141, 87, 232, 59, 46, 173, 16, 247, 173, 4, - 219, 165, 234, 8, 217, 233, 163, 13, 10, 160, 22, 87, 232, 2, 9, 92, 177, - 35, 67, 55, 104, 51, 204, 231, 81, 209, 62, 31, 117, 56, 141, 78, 109, 148, - 118, 191, 93, 193, 59, 30, 88, 237, 19, 169, 14, 11, 150, 102, 215, 144, 69, - 246, 32, 159, 110, 49, 75, 78, 225, 121, 184, 206, 234, 126, 171, 164, 43, - 237, 244, 63, 83, 70, 136, 213, 244, 121, 184, 34, 201, 249, 95, 64, 165, - 99, 14, 195, 231, 18, 121, 20, 156, 80, 231, 133, 197, 0, 94, 195, 22, 251, - 255, 174, 213, 103, 75, 88, 58, 138, 66, 37, 85, 162, 15, 242, 29, 49, 147, - 191, 163, 170, 109, 195, 22, 63, 197, 149, 117, 100, 36, 81, 115, 203, 126, - 62, 86, 103, 193, 182, 69, 238, 233, 162, 62, 248, 132, 158, 212, 208, 187, - 127, 212, 198, 169, 245, 26, 153, 28, 207, 85, 65, 145, 200, 23, 196, 38, - 64, 49, 54, 233, 185, 72, 156, 86, 230, 127, 152, 108, 184, 240, 109, 8, - 103, 228, 206, 142, 73, 74, 214, 52, 182, 203, 82, 201, 175, 188, 111, 42, - 232, 8, 177, 131, 47, 237, 92, 120, 210, 124, 48, 185, 215, 137, 36, 70, - 162, 164, 119, 0, 155, 20, 57, 33, 27, 220, 77, 254, 233, 190, 106, 135, 21, - 194, 57, 238, 95, 162, 78, 164, 33, 210, 215, 43, 100, 96, 232, 87, 19, 43, - 65, 240, 183, 17, 131, 247, 97, 241, 7, 111, 159, 40, 252, 45, 228, 76, 71, - 46, 85, 181, 54, 41, 135, 162, 144, 227, 128, 121, 173, 207, 119, 54, 19, - 197, 23, 231, 176, 125, 190, 32, 76, 60, 34, 24, 160, 42, 73, 190, 124, 99, - 5, 9, 214, 6, 220, 177, 206, 79, 222, 10, 142, 250, 63, 179, 67, 21, 159, - 57, 126, 239, 28, 238, 240, 107, 79, 185, 174, 232, 168, 146, 128, 229, 119, - 19, 21, 33, 239, 193, 42, 178, 152, 124, 24, 203, 131, 193, 93, 162, 2, 208, - 231, 20, 203, 232, 47, 54, 114, 255, 236, 97, 99, 156, 15, 160, 75, 60, 111, - 59, 35, 25, 230, 43, 91, 170, 161, 74, 70, 179, 180, 251, 71, 197, 240, 104, - 42, 39, 202, 206, 12, 115, 249, 138, 55, 252, 216, 61, 185, 121, 76, 137, - 172, 166, 88, 92, 130, 18, 52, 67, 13, 187, 49, 147, 212, 77, 74, 56, 59, - 123, 99, 205, 36, 137, 96, 111, 148, 121, 157, 2, 83, 246, 86, 156, 152, 98, - 172, 77, 244, 214, 225, 184, 240, 121, 144, 56, 213, 161, 43, 67, 4, 161, - 104, 202, 91, 134, 247, 108, 24, 46, 187, 63, 216, 50, 125, 120, 17, 216, - 22, 228, 156, 253, 7, 180, 15, 130, 180, 72, 71, 169, 3, 236, 247, 11, 170, - 32, 76, 236, 225, 133, 250, 20, 235, 200, 143, 89, 25, 158, 49, 158, 164, - 213, 221, 81, 120, 241, 150, 210, 19, 79, 165, 24, 35, 170, 182, 242, 255, - 143, 171, 148, 140, 41, 207, 186, 98, 224, 16, 152, 224, 38, 110, 175, 169, - 111, 132, 201, 178, 114, 25, 196, 50, 149, 158, 193, 180, 101, 183, 92, 109, - 131, 102, 119, 123, 78, 107, 223, 4, 1, 206, 140, 130, 237, 205, 36, 18, - 180, 197, 154, 26, 236, 140, 173, 230, 101, 35, 189, 121, 104, 21, 75, 81, - 224, 186, 212, 81, 107, 66, 244, 235, 64, 90, 206, 39, 44, 43, 162, 187, 63, - 229, 217, 154, 185, 157, 24, 125, 252, 91, 136, 59, 47, 182, 200, 73, 19, - 137, 132, 81, 16, 234, 227, 210, 32, 16, 160, 188, 250, 27, 190, 164, 53, - 244, 219, 199, 177, 146, 117, 50, 99, 72, 235, 37, 154, 72, 51, 203, 61, 39, - 230, 34, 132, 117, 217, 167, 201, 42, 17, 76, 72, 103, 172, 93, 169, 29, 76, - 88, 178, 226, 32, 53, 190, 60, 210, 132, 113, 198, 26, 70, 179, 47, 34, 184, - 88, 178, 208, 1, 196, 89, 136, 167, 33, 38, 9, 255, 89, 202, 27, 93, 229, - 100, 192, 24, 234, 200, 186, 125, 231, 212, 188, 11, 29, 51, 189, 70, 147, - 176, 231, 81, 16, 114, 152, 159, 21, 124, 185, 208, 50, 74, 211, 113, 207, - 35, 54, 173, 205, 133, 52, 167, 199, 87, 158, 120, 33, 204, 163, 146, 233, - 21, 61, 28, 102, 48, 232, 184, 15, 219, 238, 240, 215, 222, 239, 3, 110, - 180, 95, 103, 147, 236, 10, 57, 195, 159, 231, 50, 92, 145, 165, 44, 204, - 121, 187, 9, 210, 80, 86, 251, 169, 132, 236, 248, 23, 207, 222, 227, 13, - 53, 1, 88, 69, 105, 13, 238, 202, 251, 194, 245, 14, 38, 1, 245, 157, 212, - 162, 182, 217, 230, 115, 139, 175, 219, 199, 74, 124, 186, 158, 3, 220, 87, - 220, 177, 85, 13, 58, 168, 223, 6, 238, 156, 80, 121, 44, 166, 176, 0, 48, - 98, 70, 93, 78, 50, 192, 16, 186, 2, 233, 105, 105, 120, 195, 17, 100, 141, - 214, 158, 144, 63, 4, 88, 190, 101, 209, 55, 119, 46, 128, 117, 225, 121, - 204, 195, 19, 61, 170, 116, 251, 225, 230, 28, 27, 249, 84, 195, 224, 190, - 60, 212, 83, 3, 148, 204, 4, 103, 50, 233, 175, 207, 47, 51, 216, 79, 251, - 150, 81, 171, 7, 145, 55, 188, 187, 217, 200, 155, 246, 85, 42, 123, 18, - 112, 192, 116, 163, 40, 187, 132, 192, 210, 188, 106, 117, 217, 185, 183, - 202, 33, 11, 205, 10, 61, 52, 15, 66, 131, 121, 112, 26, 96, 166, 241, 1, - 68, 206, 80, 92, 132, 83, 89, 126, 135, 157, 4, 202, 16, 5, 131, 112, 62, - 56, 234, 176, 213, 119, 205, 203, 17, 106, 156, 117, 251, 135, 21, 73, 219, - 238, 3, 88, 21, 71, 136, 118, 0, 7, 106, 151, 200, 221, 179, 206, 50, 198, - 27, 118, 181, 27, 85, 35, 248, 44, 57, 15, 221, 97, 121, 4, 167, 111, 182, - 207, 195, 52, 134, 195, 128, 173, 111, 98, 152, 29, 138, 197, 175, 171, 247, - 194, 20, 134, 209, 232, 94, 17, 203, 139, 30, 237, 187, 243, 16, 180, 43, - 105, 236, 66, 175, 170, 139, 24, 99, 28, 225, 141, 96, 250, 119, 0, 111, - 212, 34, 217, 42, 134, 88, 78, 76, 126, 169, 168, 59, 154, 93, 54, 43, 161, - 29, 111, 124, 59, 225, 52, 86, 147, 38, 151, 161, 36, 119, 204, 164, 121, - 46, 186, 65, 84, 70, 38, 15, 203, 48, 168, 235, 231, 30, 55, 95, 36, 10, 20, - 166, 109, 8, 18, 109, 251, 213, 82, 142, 240, 49, 249, 180, 78, 69, - ]), - 'ML-DSA-65': new Uint8Array([ - 48, 130, 7, 178, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 3, 130, 7, - 161, 0, 216, 177, 233, 60, 151, 24, 246, 66, 175, 161, 192, 118, 9, 177, 87, - 232, 5, 216, 49, 254, 251, 160, 51, 216, 250, 171, 229, 104, 149, 117, 135, - 107, 5, 239, 244, 167, 83, 57, 49, 153, 29, 135, 108, 138, 117, 236, 120, - 65, 89, 65, 17, 201, 127, 147, 246, 103, 238, 204, 25, 83, 240, 29, 173, - 127, 140, 1, 88, 40, 43, 134, 51, 19, 125, 131, 224, 50, 167, 82, 20, 217, - 215, 162, 41, 95, 215, 56, 130, 226, 177, 216, 20, 169, 133, 85, 140, 9, - 105, 172, 54, 121, 0, 87, 202, 18, 93, 96, 147, 103, 127, 164, 63, 197, 97, - 49, 230, 125, 53, 80, 64, 20, 239, 29, 90, 118, 102, 221, 177, 6, 220, 220, - 170, 107, 107, 18, 138, 125, 138, 70, 66, 60, 185, 232, 209, 4, 100, 17, - 118, 24, 181, 110, 241, 50, 250, 138, 209, 19, 84, 220, 61, 96, 80, 128, 81, - 101, 160, 9, 5, 53, 33, 112, 60, 59, 195, 79, 115, 190, 101, 93, 56, 171, - 146, 51, 82, 233, 66, 225, 226, 211, 72, 58, 9, 74, 222, 185, 175, 211, 156, - 164, 68, 188, 119, 46, 14, 64, 160, 13, 207, 60, 81, 68, 108, 148, 59, 88, - 88, 92, 88, 171, 249, 204, 160, 137, 222, 234, 168, 233, 3, 86, 224, 174, - 105, 224, 1, 177, 184, 230, 236, 30, 85, 249, 56, 105, 211, 50, 83, 168, - 139, 28, 175, 181, 22, 89, 166, 215, 152, 218, 184, 111, 65, 24, 82, 71, - 185, 100, 172, 66, 178, 6, 215, 164, 252, 56, 40, 198, 207, 152, 110, 186, - 207, 39, 235, 179, 38, 215, 88, 105, 109, 177, 130, 91, 5, 223, 164, 78, - 241, 176, 125, 197, 94, 100, 40, 214, 251, 239, 253, 88, 154, 14, 75, 254, - 94, 210, 86, 244, 51, 95, 168, 139, 213, 73, 87, 151, 209, 150, 126, 88, 69, - 251, 116, 157, 122, 96, 212, 206, 42, 218, 38, 85, 184, 50, 246, 188, 35, - 72, 60, 226, 155, 246, 86, 209, 110, 133, 161, 129, 126, 80, 154, 238, 64, - 64, 170, 156, 177, 225, 52, 87, 42, 88, 154, 174, 246, 30, 84, 143, 221, 51, - 27, 65, 60, 40, 22, 120, 42, 145, 34, 82, 235, 79, 20, 215, 211, 231, 151, - 108, 119, 53, 116, 190, 13, 139, 199, 189, 84, 54, 186, 222, 90, 116, 253, - 227, 207, 104, 209, 118, 42, 144, 94, 22, 219, 198, 211, 216, 171, 75, 245, - 61, 240, 157, 108, 81, 19, 238, 39, 120, 210, 242, 63, 126, 6, 15, 18, 97, - 232, 207, 184, 84, 239, 72, 115, 90, 95, 112, 78, 45, 201, 13, 102, 208, - 151, 146, 253, 153, 177, 115, 14, 194, 184, 107, 118, 120, 63, 105, 89, 144, - 60, 242, 80, 106, 32, 11, 204, 170, 165, 221, 182, 31, 187, 159, 216, 118, - 218, 207, 182, 107, 136, 211, 162, 231, 196, 128, 83, 251, 192, 189, 149, 1, - 245, 36, 146, 159, 11, 116, 30, 191, 141, 182, 157, 227, 91, 88, 72, 224, - 55, 195, 96, 245, 135, 249, 142, 16, 229, 237, 27, 60, 2, 91, 138, 82, 197, - 210, 40, 8, 123, 172, 202, 207, 119, 199, 190, 102, 40, 141, 174, 93, 211, - 219, 134, 105, 26, 103, 100, 102, 62, 130, 224, 135, 173, 82, 224, 200, 213, - 76, 211, 38, 181, 16, 97, 99, 75, 14, 42, 162, 223, 237, 141, 1, 29, 140, - 191, 146, 49, 236, 179, 88, 202, 220, 124, 239, 231, 131, 101, 134, 111, 28, - 54, 151, 172, 67, 167, 113, 96, 204, 63, 76, 169, 95, 14, 175, 149, 189, - 173, 39, 177, 102, 23, 158, 102, 236, 224, 70, 203, 190, 132, 230, 136, 3, - 28, 201, 131, 148, 164, 219, 181, 208, 26, 239, 111, 86, 35, 102, 133, 114, - 113, 180, 184, 82, 180, 106, 124, 248, 126, 87, 177, 165, 176, 204, 128, - 141, 179, 141, 34, 119, 160, 57, 206, 168, 95, 197, 110, 79, 60, 48, 170, - 125, 206, 147, 137, 156, 85, 46, 7, 193, 228, 150, 22, 46, 147, 51, 153, - 157, 248, 151, 253, 114, 58, 126, 38, 127, 19, 225, 99, 183, 235, 175, 90, - 166, 8, 233, 141, 10, 85, 232, 147, 7, 20, 137, 240, 84, 231, 86, 134, 50, - 212, 201, 6, 253, 18, 150, 114, 160, 140, 2, 254, 189, 152, 14, 68, 110, 50, - 134, 199, 73, 237, 56, 116, 110, 135, 36, 40, 14, 167, 50, 71, 81, 9, 178, - 54, 182, 247, 64, 32, 204, 116, 92, 131, 40, 30, 246, 188, 236, 182, 187, - 132, 239, 124, 136, 238, 146, 137, 247, 87, 52, 15, 78, 108, 135, 178, 101, - 70, 199, 193, 192, 144, 196, 106, 186, 141, 42, 101, 214, 196, 67, 175, 38, - 8, 189, 148, 166, 253, 221, 144, 119, 81, 1, 232, 175, 81, 237, 13, 188, - 220, 230, 47, 115, 184, 179, 0, 51, 118, 39, 22, 114, 232, 88, 15, 121, 216, - 130, 107, 173, 108, 175, 225, 113, 40, 223, 185, 6, 244, 227, 73, 38, 64, - 84, 10, 200, 53, 81, 179, 217, 106, 172, 59, 161, 70, 180, 70, 48, 56, 46, - 233, 133, 245, 57, 120, 154, 167, 49, 109, 188, 152, 245, 181, 1, 159, 247, - 44, 167, 152, 6, 191, 246, 38, 120, 141, 57, 241, 168, 60, 38, 6, 82, 248, - 87, 85, 0, 10, 22, 19, 44, 178, 63, 38, 78, 1, 210, 166, 140, 3, 199, 112, - 135, 155, 36, 13, 204, 124, 47, 5, 190, 103, 91, 205, 147, 248, 115, 177, - 196, 180, 234, 85, 35, 24, 182, 16, 207, 107, 167, 10, 54, 193, 146, 71, 95, - 45, 109, 184, 43, 101, 155, 184, 55, 171, 196, 136, 89, 227, 84, 183, 31, 0, - 137, 230, 146, 250, 6, 27, 225, 241, 11, 95, 124, 248, 133, 171, 149, 67, - 73, 19, 110, 104, 173, 86, 6, 246, 195, 196, 200, 175, 53, 18, 198, 223, - 140, 85, 208, 253, 204, 220, 255, 232, 88, 238, 20, 97, 24, 52, 13, 3, 179, - 62, 151, 101, 67, 33, 79, 253, 157, 253, 233, 197, 109, 130, 78, 11, 165, - 214, 200, 41, 157, 63, 46, 175, 251, 246, 225, 227, 199, 92, 107, 216, 58, - 124, 226, 202, 153, 92, 31, 250, 182, 92, 99, 0, 110, 18, 78, 228, 166, 190, - 67, 88, 245, 155, 139, 82, 152, 39, 204, 74, 140, 95, 82, 82, 160, 147, 144, - 33, 0, 242, 200, 22, 102, 160, 233, 102, 224, 42, 205, 240, 56, 95, 197, - 226, 175, 235, 240, 125, 10, 51, 12, 246, 150, 234, 173, 95, 132, 173, 174, - 1, 161, 23, 39, 52, 168, 87, 54, 4, 66, 201, 34, 155, 82, 133, 170, 76, 52, - 226, 109, 163, 19, 34, 184, 226, 39, 20, 75, 72, 201, 70, 188, 71, 182, 230, - 6, 19, 255, 8, 145, 193, 63, 81, 150, 24, 72, 89, 168, 74, 98, 173, 133, 67, - 227, 44, 252, 252, 227, 192, 125, 20, 227, 144, 24, 31, 48, 67, 67, 48, 94, - 163, 52, 219, 163, 225, 214, 214, 109, 211, 122, 213, 198, 90, 204, 40, 97, - 211, 121, 17, 28, 132, 246, 110, 230, 51, 197, 42, 162, 143, 199, 158, 215, - 210, 133, 60, 65, 127, 1, 153, 193, 22, 171, 250, 114, 204, 246, 255, 126, - 25, 96, 44, 164, 102, 172, 211, 23, 245, 122, 48, 221, 249, 138, 148, 134, - 206, 135, 246, 42, 235, 198, 89, 189, 45, 125, 204, 69, 193, 48, 29, 144, - 125, 224, 127, 66, 1, 134, 141, 224, 211, 193, 141, 69, 128, 75, 167, 244, - 160, 120, 54, 191, 214, 29, 40, 249, 15, 46, 68, 141, 91, 242, 91, 80, 252, - 109, 122, 154, 64, 153, 56, 65, 254, 106, 18, 4, 172, 171, 136, 80, 98, 79, - 133, 255, 4, 100, 191, 144, 171, 219, 46, 132, 181, 130, 228, 107, 68, 32, - 123, 201, 17, 67, 35, 144, 180, 160, 30, 125, 9, 55, 184, 172, 0, 159, 250, - 232, 83, 168, 162, 102, 158, 121, 208, 177, 116, 163, 160, 80, 241, 46, 156, - 58, 203, 240, 67, 176, 244, 170, 160, 115, 122, 141, 154, 101, 218, 178, - 119, 130, 195, 32, 207, 51, 149, 98, 51, 219, 57, 121, 216, 156, 101, 218, - 184, 220, 204, 41, 181, 149, 63, 80, 194, 11, 143, 164, 219, 23, 123, 141, - 119, 43, 94, 78, 175, 89, 165, 48, 167, 44, 45, 219, 197, 15, 202, 118, 116, - 245, 151, 218, 14, 199, 96, 27, 102, 206, 198, 123, 222, 178, 210, 20, 200, - 38, 25, 124, 58, 102, 92, 197, 107, 51, 5, 236, 125, 173, 198, 113, 144, - 108, 177, 22, 104, 223, 165, 39, 9, 84, 87, 124, 80, 153, 8, 212, 76, 2, 28, - 12, 90, 212, 129, 148, 212, 229, 63, 29, 200, 113, 171, 154, 107, 189, 202, - 22, 147, 7, 32, 253, 70, 37, 224, 98, 199, 129, 21, 54, 49, 52, 124, 84, 40, - 190, 194, 108, 73, 26, 15, 124, 87, 87, 198, 217, 122, 127, 82, 167, 131, - 59, 8, 172, 49, 162, 61, 64, 79, 196, 205, 65, 110, 75, 130, 128, 197, 182, - 251, 110, 141, 197, 184, 166, 244, 246, 217, 20, 105, 85, 42, 80, 251, 77, - 59, 204, 247, 179, 218, 181, 124, 209, 4, 28, 118, 234, 145, 237, 140, 106, - 54, 88, 82, 28, 235, 68, 221, 109, 139, 11, 166, 182, 63, 142, 194, 255, - 213, 219, 116, 158, 31, 224, 119, 126, 232, 160, 144, 1, 177, 92, 219, 162, - 49, 181, 116, 163, 104, 245, 193, 188, 26, 172, 15, 190, 135, 207, 106, 246, - 13, 132, 76, 189, 160, 25, 123, 26, 20, 48, 203, 59, 209, 69, 235, 103, 253, - 160, 108, 83, 206, 70, 98, 0, 2, 57, 162, 202, 63, 45, 89, 173, 201, 254, - 254, 253, 143, 21, 77, 131, 184, 234, 37, 68, 206, 69, 186, 179, 145, 147, - 135, 42, 137, 152, 253, 213, 240, 13, 122, 161, 218, 186, 180, 213, 162, - 150, 231, 63, 112, 182, 233, 86, 12, 225, 195, 133, 37, 28, 22, 147, 201, - 200, 197, 115, 3, 138, 194, 86, 79, 247, 27, 241, 149, 128, 197, 8, 11, 134, - 53, 118, 175, 248, 253, 114, 91, 31, 192, 253, 209, 111, 31, 228, 244, 184, - 179, 146, 145, 167, 137, 155, 184, 218, 38, 62, 187, 22, 181, 193, 93, 16, - 9, 195, 42, 198, 225, 100, 144, 148, 223, 184, 40, 117, 32, 131, 94, 93, 83, - 88, 125, 95, 220, 20, 206, 7, 228, 78, 54, 238, 178, 196, 38, 245, 95, 8, - 235, 106, 17, 175, 142, 193, 60, 179, 53, 244, 92, 147, 244, 218, 95, 127, - 251, 128, 42, 105, 82, 243, 224, 213, 25, 91, 151, 22, 201, 18, 25, 230, - 165, 85, 25, 249, 170, 160, 171, 210, 209, 32, 154, 124, 245, 60, 30, 255, - 138, 154, 29, 85, 156, 232, 177, 78, 14, 137, 52, 215, 247, 26, 211, 115, - 72, 20, 133, 232, 1, 151, 251, 63, 45, 120, 69, 49, 209, 130, 255, 2, 218, - 21, 251, 16, 86, 30, 62, 136, 92, 149, 60, 6, 125, 129, 145, 235, 102, 190, - 144, 248, 1, 53, 135, 21, 158, 44, 158, 230, 246, 172, 249, 161, 105, 204, - 49, 60, 70, 63, 127, 163, 231, 175, 174, 234, 147, 185, 62, 5, 244, 156, 4, - 31, 39, 156, 176, 154, 251, 166, 143, 212, 43, 30, 97, 50, 37, 176, 155, 77, - 149, 102, - ]), - 'ML-DSA-87': new Uint8Array([ - 48, 130, 10, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 3, 130, 10, - 33, 0, 146, 184, 67, 40, 172, 27, 204, 27, 135, 22, 109, 223, 127, 23, 97, - 130, 198, 228, 199, 62, 178, 21, 173, 20, 88, 180, 205, 168, 17, 164, 135, - 92, 85, 146, 76, 194, 152, 80, 239, 157, 33, 21, 239, 182, 176, 254, 124, - 80, 135, 138, 87, 169, 103, 99, 87, 5, 91, 161, 239, 59, 18, 246, 148, 20, - 32, 60, 117, 245, 182, 156, 196, 230, 82, 117, 228, 211, 81, 45, 115, 217, - 23, 95, 138, 95, 103, 124, 32, 89, 187, 48, 251, 103, 81, 234, 76, 4, 57, - 197, 71, 48, 125, 169, 195, 147, 183, 142, 166, 8, 147, 7, 77, 240, 111, 44, - 168, 23, 89, 107, 95, 220, 75, 202, 44, 25, 244, 200, 160, 0, 174, 111, 107, - 204, 22, 36, 122, 191, 101, 33, 52, 252, 14, 47, 25, 109, 135, 48, 131, 253, - 195, 237, 60, 86, 14, 119, 85, 28, 182, 139, 136, 191, 59, 187, 90, 126, - 207, 168, 238, 184, 83, 77, 254, 208, 21, 57, 104, 188, 228, 134, 82, 249, - 190, 249, 163, 120, 111, 68, 225, 210, 131, 29, 151, 153, 146, 71, 163, 104, - 225, 194, 33, 64, 213, 92, 145, 253, 42, 32, 233, 95, 224, 72, 184, 119, - 192, 113, 253, 177, 153, 246, 240, 49, 103, 170, 229, 82, 69, 186, 36, 252, - 29, 124, 255, 25, 148, 5, 160, 159, 105, 157, 185, 25, 158, 122, 145, 30, - 245, 51, 205, 62, 56, 154, 23, 52, 0, 225, 177, 105, 195, 131, 177, 151, - 197, 114, 110, 128, 227, 127, 176, 28, 252, 217, 56, 61, 136, 148, 190, 124, - 108, 129, 62, 243, 235, 37, 70, 228, 233, 10, 67, 124, 120, 58, 164, 83, 57, - 80, 39, 204, 98, 28, 199, 136, 75, 12, 51, 255, 24, 130, 127, 19, 239, 160, - 94, 137, 75, 15, 82, 158, 252, 163, 43, 236, 193, 234, 27, 74, 69, 14, 179, - 171, 10, 169, 27, 138, 172, 213, 189, 222, 167, 110, 24, 11, 118, 151, 223, - 94, 154, 125, 9, 21, 137, 70, 128, 51, 102, 52, 105, 104, 157, 54, 186, 75, - 217, 226, 169, 71, 125, 177, 253, 218, 85, 236, 242, 25, 215, 147, 181, 104, - 242, 82, 75, 50, 165, 49, 102, 128, 82, 237, 170, 134, 162, 196, 56, 247, - 199, 138, 102, 118, 37, 66, 114, 165, 177, 156, 251, 39, 199, 12, 167, 246, - 169, 150, 108, 91, 192, 42, 68, 192, 244, 255, 107, 18, 191, 7, 73, 19, 174, - 28, 116, 66, 131, 96, 173, 60, 131, 190, 249, 219, 246, 71, 182, 124, 183, - 129, 101, 109, 95, 180, 78, 17, 140, 182, 62, 80, 195, 184, 253, 176, 169, - 153, 1, 29, 83, 39, 252, 150, 41, 219, 176, 48, 151, 108, 60, 255, 239, 0, - 85, 101, 193, 110, 204, 12, 254, 22, 136, 15, 154, 217, 88, 13, 28, 252, - 232, 48, 32, 33, 41, 221, 103, 227, 228, 177, 54, 175, 195, 106, 174, 140, - 54, 128, 108, 214, 228, 215, 118, 226, 206, 171, 21, 155, 162, 152, 135, - 203, 16, 170, 130, 100, 173, 155, 243, 80, 40, 98, 157, 248, 7, 101, 88, - 199, 218, 224, 141, 82, 238, 121, 92, 82, 97, 49, 31, 155, 61, 63, 84, 227, - 90, 143, 164, 59, 216, 101, 19, 35, 134, 2, 20, 18, 197, 97, 215, 169, 85, - 220, 75, 254, 91, 125, 144, 43, 65, 128, 29, 66, 77, 184, 172, 89, 123, 203, - 231, 254, 59, 18, 249, 204, 249, 220, 153, 84, 166, 63, 23, 108, 120, 145, - 216, 67, 223, 123, 248, 15, 253, 63, 191, 126, 84, 95, 98, 141, 66, 200, - 129, 194, 174, 30, 80, 48, 75, 113, 14, 102, 101, 218, 249, 14, 203, 24, 6, - 11, 89, 99, 56, 49, 17, 148, 160, 242, 101, 191, 102, 227, 115, 33, 107, 71, - 235, 6, 141, 68, 161, 162, 165, 227, 159, 82, 253, 54, 157, 214, 255, 141, - 151, 154, 134, 150, 93, 141, 97, 158, 244, 180, 135, 42, 10, 3, 148, 9, 152, - 149, 20, 18, 237, 253, 180, 136, 165, 13, 80, 195, 220, 43, 3, 178, 10, 127, - 144, 2, 207, 209, 246, 40, 110, 38, 133, 9, 22, 180, 11, 223, 116, 236, 205, - 186, 25, 183, 155, 165, 77, 206, 101, 255, 106, 223, 70, 10, 22, 176, 119, - 142, 163, 197, 178, 251, 216, 112, 237, 63, 201, 77, 219, 196, 2, 176, 48, - 15, 207, 91, 74, 236, 21, 8, 205, 126, 77, 28, 13, 26, 28, 202, 250, 100, - 79, 134, 209, 193, 78, 202, 58, 248, 124, 215, 64, 143, 244, 17, 23, 163, - 162, 241, 249, 49, 210, 168, 203, 213, 135, 77, 14, 29, 35, 193, 234, 58, - 12, 106, 165, 163, 251, 192, 115, 251, 7, 198, 189, 93, 207, 178, 246, 50, - 189, 185, 51, 45, 84, 140, 194, 34, 46, 92, 90, 136, 81, 81, 53, 52, 253, - 128, 247, 131, 243, 21, 207, 245, 141, 49, 178, 213, 214, 211, 8, 17, 234, - 133, 225, 104, 197, 186, 224, 117, 1, 173, 104, 17, 177, 161, 223, 71, 195, - 159, 194, 45, 177, 116, 26, 187, 193, 161, 213, 179, 158, 8, 122, 186, 122, - 191, 158, 5, 12, 178, 235, 78, 132, 78, 189, 16, 86, 110, 73, 51, 129, 255, - 242, 110, 63, 6, 53, 209, 110, 132, 236, 43, 239, 192, 221, 138, 1, 128, - 176, 0, 113, 85, 119, 201, 36, 188, 202, 9, 223, 98, 196, 42, 130, 158, 149, - 200, 150, 202, 132, 118, 153, 97, 54, 195, 154, 15, 45, 246, 129, 144, 255, - 231, 75, 25, 56, 47, 178, 98, 10, 106, 84, 56, 113, 161, 227, 37, 246, 1, - 245, 129, 173, 70, 186, 11, 28, 125, 198, 243, 225, 113, 130, 5, 138, 52, - 251, 194, 152, 105, 48, 214, 13, 246, 228, 75, 236, 194, 223, 177, 64, 150, - 97, 167, 20, 27, 74, 76, 166, 199, 239, 91, 240, 8, 22, 54, 41, 63, 35, 112, - 255, 251, 88, 252, 147, 173, 185, 43, 98, 83, 155, 230, 176, 55, 161, 8, 83, - 15, 110, 151, 241, 110, 168, 203, 190, 198, 218, 152, 144, 150, 58, 123, 11, - 123, 250, 104, 113, 198, 93, 1, 152, 51, 172, 140, 246, 115, 113, 229, 218, - 166, 200, 35, 123, 16, 133, 169, 191, 59, 103, 12, 114, 15, 60, 37, 4, 92, - 208, 54, 31, 79, 56, 225, 6, 11, 74, 107, 79, 225, 239, 16, 73, 249, 234, - 197, 129, 230, 97, 39, 115, 49, 96, 141, 41, 242, 225, 177, 214, 18, 103, - 34, 229, 37, 176, 241, 99, 82, 227, 195, 77, 32, 64, 4, 120, 49, 199, 209, - 139, 2, 4, 222, 233, 45, 151, 141, 142, 252, 41, 124, 231, 13, 144, 63, 212, - 252, 145, 34, 142, 232, 152, 84, 135, 87, 175, 46, 53, 139, 60, 168, 135, - 167, 101, 253, 127, 152, 138, 154, 31, 231, 198, 77, 89, 182, 9, 54, 103, - 119, 100, 218, 245, 44, 191, 74, 30, 152, 84, 22, 62, 159, 131, 163, 223, 3, - 51, 194, 241, 49, 9, 213, 43, 214, 201, 75, 158, 198, 22, 203, 209, 190, - 199, 189, 75, 4, 6, 72, 60, 241, 113, 171, 30, 42, 143, 73, 51, 72, 206, - 110, 175, 203, 195, 199, 15, 155, 208, 166, 121, 26, 132, 59, 44, 72, 155, - 7, 48, 122, 132, 224, 142, 3, 7, 21, 207, 11, 30, 112, 18, 149, 146, 127, - 41, 104, 197, 169, 86, 213, 108, 253, 111, 160, 5, 11, 202, 172, 233, 32, 5, - 52, 92, 124, 152, 162, 11, 88, 28, 166, 248, 141, 251, 38, 161, 53, 49, 136, - 246, 183, 85, 9, 165, 115, 108, 18, 208, 218, 129, 165, 163, 131, 34, 32, - 94, 226, 121, 93, 24, 87, 226, 105, 25, 242, 128, 198, 78, 26, 237, 21, 92, - 33, 121, 8, 119, 131, 140, 193, 14, 60, 139, 130, 19, 65, 96, 50, 5, 249, - 12, 27, 51, 23, 195, 89, 255, 47, 23, 109, 62, 202, 190, 5, 131, 92, 91, 39, - 27, 209, 132, 146, 95, 98, 66, 26, 230, 186, 236, 186, 162, 149, 81, 143, - 221, 21, 79, 171, 236, 21, 161, 19, 135, 10, 213, 168, 200, 135, 19, 221, - 177, 207, 106, 214, 194, 124, 220, 53, 45, 176, 245, 178, 189, 49, 242, 22, - 230, 154, 241, 146, 230, 187, 180, 244, 158, 145, 197, 225, 51, 150, 140, - 26, 175, 78, 142, 243, 232, 221, 137, 205, 130, 178, 54, 216, 136, 118, 212, - 33, 90, 206, 18, 224, 158, 44, 23, 144, 204, 24, 184, 48, 81, 233, 124, 20, - 222, 77, 119, 144, 22, 145, 241, 19, 206, 135, 252, 164, 114, 84, 37, 175, - 107, 67, 243, 183, 137, 213, 53, 236, 41, 73, 50, 34, 146, 218, 204, 68, - 235, 158, 150, 139, 133, 75, 248, 157, 7, 0, 53, 68, 44, 156, 110, 56, 197, - 209, 201, 0, 155, 225, 85, 35, 169, 193, 231, 36, 31, 142, 101, 168, 29, - 192, 31, 128, 81, 191, 253, 184, 153, 226, 214, 1, 27, 6, 0, 192, 36, 101, - 72, 105, 150, 226, 3, 21, 12, 127, 72, 250, 223, 240, 136, 249, 157, 129, - 247, 91, 178, 157, 208, 86, 146, 23, 176, 150, 35, 211, 155, 22, 207, 119, - 168, 167, 122, 180, 183, 106, 97, 138, 87, 96, 34, 141, 110, 145, 231, 226, - 35, 115, 232, 129, 54, 186, 128, 190, 238, 37, 169, 194, 37, 24, 237, 211, - 164, 111, 54, 88, 245, 125, 67, 78, 194, 11, 194, 235, 217, 87, 203, 14, - 220, 189, 107, 68, 94, 139, 66, 230, 5, 54, 64, 28, 246, 143, 75, 127, 239, - 243, 20, 251, 189, 246, 246, 151, 90, 219, 227, 242, 223, 205, 40, 124, 245, - 4, 189, 72, 39, 145, 110, 96, 120, 164, 27, 117, 146, 177, 30, 76, 173, 106, - 130, 228, 192, 189, 59, 167, 30, 127, 178, 164, 5, 133, 80, 199, 207, 216, - 189, 156, 93, 222, 150, 129, 81, 193, 180, 38, 59, 8, 214, 210, 95, 150, - 182, 175, 148, 43, 153, 169, 66, 62, 135, 140, 159, 89, 195, 253, 3, 132, - 180, 164, 244, 243, 232, 71, 196, 200, 158, 194, 114, 115, 193, 88, 161, - 185, 235, 247, 14, 126, 225, 176, 111, 17, 79, 77, 245, 80, 229, 174, 6, - 180, 156, 217, 85, 174, 201, 255, 237, 85, 83, 53, 188, 153, 98, 91, 193, - 21, 211, 49, 145, 196, 252, 52, 66, 226, 131, 203, 214, 130, 237, 194, 208, - 174, 102, 133, 220, 235, 222, 79, 232, 36, 21, 161, 248, 51, 185, 164, 156, - 95, 121, 65, 57, 233, 183, 29, 199, 105, 104, 12, 90, 195, 186, 81, 199, - 176, 1, 87, 16, 226, 192, 206, 185, 197, 46, 34, 75, 174, 153, 238, 15, 50, - 87, 226, 96, 26, 197, 202, 73, 235, 19, 140, 9, 79, 12, 52, 83, 76, 85, 146, - 234, 24, 151, 179, 178, 118, 58, 162, 223, 103, 69, 244, 231, 135, 167, 204, - 117, 166, 60, 237, 82, 63, 11, 4, 207, 10, 146, 54, 126, 191, 79, 133, 60, - 128, 34, 136, 170, 23, 84, 81, 38, 94, 9, 130, 245, 100, 115, 209, 34, 228, - 158, 101, 216, 135, 208, 207, 191, 169, 115, 252, 144, 139, 226, 252, 6, 44, - 221, 134, 170, 87, 11, 46, 124, 58, 219, 179, 238, 6, 98, 216, 18, 174, 42, - 12, 97, 126, 85, 245, 81, 220, 232, 135, 114, 21, 125, 135, 225, 182, 245, - 228, 223, 242, 62, 158, 35, 76, 6, 110, 25, 184, 206, 124, 237, 54, 252, - 199, 44, 78, 89, 0, 135, 44, 176, 57, 168, 36, 221, 173, 77, 214, 209, 60, - 1, 202, 238, 237, 61, 90, 47, 114, 230, 92, 238, 235, 18, 151, 220, 243, - 225, 163, 159, 139, 189, 253, 62, 225, 182, 202, 59, 7, 83, 99, 129, 118, - 175, 37, 246, 85, 119, 251, 246, 69, 180, 247, 37, 24, 194, 89, 158, 97, - 230, 247, 254, 145, 102, 89, 77, 68, 245, 3, 103, 83, 28, 45, 168, 30, 189, - 151, 112, 120, 215, 84, 90, 198, 85, 85, 129, 55, 127, 124, 28, 137, 229, - 139, 54, 88, 229, 105, 81, 212, 83, 28, 107, 250, 82, 164, 43, 24, 15, 57, - 206, 156, 19, 145, 95, 57, 169, 8, 128, 211, 29, 213, 195, 148, 27, 73, 186, - 221, 242, 11, 167, 78, 246, 133, 18, 118, 67, 236, 59, 19, 112, 254, 93, - 168, 157, 118, 0, 107, 248, 57, 149, 67, 222, 123, 225, 207, 251, 69, 218, - 56, 110, 162, 19, 25, 209, 209, 213, 200, 158, 70, 9, 100, 208, 77, 48, 255, - 151, 200, 0, 68, 230, 70, 120, 209, 29, 86, 225, 188, 189, 226, 101, 42, - 176, 32, 147, 121, 72, 151, 130, 217, 13, 66, 148, 84, 129, 215, 249, 164, - 174, 187, 80, 85, 185, 245, 108, 169, 119, 59, 178, 144, 229, 63, 194, 132, - 250, 131, 82, 161, 125, 126, 255, 252, 220, 204, 104, 231, 201, 136, 246, - 116, 43, 88, 233, 0, 43, 128, 214, 40, 59, 81, 147, 139, 132, 69, 24, 233, - 21, 14, 91, 230, 241, 19, 138, 163, 55, 13, 221, 47, 64, 140, 248, 6, 38, - 164, 16, 219, 63, 33, 180, 71, 151, 0, 234, 103, 58, 213, 222, 163, 95, 132, - 1, 178, 146, 66, 124, 242, 223, 102, 129, 192, 214, 194, 117, 162, 252, 246, - 143, 42, 70, 139, 97, 168, 64, 141, 190, 115, 126, 93, 175, 59, 49, 9, 184, - 88, 201, 100, 182, 142, 145, 244, 72, 128, 203, 49, 196, 5, 5, 18, 46, 34, - 87, 171, 132, 158, 128, 75, 194, 8, 242, 52, 156, 229, 245, 56, 245, 88, 14, - 195, 110, 166, 51, 158, 245, 195, 120, 17, 166, 66, 100, 212, 188, 243, 2, - 236, 90, 8, 16, 35, 151, 122, 175, 115, 168, 186, 191, 60, 71, 23, 81, 217, - 79, 203, 239, 61, 146, 247, 168, 112, 83, 102, 146, 222, 178, 45, 247, 63, - 23, 181, 3, 136, 208, 62, 154, 203, 35, 250, 238, 61, 98, 207, 90, 169, 175, - 36, 227, 9, 182, 78, 226, 99, 89, 67, 105, 185, 35, 242, 162, 54, 99, 60, - 148, 14, 118, 1, 26, 120, 62, 82, 62, 222, 34, 99, 58, 174, 145, 199, 190, - 21, 182, 117, 238, 13, 170, 29, 67, 149, 44, 90, 94, 181, 125, 182, 186, 82, - 55, 105, 253, 29, 212, 67, 134, 204, 227, 94, 255, 127, 72, 157, 140, 142, - 224, 77, 149, 29, 170, 45, 163, 214, 209, 46, 28, 125, 177, 111, 2, 92, 121, - 252, 166, 204, 227, 173, 51, 60, 162, 243, 202, 207, 103, 30, 153, 182, 116, - 182, 130, 98, 59, 25, 141, 239, 49, 224, 176, 27, 237, 218, 76, 68, 189, - 108, 185, 136, 255, 105, 150, 11, 153, 44, 248, 139, 199, 178, 235, 85, 115, - 121, 144, 87, 221, 50, 222, 238, 16, 20, 51, 190, 93, 248, 228, 84, 228, - 115, 31, 229, 227, 137, 180, 44, 115, 224, 119, 129, 181, 134, 224, 144, - 186, 123, 208, 118, 96, 101, 177, 191, 232, 171, 6, 17, 247, 187, 173, 84, - 70, 249, 19, 191, 116, 172, 126, 131, 216, 123, 225, 151, 55, 205, 177, 93, - 139, 117, - ]), -}; +var { pkcs8, spki } = getMldsaKeyFixtures(); // Test message to sign (same for all variants) var data = new Uint8Array([ diff --git a/WebCryptoAPI/sign_verify/rsa.js b/WebCryptoAPI/sign_verify/rsa.js index 667f5d2793e48c..8a87ba88cb4b95 100644 --- a/WebCryptoAPI/sign_verify/rsa.js +++ b/WebCryptoAPI/sign_verify/rsa.js @@ -1,581 +1,106 @@ - function run_test() { - setup({explicit_done: true}); - - var subtle = self.crypto.subtle; // Change to test prefixed implementations - - // When are all these tests really done? When all the promises they use have resolved. - var all_promises = []; - - // Source file [algorithm_name]_vectors.js provides the getTestVectors method - // for the algorithm that drives these tests. - var testVectors = getTestVectors(); - - // Test verification first, because signing tests rely on that working - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - var operation = subtle.verify({ - ...vector.algorithm, - get name() { - signature[0] = vector.signature[0]; - return vector.algorithm.name; - } - }, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with altered signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with an altered buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature[0] = 255 - signature[0]; - return operation; - }, vector.name + " verification with altered signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with altered signature after call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer during call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify({ - ...vector.algorithm, - get name() { - signature.buffer.transfer(); - return vector.algorithm.name; - } - }, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification with transferred signature during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature during call"); - }); - - all_promises.push(promise); - }); - - // Test verification with a transferred buffer after call - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - var operation = subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - signature.buffer.transfer(); - return operation; - }, vector.name + " verification with transferred signature after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with transferred signature after call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - var operation = subtle.verify({ - ...vector.algorithm, - get name() { - plaintext[0] = vector.plaintext[0]; - return vector.algorithm.name; - } - }, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with altered plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is altered after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext[0] = 255 - plaintext[0]; - return operation; - }, vector.name + " with altered plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with altered plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failed verification if plaintext is transferred during call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify({ - ...vector.algorithm, - get name() { - plaintext.buffer.transfer(); - return vector.algorithm.name; - } - }, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature is NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " with transferred plaintext during call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext during call"); - }); - - all_promises.push(promise); - }); - - // Check for successful verification even if plaintext is transferred after call. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Signature verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - plaintext.buffer.transfer(); - return operation; - }, vector.name + " with transferred plaintext after call"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " with transferred plaintext after call"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to using privateKey to verify. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - return subtle.verify(vector.algorithm, vector.privateKey, vector.signature, vector.plaintext) - .then(function(plaintext) { - assert_unreached("Should have thrown error for using privateKey to verify in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " using privateKey to verify"); - - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " using privateKey to verify"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to using publicKey to sign. - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - return subtle.sign(vector.algorithm, vector.publicKey, vector.plaintext) - .then(function(signature) { - assert_unreached("Should have thrown error for using publicKey to sign in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " using publicKey to sign"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " using publicKey to sign"); - }); - - all_promises.push(promise); - }); - - // Check for failures due to no "verify" usage. - testVectors.forEach(function(originalVector) { - var vector = Object.assign({}, originalVector); - - var promise = importVectorKeys(vector, [], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - return subtle.verify(vector.algorithm, vector.publicKey, vector.signature, vector.plaintext) - .then(function(plaintext) { - assert_unreached("Should have thrown error for no verify usage in " + vector.name + ": '" + err.message + "'"); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should throw InvalidAccessError instead of '" + err.message + "'"); - }); - }, vector.name + " no verify usage"); - }, function(err) { - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " no verify usage"); - }); - - all_promises.push(promise); - }); - - // Check for successful signing and verification. - testVectors.forEach(function(vector) { - // RSA signing is deterministic with PKCS#1 v1.5, or PSS with zero-length salts. - const isDeterministic = !("saltLength" in vector.algorithm) || vector.algorithm.saltLength == 0; - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - return subtle.sign(vector.algorithm, vector.privateKey, vector.plaintext) - .then(function(signature) { - if (isDeterministic) { - // If deterministic, we can check the output matches. Otherwise, we can only check it verifies. - assert_true(equalBuffers(signature, vector.signature), "Signing did not give the expected output"); - } - // Can we verify the new signature? - return subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_true(is_verified, "Round trip verifies"); - return signature; - }, function(err) { - assert_unreached("verify error for test " + vector.name + ": '" + err.message + "'"); - }); - }) - .then(function(priorSignature) { - // Will a second signing give us different signature? It should for PSS with non-empty salt - return subtle.sign(vector.algorithm, vector.privateKey, vector.plaintext) - .then(function(signature) { - if (isDeterministic) { - assert_true(equalBuffers(priorSignature, signature), "Two signings with empty salt give same signature") - } else { - assert_false(equalBuffers(priorSignature, signature), "Two signings with a salt give different signatures") - } - }, function(err) { - assert_unreached("second time verify error for test " + vector.name + ": '" + err.message + "'"); - }); - }, function(err) { - assert_unreached("sign error for test " + vector.name + ": '" + err.message + "'"); - }); - }, vector.name + " round trip"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested signing or verifying - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " round trip"); - }); - - all_promises.push(promise); - }); - - - // Test signing with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var alteredVector = Object.assign({}, vector); - alteredVector.algorithm = Object.assign({}, vector.algorithm); - if (vector.algorithm.name === "RSA-PSS") { - alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5"; - } else { - alteredVector.algorithm.name = "RSA-PSS"; - } - - var promise = importVectorKeys(alteredVector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var operation = subtle.sign(vector.algorithm, alteredVector.privateKey, vector.plaintext) - .then(function(signature) { - assert_unreached("Signing should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - - return operation; - }, vector.name + " signing with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " signing with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Test verification with the wrong algorithm - testVectors.forEach(function(vector) { - // Want to get the key for the wrong algorithm - var alteredVector = Object.assign({}, vector); - alteredVector.algorithm = Object.assign({}, vector.algorithm); - if (vector.algorithm.name === "RSA-PSS") { - alteredVector.algorithm.name = "RSASSA-PKCS1-v1_5"; - } else { - alteredVector.algorithm.name = "RSA-PSS"; - } - - var promise = importVectorKeys(alteredVector, ["verify"], ["sign"]) - .then(function(vectors) { - // Some tests are sign only - if (!("signature" in vector)) { - return; + const subtle = self.crypto.subtle; + const testVectors = getTestVectors().map( + vector => ({...vector, data: vector.plaintext}) + ); + const importAlgorithm = vector => ({ + name: vector.algorithm.name, + hash: vector.hash, + }); + + runSignatureTests({ + vectors: testVectors, + algorithmIdentifier(vector) { + return vector.algorithm; + }, + importAlgorithm, + dataLabel: "plaintext", + shortSignature: false, + wrongVerifyLabel: " verification with wrong algorithm name", + alteredSignatureLabel: " verification failure with altered signature", + alteredDataLabel: " verification failure with altered plaintext", + async wrongKey(vector, operation) { + const name = vector.algorithm.name === "RSA-PSS" + ? "RSASSA-PKCS1-v1_5" + : "RSA-PSS"; + const isSign = operation === "sign"; + return subtle.importKey( + isSign ? vector.privateKeyFormat : vector.publicKeyFormat, + isSign ? vector.privateKeyBuffer : vector.publicKeyBuffer, + {name, hash: vector.hash}, + false, + [operation] + ); + }, + async roundTrip({ + vector, + algorithm, + verificationKey, + signingKey, + }) { + const isDeterministic = !("saltLength" in algorithm) || + algorithm.saltLength === 0; + const signature = await subtle.sign( + algorithm, + signingKey, + vector.data + ); + + if (isDeterministic) { + assert_true( + equalBuffers(signature, vector.signature), + "Signing did not give the expected output" + ); } - promise_test(function(test) { - var operation = subtle.verify(vector.algorithm, alteredVector.publicKey, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_unreached("Verification should not have succeeded for " + vector.name); - }, function(err) { - assert_equals(err.name, "InvalidAccessError", "Should have thrown InvalidAccessError instead of '" + err.message + "'"); - }); - return operation; - }, vector.name + " verification with wrong algorithm name"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification with wrong algorithm name"); - }); - - all_promises.push(promise); - }); - - // Verification should fail with wrong signature - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var signature = copyBuffer(vector.signature); - signature[0] = 255 - signature[0]; - var operation = subtle.verify(vector.algorithm, vector.publicKey, signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure with altered signature"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure with altered signature"); - }); - - all_promises.push(promise); + const isVerified = await subtle.verify( + algorithm, + verificationKey, + signature, + vector.data + ); + assert_true(isVerified, "Round trip verifies"); + + const secondSignature = await subtle.sign( + algorithm, + signingKey, + vector.data + ); + if (isDeterministic) { + assert_true( + equalBuffers(signature, secondSignature), + "Two signings with empty salt give same signature" + ); + } else { + assert_false( + equalBuffers(signature, secondSignature), + "Two signings with a salt give different signatures" + ); + } + }, }); - // [RSA-PSS] Verification should fail with wrong saltLength testVectors.forEach(function(vector) { - if (vector.algorithm.name === "RSA-PSS") { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - const saltLength = vector.algorithm.saltLength === 32 ? 48 : 32; - var operation = subtle.verify({ ...vector.algorithm, saltLength }, vector.publicKey, vector.signature, vector.plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure with wrong saltLength"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure with wrong saltLength"); - }); - - all_promises.push(promise); + if (vector.algorithm.name !== "RSA-PSS") { + return; } - }); - // Verification should fail with wrong plaintext - testVectors.forEach(function(vector) { - var promise = importVectorKeys(vector, ["verify"], ["sign"]) - .then(function(vectors) { - promise_test(function(test) { - var plaintext = copyBuffer(vector.plaintext); - plaintext[0] = 255 - plaintext[0]; - var operation = subtle.verify(vector.algorithm, vector.publicKey, vector.signature, plaintext) - .then(function(is_verified) { - assert_false(is_verified, "Signature NOT verified"); - }, function(err) { - assert_unreached("Verification should not throw error " + vector.name + ": '" + err.message + "'"); - }); - - return operation; - }, vector.name + " verification failure with altered plaintext"); - - }, function(err) { - // We need a failed test if the importVectorKey operation fails, so - // we know we never tested verification. - promise_test(function(test) { - assert_unreached("importVectorKeys failed for " + vector.name + ". Message: ''" + err.message + "''"); - }, "importVectorKeys step: " + vector.name + " verification failure with altered plaintext"); - }); - - all_promises.push(promise); + promise_test(async function() { + const key = await subtle.importKey( + vector.publicKeyFormat, + vector.publicKeyBuffer, + importAlgorithm(vector), + false, + ["verify"] + ); + const saltLength = vector.algorithm.saltLength === 32 ? 48 : 32; + const isVerified = await subtle.verify( + {...vector.algorithm, saltLength}, + key, + vector.signature, + vector.data + ); + assert_false(isVerified, "Signature NOT verified"); + }, vector.name + " verification failure with wrong saltLength"); }); - - - promise_test(function() { - return Promise.all(all_promises) - .then(function() {done();}) - .catch(function() {done();}) - }, "setup"); - - // A test vector has all needed fields for signing and verifying, EXCEPT that the - // key field may be null. This function replaces that null with the Correct - // CryptoKey object. - // - // Returns a Promise that yields an updated vector on success. - function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) { - var publicPromise, privatePromise; - - if (vector.publicKey !== null) { - publicPromise = new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - publicPromise = subtle.importKey(vector.publicKeyFormat, vector.publicKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, publicKeyUsages) - .then(function(key) { - vector.publicKey = key; - return vector; - }); // Returns a copy of the sourceBuffer it is sent. - } - - if (vector.privateKey !== null) { - privatePromise = new Promise(function(resolve, reject) { - resolve(vector); - }); - } else { - privatePromise = subtle.importKey(vector.privateKeyFormat, vector.privateKeyBuffer, {name: vector.algorithm.name, hash: vector.hash}, false, privateKeyUsages) - .then(function(key) { - vector.privateKey = key; - return vector; - }); - } - - return Promise.all([publicPromise, privatePromise]); - } - - return; } diff --git a/WebCryptoAPI/sign_verify/rsa_pkcs.https.any.js b/WebCryptoAPI/sign_verify/rsa_pkcs.https.any.js index 3e3a8c23bf53cf..43b87658d21f56 100644 --- a/WebCryptoAPI/sign_verify/rsa_pkcs.https.any.js +++ b/WebCryptoAPI/sign_verify/rsa_pkcs.https.any.js @@ -1,6 +1,8 @@ // META: title=WebCryptoAPI: sign() and verify() Using RSASSA-PKCS1-v1_5 // META: script=../util/helpers.js +// META: script=../util/rsa_key_fixtures.js // META: script=rsa_pkcs_vectors.js +// META: script=signature.js // META: script=rsa.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/rsa_pkcs_vectors.js b/WebCryptoAPI/sign_verify/rsa_pkcs_vectors.js index 71e5d8571bc8ef..f1eca448a988e1 100644 --- a/WebCryptoAPI/sign_verify/rsa_pkcs_vectors.js +++ b/WebCryptoAPI/sign_verify/rsa_pkcs_vectors.js @@ -18,8 +18,9 @@ // plaintext - the text to encrypt // signature - the expected signature function getTestVectors() { - var pkcs8 = new Uint8Array([48, 130, 4, 191, 2, 1, 0, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 4, 169, 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 211, 87, 96, 146, 230, 41, 87, 54, 69, 68, 231, 228, 35, 59, 123, 219, 41, 61, 178, 8, 81, 34, 196, 121, 50, 133, 70, 249, 240, 247, 18, 246, 87, 196, 177, 120, 104, 201, 48, 144, 140, 197, 148, 247, 237, 0, 192, 20, 66, 193, 175, 4, 194, 246, 120, 164, 139, 162, 200, 15, 209, 113, 62, 48, 181, 172, 80, 120, 122, 195, 81, 101, 137, 241, 113, 150, 127, 99, 134, 173, 163, 73, 0, 166, 187, 4, 238, 206, 164, 43, 240, 67, 206, 217, 160, 249, 77, 12, 192, 158, 145, 155, 157, 113, 102, 192, 138, 182, 206, 32, 70, 64, 174, 164, 196, 146, 13, 182, 216, 110, 185, 22, 208, 220, 192, 244, 52, 26, 16, 56, 4, 41, 231, 225, 3, 33, 68, 234, 148, 157, 232, 246, 192, 204, 191, 149, 250, 142, 146, 141, 112, 216, 163, 140, 225, 104, 219, 69, 246, 241, 52, 102, 61, 111, 101, 111, 92, 234, 188, 114, 93, 168, 192, 42, 171, 234, 170, 19, 172, 54, 167, 92, 192, 186, 225, 53, 223, 49, 20, 182, 101, 137, 199, 237, 60, 182, 21, 89, 174, 90, 56, 79, 22, 43, 250, 128, 219, 228, 97, 127, 134, 195, 241, 208, 16, 201, 79, 226, 201, 191, 1, 154, 110, 99, 179, 239, 192, 40, 212, 60, 238, 97, 28, 133, 236, 38, 60, 144, 108, 70, 55, 114, 198, 145, 27, 25, 238, 192, 150, 202, 118, 236, 94, 49, 225, 227, 2, 3, 1, 0, 1, 2, 130, 1, 1, 0, 139, 55, 92, 203, 135, 200, 37, 197, 255, 61, 83, 208, 9, 145, 110, 150, 65, 5, 126, 24, 82, 114, 39, 160, 122, 178, 38, 190, 16, 136, 129, 58, 59, 56, 187, 123, 72, 243, 119, 5, 81, 101, 250, 42, 147, 57, 210, 77, 198, 103, 213, 197, 186, 52, 39, 230, 164, 129, 23, 110, 172, 21, 255, 212, 144, 104, 49, 30, 28, 40, 59, 159, 58, 142, 12, 184, 9, 180, 99, 12, 80, 170, 143, 62, 69, 166, 11, 53, 158, 25, 191, 140, 187, 94, 202, 214, 78, 118, 31, 16, 149, 116, 63, 243, 106, 175, 92, 240, 236, 185, 127, 237, 173, 221, 166, 11, 91, 243, 93, 129, 26, 117, 184, 34, 35, 12, 250, 160, 25, 47, 173, 64, 84, 126, 39, 84, 72, 170, 51, 22, 191, 142, 43, 76, 224, 133, 79, 199, 112, 139, 83, 123, 162, 45, 19, 33, 11, 9, 174, 195, 122, 39, 89, 239, 192, 130, 161, 83, 27, 35, 169, 23, 48, 3, 125, 222, 78, 242, 107, 95, 150, 239, 220, 195, 159, 211, 76, 52, 90, 213, 28, 187, 228, 79, 229, 139, 138, 59, 78, 201, 151, 134, 108, 8, 109, 255, 27, 136, 49, 239, 10, 31, 234, 38, 60, 247, 218, 205, 3, 192, 76, 188, 194, 178, 121, 229, 127, 165, 185, 83, 153, 107, 251, 29, 214, 136, 23, 175, 127, 180, 44, 222, 247, 165, 41, 74, 87, 250, 194, 184, 173, 115, 159, 27, 2, 153, 2, 129, 129, 0, 251, 248, 51, 194, 198, 49, 201, 112, 36, 12, 142, 116, 133, 240, 106, 62, 162, 168, 72, 34, 81, 26, 134, 39, 221, 70, 78, 248, 175, 175, 113, 72, 209, 164, 37, 182, 184, 101, 125, 221, 82, 70, 131, 43, 142, 83, 48, 32, 197, 187, 181, 104, 133, 90, 106, 236, 62, 66, 33, 215, 147, 241, 220, 91, 47, 37, 132, 226, 65, 94, 72, 233, 162, 189, 41, 43, 19, 64, 49, 249, 156, 142, 180, 47, 192, 188, 208, 68, 155, 242, 44, 230, 222, 201, 112, 20, 239, 229, 172, 147, 235, 232, 53, 135, 118, 86, 37, 44, 187, 177, 108, 65, 91, 103, 177, 132, 210, 40, 69, 104, 162, 119, 213, 147, 53, 88, 92, 253, 2, 129, 129, 0, 214, 184, 206, 39, 199, 41, 93, 93, 22, 252, 53, 112, 237, 100, 200, 218, 147, 3, 250, 210, 148, 136, 193, 166, 94, 154, 215, 17, 249, 3, 112, 24, 125, 187, 253, 129, 49, 109, 105, 100, 139, 200, 140, 197, 200, 53, 81, 175, 255, 69, 222, 186, 207, 182, 17, 5, 247, 9, 228, 195, 8, 9, 185, 0, 49, 235, 214, 134, 36, 68, 150, 198, 246, 158, 105, 46, 189, 200, 20, 246, 66, 57, 244, 173, 21, 117, 110, 203, 120, 197, 165, 176, 153, 49, 219, 24, 48, 119, 197, 70, 163, 140, 76, 116, 56, 137, 173, 61, 62, 208, 121, 181, 98, 46, 208, 18, 15, 160, 225, 249, 59, 89, 61, 183, 216, 82, 224, 95, 2, 129, 128, 56, 135, 75, 157, 131, 247, 129, 120, 206, 45, 158, 252, 23, 92, 131, 137, 127, 214, 127, 48, 107, 191, 166, 159, 100, 238, 52, 35, 104, 206, 212, 124, 128, 195, 241, 206, 23, 122, 117, 141, 100, 186, 251, 12, 151, 134, 164, 66, 133, 250, 1, 205, 236, 53, 7, 205, 238, 125, 201, 183, 226, 178, 29, 60, 187, 204, 16, 14, 238, 153, 103, 132, 59, 5, 115, 41, 253, 204, 166, 41, 152, 237, 15, 17, 179, 140, 232, 176, 171, 199, 222, 57, 1, 124, 113, 207, 208, 174, 87, 84, 108, 85, 145, 68, 205, 208, 175, 208, 100, 95, 126, 168, 255, 7, 185, 116, 209, 237, 68, 253, 31, 142, 0, 245, 96, 191, 109, 69, 2, 129, 129, 0, 133, 41, 239, 144, 115, 207, 143, 123, 95, 249, 226, 26, 186, 223, 58, 65, 115, 211, 144, 6, 112, 223, 175, 89, 66, 106, 188, 223, 4, 147, 193, 61, 47, 29, 27, 70, 184, 36, 166, 172, 24, 148, 179, 217, 37, 37, 12, 24, 30, 52, 114, 193, 96, 120, 5, 110, 177, 154, 141, 40, 247, 31, 48, 128, 146, 117, 52, 129, 212, 148, 68, 253, 247, 140, 158, 166, 194, 68, 7, 220, 1, 142, 119, 211, 175, 239, 56, 91, 47, 247, 67, 158, 150, 35, 121, 65, 51, 45, 212, 70, 206, 190, 255, 219, 68, 4, 254, 79, 113, 89, 81, 97, 208, 22, 64, 44, 51, 77, 15, 87, 198, 26, 190, 79, 249, 244, 203, 249, 2, 129, 129, 0, 135, 216, 119, 8, 212, 103, 99, 228, 204, 190, 178, 209, 233, 113, 46, 91, 240, 33, 109, 112, 222, 148, 32, 165, 178, 6, 155, 116, 89, 185, 159, 93, 159, 127, 47, 173, 124, 215, 154, 174, 230, 122, 127, 154, 52, 67, 126, 60, 121, 168, 74, 240, 205, 141, 233, 223, 242, 104, 235, 12, 71, 147, 245, 1, 249, 136, 213, 64, 246, 211, 71, 92, 32, 121, 184, 34, 122, 35, 217, 104, 222, 196, 227, 198, 101, 3, 24, 113, 147, 69, 150, 48, 71, 43, 253, 182, 186, 29, 231, 134, 199, 151, 250, 111, 78, 166, 90, 42, 132, 25, 38, 47, 41, 103, 136, 86, 203, 115, 201, 189, 75, 200, 155, 94, 4, 27, 34, 119]); - var spki = new Uint8Array([48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 211, 87, 96, 146, 230, 41, 87, 54, 69, 68, 231, 228, 35, 59, 123, 219, 41, 61, 178, 8, 81, 34, 196, 121, 50, 133, 70, 249, 240, 247, 18, 246, 87, 196, 177, 120, 104, 201, 48, 144, 140, 197, 148, 247, 237, 0, 192, 20, 66, 193, 175, 4, 194, 246, 120, 164, 139, 162, 200, 15, 209, 113, 62, 48, 181, 172, 80, 120, 122, 195, 81, 101, 137, 241, 113, 150, 127, 99, 134, 173, 163, 73, 0, 166, 187, 4, 238, 206, 164, 43, 240, 67, 206, 217, 160, 249, 77, 12, 192, 158, 145, 155, 157, 113, 102, 192, 138, 182, 206, 32, 70, 64, 174, 164, 196, 146, 13, 182, 216, 110, 185, 22, 208, 220, 192, 244, 52, 26, 16, 56, 4, 41, 231, 225, 3, 33, 68, 234, 148, 157, 232, 246, 192, 204, 191, 149, 250, 142, 146, 141, 112, 216, 163, 140, 225, 104, 219, 69, 246, 241, 52, 102, 61, 111, 101, 111, 92, 234, 188, 114, 93, 168, 192, 42, 171, 234, 170, 19, 172, 54, 167, 92, 192, 186, 225, 53, 223, 49, 20, 182, 101, 137, 199, 237, 60, 182, 21, 89, 174, 90, 56, 79, 22, 43, 250, 128, 219, 228, 97, 127, 134, 195, 241, 208, 16, 201, 79, 226, 201, 191, 1, 154, 110, 99, 179, 239, 192, 40, 212, 60, 238, 97, 28, 133, 236, 38, 60, 144, 108, 70, 55, 114, 198, 145, 27, 25, 238, 192, 150, 202, 118, 236, 94, 49, 225, 227, 2, 3, 1, 0, 1]); + var keyFixtures = getRsaKeyFixtures(); + var pkcs8 = keyFixtures.pkcs8; + var spki = keyFixtures.spki; // plaintext var plaintext = new Uint8Array([95, 77, 186, 79, 50, 12, 12, 232, 118, 114, 90, 252, 229, 251, 210, 91, 248, 62, 90, 113, 37, 160, 140, 175, 231, 60, 62, 186, 196, 33, 119, 157, 249, 213, 93, 24, 12, 58, 233, 148, 38, 69, 225, 216, 47, 238, 140, 157, 41, 75, 60, 177, 160, 138, 153, 49, 32, 27, 60, 14, 129, 252, 71, 202, 207, 131, 21, 162, 175, 102, 50, 65, 19, 195, 182, 98, 48, 195, 70, 8, 196, 244, 89, 54, 52, 206, 2, 178, 103, 54, 34, 119, 240, 168, 64, 202, 116, 188, 61, 26, 98, 54, 149, 44, 94, 215, 170, 248, 168, 254, 203, 221, 250, 117, 132, 230, 151, 140, 234, 93, 42, 91, 159, 183, 241, 180, 140, 139, 11, 229, 138, 48, 82, 2, 117, 77, 131, 118, 16, 115, 116, 121, 60, 240, 38, 170, 238, 83, 0, 114, 125, 131, 108, 215, 30, 113, 179, 69, 221, 178, 228, 68, 70, 255, 197, 185, 1, 99, 84, 19, 137, 13, 145, 14, 163, 128, 152, 74, 144, 25, 16, 49, 50, 63, 22, 219, 204, 157, 107, 225, 104, 184, 72, 133, 56, 76, 160, 62, 18, 96, 10, 193, 194, 72, 2, 138, 243, 114, 108, 201, 52, 99, 136, 46, 168, 192, 42, 171]); diff --git a/WebCryptoAPI/sign_verify/rsa_pss.https.any.js b/WebCryptoAPI/sign_verify/rsa_pss.https.any.js index 399baba784687d..c3ed8355f3f85f 100644 --- a/WebCryptoAPI/sign_verify/rsa_pss.https.any.js +++ b/WebCryptoAPI/sign_verify/rsa_pss.https.any.js @@ -1,6 +1,8 @@ // META: title=WebCryptoAPI: sign() and verify() Using RSA-PSS // META: script=../util/helpers.js +// META: script=../util/rsa_key_fixtures.js // META: script=rsa_pss_vectors.js +// META: script=signature.js // META: script=rsa.js // META: timeout=long diff --git a/WebCryptoAPI/sign_verify/rsa_pss_vectors.js b/WebCryptoAPI/sign_verify/rsa_pss_vectors.js index c3ce77960629b2..224bacc3d1bb8b 100644 --- a/WebCryptoAPI/sign_verify/rsa_pss_vectors.js +++ b/WebCryptoAPI/sign_verify/rsa_pss_vectors.js @@ -18,8 +18,9 @@ // plaintext - the text to encrypt // signature - the expected signature function getTestVectors() { - var pkcs8 = new Uint8Array([48, 130, 4, 191, 2, 1, 0, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 4, 169, 48, 130, 4, 165, 2, 1, 0, 2, 130, 1, 1, 0, 211, 87, 96, 146, 230, 41, 87, 54, 69, 68, 231, 228, 35, 59, 123, 219, 41, 61, 178, 8, 81, 34, 196, 121, 50, 133, 70, 249, 240, 247, 18, 246, 87, 196, 177, 120, 104, 201, 48, 144, 140, 197, 148, 247, 237, 0, 192, 20, 66, 193, 175, 4, 194, 246, 120, 164, 139, 162, 200, 15, 209, 113, 62, 48, 181, 172, 80, 120, 122, 195, 81, 101, 137, 241, 113, 150, 127, 99, 134, 173, 163, 73, 0, 166, 187, 4, 238, 206, 164, 43, 240, 67, 206, 217, 160, 249, 77, 12, 192, 158, 145, 155, 157, 113, 102, 192, 138, 182, 206, 32, 70, 64, 174, 164, 196, 146, 13, 182, 216, 110, 185, 22, 208, 220, 192, 244, 52, 26, 16, 56, 4, 41, 231, 225, 3, 33, 68, 234, 148, 157, 232, 246, 192, 204, 191, 149, 250, 142, 146, 141, 112, 216, 163, 140, 225, 104, 219, 69, 246, 241, 52, 102, 61, 111, 101, 111, 92, 234, 188, 114, 93, 168, 192, 42, 171, 234, 170, 19, 172, 54, 167, 92, 192, 186, 225, 53, 223, 49, 20, 182, 101, 137, 199, 237, 60, 182, 21, 89, 174, 90, 56, 79, 22, 43, 250, 128, 219, 228, 97, 127, 134, 195, 241, 208, 16, 201, 79, 226, 201, 191, 1, 154, 110, 99, 179, 239, 192, 40, 212, 60, 238, 97, 28, 133, 236, 38, 60, 144, 108, 70, 55, 114, 198, 145, 27, 25, 238, 192, 150, 202, 118, 236, 94, 49, 225, 227, 2, 3, 1, 0, 1, 2, 130, 1, 1, 0, 139, 55, 92, 203, 135, 200, 37, 197, 255, 61, 83, 208, 9, 145, 110, 150, 65, 5, 126, 24, 82, 114, 39, 160, 122, 178, 38, 190, 16, 136, 129, 58, 59, 56, 187, 123, 72, 243, 119, 5, 81, 101, 250, 42, 147, 57, 210, 77, 198, 103, 213, 197, 186, 52, 39, 230, 164, 129, 23, 110, 172, 21, 255, 212, 144, 104, 49, 30, 28, 40, 59, 159, 58, 142, 12, 184, 9, 180, 99, 12, 80, 170, 143, 62, 69, 166, 11, 53, 158, 25, 191, 140, 187, 94, 202, 214, 78, 118, 31, 16, 149, 116, 63, 243, 106, 175, 92, 240, 236, 185, 127, 237, 173, 221, 166, 11, 91, 243, 93, 129, 26, 117, 184, 34, 35, 12, 250, 160, 25, 47, 173, 64, 84, 126, 39, 84, 72, 170, 51, 22, 191, 142, 43, 76, 224, 133, 79, 199, 112, 139, 83, 123, 162, 45, 19, 33, 11, 9, 174, 195, 122, 39, 89, 239, 192, 130, 161, 83, 27, 35, 169, 23, 48, 3, 125, 222, 78, 242, 107, 95, 150, 239, 220, 195, 159, 211, 76, 52, 90, 213, 28, 187, 228, 79, 229, 139, 138, 59, 78, 201, 151, 134, 108, 8, 109, 255, 27, 136, 49, 239, 10, 31, 234, 38, 60, 247, 218, 205, 3, 192, 76, 188, 194, 178, 121, 229, 127, 165, 185, 83, 153, 107, 251, 29, 214, 136, 23, 175, 127, 180, 44, 222, 247, 165, 41, 74, 87, 250, 194, 184, 173, 115, 159, 27, 2, 153, 2, 129, 129, 0, 251, 248, 51, 194, 198, 49, 201, 112, 36, 12, 142, 116, 133, 240, 106, 62, 162, 168, 72, 34, 81, 26, 134, 39, 221, 70, 78, 248, 175, 175, 113, 72, 209, 164, 37, 182, 184, 101, 125, 221, 82, 70, 131, 43, 142, 83, 48, 32, 197, 187, 181, 104, 133, 90, 106, 236, 62, 66, 33, 215, 147, 241, 220, 91, 47, 37, 132, 226, 65, 94, 72, 233, 162, 189, 41, 43, 19, 64, 49, 249, 156, 142, 180, 47, 192, 188, 208, 68, 155, 242, 44, 230, 222, 201, 112, 20, 239, 229, 172, 147, 235, 232, 53, 135, 118, 86, 37, 44, 187, 177, 108, 65, 91, 103, 177, 132, 210, 40, 69, 104, 162, 119, 213, 147, 53, 88, 92, 253, 2, 129, 129, 0, 214, 184, 206, 39, 199, 41, 93, 93, 22, 252, 53, 112, 237, 100, 200, 218, 147, 3, 250, 210, 148, 136, 193, 166, 94, 154, 215, 17, 249, 3, 112, 24, 125, 187, 253, 129, 49, 109, 105, 100, 139, 200, 140, 197, 200, 53, 81, 175, 255, 69, 222, 186, 207, 182, 17, 5, 247, 9, 228, 195, 8, 9, 185, 0, 49, 235, 214, 134, 36, 68, 150, 198, 246, 158, 105, 46, 189, 200, 20, 246, 66, 57, 244, 173, 21, 117, 110, 203, 120, 197, 165, 176, 153, 49, 219, 24, 48, 119, 197, 70, 163, 140, 76, 116, 56, 137, 173, 61, 62, 208, 121, 181, 98, 46, 208, 18, 15, 160, 225, 249, 59, 89, 61, 183, 216, 82, 224, 95, 2, 129, 128, 56, 135, 75, 157, 131, 247, 129, 120, 206, 45, 158, 252, 23, 92, 131, 137, 127, 214, 127, 48, 107, 191, 166, 159, 100, 238, 52, 35, 104, 206, 212, 124, 128, 195, 241, 206, 23, 122, 117, 141, 100, 186, 251, 12, 151, 134, 164, 66, 133, 250, 1, 205, 236, 53, 7, 205, 238, 125, 201, 183, 226, 178, 29, 60, 187, 204, 16, 14, 238, 153, 103, 132, 59, 5, 115, 41, 253, 204, 166, 41, 152, 237, 15, 17, 179, 140, 232, 176, 171, 199, 222, 57, 1, 124, 113, 207, 208, 174, 87, 84, 108, 85, 145, 68, 205, 208, 175, 208, 100, 95, 126, 168, 255, 7, 185, 116, 209, 237, 68, 253, 31, 142, 0, 245, 96, 191, 109, 69, 2, 129, 129, 0, 133, 41, 239, 144, 115, 207, 143, 123, 95, 249, 226, 26, 186, 223, 58, 65, 115, 211, 144, 6, 112, 223, 175, 89, 66, 106, 188, 223, 4, 147, 193, 61, 47, 29, 27, 70, 184, 36, 166, 172, 24, 148, 179, 217, 37, 37, 12, 24, 30, 52, 114, 193, 96, 120, 5, 110, 177, 154, 141, 40, 247, 31, 48, 128, 146, 117, 52, 129, 212, 148, 68, 253, 247, 140, 158, 166, 194, 68, 7, 220, 1, 142, 119, 211, 175, 239, 56, 91, 47, 247, 67, 158, 150, 35, 121, 65, 51, 45, 212, 70, 206, 190, 255, 219, 68, 4, 254, 79, 113, 89, 81, 97, 208, 22, 64, 44, 51, 77, 15, 87, 198, 26, 190, 79, 249, 244, 203, 249, 2, 129, 129, 0, 135, 216, 119, 8, 212, 103, 99, 228, 204, 190, 178, 209, 233, 113, 46, 91, 240, 33, 109, 112, 222, 148, 32, 165, 178, 6, 155, 116, 89, 185, 159, 93, 159, 127, 47, 173, 124, 215, 154, 174, 230, 122, 127, 154, 52, 67, 126, 60, 121, 168, 74, 240, 205, 141, 233, 223, 242, 104, 235, 12, 71, 147, 245, 1, 249, 136, 213, 64, 246, 211, 71, 92, 32, 121, 184, 34, 122, 35, 217, 104, 222, 196, 227, 198, 101, 3, 24, 113, 147, 69, 150, 48, 71, 43, 253, 182, 186, 29, 231, 134, 199, 151, 250, 111, 78, 166, 90, 42, 132, 25, 38, 47, 41, 103, 136, 86, 203, 115, 201, 189, 75, 200, 155, 94, 4, 27, 34, 119]); - var spki = new Uint8Array([48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 211, 87, 96, 146, 230, 41, 87, 54, 69, 68, 231, 228, 35, 59, 123, 219, 41, 61, 178, 8, 81, 34, 196, 121, 50, 133, 70, 249, 240, 247, 18, 246, 87, 196, 177, 120, 104, 201, 48, 144, 140, 197, 148, 247, 237, 0, 192, 20, 66, 193, 175, 4, 194, 246, 120, 164, 139, 162, 200, 15, 209, 113, 62, 48, 181, 172, 80, 120, 122, 195, 81, 101, 137, 241, 113, 150, 127, 99, 134, 173, 163, 73, 0, 166, 187, 4, 238, 206, 164, 43, 240, 67, 206, 217, 160, 249, 77, 12, 192, 158, 145, 155, 157, 113, 102, 192, 138, 182, 206, 32, 70, 64, 174, 164, 196, 146, 13, 182, 216, 110, 185, 22, 208, 220, 192, 244, 52, 26, 16, 56, 4, 41, 231, 225, 3, 33, 68, 234, 148, 157, 232, 246, 192, 204, 191, 149, 250, 142, 146, 141, 112, 216, 163, 140, 225, 104, 219, 69, 246, 241, 52, 102, 61, 111, 101, 111, 92, 234, 188, 114, 93, 168, 192, 42, 171, 234, 170, 19, 172, 54, 167, 92, 192, 186, 225, 53, 223, 49, 20, 182, 101, 137, 199, 237, 60, 182, 21, 89, 174, 90, 56, 79, 22, 43, 250, 128, 219, 228, 97, 127, 134, 195, 241, 208, 16, 201, 79, 226, 201, 191, 1, 154, 110, 99, 179, 239, 192, 40, 212, 60, 238, 97, 28, 133, 236, 38, 60, 144, 108, 70, 55, 114, 198, 145, 27, 25, 238, 192, 150, 202, 118, 236, 94, 49, 225, 227, 2, 3, 1, 0, 1]); + var keyFixtures = getRsaKeyFixtures(); + var pkcs8 = keyFixtures.pkcs8; + var spki = keyFixtures.spki; // plaintext for RSA-PSS var plaintext = new Uint8Array([95, 77, 186, 79, 50, 12, 12, 232, 118, 114, 90, 252, 229, 251, 210, 91, 248, 62, 90, 113, 37, 160, 140, 175, 231, 60, 62, 186, 196, 33, 119, 157, 249, 213, 93, 24, 12, 58, 233, 148, 38, 69, 225, 216, 47, 238, 140, 157, 41, 75, 60, 177, 160, 138, 153, 49, 32, 27, 60, 14, 129, 252, 71, 202, 207, 131, 21, 162, 175, 102, 50, 65, 19, 195, 182, 98, 48, 195, 70, 8, 196, 244, 89, 54, 52, 206, 2, 178, 103, 54, 34, 119, 240, 168, 64, 202, 116, 188, 61, 26, 98, 54, 149, 44, 94, 215, 170, 248, 168, 254, 203, 221, 250, 117, 132, 230, 151, 140, 234, 93, 42, 91, 159, 183, 241, 180, 140, 139, 11, 229, 138, 48, 82, 2, 117, 77, 131, 118, 16, 115, 116, 121, 60, 240, 38, 170, 238, 83, 0, 114, 125, 131, 108, 215, 30, 113, 179, 69, 221, 178, 228, 68, 70, 255, 197, 185, 1, 99, 84, 19, 137, 13, 145, 14, 163, 128, 152, 74, 144, 25, 16, 49, 50, 63, 22, 219, 204, 157, 107, 225, 104, 184, 72, 133, 56, 76, 160, 62, 18, 96, 10, 193, 194, 72, 2, 138, 243, 114, 108, 201, 52, 99, 136, 46, 168, 192, 42, 171]); diff --git a/WebCryptoAPI/sign_verify/signature.js b/WebCryptoAPI/sign_verify/signature.js new file mode 100644 index 00000000000000..2d734e1d973e71 --- /dev/null +++ b/WebCryptoAPI/sign_verify/signature.js @@ -0,0 +1,368 @@ +function runSignatureTests(options) { + const subtle = self.crypto.subtle; + const publicKeyCache = new WeakMap(); + const privateKeyCache = new WeakMap(); + const dataLabel = options.dataLabel || 'data'; + + function algorithmIdentifier(vector) { + return options.algorithmIdentifier(vector); + } + + function algorithmName(vector) { + const algorithm = algorithmIdentifier(vector); + return typeof algorithm === 'string' ? algorithm : algorithm.name; + } + + function algorithmWithNameGetter(vector, getter) { + const algorithm = algorithmIdentifier(vector); + const result = typeof algorithm === 'string' ? {} : { ...algorithm }; + Object.defineProperty(result, 'name', { + enumerable: true, + get: getter, + }); + return result; + } + + function importAlgorithm(vector) { + return options.importAlgorithm + ? options.importAlgorithm(vector) + : {name: algorithmName(vector)}; + } + + function cachedKey(cache, vector, usages, importer) { + let keys = cache.get(vector); + if (keys === undefined) { + keys = new Map(); + cache.set(vector, keys); + } + + const cacheKey = usages.join(','); + if (!keys.has(cacheKey)) { + keys.set(cacheKey, importer()); + } + return keys.get(cacheKey); + } + + function publicKey(vector, usages = ['verify']) { + return cachedKey(publicKeyCache, vector, usages, function () { + return subtle.importKey( + vector.publicKeyFormat || 'spki', + vector.publicKeyBuffer, + importAlgorithm(vector), + false, + usages + ); + }); + } + + function privateKey(vector, usages = ['sign']) { + return cachedKey(privateKeyCache, vector, usages, function () { + return subtle.importKey( + vector.privateKeyFormat || 'pkcs8', + vector.privateKeyBuffer, + importAlgorithm(vector), + false, + usages + ); + }); + } + + async function assertInvalidAccess(operation, message) { + let error; + try { + await operation(); + } catch (caught) { + error = caught; + } + assert_not_equals(error, undefined, message); + assert_equals( + error.name, + 'InvalidAccessError', + "Should have thrown InvalidAccessError instead of '" + error.message + "'" + ); + } + + options.vectors.forEach(function (vector) { + const algorithm = algorithmIdentifier(vector); + + promise_test(async function () { + const key = await publicKey(vector); + const isVerified = await subtle.verify( + algorithm, + key, + vector.signature, + vector.data + ); + assert_true(isVerified, 'Signature verified'); + }, vector.name + ' verification'); + + promise_test(async function () { + const key = await publicKey(vector); + const signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + const duringCallAlgorithm = algorithmWithNameGetter(vector, function () { + signature[0] = vector.signature[0]; + return algorithmName(vector); + }); + const isVerified = await subtle.verify( + duringCallAlgorithm, + key, + signature, + vector.data + ); + assert_true(isVerified, 'Signature verified'); + }, vector.name + ' verification with altered signature during call'); + + promise_test(async function () { + const key = await publicKey(vector); + const signature = copyBuffer(vector.signature); + const operation = subtle.verify(algorithm, key, signature, vector.data); + signature[0] = 255 - signature[0]; + assert_true(await operation, 'Signature verified'); + }, vector.name + ' verification with altered signature after call'); + + promise_test(async function () { + const key = await publicKey(vector); + const signature = copyBuffer(vector.signature); + const duringCallAlgorithm = algorithmWithNameGetter(vector, function () { + signature.buffer.transfer(); + return algorithmName(vector); + }); + const isVerified = await subtle.verify( + duringCallAlgorithm, + key, + signature, + vector.data + ); + assert_false(isVerified, 'Signature is NOT verified'); + }, vector.name + ' verification with transferred signature during call'); + + promise_test(async function () { + const key = await publicKey(vector); + const signature = copyBuffer(vector.signature); + const operation = subtle.verify(algorithm, key, signature, vector.data); + signature.buffer.transfer(); + assert_true(await operation, 'Signature verified'); + }, vector.name + ' verification with transferred signature after call'); + + promise_test(async function () { + const key = await publicKey(vector); + const data = copyBuffer(vector.data); + data[0] = 255 - data[0]; + const duringCallAlgorithm = algorithmWithNameGetter(vector, function () { + data[0] = vector.data[0]; + return algorithmName(vector); + }); + const isVerified = await subtle.verify( + duringCallAlgorithm, + key, + vector.signature, + data + ); + assert_true(isVerified, 'Signature verified'); + }, vector.name + ' with altered ' + dataLabel + ' during call'); + + promise_test(async function () { + const key = await publicKey(vector); + const data = copyBuffer(vector.data); + const operation = subtle.verify(algorithm, key, vector.signature, data); + data[0] = 255 - data[0]; + assert_true(await operation, 'Signature verified'); + }, vector.name + ' with altered ' + dataLabel + ' after call'); + + promise_test(async function () { + const key = await publicKey(vector); + const data = copyBuffer(vector.data); + const duringCallAlgorithm = algorithmWithNameGetter(vector, function () { + data.buffer.transfer(); + return algorithmName(vector); + }); + const isVerified = await subtle.verify( + duringCallAlgorithm, + key, + vector.signature, + data + ); + assert_false(isVerified, 'Signature is NOT verified'); + }, vector.name + ' with transferred ' + dataLabel + ' during call'); + + promise_test(async function () { + const key = await publicKey(vector); + const data = copyBuffer(vector.data); + const operation = subtle.verify(algorithm, key, vector.signature, data); + data.buffer.transfer(); + assert_true(await operation, 'Signature verified'); + }, vector.name + ' with transferred ' + dataLabel + ' after call'); + + promise_test(async function () { + const key = await privateKey(vector); + await assertInvalidAccess( + () => subtle.verify(algorithm, key, vector.signature, vector.data), + 'Using a private key to verify should fail' + ); + }, vector.name + ' using privateKey to verify'); + + promise_test(async function () { + const key = await publicKey(vector); + await assertInvalidAccess( + () => subtle.sign(algorithm, key, vector.data), + 'Using a public key to sign should fail' + ); + }, vector.name + ' using publicKey to sign'); + + promise_test(async function () { + const key = await publicKey(vector, []); + await assertInvalidAccess( + () => subtle.verify(algorithm, key, vector.signature, vector.data), + 'Verifying without the verify usage should fail' + ); + }, vector.name + ' no verify usage'); + + promise_test(async function () { + const verificationKey = await publicKey(vector); + const signingKey = await privateKey(vector); + + if (options.roundTrip) { + await options.roundTrip({ + subtle, + vector, + algorithm, + verificationKey, + signingKey, + }); + return; + } + + if (options.katFirst) { + const vectorSignatureIsVerified = await subtle.verify( + algorithm, + verificationKey, + vector.signature, + vector.data + ); + assert_true( + vectorSignatureIsVerified, + 'Known-answer signature verified' + ); + } + + const signature = await subtle.sign(algorithm, signingKey, vector.data); + + if (!options.katFirst || !equalBuffers(signature, vector.signature)) { + const generatedSignatureIsVerified = await subtle.verify( + algorithm, + verificationKey, + signature, + vector.data + ); + assert_true( + generatedSignatureIsVerified, + 'Generated signature verified' + ); + } + }, vector.name + ' round trip'); + + promise_test(async function () { + const wrongKey = options.wrongKey + ? await options.wrongKey(vector, 'sign') + : await subtle.generateKey( + {name: 'HMAC', hash: 'SHA-1'}, + false, + ['sign', 'verify'] + ); + await assertInvalidAccess( + () => subtle.sign(algorithm, wrongKey, vector.data), + 'Signing with a key for another algorithm should fail' + ); + }, vector.name + ' signing with wrong algorithm name'); + + promise_test(async function () { + const wrongKey = options.wrongKey + ? await options.wrongKey(vector, 'verify') + : await subtle.generateKey( + {name: 'HMAC', hash: 'SHA-1'}, + false, + ['sign', 'verify'] + ); + await assertInvalidAccess( + () => subtle.verify(algorithm, wrongKey, vector.signature, vector.data), + 'Verifying with a key for another algorithm should fail' + ); + }, vector.name + + (options.wrongVerifyLabel || ' verifying with wrong algorithm name')); + + promise_test(async function () { + const key = await publicKey(vector); + const signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + const isVerified = await subtle.verify( + algorithm, + key, + signature, + vector.data + ); + assert_false(isVerified, 'Signature NOT verified'); + }, vector.name + + (options.alteredSignatureLabel || + ' verification failure due to altered signature')); + + if (options.shortSignature !== false) { + promise_test(async function () { + const key = await publicKey(vector); + const signature = vector.signature.slice(1); + const isVerified = await subtle.verify( + algorithm, + key, + signature, + vector.data + ); + assert_false(isVerified, 'Signature NOT verified'); + }, vector.name + ' verification failure due to shortened signature'); + } + + promise_test(async function () { + const key = await publicKey(vector); + const data = copyBuffer(vector.data); + data[0] = 255 - data[0]; + const isVerified = await subtle.verify( + algorithm, + key, + vector.signature, + data + ); + assert_false(isVerified, 'Signature NOT verified'); + }, vector.name + + (options.alteredDataLabel || + ' verification failure due to altered ' + dataLabel)); + + if (options.generatedKeys) { + promise_test(async function () { + const key = await subtle.generateKey(algorithm, false, ['sign', 'verify']); + const signature = await subtle.sign( + algorithm, + key.privateKey, + vector.data + ); + const isVerified = await subtle.verify( + algorithm, + key.publicKey, + signature, + vector.data + ); + assert_true(isVerified, 'Verification failed.'); + }, 'Sign and verify using generated ' + algorithmName(vector) + ' keys.'); + } + }); + + (options.invalidVectors || []).forEach(function (vector) { + promise_test(async function () { + const isVerified = await subtle.verify( + algorithmIdentifier(vector), + await publicKey(vector), + vector.signature, + vector.data + ); + assert_false(isVerified, 'Signature unexpectedly verified'); + }, vector.name + ' verification'); + }); +} diff --git a/WebCryptoAPI/supports-modern.tentative.https.any.js b/WebCryptoAPI/supports-modern.tentative.https.any.js index ca23b782317762..97cf9dff48aee2 100644 --- a/WebCryptoAPI/supports-modern.tentative.https.any.js +++ b/WebCryptoAPI/supports-modern.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCrypto API: supports method tests for algorithms in https://wicg.github.io/webcrypto-modern-algos/ // META: script=util/helpers.js +// META: script=util/supports.js 'use strict'; @@ -58,73 +59,11 @@ const operations = [ ]; // Test that supports method exists and is a static method -test(() => { - assert_true( - typeof SubtleCrypto.supports === 'function', - 'SubtleCrypto.supports should be a function'); -}, 'SubtleCrypto.supports method exists'); +testSupportsMethod(); // Test standard WebCrypto algorithms for requested operations -for (const [algorithmName, algorithmInfo] of Object.entries(modernAlgorithms)) { - for (const operation of operations) { - promise_test(async (t) => { - const isSupported = algorithmInfo.operations.includes(operation); - - // Use appropriate algorithm parameters for each operation - let algorithm; - let lengthOrAdditionalAlgorithm; - switch (operation) { - case 'generateKey': - algorithm = algorithmInfo.keyGenParams || algorithmName; - break; - case 'importKey': - algorithm = algorithmInfo.importParams || algorithmName; - break; - case 'sign': - case 'verify': - algorithm = algorithmInfo.signParams || algorithmName; - break; - case 'encrypt': - case 'decrypt': - algorithm = algorithmInfo.encryptParams || algorithmName; - break; - case 'deriveBits': - algorithm = algorithmInfo.deriveBitsParams || algorithmName; - if (algorithm?.public instanceof Promise) { - algorithm.public = (await algorithm.public).publicKey; - } - if (algorithmName === 'PBKDF2' || algorithmName === 'HKDF') { - lengthOrAdditionalAlgorithm = 256; - } - break; - case 'digest': - algorithm = algorithmName; - break; - case 'encapsulateKey': - case 'encapsulateBits': - case 'decapsulateKey': - case 'decapsulateBits': - algorithm = algorithmName; - if (operation === 'encapsulateKey' || operation === 'decapsulateKey') { - lengthOrAdditionalAlgorithm = { name: 'AES-GCM', length: 256 }; - } - break; - default: - algorithm = algorithmName; - } - - const result = SubtleCrypto.supports(operation, algorithm, lengthOrAdditionalAlgorithm); - - if (isSupported) { - assert_true(result, `${algorithmName} should support ${operation}`); - } else { - assert_false( - result, `${algorithmName} should not support ${operation}`); - } - }, `supports(${operation}, ${algorithmName})`); - } -} +runSupportsTests(modernAlgorithms, operations); // Test some algorithm objects with valid parameters test(() => { diff --git a/WebCryptoAPI/supports.tentative.https.any.js b/WebCryptoAPI/supports.tentative.https.any.js index ac3a32c741000c..fcccbecd6916b9 100644 --- a/WebCryptoAPI/supports.tentative.https.any.js +++ b/WebCryptoAPI/supports.tentative.https.any.js @@ -1,5 +1,6 @@ // META: title=WebCrypto API: supports method tests // META: script=util/helpers.js +// META: script=util/supports.js 'use strict'; @@ -156,12 +157,7 @@ const operations = [ ]; // Test that supports method exists and is a static method -test(() => { - assert_true( - typeof SubtleCrypto.supports === 'function', - 'SubtleCrypto.supports should be a function' - ); -}, 'SubtleCrypto.supports method exists'); +testSupportsMethod(); // Test invalid operation names test(() => { @@ -192,57 +188,7 @@ test(() => { }, 'supports returns false for invalid algorithms'); // Test standard WebCrypto algorithms for requested operations -for (const [algorithmName, algorithmInfo] of Object.entries( - standardAlgorithms -)) { - for (const operation of operations) { - promise_test(async (t) => { - const isSupported = algorithmInfo.operations.includes(operation); - - // Use appropriate algorithm parameters for each operation - let algorithm; - let length; - switch (operation) { - case 'generateKey': - algorithm = algorithmInfo.keyGenParams || algorithmName; - break; - case 'importKey': - algorithm = algorithmInfo.importParams || algorithmName; - break; - case 'sign': - case 'verify': - algorithm = algorithmInfo.signParams || algorithmName; - break; - case 'encrypt': - case 'decrypt': - algorithm = algorithmInfo.encryptParams || algorithmName; - break; - case 'deriveBits': - algorithm = algorithmInfo.deriveBitsParams || algorithmName; - if (algorithm?.public instanceof Promise) { - algorithm.public = (await algorithm.public).publicKey; - } - if (algorithmName === 'PBKDF2' || algorithmName === 'HKDF') { - length = 256; - } - break; - case 'digest': - algorithm = algorithmName; - break; - default: - algorithm = algorithmName; - } - - const result = SubtleCrypto.supports(operation, algorithm, length); - - if (isSupported) { - assert_true(result, `${algorithmName} should support ${operation}`); - } else { - assert_false(result, `${algorithmName} should not support ${operation}`); - } - }, `supports(${operation}, ${algorithmName})`); - } -} +runSupportsTests(standardAlgorithms, operations); // Test algorithm objects (not just strings) test(() => { diff --git a/WebCryptoAPI/tools/generate.py b/WebCryptoAPI/tools/generate.py index 35ba0f0031555f..656951d0f5b5b1 100644 --- a/WebCryptoAPI/tools/generate.py +++ b/WebCryptoAPI/tools/generate.py @@ -1,77 +1,246 @@ -# script to generate the generateKey tests - -import os - -here = os.path.dirname(__file__) - -successes_html = """ - - -
- Warning! RSA key generation is intrinsically - very slow, so the related tests can take up to - several minutes to complete, depending on browser! -
- - -""" - -failures_html = """ - - -