Is gcry_ac_data_encrypt_scheme() not re-entrant?
Manu Srivastava
mastermanu2004 at gmail.com
Fri Jul 18 04:06:49 CEST 2008
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
More information about the Gcrypt-devel
mailing list