bug in gcrypt's bit manipulation routines
bpgcrypt at itaparica.org
bpgcrypt at itaparica.org
Mon Jul 31 18:33:14 CEST 2006
hi,
it seems to me that I found some bugs in the bit manipulation routines of
libgcrypt-1.2.2:
1. The function gcry_mpi_set_bit ommits the (re-)allocation of enough
memory to store an MPI of the needed size. The following code snippet
demonstrates this:
#include <stdio.h>
#include <gcrypt.h>
int main()
{
gcry_mpi_t a;
int i;
a = gcry_mpi_new(0);
gcry_mpi_randomize(a, 50, GCRY_WEAK_RANDOM); // get 50 random bits
gcry_mpi_set_ui(a, 0); // "reset" them to 0
for(i = 50; i >= 0; i--) // display a string of 0s
printf("%d", gcry_mpi_test_bit(a, i));
printf("\n");
gcry_mpi_set_bit(a, 49); // set bit 49
for(i = 50; i >= 0; i--) // this string has unexpected
printf("%d", gcry_mpi_test_bit(a, i)); // random bit content!
printf("\n");
}
Of course one would expect that all but one of the bits in the second
output line should be cleared, but they aren't. An example output follows
000000000000000000000000000000000000000000000000000
111001001101101001100000000000000000000000000000000
The problem can be tracked down to libgcrypt-1.2.2/mpi/mpi-bit.c :
void
gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
{
unsigned int limbno, bitno;
limbno = n / BITS_PER_MPI_LIMB;
bitno = n % BITS_PER_MPI_LIMB;
if( limbno >= a->nlimbs ) { /* resize */
if( a->alloced >= limbno ) /* XXXXXXXXXXXX */
mpi_resize(a, limbno+1 );
a->nlimbs = limbno+1;
}
a->d[limbno] |= (A_LIMB_1<<bitno);
}
To me it seems that the line I marked with XXXXX should contain a "<="
instead of the ">=". The same is true for the function
gcry_mpi_set_highbit in the same file.
BTW: The code
a = gcry_mpi_new(0); gcry_mpi_set_bit(a, 10000);
immediately leads to a segmentation violation on my machine.
2. The routine gcry_mpi_rshift always interpretes the "shift value" N
as (N % 32). This behaviour is commented (a little bit) in
libgcrypt-1.2.2/mpi/generic/mpih-rshift.c
* Argument constraints:
* 1. 0 < CNT < BITS_PER_MP_LIMB
But this is NOT documented in the gcrypt manual:
-- Function: void gcry_mpi_rshift (gcry_mpi_t X, gcry_mpi_t A,
unsigned int N)
Shift the value of A by N bits to the right and store the result
in X.
I cannot decide ultimately weather the error here is in the code or
in the documentation. I personally would absolutely prefer an rshift
implementation that can handly arbitrary large Ns.
3. HMAC-SHA256 calculation via
gcry_md_open(&mh, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
aborts with some "no secure memory allocated" message. This can be
fixed by explicitely doing a
gcry_control(GCRYCTL_INIT_SECMEM, 1);
but as the gcry_control function isn't documented properly, this
necessity cannot be deduced from the docs. It took me hours of
source reading to get the HMAC-256 to work. Again it is not me to
decide weather this is a bug in the lib or a misdocumentation.
Thank you for libgcrypt!
bp
More information about the Gcrypt-devel
mailing list