From mastermanu2004 at gmail.com Fri Jul 18 04:06:49 2008 From: mastermanu2004 at gmail.com (Manu Srivastava) Date: Thu, 17 Jul 2008 19:06:49 -0700 Subject: Is gcry_ac_data_encrypt_scheme() not re-entrant? Message-ID: <4dbf9300807171906l7ee4c1age1ff4b9cd782c7f@mail.gmail.com> The libgcrypt manual states that multi-threading should not be an issue, but some behavior I observed prompted me to ask some questions about this property. Let us say that I am using 2048-bit RSA (256 byte blocks) and I that wish to encrypt two separate strings. I initialize the appropriate gcry_ac_io_t structures and then make a call to gcry_ac_data_encrypt_scheme as follows: int encrypt_message(struct crypto_context *cntxt, unsigned char *message, size_t num_bytes, unsigned char **cipher, size_t *cipher) { gcry_ac_io_t io_plaintext; gcry_ac_io_t io_cipher; gcry_ac_io_init(&io_plaintext, GCRY_AC_IO_READABLE, GCRY_AC_IO_STRING, message, num_bytes); gcry_ac_io_init(&io_cipher, GCRY_AC_IO_WRITABLE, GCRY_AC_IO_STRING, &cipher, &cipher_size); err = gcry_ac_data_encrypt_scheme (cntxt->handle, GCRY_AC_ES_PKCS_V1_5, 0, NULL, pub_key, &io_plaintext, &io_cipher); } I encrypt the first string as follows: encrypt_message(my_context, "my string 1", 12, &BUFFER, &BUFFER_SIZE); The result is that a pointer to a cipher array of size 256 bytes is placed in BUFFER, which is precisely what I want. I then encrypt the second string: encrypt_message(my_context, "my string 2", 12, &BUFFER2, &BUFFER_SIZE2) Here is where the issue is. Rather than generating a new array and placing the cipher for string 2 in it, it concatenates this cipher for string 2 with the cipher for string 1! Thus, BUFFER2 points to BUFFER (assuming a re-allocation gave it the same pointer) and BUFFER_SIZE is now 512 bytes! But I really just wanted two disparate cipher buffers of 256 bytes each! Quick questions regarding this behavior: 1) Is there a way around the results described above? In particular, can it be the way I want it to be - each cipher is allocated in its own array rather than successive ciphers being concatenated together? Or do I have to do this manually (i.e. copy chunks of 256 bytes of cipher into their own arrays). An alternative way to pose this question is: Can I "clear" the state so that the next cipher I generate is in its own array? 2) More importantly, is this re-entrant? If I have multiple threads (each with their own gcry_ac_handle_t), then is there a risk of thread 2's cipher being placed contiguously after thread 1's cipher? (This issue would make it impossible to use the encrypt_scheme() methods in a MT environment). Is this also expected behavior? Thanks, Manu From mastermanu2004 at gmail.com Fri Jul 18 05:37:07 2008 From: mastermanu2004 at gmail.com (Manu Srivastava) Date: Thu, 17 Jul 2008 20:37:07 -0700 Subject: Is gcry_ac_data_encrypt_scheme() not re-entrant? In-Reply-To: <4dbf9300807171906l7ee4c1age1ff4b9cd782c7f@mail.gmail.com> References: <4dbf9300807171906l7ee4c1age1ff4b9cd782c7f@mail.gmail.com> Message-ID: <4dbf9300807172037w54632811gdf230cc38a120c3d@mail.gmail.com> Nevermind, I did not realize that the value of *cipher when passed to gcry_ac_io_init() needs to be NULL to avoid regrowing the array. (Also, the ampersands should not be there for initializing the second gcry_ac_io_t struct although that was a typo in the email and independent of the issue I was encountering). On Thu, Jul 17, 2008 at 7:06 PM, Manu Srivastava wrote: > The libgcrypt manual states that multi-threading should not be an > issue, but some behavior I observed prompted me to ask some questions > about this property. > > Let us say that I am using 2048-bit RSA (256 byte blocks) and I that > wish to encrypt two separate strings. > > I initialize the appropriate gcry_ac_io_t structures and then make a > call to gcry_ac_data_encrypt_scheme as follows: > > int encrypt_message(struct crypto_context *cntxt, unsigned char > *message, size_t num_bytes, > unsigned char **cipher, size_t *cipher) > { > gcry_ac_io_t io_plaintext; > gcry_ac_io_t io_cipher; > > > gcry_ac_io_init(&io_plaintext, GCRY_AC_IO_READABLE, GCRY_AC_IO_STRING, > message, num_bytes); > > gcry_ac_io_init(&io_cipher, GCRY_AC_IO_WRITABLE, GCRY_AC_IO_STRING, > &cipher, &cipher_size); > > err = gcry_ac_data_encrypt_scheme (cntxt->handle, > GCRY_AC_ES_PKCS_V1_5, 0, NULL, pub_key, > &io_plaintext, &io_cipher); > } > > I encrypt the first string as follows: > encrypt_message(my_context, "my string 1", 12, &BUFFER, &BUFFER_SIZE); > The result is that a pointer to a cipher array of size 256 bytes is > placed in BUFFER, > which is precisely what I want. > > > I then encrypt the second string: > encrypt_message(my_context, "my string 2", 12, &BUFFER2, &BUFFER_SIZE2) > > Here is where the issue is. Rather than generating a new array and > placing the cipher for > string 2 in it, it concatenates this cipher for string 2 with the > cipher for string 1! Thus, > BUFFER2 points to BUFFER (assuming a re-allocation gave it the same > pointer) and BUFFER_SIZE > is now 512 bytes! But I really just wanted two disparate cipher > buffers of 256 bytes each! > > Quick questions regarding this behavior: > > 1) Is there a way around the results described above? In particular, > can it be the way I want it to be - > each cipher is allocated in its own array rather than successive > ciphers being concatenated together? > Or do I have to do this manually (i.e. copy chunks of 256 bytes of > cipher into their own arrays). > An alternative way to pose this question is: Can I "clear" the > state so that the next cipher I generate > is in its own array? > > 2) More importantly, is this re-entrant? If I have multiple threads > (each with their own gcry_ac_handle_t), > then is there a risk of thread 2's cipher being placed > contiguously after thread 1's cipher? (This issue would > make it impossible to use the encrypt_scheme() methods in a MT environment). > > Is this also expected behavior? > > Thanks, > Manu > From mastermanu2004 at gmail.com Sun Jul 20 00:21:15 2008 From: mastermanu2004 at gmail.com (Manu Srivastava) Date: Sat, 19 Jul 2008 15:21:15 -0700 Subject: Memory leak in gcry_ac_key_destroy? Message-ID: <4dbf9300807191521o48761267i9dcf4fcac4367734@mail.gmail.com> Hi, In the function _gcry_ac_key_destroy, Is there a reason that: gcry_free(key->data->data) is omitted? Furthermore, for each element in key->data->data, shouldn't there also be a gcry_free(key->data->data[i].name)? Finally, is it reasonable to replace the if(key->data) block with gcry_ac_data_destroy(key->data)? I ask because I am using the ac library for encrypting messages and I need to make sure all memory leaks are plugged. According to valgrind there is a memory leak tied to memory allocated in gcry_ac_key_init, and when I place the above two lines in the destruction function, it fixes it. -manu ac.c (~ line 1683) void _gcry_ac_key_destroy (gcry_ac_key_t key) { unsigned int i; if (key) { if (key->data) { for (i = 0; i < key->data->data_n; i++) { if (key->data->data[i].mpi != NULL) { gcry_mpi_release (key->data->data[i].mpi); //gcry_free(key->data->data[i].name); *should insert this*? } } //gcry_free(key->data->data); *should insert this*? gcry_free (key->data); } gcry_free (key); } } From wk at gnupg.org Sun Jul 20 16:33:33 2008 From: wk at gnupg.org (Werner Koch) Date: Sun, 20 Jul 2008 16:33:33 +0200 Subject: Memory leak in gcry_ac_key_destroy? In-Reply-To: <4dbf9300807191521o48761267i9dcf4fcac4367734@mail.gmail.com> (Manu Srivastava's message of "Sat, 19 Jul 2008 15:21:15 -0700") References: <4dbf9300807191521o48761267i9dcf4fcac4367734@mail.gmail.com> Message-ID: <87r69o62wy.fsf@wheatstone.g10code.de> On Sun, 20 Jul 2008 00:21, mastermanu2004 at gmail.com said: > In the function _gcry_ac_key_destroy, Is there a reason that: > gcry_free(key->data->data) is omitted? The reason is that thare are some conceptual bugs in the ac interface: The ownership of some memory objects are not always clear and thus it is hard to free them at the right place. I have given up on fixing them. This is one reasons for the deprecation of the ac interface. > I ask because I am using the ac library for encrypting messages and I If it is at all possible for you, you should migrate to the pk interface. Salam-Shalom, Werner -- Die Gedanken sind frei. Auschnahme regelt ein Bundeschgesetz. From mashrom.head at gmail.com Wed Jul 30 14:42:30 2008 From: mashrom.head at gmail.com (Jabka Atu) Date: Wed, 30 Jul 2008 15:42:30 +0300 Subject: What size should i use in encrypt/decrypt in ARC4 ? In-Reply-To: <39ea6580807300505te060b1dx8753001cec33d62d@mail.gmail.com> References: <39ea6580807300505te060b1dx8753001cec33d62d@mail.gmail.com> Message-ID: <39ea6580807300542j48521a63o32915bdbc9c041d5@mail.gmail.com> Howdy ,.. I cannot understand what values i should use in encrypt /decrypt when using gcry_cipher_encrypt : for example when i run this code : char * plain_text = "Attack at down"; char * c_str ; c_str = new char[ strlen(plain_text) + 1 ]; strcpy ( c_str, plain_text); gcry_check_version(NULL) gcry_control( GCRYCTL_DISABLE_SECMEM_WARN ); gcry_control( GCRYCTL_INIT_SECMEM, 16384, 0 ); gcry_cipher_open (&cipher_handler, GCRY_CIPHER_ARCFOUR,GCRY_CIPHER_MODE_STREAM, 0); gcry_cipher_setkey (cipher_handler,"Secret", 128); gcry_cipher_encrypt (cipher_handler,c_str,strlen(c_str) , NULL,0); cout< From agl at imperialviolet.org Wed Jul 30 17:58:15 2008 From: agl at imperialviolet.org (Adam Langley) Date: Wed, 30 Jul 2008 08:58:15 -0700 Subject: What size should i use in encrypt/decrypt in ARC4 ? In-Reply-To: <39ea6580807300542j48521a63o32915bdbc9c041d5@mail.gmail.com> References: <39ea6580807300505te060b1dx8753001cec33d62d@mail.gmail.com> <39ea6580807300542j48521a63o32915bdbc9c041d5@mail.gmail.com> Message-ID: <396556a20807300858s7842dbb8xfe56ff0931fabdff@mail.gmail.com> On Wed, Jul 30, 2008 at 5:42 AM, Jabka Atu wrote: > char * plain_text = "Attack at down"; Firstly, it should be 'dawn', otherwise you army will return -EINVAL and the barbarian hoards will overrun them ;) > gcry_cipher_encrypt (cipher_handler,c_str,strlen(c_str) , NULL,0); > cout< > gcry_cipher_decrypt (cipher_handler, c_str,strlen(c_str),NULL,0); > cout< > i get the next output : > > ??g?zB?QK]o > ??A?R???? 2?9? I'm just guessing here, but it's a stream cipher and you're reusing the same cipher_handler. If you tried creating two handles for the cipher (and setting the same key on both, of course) and used one for encryption and the other for decryption, you might have better luck. The reason is that RC4 mutates itself as it processes the plaintext[1] AGL [1] http://en.wikipedia.org/wiki/RC4 -- Adam Langley agl at imperialviolet.org http://www.imperialviolet.org From mashrom.head at gmail.com Wed Jul 30 22:25:15 2008 From: mashrom.head at gmail.com (Jabka Atu) Date: Wed, 30 Jul 2008 23:25:15 +0300 Subject: Comment should be added to officeal documentation Message-ID: <4890CE2B.2080905@gmail.com> Sorry for my newbness but i don't how to contact the authers of libgcrypt manual . The next comment should be added in encrypt / decrypt : "When using ARCFOUR you should use two different handlers (one for encryption and other for decryption with the same key ) ." Special thank that gave me that solutione ( i wasted 36 coding hours on that ) . -- ---==== Jabka Atu ===--- bsh83.blogspot.com ---=== Encryption is a way of life ===--- From agl at imperialviolet.org Wed Jul 30 22:52:47 2008 From: agl at imperialviolet.org (Adam Langley) Date: Wed, 30 Jul 2008 13:52:47 -0700 Subject: Comment should be added to officeal documentation In-Reply-To: <4890CE2B.2080905@gmail.com> References: <4890CE2B.2080905@gmail.com> Message-ID: <396556a20807301352v3a563c60j1f360150d503e83d@mail.gmail.com> On Wed, Jul 30, 2008 at 1:25 PM, Jabka Atu wrote: > The next comment should be added in encrypt / decrypt : > > > "When using ARCFOUR you should use two different handlers (one for > encryption and other for decryption with the same key ) ." > > > Special thank that gave me that solutione ( i wasted 36 > coding hours on that ) . Well... that's true of any handle which keeps state, right? What about CTR mode block ciphers, or CBC, or ... Or the K(block) style stream ciphers like Salsa20.. or probably anything that isn't ECB. It's been a while since I used the gcrypt API, but I believe that's true. AGL -- Adam Langley agl at imperialviolet.org http://www.imperialviolet.org From wk at gnupg.org Thu Jul 31 11:11:39 2008 From: wk at gnupg.org (Werner Koch) Date: Thu, 31 Jul 2008 11:11:39 +0200 Subject: Comment should be added to officeal documentation In-Reply-To: <396556a20807301352v3a563c60j1f360150d503e83d@mail.gmail.com> (Adam Langley's message of "Wed, 30 Jul 2008 13:52:47 -0700") References: <4890CE2B.2080905@gmail.com> <396556a20807301352v3a563c60j1f360150d503e83d@mail.gmail.com> Message-ID: <871w1amn90.fsf@wheatstone.g10code.de> On Wed, 30 Jul 2008 22:52, agl at imperialviolet.org said: > Well... that's true of any handle which keeps state, right? What about > CTR mode block ciphers, or CBC, or ... Or the K(block) style stream > ciphers like Salsa20.. or probably anything that isn't ECB. It's been > a while since I used the gcrypt API, but I believe that's true. You are right. A context/handle is there to convey state - if we would not need state there would be no need for a context. The problem at hand is an improper use of the API. If you want to start a operation you alocate a context, set the key and the IV and start. Do the same if you are going to decrypt. Actually you don't need to get a allocate new context but call gcry_cipher_reset to put it back into a vanilla state. I also advice against the use of arcfour becuase there are so many things you can get wrong in using this particular stream cipher. It is pretty easy to use arcfour in an unsafe way and have the community fun decrypting it. Use AES and never use ECB mode with any cipher. Shalom-Salam, Werner -- Die Gedanken sind frei. Auschnahme regelt ein Bundeschgesetz. From mashrom.head at gmail.com Thu Jul 31 22:51:40 2008 From: mashrom.head at gmail.com (Jabka Atu) Date: Thu, 31 Jul 2008 23:51:40 +0300 Subject: Encrypted line changes on each run . Message-ID: <489225DC.4090101@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I wrote a small application to understand ARCFOUR use . for some reason the encrypted text changes each time i run it : So if i store it in a file and read it from file after 30 minuts i can't decrypt it . but if i run this as it is it works fine #include #include #include int read2 ( char * filename , char * buffer , size_t size ) { FILE * fp = NULL; fp = fopen ( filename , "rb" ); if ( fp == NULL ) return 1; fread ( buffer, size, 1, fp ); fclose ( fp ); } int write2 ( char * filename , char * buffer , size_t size ) { FILE * fp = NULL; fp = fopen ( filename , "wb" ); if ( fp == NULL ) return 1; fwrite ( buffer, size, 1, fp ); fclose ( fp ); } int main() { gcry_cipher_hd_t handle; gcry_cipher_hd_t handle2; gcry_error_t err = 0; char * plain_text ; char * out ; char * deout ; int i ; char key[] = "This is really strange , i read the documentation i googled for two days and nothing , i can't encrypt && decrypt"; char text[] = "Text to encrypt bla bla bla bla bla bla bla soo This is really strange , i read the documentation i googled for two days and nothing , i can't encrypt && decrypt"; size_t size_of_plain_text = strlen ( text ) + 1; size_t size_of_buffers = size_of_plain_text ; plain_text = ( char * ) malloc ( size_of_plain_text ); out = ( char * ) malloc ( size_of_buffers ); deout = ( char * ) malloc ( size_of_buffers ); assert ( plain_text ); assert ( out ); assert ( deout ); //Just null all for ( i = 0 ;i < size_of_buffers; i++ ) { out[i] = '0'; deout[i] = '0'; } strcpy ( plain_text , text ); gcry_check_version ( NULL ); gcry_control ( GCRYCTL_DISABLE_SECMEM_WARN ); gcry_control ( GCRYCTL_INIT_SECMEM, 16384, 0 ); { err = gcry_cipher_open ( &handle2, GCRY_CIPHER_ARCFOUR,GCRY_CIPHER_MODE_STREAM,0 ); err = gcry_cipher_open ( &handle, GCRY_CIPHER_ARCFOUR,GCRY_CIPHER_MODE_STREAM,0 ); if ( err ) { fprintf ( stderr, "Failure: %s/%s\n", gcry_strsource ( err ), gcry_strerror ( err ) ); } err = gcry_cipher_setkey ( handle , key ,256 ); err = gcry_cipher_setkey ( handle2 , key,256 ); if ( err ) { fprintf ( stderr, "Failure: %s/%s\n", gcry_strsource ( err ), gcry_strerror ( err ) ); } } err = gcry_cipher_encrypt ( handle, ( unsigned char * ) out, size_of_buffers , ( const unsigned char * ) plain_text,size_of_plain_text ); if ( err ) { fprintf ( stderr, "Failure: %s/%s\n", gcry_strsource ( err ), gcry_strerror ( err ) ); } write2 ( "/tmp/encrypt",out,size_of_buffers ); for ( i = 0 ;i < size_of_buffers; i++ ) out[i] = '0'; read2 ( "/tmp/encrypt",out,size_of_buffers ); err = gcry_cipher_encrypt ( handle2, ( unsigned char * ) deout, size_of_buffers, ( const unsigned char * ) out,size_of_buffers ); if ( err ) { fprintf ( stderr, "Failure: %s/%s\n", gcry_strsource ( err ), gcry_strerror ( err ) ); } printf ( "The result is : %d\n%s\n%s\n", strcmp ( deout,text ),deout , text ); free ( plain_text ); free ( out ); free ( deout ); gcry_cipher_close ( handle ); gcry_cipher_close ( handle2 ); return 0; } - -- - ---==== Jabka Atu ===--- bsh83.blogspot.com - ---=== Encryption is a way of life ===--- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQIcBAEBAgAGBQJIkiXbAAoJEJzNKvbZ7QAsd1kP/jX6J98MJk+7A2NaullApszr jHrc0dQ8C3pd4JK3iXlDHWd1+wkuhInlQeBwXDNHex1KBxdHwqp1YFA1Yv4wFVSB b66Yec1PUG/++QR8WaWxvvuViS2Je2L9BZIE85QOt1KwuMUjz4lyM8ZyF+UfTl6+ R+tcTY5hAOCvS76SIbgOQAdMSUfO3QzgRGaOSTxI+EYtasuKw1bnaFHC0wM/NcJG sV/PocRS2b3dL3PPbs3//I42+oUfmCC6yr9H1tRtMRzPED90Fs4L4SyLKQqmo7G8 OdjaL+sx5qApiy1LBSiM1DC0PJNqLToETnTHLRFvN2Fl/CcNcsTk7gxOhXFVPm6H MpTXIoBzFrz4enTyzIG/cqbg0t/nYwt/4BLCqn17Pk/MeWlJC29/SpOggkUPdtzB czh7PofngJXEJ/aEPAaUc1CnRHhU5emIKhIaM6Ri4KoKBLvY0tO57x1KuK86aiH4 3iEkWyooVAU32e/+Xh8UtQYtWLWSstfv8kcIYUhae3N8J4hn88BVNTCxJCzY7ytf Pfwab4tMkN485//JS6uZ8mQkkhhcezt9YfQC/+DT3C65ubHTa2F2JjwReDb5y9Mx E+zMLa6/GsNnnhsg2T3d4cFS7WcHN7eZdXlVPhHqaSNbUC1oG7LJpPiTOR/DIIzs mIfVc/YUoqLs2CyIHb0Z =1o9i -----END PGP SIGNATURE-----