shadowsocks/shadowsocks-windows · critical · System.Exception
openssl: fail to init ctx
Error message
openssl: fail to init ctx
What it means
Thrown from AEADOpenSSLEncryptor.InitCipher when the first EVP_CipherInit_ex returns != 1. This call initialises the context with the cipher (from _cipherInfoPtr) and the encrypt/decrypt flag, passing null key/IV. Failure means OpenSSL rejected the cipher/context combination at setup.
Source
Thrown at shadowsocks-csharp/Encryption/AEAD/AEADOpenSSLEncryptor.cs:68
if (_cipherInfoPtr == IntPtr.Zero) throw new System.Exception("openssl: cipher not found");
IntPtr ctx = OpenSSL.EVP_CIPHER_CTX_new();
if (ctx == IntPtr.Zero) throw new System.Exception("openssl: fail to create ctx");
if (isEncrypt)
{
_encryptCtx = ctx;
}
else
{
_decryptCtx = ctx;
}
DeriveSessionKey(isEncrypt ? _encryptSalt : _decryptSalt, _Masterkey,
isEncrypt ? _opensslEncSubkey : _opensslDecSubkey);
var ret = OpenSSL.EVP_CipherInit_ex(ctx, _cipherInfoPtr, IntPtr.Zero, null, null,
isEncrypt ? OpenSSL.OPENSSL_ENCRYPT : OpenSSL.OPENSSL_DECRYPT);
if (ret != 1) throw new System.Exception("openssl: fail to init ctx");
ret = OpenSSL.EVP_CIPHER_CTX_set_key_length(ctx, keyLen);
if (ret != 1) throw new System.Exception("openssl: fail to set key length");
ret = OpenSSL.EVP_CIPHER_CTX_ctrl(ctx, OpenSSL.EVP_CTRL_AEAD_SET_IVLEN,
nonceLen, IntPtr.Zero);
if (ret != 1) throw new System.Exception("openssl: fail to set AEAD nonce length");
ret = OpenSSL.EVP_CipherInit_ex(ctx, IntPtr.Zero, IntPtr.Zero,
isEncrypt ? _opensslEncSubkey : _opensslDecSubkey,
null,
isEncrypt ? OpenSSL.OPENSSL_ENCRYPT : OpenSSL.OPENSSL_DECRYPT);
if (ret != 1) throw new System.Exception("openssl: cannot set key");
OpenSSL.EVP_CIPHER_CTX_set_padding(ctx, 0);
}
public override void cipherEncrypt(byte[] plaintext, uint plen, byte[] ciphertext, ref uint clen)
{
View on GitHub (pinned to 891d971682)
Solutions
- Ensure _cipherInfoPtr is non-null (error 14 guards this) and that the OpenSSL runtime matches the binding version.
- Use a single, consistent OpenSSL version across the app and all native deps.
- Verify the context is freshly created (error 15) and not reused without EVP_CIPHER_CTX_reset.
Example fix
// before
var ret = OpenSSL.EVP_CipherInit_ex(ctx, _cipherInfoPtr, IntPtr.Zero, null, null, isEncrypt ? OpenSSL.OPENSSL_ENCRYPT : OpenSSL.OPENSSL_DECRYPT);
if (ret != 1) throw new System.Exception("openssl: fail to init ctx");
// after
if (ret != 1)
throw new System.Exception($"openssl: fail to init ctx (ret={ret}, cipher={_innerLibName}); check OpenSSL ABI version"); Defensive patterns
Strategy: validation
Validate before calling
// Validate cipher info and context freshness before init
if (_cipherInfoPtr == IntPtr.Zero) throw new InvalidOperationException("no cipher info");
if (ctx == IntPtr.Zero) throw new InvalidOperationException("no ctx"); Try / catch
try { OpenSSL.EVP_CipherInit_ex(...); }
catch (Exception ex) when (ex.Message.Contains("fail to init ctx"))
{ /* recreate ctx, verify OpenSSL ABI, fall back to mbedTLS */ } Prevention
- Use one consistent OpenSSL version across all native dependencies.
- Create a fresh context per session and reset before reuse.
- Cross-check binding headers against the runtime library version.
When it happens
Trigger: _cipherInfoPtr is invalid/null for this OpenSSL version; the context was created but is in a bad state; the cipher requires initialisation options this build does not provide; mismatch between OpenSSL headers used to build the bindings and the runtime library.
Common situations: ABI mismatch between binding and runtime OpenSSL; a cipher present at compile time but not at runtime; calling EVP_CipherInit_ex on an already-initialised context that was not reset.
Related errors
- openssl: cannot set key
- openssl: cipher not found
- openssl: fail to create ctx
- openssl: fail to set key length
- openssl: fail to set AEAD nonce length
AI-assisted analysis of shadowsocks/shadowsocks-windows@891d971682 (2026-08-13).
Data as JSON: /api/errors/f93feb0a11c46e74.
Report an issue: GitHub.