Is gcry_ac_data_encrypt_scheme() not re-entrant?

Manu Srivastava mastermanu2004 at
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?


More information about the Gcrypt-devel mailing list