What is the problem this feature will solve?
SM4-GCM and SM4-CCM are documented as available in OpenSSL 3.x default provider (EVP_CIPHER-SM4), and the source files (cipher_sm4_gcm.c, cipher_sm4_ccm.c) are included in Node.js's OpenSSL build (deps/openssl/config/archs/*/openssl.gypi and providers/implementations/ciphers/build.info). However, these ciphers are not registered at runtime.
This affects cross-language interoperability for projects using SM4-GCM (e.g., Java BouncyCastle) that need Node.js decryption support, and China compliance (GM/T 0002) scenarios requiring authenticated encryption with SM4.
Reproduction
const crypto = require('node:crypto');
console.log('Node.js:', process.version); // v24.18.0
console.log('OpenSSL:', process.versions.openssl); // 3.5.7
console.log('FIPS:', crypto.getFips()); // 0
// SM4-GCM not in getCiphers()
console.log(crypto.getCiphers().filter(c => c.includes('sm4')));
// → [ 'sm4', 'sm4-cbc', 'sm4-cfb', 'sm4-ctr', 'sm4-ecb', 'sm4-ofb' ]
// Missing: sm4-gcm, sm4-ccm, sm4-xts
// getCipherInfo returns undefined
console.log(crypto.getCipherInfo('sm4-gcm')); // → undefined
console.log(crypto.getCipherInfo('sm4-cbc')); // → { mode: 'cbc', nid: 1134, ... }
// createCipheriv throws
try {
crypto.createCipheriv('sm4-gcm', Buffer.alloc(16), Buffer.alloc(12));
} catch (e) {
console.log(e.message); // → "Unknown cipher"
}
Evidence that this is a Node.js build issue (not OpenSSL)
- OpenSSL docs list SM4-GCM/CCM/XTS as available in the default provider since 3.1+.
- Python
cryptography library (linking system OpenSSL 3.x) supports SM4-GCM.
- Source files are compiled:
deps/openssl/config/archs/VC-WAN64A/no-asm/openssl.gypi includes:
'openssl/providers/implementations/ciphers/cipher_sm4_gcm.c',
'openssl/providers/implementations/ciphers/cipher_sm4_gcm_hw.c',
'openssl/providers/implementations/ciphers/cipher_sm4_ccm.c',
'openssl/providers/implementations/ciphers/cipher_sm4_ccm_hw.c',
'openssl/providers/implementations/ciphers/cipher_sm4_xts.c',
'openssl/providers/implementations/ciphers/cipher_sm4_xts_hw.c',
build.info includes them unconditionally (given !$disabled{sm4}, and SM4-CBC works).
- No
no-sm4 in Configure options (deps/openssl/config/Makefile COPTS).
Suspected root cause
Node.js builds OpenSSL with enable-fips. The FIPS module build process may regenerate or filter the default provider's OSSL_ALGORITHM dispatch table, causing SM4-GCM/CCM/XTS registration entries to be dropped while basic SM4 modes (CBC, CTR, ECB, OFB, CFB) are retained.
Additionally, deps/ncrypto/ncrypto.cc line 4304 uses the legacy API:
const Cipher Cipher::FromName(const char* name) {
return Cipher(EVP_get_cipherbyname(name));
}
Even if the provider registration is fixed, EVP_get_cipherbyname() may not resolve provider-only ciphers that lack a legacy EVP_CIPHER object (per openssl/openssl#13667: "There never will be an evp_sm4_gcm() function"). A fallback to EVP_CIPHER_fetch(NULL, name, NULL) may be needed.
What is the feature you are proposing?
- Investigate why SM4-GCM/CCM/XTS are not registered in the default provider at runtime despite being compiled.
- If the
enable-fips build path is the cause, ensure non-FIPS algorithms remain registered in the default provider.
- Consider adding an
EVP_CIPHER_fetch fallback in Cipher::FromName() for forward compatibility with provider-only ciphers.
Environment
- Node.js: v24.18.0
- OpenSSL: 3.5.7
- OS: Windows 11 24H2
- FIPS mode: disabled (0)
What is the problem this feature will solve?
SM4-GCM and SM4-CCM are documented as available in OpenSSL 3.x default provider (EVP_CIPHER-SM4), and the source files (
cipher_sm4_gcm.c,cipher_sm4_ccm.c) are included in Node.js's OpenSSL build (deps/openssl/config/archs/*/openssl.gypiandproviders/implementations/ciphers/build.info). However, these ciphers are not registered at runtime.This affects cross-language interoperability for projects using SM4-GCM (e.g., Java BouncyCastle) that need Node.js decryption support, and China compliance (GM/T 0002) scenarios requiring authenticated encryption with SM4.
Reproduction
Evidence that this is a Node.js build issue (not OpenSSL)
cryptographylibrary (linking system OpenSSL 3.x) supports SM4-GCM.deps/openssl/config/archs/VC-WAN64A/no-asm/openssl.gypiincludes:build.infoincludes them unconditionally (given!$disabled{sm4}, and SM4-CBC works).no-sm4in Configure options (deps/openssl/config/MakefileCOPTS).Suspected root cause
Node.js builds OpenSSL with
enable-fips. The FIPS module build process may regenerate or filter the default provider'sOSSL_ALGORITHMdispatch table, causing SM4-GCM/CCM/XTS registration entries to be dropped while basic SM4 modes (CBC, CTR, ECB, OFB, CFB) are retained.Additionally,
deps/ncrypto/ncrypto.ccline 4304 uses the legacy API:Even if the provider registration is fixed,
EVP_get_cipherbyname()may not resolve provider-only ciphers that lack a legacyEVP_CIPHERobject (per openssl/openssl#13667: "There never will be anevp_sm4_gcm()function"). A fallback toEVP_CIPHER_fetch(NULL, name, NULL)may be needed.What is the feature you are proposing?
enable-fipsbuild path is the cause, ensure non-FIPS algorithms remain registered in the default provider.EVP_CIPHER_fetchfallback inCipher::FromName()for forward compatibility with provider-only ciphers.Environment