Hi Ger,

Thanks for your detailed response. My counter-responses are inlined.


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 */


---------
AM: Yes, this is the problem. I see this assert holds (meaning cipher->ctrl
is NULL).
Whereas in the encryption part, it is correct.
---------



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.


------------
AM: Either the corruption happens in this call, or in the preceeding
EVP_CIPHER_CTX_init 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...)

---------
AM: I am on OpenSSL 0.9.8h 28 May 2008. So, reasonably recent.
---------

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.

------
AM: This is now very clear. Thanks for explaining how the function is being
defined.
Initial doubts on this function is gone.
-------



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);

----------
AM: error: cannot convert `int (* const*)(EVP_CIPHER_CTX*, int, int,
   void*)' to `int (*)(EVP_CIPHER_CTX*, int, int, void*)' in assignment


dbg_var is a function pointer variable, so I do: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).

------------------
AM: The assert fails right at the start of the function. If I remove that
and put it after the
EVP_CIPHER_CTX_init call, even then it fails. It means, that somehow this is
not taking. I will have
to investigate more.
------------------


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


DISCLAIMER
==========
This e-mail may contain privileged and confidential information which is the 
property of Persistent Systems Ltd. It is intended only for the use of the 
individual or entity to which it is addressed. If you are not the intended 
recipient, you are not authorized to read, retain, copy, print, distribute or 
use this message. If you have received this communication in error, please 
notify the sender and delete all copies of this message. Persistent Systems 
Ltd. does not accept any liability for virus infected mails.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to