Response below: On Tue, Aug 12, 2008 at 7:27 AM, Ambarish Mitra <[EMAIL PROTECTED]> wrote: > The output was: > 933945:error:0607C084:lib(6):func(124):reason(132):evp_enc.c:523: > 933945:error:0607B086:lib(6):func(123):reason(134):evp_enc.c:170: > > [EMAIL PROTECTED] openssl errstr 0607C084 > error:0607C084:digital envelope routines:EVP_CIPHER_CTX_ctrl:ctrl not > implemented > > [EMAIL PROTECTED] openssl errstr 0607B086 > error:0607B086:digital envelope routines:EVP_CipherInit:initialization error > > > > It says "ctrl not implemented". This looks very strange to me because the > same function (EVP_CipherInit_ex) works okay in the encryption stage, this > fails only in the decryption stage. What is the meaning of "ctrl not > implemented"? And why would this be not implemented in decryption stage, but > be implemented in encryption stage? > > Any pointers on how to resolve or fix this problem?
Well, this looks like I am barking up the wrong tree as well. Because this is OpenSSL's way of saying "you don't have a 'ctrl' method' for your cipher" which is exactly the thing that caused the crash (ctrl is a NULL instead of a function pointer), but the /why/ must originate from /before/ you even called EVP_CipherInit_ex() as you feed that one a 'cipher', where, I /assume/, these conditions apply: assert(cipher != NULL); /* expected and okay */ assert(cipher->ctrl == NULL); /* this will cause CipherInit_ex() to fail and is definitely NOT what one would expect */ The second one is the fault and must be caused by code /preceeding/ EVP_CipherInit_ex(). Which, when I refer back to the original email of yours, is the EVP_des_ede3_cbc() call. This is starting to get weird (or I am looking at it from a completely /wrong/ angle here). Anyway, I'll just describe what I see in the code and what you should expect and can test for. (Note that I am looking at 0.9.9 latest CVS so things may be slightly different for you; the process should be the same however...) When you grep for EVP_des_ede3_cbc() in the OpenSSL code you will only find the function prototype. That is because the definition is part of a macro called BLOCK_CIPHER_defs in e_des3.c. That macro expands into a call to (among others) the BLOCK_CIPHER_def_cbc() macro in evp_locl.h (and NOTICE the 'ctrl' parameter being passed along: that's a reference to the des3_ctrl() function) This macro in turn expands to a macro called BLOCK_CIPHER_def1() which generates a static const data object and a 'get' function, constructed from the parts passed: that 'get' function (which returns the address (pointer to) that static object) is your EVP_ ## des_ede3 ## _cbc() --> EVP_des_ede3_cbc() function (notice how I wrote that first: that's to show what the C preprocessor does: ## is a parameter concatenation operator; I have found that few people know this, hence the explicit mention here. This also explains (in code) why your linker will find the function EVP_des_ede3_cbc() but when you grep for it, you only get the prototype: its name is constructed by an OPenSSL macro. So far, nothing weird. Now, considering your case, it means that cipher->ctrl == NULL (or OPenSSL wouldn't have spit out that error you reported), which means that /either/ des3_ctrl() suddenly and miraculously turned into a NULL pointer OR that the data object pointed at by EVP_des_ede3_cbc() has been corrupted in some way by previous actions. Which leads me to the next thought: is this the very first time you call EVP_des_ede3_cbc() directly or indirectly in your code? (Because this has got the stink of 'data corruption' if I am any judge.) Hm, one way to find out if the des_ede3_cbc cipher definition object gets corrupted somewhere /before/ you get to EVP_CipherInit_ex(), you may need to debug the code using a debugger which can breakpoint on data changes (i.e. break on change of byte/bytes at address X, where address to monitor is &EVP_des_ede3_cbc()->cipher (note the & here). The fun bit here is that it doesn't look like a missing case of is does not look like a case of missing SSL_library_init() or OpenSSL_add_all_ciphers() -- both common mistakes -- as EVP_des_ede3_cbc() should work perfectly without either of those setup calls. So, assuming I am correct in guessing that assert(cipher->ctrl != NULL); fails immediately before you call EVP_CipherInit_ex(..., cipher, ...), you can either go the debugger route or do the same in code: create a global variable like this: typedef int dbg_ctrl_func_t(EVP_CIPHER_CTX *, int, int, void *); /* global var */ dbg_ctrl_func_t *dbg_var = 0; then somewhere at the start of your app, do this: dbg_var = &(EVP_des_ede3_cbc()->ctrl); assert(*dbg_var != NULL); /* *dbg_var == EVP...()->cipher */ assert(*dbg_var == EVP_des_ede3_cbc()->ctrl); and plonk the next asserts in all spots where you think it might get touched: assert(*dbg_var != NULL); assert(*dbg_var == EVP_des_ede3_cbc()->ctrl); as somewhere along those assert()s should barf a hairball (== report an error and abort). The above code is for when you don't have a debugger which can watch for data changes at address &EVP_des_ede3_cbc()->ctrl I hope I didn't loose you in there; if you have questions though, just ask. Caveat: I am not 100% sure this is the right direction to take, but if it isn't, I don't see where my analysis went pear shaped. Better thoughts are always welcome. -- Met vriendelijke groeten / Best regards, Ger Hobbelt -------------------------------------------------- web: http://www.hobbelt.com/ http://www.hebbut.net/ mail: [EMAIL PROTECTED] mobile: +31-6-11 120 978 -------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]