| // 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'; |
| |
| const modernAlgorithms = { |
| // Asymmetric algorithms |
| 'ML-DSA-44': { |
| operations: ['generateKey', 'importKey', 'sign', 'verify', 'getPublicKey'], |
| }, |
| 'ML-DSA-65': { |
| operations: ['generateKey', 'importKey', 'sign', 'verify', 'getPublicKey'], |
| }, |
| 'ML-DSA-87': { |
| operations: ['generateKey', 'importKey', 'sign', 'verify', 'getPublicKey'], |
| }, |
| 'ML-KEM-512': { |
| operations: [ |
| 'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits', |
| 'decapsulateKey', 'decapsulateBits', 'getPublicKey' |
| ], |
| }, |
| 'ML-KEM-768': { |
| operations: [ |
| 'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits', |
| 'decapsulateKey', 'decapsulateBits', 'getPublicKey' |
| ], |
| }, |
| 'ML-KEM-1024': { |
| operations: [ |
| 'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits', |
| 'decapsulateKey', 'decapsulateBits', 'getPublicKey' |
| ], |
| }, |
| 'MLKEM768-P256': { |
| operations: [ |
| 'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits', |
| 'decapsulateKey', 'decapsulateBits', 'getPublicKey' |
| ], |
| }, |
| 'MLKEM768-X25519': { |
| operations: [ |
| 'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits', |
| 'decapsulateKey', 'decapsulateBits', 'getPublicKey' |
| ], |
| }, |
| 'MLKEM1024-P384': { |
| operations: [ |
| 'generateKey', 'importKey', 'encapsulateKey', 'encapsulateBits', |
| 'decapsulateKey', 'decapsulateBits', 'getPublicKey' |
| ], |
| }, |
| |
| // Symmetric algorithms |
| 'ChaCha20-Poly1305': { |
| operations: ['generateKey', 'importKey', 'encrypt', 'decrypt'], |
| encryptParams: {name: 'ChaCha20-Poly1305', iv: new Uint8Array(12)}, |
| }, |
| |
| }; |
| |
| const operations = [ |
| 'generateKey', |
| 'importKey', |
| 'sign', |
| 'verify', |
| 'encrypt', |
| 'decrypt', |
| 'deriveBits', |
| 'digest', |
| 'encapsulateKey', |
| 'encapsulateBits', |
| 'decapsulateKey', |
| 'decapsulateBits', |
| 'getPublicKey', |
| ]; |
| |
| // Test that supports method exists and is a static method |
| testSupportsMethod(); |
| |
| |
| // Test standard WebCrypto algorithms for requested operations |
| runSupportsTests(modernAlgorithms, operations); |
| |
| ['ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87'].forEach(name => { |
| ['sign', 'verify'].forEach(operation => { |
| test(() => { |
| assert_true( |
| SubtleCrypto.supports(operation, { |
| name, |
| context: new Uint8Array(255), |
| }), |
| `${name} ${operation} supports a 255-byte context` |
| ); |
| assert_false( |
| SubtleCrypto.supports(operation, { |
| name, |
| context: new Uint8Array(256), |
| }), |
| `${name} ${operation} rejects a 256-byte context` |
| ); |
| }, `supports validates ${name} ${operation} context length`); |
| }); |
| }); |
| |
| const mlKemImportedKeyCases = [ |
| { |
| description: 'a matching HMAC length', |
| additionalAlgorithm: {name: 'HMAC', hash: 'SHA-256', length: 256}, |
| expected: true, |
| }, |
| { |
| description: 'an algorithm without raw-secret import', |
| additionalAlgorithm: 'Ed25519', |
| expected: false, |
| }, |
| { |
| description: 'an HMAC length shorter than the shared secret', |
| additionalAlgorithm: {name: 'HMAC', hash: 'SHA-256', length: 128}, |
| expected: false, |
| }, |
| { |
| description: 'an HMAC length longer than the shared secret', |
| additionalAlgorithm: {name: 'HMAC', hash: 'SHA-256', length: 512}, |
| expected: false, |
| }, |
| ]; |
| |
| ['encapsulateKey', 'decapsulateKey'].forEach(operation => { |
| mlKemImportedKeyCases.forEach(({ |
| description, |
| additionalAlgorithm, |
| expected, |
| }) => { |
| test(() => { |
| assert_equals( |
| SubtleCrypto.supports( |
| operation, |
| 'ML-KEM-768', |
| additionalAlgorithm |
| ), |
| expected, |
| `ML-KEM-768 ${operation} with ${description}` |
| ); |
| }, `supports ${operation} with ${description}`); |
| }); |
| }); |
| |
| // Test some algorithm objects with valid parameters |
| test(() => { |
| assert_true( |
| SubtleCrypto.supports('encrypt', { |
| name: 'ChaCha20-Poly1305', |
| iv: new Uint8Array(12), |
| tagLength: 128, |
| }), |
| 'ChaCha20-Poly1305 encrypt with valid tagLength'); |
| }, 'supports returns true for algorithm objects with valid parameters'); |
| |
| // Test some algorithm objects with invalid parameters |
| test(() => { |
| assert_false( |
| SubtleCrypto.supports('encrypt', { |
| name: 'ChaCha20-Poly1305', |
| iv: new Uint8Array(12), |
| tagLength: 100, |
| }), |
| 'ChaCha20-Poly1305 encrypt with invalid tagLength'); |
| |
| assert_false( |
| SubtleCrypto.supports('encrypt', { |
| name: 'ChaCha20-Poly1305', |
| iv: new Uint8Array(10), |
| tagLength: 128, |
| }), |
| 'ChaCha20-Poly1305 encrypt with invalid iv'); |
| }, 'supports returns false for algorithm objects with invalid parameters'); |
| |
| |
| done(); |