|
View:
New views
8 Messages
—
Rating Filter:
Alert me
|
|
|
EVP_CipherInit_ex because cipher->do_cipher is NULLHi all,
I am using the EVP API for encryption and decryption (Code snippet below). The encrypion works fine, but the decryption fails in EVP_CipherInit_ex. Both the codes are identical except that the said function uses 1 as the last argument for encryption and 0 for decryption. I am on Redhat Linux, OpenSSL 0.9.8h 28 May 2008, and g++ 3.3.2 compiler. (C++ compiler) The EVP_CipherInit_ex function returned 0 - indicating failure. Upon investigation, I found out that the context cipher function pointer "do_cipher" is NULL. I have no clue why this will be NULL. In encryption, do_cipher is not NULL; only in decryption, this pointer is NULL. Is there any way to resolve/fix this issue? Do I need to do anything else? I could not find the definition of EVP_des_ede3_cbc() in the openssl codebase. unsigned char initVector[8] = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; //The init vector will be derived from this unsigned char iv[EVP_MAX_IV_LENGTH], key[EVP_MAX_KEY_LENGTH]; EVP_CIPHER_CTX ctx; unsigned char keyInput[24] = {0x3F,0x6F,0x6B,0x69,0x20,0x5E,0x5F,0x45,0x65,0x54,0x5D,0x56,0x63,0x68,0x6E, 0x6F,0x14,0x32,0x2C,0x41,0x3F,0xD3,0x9B,0xA3}; memcpy(iv,initVector,sizeof(iv)); EVP_CIPHER_CTX_init(&ctx); int r2 = EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, keyInput, iv, 0); fprintf(stderr, "cipher initEX ret =%d\n",r2); if (ctx.cipher->do_cipher == NULL) fprintf(stderr, "do_cipher is NULL!!\n"); // This prints, meaning do_cipher is NULL!! // //.. CipherUpdate/Final follow. Not shown here. // 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@... Automated List Manager majordomo@... |
|
|
Re: EVP_CipherInit_ex because cipher->do_cipher is NULLOn Thu, Aug 7, 2008 at 8:13 AM, Ambarish Mitra
<ambarish_mitra@...> wrote: > The EVP_CipherInit_ex function returned 0 - indicating failure. Upon What does OpenSSL report as error code/description? (E.g. when using ERR_print_errors() - see the documentation for how to use) Ger -- Met vriendelijke groeten / Best regards, Ger Hobbelt -------------------------------------------------- web: http://www.hobbelt.com/ http://www.hebbut.net/ mail: ger@... mobile: +31-6-11 120 978 -------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@... Automated List Manager majordomo@... |
|
|
RE: EVP_CipherInit_ex because cipher->do_cipher is NULL-----Original Message----- From: owner-openssl-users@... [mailto:owner-openssl-users@...]On Behalf Of Ger Hobbelt Sent: Friday, August 08, 2008 3:54 PM To: openssl-users@... Subject: Re: EVP_CipherInit_ex because cipher->do_cipher is NULL On Thu, Aug 7, 2008 at 8:13 AM, Ambarish Mitra <ambarish_mitra@...> wrote: > The EVP_CipherInit_ex function returned 0 - indicating failure. Upon What does OpenSSL report as error code/description? (E.g. when using ERR_print_errors() - see the documentation for how to use) Ger Hi Ger, I tried your suggestion: ... ... int r2 = EVP_CipherInit_ex(&ctx, cipher, NULL, key, iv, DECRYPT); ERR_print_errors_fp(stderr); ... ... 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: [ambarish@ps2844]$ openssl errstr 0607C084 error:0607C084:digital envelope routines:EVP_CIPHER_CTX_ctrl:ctrl not implemented [ambarish@ps2844]$ 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? Thanks. 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@... Automated List Manager majordomo@... |
|
|
Re: EVP_CipherInit_ex because cipher->do_cipher is NULLResponse below:
On Tue, Aug 12, 2008 at 7:27 AM, Ambarish Mitra <ambarish_mitra@...> 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: > > [ambarish@ps2844]$ openssl errstr 0607C084 > error:0607C084:digital envelope routines:EVP_CIPHER_CTX_ctrl:ctrl not > implemented > > [ambarish@ps2844]$ 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: ger@... mobile: +31-6-11 120 978 -------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@... Automated List Manager majordomo@... |
|
|
RE: EVP_CipherInit_ex because cipher->do_cipher is NULLHi Ger,
Thanks for your detailed response. My counter-responses are inlined. Response below: On Tue, Aug 12, 2008 at 7:27 AM, Ambarish Mitra <ambarish_mitra@...> 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: > > [ambarish@ps2844]$ openssl errstr 0607C084 > error:0607C084:digital envelope routines:EVP_CIPHER_CTX_ctrl:ctrl not > implemented > > [ambarish@ps2844]$ openssl errstr 0607B086 > error:0607B086:digital envelope routines:EVP_CipherInit:initialization > > > > 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: ger@... 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@... Automated List Manager majordomo@... |
|
|
Re: EVP_CipherInit_ex because cipher->do_cipher is NULLOn Thu, Aug 14, 2008 at 3:30 PM, Ambarish Mitra
<ambarish_mitra@...> wrote: > ------------ > AM: Either the corruption happens in this call, or in the preceeding > EVP_CIPHER_CTX_init call. > ------------ Since the assert() already fails before the init_ex call, it looks like my guess is probably correct: the point in my last email is that the 'cipher' struct must already be incorrect /some time before/ the init_ex() call. In other words: the error is not in the init_ex() call (thast's why I said I was barking up the wrong tree) but in the code that precedes it. I do not know where the 'cipher' variable starts it's life in your code, but right when it starts, I would put the first assert(cipher->ctrl != NULL) check. If THAT assert() fails (which I expect it will), it means the OpenSSL internal (constant!) data pointed at by the EVP_des_ede3_cbc() gets corrupted permanently even earlier. Which is why I said you might want to (a) use a debugger which can break on data change -- so you can detect which bit of code is changing the 'ctrl' pointer value -- or use the global var + assert() set as described lateron in my last email. I am fairly certain now that we are looking at some sort of memory corruption issue - and the trouble is locating where that corruption is caused. One thing I am willing to bet on by now: the corruption will have taken place before you reach that last EVP_CipherInit_ex(...,cipher,...) call and my guess is that it already happened /before/ your last call to EVP_des_ede3_cbc() as well. > --------- > AM: I am on OpenSSL 0.9.8h 28 May 2008. So, reasonably recent. > --------- Good. Shouldn't be too different then when you look at the source code of OpenSSL itself. > ------ > AM: This is now very clear. Thanks for explaining how the function is being > defined. > Initial doubts on this function is gone. > ------- Excellent. You have a type of bug which (IMO) requires the ability to see what's going on under the hood as well; not because OpenSSL is at fault (my guess it's something hidden in your application code, but we need to check further to find out who and where exactly). > typedef int dbg_ctrl_func_t(EVP_CIPHER_CTX *, int, int, void *); [...] > ---------- > AM: error: cannot convert `int (* const*)(EVP_CIPHER_CTX*, int, int, > void*)' to `int (*)(EVP_CIPHER_CTX*, int, int, void*)' in assignment My mistake. Make sure the typedef matches the type for the 'ctrl' member in the 'cipher' struct type exactly. I forgot one level of indirection ('*'), hence the error. What the global var should store is a pointer to the DATA space of 'EVP_des_ede3_cbc()->ctrl', i.e. the bytes which store the value in 'EVP_des_ede3_cbc()->ctrl'. When that value changes, it means someone/something just assigned a new value to 'EVP_des_ede3_cbc()->ctrl' and THAT is wrong (as 'EVP_des_ede3_cbc()->ctrl' is a constant value, which is set at run-time start (pointer to function) before main() is called and should NEVER be changed afterwards. That's what all the > assert(*dbg_var != NULL); /* *dbg_var == EVP...()->cipher */ > assert(*dbg_var == EVP_des_ede3_cbc()->ctrl); should be able to find out: the error occurs before the first assert() that reports a failure, so you see that using these assert()s is really the hard way of finding the offending code where a memory-breakpoint able debugger can do this much faster. >From the fact that you use the assert()s in your code, I take it that you do not have such a debugger? --- side track ----------------------------- If you use gdb, see http://sourceware.org/gdb/current/onlinedocs/gdb_6.html#SEC34 for info how to set such 'watchpoints'. Just in case you use gdb, here's a bit of howto: at the start of main(), make sure you get the proper address to watch, which is '&EVP_des_ede3_cbc()->ctrl' (note the &; just as with the global var and asserts). Then add a watchpoint for that value like this: *(int *)0xabcd1234 where 0xabcd1234 is the value of the '&EVP_des_ede3_cbc()->ctrl' expression right at the start of main(). *(int *)0xabcd1234 should not be a NULL value, by the way. Read up on gdb at that URL if you use it and did not use it like this before. It's faster than tracking down this bugger using a series of assert()s as the assert()s can only 'narrow down the area' where the illegal ctrl field overwrite occurs, so you will need an increasing number of assert()s in your code to pinpoint the offending statement(s). ----------------------------------- > ------------------ > 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. > ------------------ You misunderstood. The assert()s should go in the code /preceding/ the init_ex call as we must find who (re)set that ->ctrl member value to NULL. EVP...init_ex() there is only the /receiver/ of the damage already done /before/. I hope you can use gdb or another debugger instead as that would speed up tracking down the offending code bit quite a bit. If you can't, copy those two assert() lines throughout the code, more is better, because we are looking for a moment since start of main() when the assert()s start to fail. When they fail, it means the bit of code that was prior (before) that and after the previous assert() block is the culprit. Add more assert()s in there to narrow down to a single line of code. As you see this is hard to do when you don't have a debugger around which can watch memory breakpoints (I checked the manual and gdb calls these 'watchpoints'; if you use another debugger, it may have this feature as all modern hardware can do this, but the name to identify it may be different, so checking your debugger's manual may help here -- the 'assert()' approach is the very last ditch and very basic approach if you don't have a debugger on the target system (which can happen to you when you develop on smaller embedded hardware)). Anyway: the important bit is: the bug is in the code /before/ the call to that OpenSSL init_ex function. Now all we need to do is find where the cipher static struct object gets corrupted. -- Met vriendelijke groeten / Best regards, Ger Hobbelt -------------------------------------------------- web: http://www.hobbelt.com/ http://www.hebbut.net/ mail: ger@... mobile: +31-6-11 120 978 -------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@... Automated List Manager majordomo@... |
|
|
RE: [Resolved] EVP_CipherInit_ex because cipher->do_cipher is NULL(Top-posting since this mail is not a direct reply)
Hi Ger, Thanks for leading me in the right direction. The problem is solved. It was my silly mistake. Actually, my main build was also linking with another library that in turn was linking with openssl. This is a 3rd party library, and I did not know that it indeed had openssl symbols. Linking: g++ -o output.bin appssl.o /dir/libssl.a /dir/libcrypto.a -L/dir/lib -laccess The above linking is correct. It statically links the ssl and crypto library, and shared links with a library called libaccess. Now, this library also has openssl symbols, which I checked by doing "nm". If I link both of these in a shared library manner (-l), then there is symbols conflict, and so it deos not work according to expectation. Now, with static linkage, it works. Thanks! -----Original Message----- From: owner-openssl-users@... [mailto:owner-openssl-users@...]On Behalf Of Ger Hobbelt Sent: Thursday, August 14, 2008 8:33 PM To: openssl-users@... Subject: Re: EVP_CipherInit_ex because cipher->do_cipher is NULL On Thu, Aug 14, 2008 at 3:30 PM, Ambarish Mitra <ambarish_mitra@...> wrote: > ------------ > AM: Either the corruption happens in this call, or in the preceeding > EVP_CIPHER_CTX_init call. > ------------ Since the assert() already fails before the init_ex call, it looks like my guess is probably correct: the point in my last email is that the 'cipher' struct must already be incorrect /some time before/ the init_ex() call. In other words: the error is not in the init_ex() call (thast's why I said I was barking up the wrong tree) but in the code that precedes it. I do not know where the 'cipher' variable starts it's life in your code, but right when it starts, I would put the first assert(cipher->ctrl != NULL) check. If THAT assert() fails (which I expect it will), it means the OpenSSL internal (constant!) data pointed at by the EVP_des_ede3_cbc() gets corrupted permanently even earlier. Which is why I said you might want to (a) use a debugger which can break on data change -- so you can detect which bit of code is changing the 'ctrl' pointer value -- or use the global var + assert() set as described lateron in my last email. I am fairly certain now that we are looking at some sort of memory corruption issue - and the trouble is locating where that corruption is caused. One thing I am willing to bet on by now: the corruption will have taken place before you reach that last EVP_CipherInit_ex(...,cipher,...) call and my guess is that it already happened /before/ your last call to EVP_des_ede3_cbc() as well. > --------- > AM: I am on OpenSSL 0.9.8h 28 May 2008. So, reasonably recent. > --------- Good. Shouldn't be too different then when you look at the source code of OpenSSL itself. > ------ > AM: This is now very clear. Thanks for explaining how the function is being > defined. > Initial doubts on this function is gone. > ------- Excellent. You have a type of bug which (IMO) requires the ability to see what's going on under the hood as well; not because OpenSSL is at fault (my guess it's something hidden in your application code, but we need to check further to find out who and where exactly). > typedef int dbg_ctrl_func_t(EVP_CIPHER_CTX *, int, int, void *); [...] > ---------- > AM: error: cannot convert `int (* const*)(EVP_CIPHER_CTX*, int, int, > void*)' to `int (*)(EVP_CIPHER_CTX*, int, int, void*)' in assignment My mistake. Make sure the typedef matches the type for the 'ctrl' member in the 'cipher' struct type exactly. I forgot one level of indirection ('*'), hence the error. What the global var should store is a pointer to the DATA space of 'EVP_des_ede3_cbc()->ctrl', i.e. the bytes which store the value in 'EVP_des_ede3_cbc()->ctrl'. When that value changes, it means someone/something just assigned a new value to 'EVP_des_ede3_cbc()->ctrl' and THAT is wrong (as 'EVP_des_ede3_cbc()->ctrl' is a constant value, which is set at run-time start (pointer to function) before main() is called and should NEVER be changed afterwards. That's what all the > assert(*dbg_var != NULL); /* *dbg_var == EVP...()->cipher */ > assert(*dbg_var == EVP_des_ede3_cbc()->ctrl); should be able to find out: the error occurs before the first assert() that reports a failure, so you see that using these assert()s is really the hard way of finding the offending code where a memory-breakpoint able debugger can do this much faster. >From the fact that you use the assert()s in your code, I take it that you do not have such a debugger? --- side track ----------------------------- If you use gdb, see http://sourceware.org/gdb/current/onlinedocs/gdb_6.html#SEC34 for info how to set such 'watchpoints'. Just in case you use gdb, here's a bit of howto: at the start of main(), make sure you get the proper address to watch, which is '&EVP_des_ede3_cbc()->ctrl' (note the &; just as with the global var and asserts). Then add a watchpoint for that value like this: *(int *)0xabcd1234 where 0xabcd1234 is the value of the '&EVP_des_ede3_cbc()->ctrl' expression right at the start of main(). *(int *)0xabcd1234 should not be a NULL value, by the way. Read up on gdb at that URL if you use it and did not use it like this before. It's faster than tracking down this bugger using a series of assert()s as the assert()s can only 'narrow down the area' where the illegal ctrl field overwrite occurs, so you will need an increasing number of assert()s in your code to pinpoint the offending statement(s). ----------------------------------- > ------------------ > 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. > ------------------ You misunderstood. The assert()s should go in the code /preceding/ the init_ex call as we must find who (re)set that ->ctrl member value to NULL. EVP...init_ex() there is only the /receiver/ of the damage already done /before/. I hope you can use gdb or another debugger instead as that would speed up tracking down the offending code bit quite a bit. If you can't, copy those two assert() lines throughout the code, more is better, because we are looking for a moment since start of main() when the assert()s start to fail. When they fail, it means the bit of code that was prior (before) that and after the previous assert() block is the culprit. Add more assert()s in there to narrow down to a single line of code. As you see this is hard to do when you don't have a debugger around which can watch memory breakpoints (I checked the manual and gdb calls these 'watchpoints'; if you use another debugger, it may have this feature as all modern hardware can do this, but the name to identify it may be different, so checking your debugger's manual may help here -- the 'assert()' approach is the very last ditch and very basic approach if you don't have a debugger on the target system (which can happen to you when you develop on smaller embedded hardware)). Anyway: the important bit is: the bug is in the code /before/ the call to that OpenSSL init_ex function. Now all we need to do is find where the cipher static struct object gets corrupted. -- Met vriendelijke groeten / Best regards, Ger Hobbelt -------------------------------------------------- web: http://www.hobbelt.com/ http://www.hebbut.net/ mail: ger@... mobile: +31-6-11 120 978 -------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@... Automated List Manager majordomo@... 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@... Automated List Manager majordomo@... |
|
|
Re: [Resolved] EVP_CipherInit_ex because cipher->do_cipher is NULLGood to hear it worked out okay. Had not anticipated the symbol
collision, so I am really glad you found is was due to that. Take care and good luck, Ger On Mon, Aug 18, 2008 at 6:49 AM, Ambarish Mitra <ambarish_mitra@...> wrote: > (Top-posting since this mail is not a direct reply) > > Hi Ger, > > Thanks for leading me in the right direction. The problem is solved. It was > my silly mistake. > > Actually, my main build was also linking with another library that in turn > was linking with openssl. This is a 3rd party library, and I did not know > that it indeed had openssl symbols. > > Linking: > g++ -o output.bin appssl.o /dir/libssl.a > /dir/libcrypto.a -L/dir/lib -laccess > > The above linking is correct. It statically links the ssl and crypto > library, and shared links with a library called libaccess. Now, this library > also has openssl symbols, which I checked by doing "nm". If I link both of > these in a shared library manner (-l), then there is symbols conflict, and > so it deos not work according to expectation. Now, with static linkage, it > works. > > Thanks! -- Met vriendelijke groeten / Best regards, Ger Hobbelt -------------------------------------------------- web: http://www.hobbelt.com/ http://www.hebbut.net/ mail: ger@... mobile: +31-6-11 120 978 -------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@... Automated List Manager majordomo@... |
| Free Forum Powered by Nabble | Forum Help |