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]

Reply via email to