Re: Using RC4 vs EVP_CIPHER
Steve, Salt shouldn't be predictable so using a fixed string isn't an option but it isn't secret. I'm using rand_bytes() to create the salt. IV. I should really use an IV with some modes. Again, its random bytes, but it doesn't have to be secret. I will also have to transmit the IV to the other side. That's not a security problem is it? Is is a problem if you use the same random bytes for the SALT and the IV? EVP_BytesToKey() also generates an IV so that isn't a problem. I'm attempting to use EVP_aes_128_ofb(). OFB mode should have an IV. I'm passing in 16 char of rand_bytes to EVP_CipherInit_ex(). Currently I'm not passing the IV to the other side. I would expect the decryption to fail since the client and the server aren't using the save IV. Its doesn't fail. This leads me to believe that the cipher isn't actually using the IV. What am I missing? int count = 0; int datal = 0; unsigned char * someSalt; unsigned char * theIV; if (!rand_seeded_p) { rand_seed(); rand_seeded_p = 1; } //setup the salt for the password someSalt = new unsigned char[saltSize]; rand_bytes(someSalt,saltSize); theIV = new unsigned char[saltSize]; rand_bytes(theIV,saltSize); //hash the password into a 128bit key datal = (unsigned long)strlen((const char *)password); EVP_BytesToKey(EVP_aes_128_ofb(), EVP_md5(), (unsigned char *) someSalt, (const unsigned char *)password, datal, count, keystr, NULL); EVP_CIPHER_CTX_init(ctx); EVP_CipherInit_ex(ctx, EVP_aes_128_ofb(), NULL, NULL, NULL, 1); /* We finished modifying parameters so now we can set key and IV */ EVP_CipherInit_ex(ctx, NULL, NULL, keystr, theIV, 1); Thanks, Sean Steve. -- Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage OpenSSL project core developer and freelance consultant. Funding needed! Details on homepage. Homepage: http://www.drh-consultancy.demon.co.uk __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED] __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Using RC4 vs EVP_CIPHER
Steve, Additionally you seem to be using an unsalted key derivation algorithm with a stream cipher (RC4). If passwords are reused then I hope you aren't sending anything sensitive that way because that is an insecure combination. Additional Questions: SALT isn't secret, correct? In this app I'm going to have to send the SALT to the other end in order for the passwords to be the same...This isn't a problem, is it? IV. I should really use an IV with some modes. Again, its random bytes, but it doesn't have to be secret. I will also have to transmit the IV to the other side. That's not a security problem is it? Is is a problem if you use the same random bytes for the SALT and the IV? Thanks, Sean P.S. The books I have are pretty clear on the IV issue, but don't really get into much details on SALT, and none mention if IV=SALT would be a bad thing. Good point. I assume what I really want to use is EVP_BytesToKey to create the key with salt. Thanks for the help! Sean __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED] __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Using RC4 vs EVP_CIPHER
On Tue, May 10, 2005, Sean Covel wrote: Steve, Additionally you seem to be using an unsalted key derivation algorithm with a stream cipher (RC4). If passwords are reused then I hope you aren't sending anything sensitive that way because that is an insecure combination. Additional Questions: SALT isn't secret, correct? In this app I'm going to have to send the SALT to the other end in order for the passwords to be the same...This isn't a problem, is it? Salt shouldn't be predictable so using a fixed string isn't an option but it isn't secret. IV. I should really use an IV with some modes. Again, its random bytes, but it doesn't have to be secret. I will also have to transmit the IV to the other side. That's not a security problem is it? Is is a problem if you use the same random bytes for the SALT and the IV? EVP_BytesToKey() also generates an IV so that isn't a problem. Steve. -- Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage OpenSSL project core developer and freelance consultant. Funding needed! Details on homepage. Homepage: http://www.drh-consultancy.demon.co.uk __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Using RC4 vs EVP_CIPHER
On Mon, Apr 25, 2005, Sean Covel wrote: Now that I've updated to the latest OpenSSL (7g) I've got a question: I implemented some RC4 functionality using the low-level rc4 functions.( RC4_Set_Key, RC4), and its working fine. The OpenSSL documentation recommends using the EVP_* functions instead of the lower level functions. It seems like it might give easy access to additional functionality, so I'm converting. Here's the problem. When I switched the code from RC4 to EVP, the program broke, in a big way. The project freezes and I have to either logout or shutdown in order to get Visual Studio 6 to die. If I'm REALLY patient (and I'm not) I can eventually get Task Manager to come up, and then click on msdev.exe (and then wait.) and then click on end-process (and wait) and then click on OK (and wait). You get the idea. A brief explanation of what the code is doing. The code is a plugin for another program. The program initializes the plugin, passes it a password, and then starts handing it chunks of text to encrypt. The program has a socket open to another identical program, doing the same thing on the other side. Kinda like a chat program. The encrypt key is for sending, the decrypt key is for receiving. All the plugin knows is the key, the input/output buffer, and the length of the chunk. I have the RC4 code and the EVP code both in there. They are controlled by a #define. Here are the relevant chunks for code. I'm trying to give enough code without over-burdening you. If you need more, let me know. [snip] Here's one problem: EVP_CIPHER_CTX_set_key_length(Dctx, 128); the length parameter is in bytes not bits. Additionally you seem to be using an unsalted key derivation algorithm with a stream cipher (RC4). If passwords are reused then I hope you aren't sending anything sensitive that way because that is an insecure combination. Steve. -- Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage OpenSSL project core developer and freelance consultant. Funding needed! Details on homepage. Homepage: http://www.drh-consultancy.demon.co.uk __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Using RC4 vs EVP_CIPHER
Steve, Dr. Stephen Henson wrote: [snip] Here are the relevant chunks for code. I'm trying to give enough code without over-burdening you. If you need more, let me know. [snip] Here's one problem: EVP_CIPHER_CTX_set_key_length(Dctx, 128); the length parameter is in bytes not bits. Thanks. Easy enough to fix. Additionally you seem to be using an unsalted key derivation algorithm with a stream cipher (RC4). If passwords are reused then I hope you aren't sending anything sensitive that way because that is an insecure combination. Good point. I assume what I really want to use is EVP_BytesToKey to create the key with salt. Thanks for the help! Sean __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Using RC4 vs EVP_CIPHER
Now that I've updated to the latest OpenSSL (7g) I've got a question: I implemented some RC4 functionality using the low-level rc4 functions.( RC4_Set_Key, RC4), and its working fine. The OpenSSL documentation recommends using the EVP_* functions instead of the lower level functions. It seems like it might give easy access to additional functionality, so I'm converting. Here's the problem. When I switched the code from RC4 to EVP, the program broke, in a big way. The project freezes and I have to either logout or shutdown in order to get Visual Studio 6 to die. If I'm REALLY patient (and I'm not) I can eventually get Task Manager to come up, and then click on msdev.exe (and then wait.) and then click on end-process (and wait) and then click on OK (and wait). You get the idea. A brief explanation of what the code is doing. The code is a plugin for another program. The program initializes the plugin, passes it a password, and then starts handing it chunks of text to encrypt. The program has a socket open to another identical program, doing the same thing on the other side. Kinda like a chat program. The encrypt key is for sending, the decrypt key is for receiving. All the plugin knows is the key, the input/output buffer, and the length of the chunk. I have the RC4 code and the EVP code both in there. They are controlled by a #define. Here are the relevant chunks for code. I'm trying to give enough code without over-burdening you. If you need more, let me know. unsigned char keystr[MD5_DIGEST_LENGTH]; #ifdef EVP EVP_CIPHER_CTX Ectx; EVP_CIPHER_CTX Dctx; #else RC4_KEY Ekey; RC4_KEY Dkey; #endif unsigned char iv[] = 12345678; PLUGIN_API int Startup(void) { //hash the password into a 128bit key EVP_Digest((unsigned char *)szExternalKey,(unsigned long)strlen((const char *)szExternalKey),keystr,NULL,EVP_md5(),NULL); #ifdef EVP EVP_CIPHER_CTX_init(Ectx); EVP_CipherInit_ex(Ectx, EVP_rc4(), NULL, NULL, NULL, 1); EVP_CIPHER_CTX_set_key_length(Ectx, 128); EVP_CipherInit_ex(Ectx, NULL, NULL, keystr, iv, 1); EVP_Digest((unsigned char *)szExternalKey,(unsigned long)strlen((const char *)szExternalKey),keystr,NULL,EVP_md5(),NULL); EVP_CIPHER_CTX_init(Dctx); EVP_CipherInit_ex(Dctx, EVP_rc4(), NULL, NULL, NULL, 0); EVP_CIPHER_CTX_set_key_length(Dctx, 128); EVP_CipherInit_ex(Dctx, NULL, NULL, keystr, iv, 0); #else RC4_set_key(Ekey,MD5_DIGEST_LENGTH,keystr); RC4_set_key(Dkey,MD5_DIGEST_LENGTH,keystr); #endif } PLUGIN_API BYTE* TransformBuffer(BYTE* pDataBuffer, int nDataLen, int* pnTransformedDataLen) { int dwByteCount = 0; BYTE* pTransBuffer = CheckLocalTransBufferSize(GiveTransDataLen(nDataLen)); if (pTransBuffer == NULL) { *pnTransformedDataLen = -1; return NULL; } #ifdef EVP if(!EVP_CipherUpdate(Ectx, pTransBuffer, dwByteCount, pDataBuffer, nDataLen)) { // Error PrintLog((DEST,TransformBuffer failed)); return NULL; } #else RC4(Ekey,nDataLen,(unsigned char *)pDataBuffer,(unsigned char *)pTransBuffer); #endif // return the transformed data length *pnTransformedDataLen = GiveTransDataLen(nDataLen); return pTransBuffer; } PLUGIN_API BYTE* RestoreBuffer(BYTE* pRestoredDataBuffer, int nDataLen, int* pnRestoredDataLen) { int dwByteCount = 0; if (pRestoredDataBuffer == NULL) { // Give the size of the transformed data buffer, based on the original data length *pnRestoredDataLen = GiveRestDataLen(nDataLen); // Ensure the pLocalRestBuffer that receive transformed data is big enough BYTE* pBuffer = CheckLocalRestBufferSize(*pnRestoredDataLen); return pBuffer; } #ifdef EVP if(!EVP_CipherUpdate(Dctx, pRestoredDataBuffer, dwByteCount, pLocalRestBuffer, nDataLen)) { // Error PrintLog((DEST,RestoreBuffer failed)); return NULL; } #else RC4(Dkey,nDataLen,(unsigned char *)pLocalRestBuffer,(unsigned char *)pRestoredDataBuffer); #endif // return the resulting data length *pnRestoredDataLen = GiveRestDataLen(nDataLen); return pLocalRestBuffer; } PLUGIN_API int Shutdown(void) { // Cleanup everything #ifdef EVP EVP_CIPHER_CTX_cleanup(Ectx); EVP_CIPHER_CTX_cleanup(Dctx); #endif return 1; } __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Using RC4 vs EVP_CIPHER
I'm continuing to test. I've noticed something else strange with the EVP_ functions... I have a test program that reads in text file A a chunk at a time, encrypts the chunk, then writes it out to B. It then reads B back in a chunk at a time, decrypts it, and writes it back out to C. Simple test. If A == C its working. I'm using RC4, a stream cipher. Technically there is no block size. If I set the chunk size to 2048, all is well. If I set it to 50, all is well. 49, good. 48, BAD!!! If I use 48 or below, it doesn't work. Encrypting with EVP_CipherUpdate APPEARS to be working. Decryption with EVP_CipherUpdate returns 1, meaning success, but the output is not decrypted, its just further garbled. My plugin application has LOTS of small chunks, and a few larger chunks getting sent. This might explain why its not working. Ring any bells? Sean Sean Covel wrote: Now that I've updated to the latest OpenSSL (7g) I've got a question: I implemented some RC4 functionality using the low-level rc4 functions.( RC4_Set_Key, RC4), and its working fine. The OpenSSL documentation recommends using the EVP_* functions instead of the lower level functions. It seems like it might give easy access to additional functionality, so I'm converting. Here's the problem. When I switched the code from RC4 to EVP, the program broke, in a big way. The project freezes and I have to either logout or shutdown in order to get Visual Studio 6 to die. If I'm REALLY patient (and I'm not) I can eventually get Task Manager to come up, and then click on msdev.exe (and then wait.) and then click on end-process (and wait) and then click on OK (and wait). You get the idea. A brief explanation of what the code is doing. The code is a plugin for another program. The program initializes the plugin, passes it a password, and then starts handing it chunks of text to encrypt. The program has a socket open to another identical program, doing the same thing on the other side. Kinda like a chat program. The encrypt key is for sending, the decrypt key is for receiving. All the plugin knows is the key, the input/output buffer, and the length of the chunk. I have the RC4 code and the EVP code both in there. They are controlled by a #define. Here are the relevant chunks for code. I'm trying to give enough code without over-burdening you. If you need more, let me know. unsigned char keystr[MD5_DIGEST_LENGTH]; #ifdef EVP EVP_CIPHER_CTX Ectx; EVP_CIPHER_CTX Dctx; #else RC4_KEY Ekey; RC4_KEY Dkey; #endif unsigned char iv[] = 12345678; PLUGIN_API int Startup(void) { //hash the password into a 128bit key EVP_Digest((unsigned char *)szExternalKey,(unsigned long)strlen((const char *)szExternalKey),keystr,NULL,EVP_md5(),NULL); #ifdef EVP EVP_CIPHER_CTX_init(Ectx); EVP_CipherInit_ex(Ectx, EVP_rc4(), NULL, NULL, NULL, 1); EVP_CIPHER_CTX_set_key_length(Ectx, 128); EVP_CipherInit_ex(Ectx, NULL, NULL, keystr, iv, 1); EVP_Digest((unsigned char *)szExternalKey,(unsigned long)strlen((const char *)szExternalKey),keystr,NULL,EVP_md5(),NULL); EVP_CIPHER_CTX_init(Dctx); EVP_CipherInit_ex(Dctx, EVP_rc4(), NULL, NULL, NULL, 0); EVP_CIPHER_CTX_set_key_length(Dctx, 128); EVP_CipherInit_ex(Dctx, NULL, NULL, keystr, iv, 0); #else RC4_set_key(Ekey,MD5_DIGEST_LENGTH,keystr); RC4_set_key(Dkey,MD5_DIGEST_LENGTH,keystr); #endif } PLUGIN_API BYTE* TransformBuffer(BYTE* pDataBuffer, int nDataLen, int* pnTransformedDataLen) { int dwByteCount = 0; BYTE* pTransBuffer = CheckLocalTransBufferSize(GiveTransDataLen(nDataLen)); if (pTransBuffer == NULL) { *pnTransformedDataLen = -1; return NULL; } #ifdef EVP if(!EVP_CipherUpdate(Ectx, pTransBuffer, dwByteCount, pDataBuffer, nDataLen)) { // Error PrintLog((DEST,TransformBuffer failed)); return NULL; } #else RC4(Ekey,nDataLen,(unsigned char *)pDataBuffer,(unsigned char *)pTransBuffer); #endif // return the transformed data length *pnTransformedDataLen = GiveTransDataLen(nDataLen); return pTransBuffer; } PLUGIN_API BYTE* RestoreBuffer(BYTE* pRestoredDataBuffer, int nDataLen, int* pnRestoredDataLen) { int dwByteCount = 0; if (pRestoredDataBuffer == NULL) { // Give the size of the transformed data buffer, based on the original data length *pnRestoredDataLen = GiveRestDataLen(nDataLen); // Ensure the pLocalRestBuffer that receive transformed data is big enough BYTE* pBuffer = CheckLocalRestBufferSize(*pnRestoredDataLen); return pBuffer; } #ifdef EVP if(!EVP_CipherUpdate(Dctx, pRestoredDataBuffer, dwByteCount, pLocalRestBuffer, nDataLen)) { //