{"record":{"id":"dd95e45e1b5f9f24","repo":"shadowsocks/shadowsocks-windows","slug":"ret-is-0","errorCode":null,"errorMessage":"ret is {0}","messagePattern":"ret is (.+?)","errorType":"exception","errorClass":"CryptoErrorException","httpStatus":null,"severity":"critical","filePath":"shadowsocks-csharp/Encryption/AEAD/AEADMbedTLSEncryptor.cs","lineNumber":91,"sourceCode":"            // buf: all plaintext\r\n            // outbuf: ciphertext + tag\r\n            int ret;\r\n            byte[] tagbuf = new byte[tagLen];\r\n            uint olen = 0;\r\n            switch (_cipher)\r\n            {\r\n                case CIPHER_AES:\r\n                    ret = MbedTLS.cipher_auth_encrypt(_encryptCtx,\r\n                        /* nonce */\r\n                        _encNonce, (uint) nonceLen,\r\n                        /* AD */\r\n                        IntPtr.Zero, 0,\r\n                        /* plain */\r\n                        plaintext, plen,\r\n                        /* cipher */\r\n                        ciphertext, ref olen,\r\n                        tagbuf, (uint) tagLen);\r\n                    if (ret != 0) throw new CryptoErrorException(String.Format(\"ret is {0}\", ret));\r\n                    Debug.Assert(olen == plen);\r\n                    // attach tag to ciphertext\r\n                    Array.Copy(tagbuf, 0, ciphertext, (int) plen, tagLen);\r\n                    clen = olen + (uint) tagLen;\r\n                    break;\r\n                default:\r\n                    throw new System.Exception(\"not implemented\");\r\n            }\r\n        }\r\n\r\n        public override void cipherDecrypt(byte[] ciphertext, uint clen, byte[] plaintext, ref uint plen)\r\n        {\r\n            // buf: ciphertext + tag\r\n            // outbuf: plaintext\r\n            int ret;\r\n            uint olen = 0;\r\n            // split tag\r\n            byte[] tagbuf = new byte[tagLen];\r","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/shadowsocks/shadowsocks-windows/blob/891d971682eefcaa2e640258d3b352a3ad3b2233/shadowsocks-csharp/Encryption/AEAD/AEADMbedTLSEncryptor.cs#L73-L109","documentation":"Thrown as CryptoErrorException from cipherEncrypt when MbedTLS.cipher_auth_encrypt (AES-GCM authenticated encryption) returns non-zero. The formatted message includes the native return code. Non-zero from an AEAD encrypt call means the operation could not complete — typically an internal GCM failure rather than bad input, since the inputs were validated earlier during setup.","triggerScenarios":"Plaintext length exceeding the cipher's per-call limits; nonce reuse collision detected internally; the encrypt context was corrupted between setup and this call; plen/tagLen combination the GCM implementation rejects.","commonSituations":"Encrypting an unusually large buffer in a single call; a context being reused after a partial failure left it in a bad state; nonce counter overflow; native memory corruption.","solutions":["Log the exact ret value and look it up in mbedTLS error codes (e.g. MBEDTLS_ERR_CIPHER_*).","Ensure the encrypt context is freshly initialized per session and not shared across threads.","Chunk very large plaintexts instead of passing them in one cipher_auth_encrypt call.","Confirm _encNonce is being incremented (IncrementNonce) and not reused."],"exampleFix":"// before\nif (ret != 0) throw new CryptoErrorException(String.Format(\"ret is {0}\", ret));\n\n// after\nif (ret != 0)\n    throw new CryptoErrorException($\"mbedTLS cipher_auth_encrypt failed (ret={ret}, plen={plen})\");","handlingStrategy":"try-catch","validationCode":"// Sanity-check plaintext length against a per-call cap\nconst int MaxChunk = 1 << 20;\nif (plen > MaxChunk) /* chunk before calling cipher_auth_encrypt */","typeGuard":null,"tryCatchPattern":"try { cipherEncrypt(plain, plen, cipher, ref clen); }\ncatch (CryptoErrorException ex)\n{ /* log ret code; close the relay, the session key/nonce state is suspect */ }","preventionTips":["Increment _encNonce exactly once per encrypted record.","Do not share the encrypt context across threads.","Chunk oversized plaintexts to avoid hitting per-call limits."],"tags":["encryption","aead","mbedtls","aes-gcm","crypto-error"],"backgroundTag":null,"analyzedSha":"891d971682eefcaa2e640258d3b352a3ad3b2233","analyzedAt":"2026-08-13T10:12:34.434Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}