Files
node/test/fixtures/webcrypto/supports-modern-algorithms.mjs
T
Filip Skokan acbc3ff133 test,benchmark: drop OpenSSL 1.x-only coverage
Delete test-crypto-ecb.js, which can no longer run anywhere: Blowfish
is available only from OpenSSL's legacy provider and is absent from
BoringSSL.

The addon and cctest version guards become OPENSSL_IS_BORINGSSL checks.
Remove legacy digest-alias coverage and unreachable OpenSSL 1.x
branches. JavaScript test and benchmark gates, skip reasons, and TLS
error expectations that distinguished OpenSSL 1.x from provider-backed
OpenSSL now distinguish BoringSSL, including PKCS12 parsing, named DH
groups, private-key serialization, RSA-PSS parameters, consolidated
provider caches, FIPS availability, and empty KMAC output. Keep the CCM
alternate finalization error only for BoringSSL.

Provider-only test skips use version-neutral terminology or state the
actual minimum OpenSSL version.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/64777
Fixes: https://github.com/nodejs/node/issues/56733
Refs: https://github.com/nodejs/node/pull/64211
Refs: https://github.com/nodejs/node/pull/63966
Refs: https://github.com/nodejs/node/pull/53329
Refs: https://github.com/nodejs/node/pull/48950
Refs: https://github.com/nodejs/node/issues/45465
Refs: https://github.com/nodejs/node/issues/42827
Refs: https://github.com/nodejs/node/issues/47076
Refs: https://github.com/nodejs/node/pull/62862
Refs: https://github.com/nodejs/node/pull/38512
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
2026-10-25 22:36:32 +01:00

309 lines
14 KiB
JavaScript

import * as crypto from 'node:crypto'
import { hasOpenSSL, isBoringSSL } from '../../common/crypto.js'
import { X25519, Ed25519 } from './supports-level-2.mjs'
import { X448, Ed448 } from './supports-secure-curves.mjs'
const boringSSL = isBoringSSL;
const fips = crypto.getFips() === 1;
const chacha = boringSSL || crypto.getCiphers().includes('chacha20-poly1305');
const pqc = hasOpenSSL(3, 5) || boringSSL;
const argon2 = hasOpenSSL(3, 2) && !fips;
const shake128 = crypto.getHashes().includes('shake128');
const shake256 = crypto.getHashes().includes('shake256');
const cshake128 = crypto.getHashes().includes('cshake128');
const cshake256 = crypto.getHashes().includes('cshake256');
const ocb = !isBoringSSL && crypto.getCiphers().includes('aes-128-ocb');
const kmac = !isBoringSSL && crypto.getMacs().includes('kmac128');
const hybridKems = !fips && pqc && (!boringSSL || shake256);
export const vectors = {
'digest': [
[false, 'cSHAKE128'],
[shake128, { name: 'cSHAKE128', outputLength: 128 }],
[shake128, { name: 'cSHAKE128', outputLength: 128, functionName: Buffer.alloc(0), customization: Buffer.alloc(0) }],
[cshake128, { name: 'cSHAKE128', outputLength: 128, functionName: Buffer.from('KMAC') }],
[false, { name: 'cSHAKE128', outputLength: 128, functionName: Buffer.from('SHAKE') }],
[cshake128, { name: 'cSHAKE128', outputLength: 128, customization: Buffer.alloc(1, 1) }],
[false, { name: 'cSHAKE128', outputLength: 128, customization: Buffer.alloc(1) }],
[false, { name: 'cSHAKE128', outputLength: 128, customization: Buffer.alloc(513) }],
[false, { name: 'cSHAKE128', outputLength: 127 }],
[false, 'cSHAKE256'],
[shake256, { name: 'cSHAKE256', outputLength: 256 }],
[shake256, { name: 'cSHAKE256', outputLength: 256, functionName: Buffer.alloc(0), customization: Buffer.alloc(0) }],
[cshake256, { name: 'cSHAKE256', outputLength: 256, functionName: Buffer.from('KMAC') }],
[false, { name: 'cSHAKE256', outputLength: 256, functionName: Buffer.from('SHAKE') }],
[cshake256, { name: 'cSHAKE256', outputLength: 256, customization: Buffer.alloc(1, 1) }],
[false, { name: 'cSHAKE256', outputLength: 256, customization: Buffer.alloc(1) }],
[false, { name: 'cSHAKE256', outputLength: 256, customization: Buffer.alloc(513) }],
[false, { name: 'cSHAKE256', outputLength: 255 }],
[false, 'TurboSHAKE128'],
[!fips, { name: 'TurboSHAKE128', outputLength: 128 }],
[!fips, { name: 'TurboSHAKE128', outputLength: 128, domainSeparation: 0x07 }],
[false, { name: 'TurboSHAKE128', outputLength: 0 }],
[false, { name: 'TurboSHAKE128', outputLength: 127 }],
[false, { name: 'TurboSHAKE128', outputLength: 128, domainSeparation: 0x00 }],
[false, { name: 'TurboSHAKE128', outputLength: 128, domainSeparation: 0x80 }],
[false, 'TurboSHAKE256'],
[!fips, { name: 'TurboSHAKE256', outputLength: 256 }],
[!fips, { name: 'TurboSHAKE256', outputLength: 256, domainSeparation: 0x07 }],
[false, { name: 'TurboSHAKE256', outputLength: 0 }],
[false, { name: 'TurboSHAKE256', outputLength: 255 }],
[false, { name: 'TurboSHAKE256', outputLength: 256, domainSeparation: 0x00 }],
[false, { name: 'TurboSHAKE256', outputLength: 256, domainSeparation: 0x80 }],
[false, 'KT128'],
[!fips, { name: 'KT128', outputLength: 128 }],
[!fips, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(0) }],
[!fips, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(512) }],
[false, { name: 'KT128', outputLength: 128, customization: Buffer.alloc(513) }],
[false, { name: 'KT128', outputLength: 0 }],
[false, { name: 'KT128', outputLength: 127 }],
[false, 'KT256'],
[!fips, { name: 'KT256', outputLength: 256 }],
[!fips, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(0) }],
[!fips, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(512) }],
[false, { name: 'KT256', outputLength: 256, customization: Buffer.alloc(513) }],
[false, { name: 'KT256', outputLength: 0 }],
[false, { name: 'KT256', outputLength: 255 }],
],
'sign': [
[pqc, 'ML-DSA-44'],
[pqc, 'ML-DSA-65'],
[pqc, 'ML-DSA-87'],
[pqc, { name: 'ML-DSA-44', context: Buffer.alloc(0) }],
[pqc, { name: 'ML-DSA-65', context: Buffer.alloc(0) }],
[pqc, { name: 'ML-DSA-87', context: Buffer.alloc(0) }],
[pqc, { name: 'ML-DSA-44', context: Buffer.alloc(32) }],
[pqc, { name: 'ML-DSA-65', context: Buffer.alloc(32) }],
[pqc, { name: 'ML-DSA-87', context: Buffer.alloc(32) }],
[pqc, { name: 'ML-DSA-44', context: Buffer.alloc(255) }],
[pqc, { name: 'ML-DSA-65', context: Buffer.alloc(255) }],
[pqc, { name: 'ML-DSA-87', context: Buffer.alloc(255) }],
[false, { name: 'ML-DSA-44', context: Buffer.alloc(256) }],
[false, { name: 'ML-DSA-65', context: Buffer.alloc(256) }],
[false, { name: 'ML-DSA-87', context: Buffer.alloc(256) }],
[false, 'Argon2d'],
[false, 'Argon2i'],
[false, 'Argon2id'],
[false, 'KMAC128'],
[false, 'KMAC256'],
[kmac, { name: 'KMAC128', outputLength: 256 }],
[false, { name: 'KMAC128', outputLength: 255 }],
[kmac, { name: 'KMAC256', outputLength: 256 }],
[false, { name: 'KMAC256', outputLength: 255 }],
],
'generateKey': [
[pqc, 'ML-DSA-44'],
[pqc, 'ML-DSA-65'],
[pqc, 'ML-DSA-87'],
[pqc && !boringSSL, 'ML-KEM-512'],
[pqc, 'ML-KEM-768'],
[pqc, 'ML-KEM-1024'],
[chacha, 'ChaCha20-Poly1305'],
[hybridKems, 'MLKEM768-P256'],
[hybridKems, 'MLKEM768-X25519'],
[hybridKems, 'MLKEM1024-P384'],
[ocb, { name: 'AES-OCB', length: 128 }],
[false, 'Argon2d'],
[false, 'Argon2i'],
[false, 'Argon2id'],
[kmac, 'KMAC128'],
[kmac, 'KMAC256'],
[kmac, { name: 'KMAC128', length: 256 }],
[kmac, { name: 'KMAC256', length: 128 }],
[false, { name: 'KMAC128', length: 0 }],
[false, { name: 'KMAC256', length: 0 }],
[false, { name: 'KMAC128', length: 1 }],
[false, { name: 'KMAC128', length: 24 }],
[kmac, { name: 'KMAC128', length: 32 }],
[false, { name: 'KMAC256', length: 1 }],
[false, { name: 'KMAC256', length: 24 }],
[kmac, { name: 'KMAC256', length: 32 }],
],
'importKey': [
[pqc, 'ML-DSA-44'],
[pqc, 'ML-DSA-65'],
[pqc, 'ML-DSA-87'],
[pqc && !boringSSL, 'ML-KEM-512'],
[pqc, 'ML-KEM-768'],
[pqc, 'ML-KEM-1024'],
[chacha, 'ChaCha20-Poly1305'],
[hybridKems, 'MLKEM768-P256'],
[hybridKems, 'MLKEM768-X25519'],
[hybridKems, 'MLKEM1024-P384'],
[ocb, { name: 'AES-OCB', length: 128 }],
[argon2, 'Argon2d'],
[argon2, 'Argon2i'],
[argon2, 'Argon2id'],
[kmac, 'KMAC128'],
[kmac, 'KMAC256'],
[kmac, { name: 'KMAC128', length: 256 }],
[kmac, { name: 'KMAC256', length: 128 }],
[false, { name: 'KMAC128', length: 0 }],
[false, { name: 'KMAC256', length: 0 }],
[false, { name: 'KMAC128', length: 1 }],
[false, { name: 'KMAC128', length: 24 }],
[kmac, { name: 'KMAC128', length: 32 }],
[false, { name: 'KMAC256', length: 1 }],
[false, { name: 'KMAC256', length: 24 }],
[kmac, { name: 'KMAC256', length: 32 }],
],
'exportKey': [
[pqc, 'ML-DSA-44'],
[pqc, 'ML-DSA-65'],
[pqc, 'ML-DSA-87'],
[pqc && !boringSSL, 'ML-KEM-512'],
[pqc, 'ML-KEM-768'],
[pqc, 'ML-KEM-1024'],
[chacha, 'ChaCha20-Poly1305'],
[hybridKems, 'MLKEM768-P256'],
[hybridKems, 'MLKEM768-X25519'],
[hybridKems, 'MLKEM1024-P384'],
[ocb, 'AES-OCB'],
[false, 'Argon2d'],
[false, 'Argon2i'],
[false, 'Argon2id'],
[kmac, 'KMAC128'],
[kmac, 'KMAC256'],
],
'getPublicKey': [
[true, 'RSA-OAEP'],
[true, 'RSA-PSS'],
[true, 'RSASSA-PKCS1-v1_5'],
[!!X25519, 'X25519'],
[!!X448, 'X448'],
[!!Ed25519, 'Ed25519'],
[!!Ed448, 'Ed448'],
[true, 'ECDH'],
[true, 'ECDSA'],
[pqc, 'ML-DSA-44'],
[pqc, 'ML-DSA-65'],
[pqc, 'ML-DSA-87'],
[pqc && !boringSSL, 'ML-KEM-512'],
[pqc, 'ML-KEM-768'],
[pqc, 'ML-KEM-1024'],
[hybridKems, 'MLKEM768-P256'],
[hybridKems, 'MLKEM768-X25519'],
[hybridKems, 'MLKEM1024-P384'],
[false, 'AES-CTR'],
[false, 'AES-CBC'],
[false, 'AES-GCM'],
[false, 'AES-OCB'],
[false, 'AES-KW'],
[false, 'ChaCha20-Poly1305'],
[false, 'Argon2d'],
[false, 'Argon2i'],
[false, 'Argon2id'],
[false, 'KMAC128'],
[false, 'KMAC256'],
],
'deriveKey': [
[argon2 && !!X25519,
{ name: 'X25519', public: X25519?.publicKey },
'Argon2d'],
[argon2 && !!X25519,
{ name: 'X25519', public: X25519?.publicKey },
'Argon2i'],
[argon2 && !!X25519,
{ name: 'X25519', public: X25519?.publicKey },
'Argon2id'],
],
'deriveBits': [
[argon2, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1 }, 32],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 0 }, 32],
[false, { name: 'Argon2d', nonce: Buffer.alloc(7), parallelism: 1, memory: 8, passes: 1 }, 32],
[argon2, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1 }, 32],
[argon2, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 2, memory: 16, passes: 1 }, 32],
[argon2, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1, secretValue: Buffer.alloc(0) }, 32],
[argon2, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1, associatedData: Buffer.alloc(0) }, 32],
[argon2, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1, version: 0x13 }, 32],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1, version: 0x14 }, 32],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 7, passes: 1 }, 32],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 2, memory: 15, passes: 1 }, 32],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1 }, null],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1 }, 24],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 1, memory: 8, passes: 1 }, 31],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 0, memory: 8, passes: 1 }, 32],
[false, { name: 'Argon2d', nonce: Buffer.alloc(8), parallelism: 16777215, memory: 8, passes: 1 }, 32],
],
'encrypt': [
[chacha, { name: 'ChaCha20-Poly1305', iv: Buffer.alloc(12) }],
[false, { name: 'ChaCha20-Poly1305', iv: Buffer.alloc(16) }],
[chacha, { name: 'ChaCha20-Poly1305', iv: Buffer.alloc(12), tagLength: 128 }],
[false, { name: 'ChaCha20-Poly1305', iv: Buffer.alloc(12), tagLength: 64 }],
[false, 'ChaCha20-Poly1305'],
[ocb, { name: 'AES-OCB', iv: Buffer.alloc(15) }],
[false, { name: 'AES-OCB', iv: Buffer.alloc(16) }],
[ocb, { name: 'AES-OCB', iv: Buffer.alloc(12), tagLength: 128 }],
[ocb, { name: 'AES-OCB', iv: Buffer.alloc(12), tagLength: 96 }],
[ocb, { name: 'AES-OCB', iv: Buffer.alloc(12), tagLength: 64 }],
[false, { name: 'AES-OCB', iv: Buffer.alloc(12), tagLength: 32 }],
[false, 'AES-OCB'],
],
'encapsulateBits': [
[pqc && !boringSSL, 'ML-KEM-512'],
[pqc, 'ML-KEM-768'],
[pqc, 'ML-KEM-1024'],
[hybridKems, 'MLKEM768-P256'],
[hybridKems, 'MLKEM768-X25519'],
[hybridKems, 'MLKEM1024-P384'],
],
'encapsulateKey': [
[pqc && !boringSSL, 'ML-KEM-512', 'AES-KW'],
[pqc, 'ML-KEM-768', 'AES-KW'],
[pqc, 'ML-KEM-768', 'AES-GCM'],
[pqc, 'ML-KEM-768', 'AES-CTR'],
[pqc, 'ML-KEM-768', 'AES-CBC'],
[pqc && chacha, 'ML-KEM-768', 'ChaCha20-Poly1305'],
[pqc, 'ML-KEM-768', 'HKDF'],
[pqc, 'ML-KEM-768', 'PBKDF2'],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256' }],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 256 }],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 255 }],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 249 }],
[false, 'ML-KEM-768', { name: 'KMAC128', length: 255 }],
[hybridKems, 'MLKEM768-P256', 'HKDF'],
[hybridKems, 'MLKEM768-X25519', 'HKDF'],
[hybridKems, 'MLKEM1024-P384', 'HKDF'],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 128 }],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 248 }],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 512 }],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 257 }],
[false, 'ML-KEM-768', { name: 'KMAC128', length: 248 }],
[false, 'ML-KEM-768', 'Ed25519'],
],
'decapsulateBits': [
[pqc && !boringSSL, 'ML-KEM-512'],
[pqc, 'ML-KEM-768'],
[pqc, 'ML-KEM-1024'],
[hybridKems, 'MLKEM768-P256'],
[hybridKems, 'MLKEM768-X25519'],
[hybridKems, 'MLKEM1024-P384'],
],
'decapsulateKey': [
[pqc && !boringSSL, 'ML-KEM-512', 'AES-KW'],
[pqc, 'ML-KEM-768', 'AES-KW'],
[pqc, 'ML-KEM-768', 'AES-GCM'],
[pqc, 'ML-KEM-768', 'AES-CTR'],
[pqc, 'ML-KEM-768', 'AES-CBC'],
[pqc && chacha, 'ML-KEM-768', 'ChaCha20-Poly1305'],
[pqc, 'ML-KEM-768', 'HKDF'],
[pqc, 'ML-KEM-768', 'PBKDF2'],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256' }],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 256 }],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 255 }],
[pqc, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 249 }],
[false, 'ML-KEM-768', { name: 'KMAC128', length: 255 }],
[hybridKems, 'MLKEM768-P256', 'HKDF'],
[hybridKems, 'MLKEM768-X25519', 'HKDF'],
[hybridKems, 'MLKEM1024-P384', 'HKDF'],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 128 }],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 248 }],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 512 }],
[false, 'ML-KEM-768', { name: 'HMAC', hash: 'SHA-256', length: 257 }],
[false, 'ML-KEM-768', { name: 'KMAC128', length: 248 }],
[false, 'ML-KEM-768', 'Ed25519'],
],
};