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

  1. Ensure _cipherInfoPtr is non-null (error 14 guards this) and that the OpenSSL runtime matches the binding version.
  2. Use a single, consistent OpenSSL version across the app and all native deps.
  3. 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

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


AI-assisted analysis of shadowsocks/shadowsocks-windows@891d971682 (2026-08-13). Data as JSON: /api/errors/f93feb0a11c46e74. Report an issue: GitHub.