Mailing List Archive

Is gcry_ac_data_encrypt_scheme() not re-entrant?
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

_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Re: Is gcry_ac_data_encrypt_scheme() not re-entrant? [ In reply to ]
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
<mastermanu2004@gmail.com> 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
>

_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel