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