Exemple #1
0
static void
test_keys( RSA_secret_key *sk, unsigned nbits )
{
    RSA_public_key pk;
    MPI test = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
    MPI out1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
    MPI out2 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );

    pk.n = sk->n;
    pk.e = sk->e;
    {	char *p = get_random_bits( nbits, 0, 0 );
	mpi_set_buffer( test, p, (nbits+7)/8, 0 );
	m_free(p);
    }

    public( out1, test, &pk );
Exemple #2
0
void
_gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor )
{
    gcry_mpi_t tmp = mpi_alloc( mpi_get_nlimbs(quot) );
    _gcry_mpi_fdiv_qr( quot, tmp, dividend, divisor);
    mpi_free(tmp);
}
Exemple #3
0
mpi_copy_gpg( MPI a )
#endif
{
    int i;
    MPI b;

    if( a && (a->flags & 4) ) {
	void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
				   : xmalloc( a->nbits );
	memcpy( p, a->d, a->nbits );
	b = mpi_set_opaque( NULL, p, a->nbits );
    }
    else if( a ) {
#ifdef M_DEBUG
	b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
			    : mpi_debug_alloc( a->nlimbs, info );
#else
	b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
			    : mpi_alloc( a->nlimbs );
#endif
	b->nlimbs = a->nlimbs;
	b->sign = a->sign;
	b->flags  = a->flags;
	b->nbits = a->nbits;
	for(i=0; i < b->nlimbs; i++ )
	    b->d[i] = a->d[i];
    }
    else
	b = NULL;
    return b;
}
Exemple #4
0
void
gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
{
  if (!round)
    {
      if (!rem)
        {
          gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs(quot));
          _gcry_mpi_tdiv_qr (quot, tmp, dividend, divisor);
          mpi_free (tmp);
        }
      else
        _gcry_mpi_tdiv_qr (quot, rem, dividend, divisor);
    }
  else if (round < 0)
    {
      if (!rem)
        _gcry_mpi_fdiv_q (quot, dividend, divisor);
      else if (!quot)
        _gcry_mpi_fdiv_r (rem, dividend, divisor);
      else
        _gcry_mpi_fdiv_qr (quot, rem, dividend, divisor);
    }
  else
    log_bug ("mpi rounding to ceiling not yet implemented\n");
}
Exemple #5
0
/****************
 * Note: This copy function should not interpret the MPI
 *	 but copy it transparently.
 */
int mpi_copy(MPI *copied, cMPI a )
{
    size_t i;
    MPI b;

    *copied = MPI_NULL;

    if ( a ) {
        b = mpi_alloc( a->nlimbs );
        if (!b)
            return -ENOMEM;

        b->nlimbs = a->nlimbs;
        b->sign = a->sign;
        b->flags  = a->flags;
        b->nbits = a->nbits;

        for (i = 0; i < b->nlimbs; i++ )
            b->d[i] = a->d[i];

        *copied = b;
    }

    return 0;
}
Exemple #6
0
mpi_alloc_like( MPI a )
#endif
{
    MPI b;

    if( a && (a->flags & 4) ) {
	void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
				   : xmalloc( a->nbits );
	memcpy( p, a->d, a->nbits );
	b = mpi_set_opaque( NULL, p, a->nbits );
    }
    else if( a ) {
#ifdef M_DEBUG
	b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
			    : mpi_debug_alloc( a->nlimbs, info );
#else
	b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
			    : mpi_alloc( a->nlimbs );
#endif
	b->nlimbs = 0;
	b->sign = 0;
	b->flags = a->flags;
	b->nbits = 0;
    }
    else
	b = NULL;
    return b;
}
Exemple #7
0
MPI
mpi_set_opaque( MPI a, void *p, unsigned int len )
{
    if( !a ) {
#ifdef M_DEBUG
	a = mpi_debug_alloc(0,"alloc_opaque");
#else
	a = mpi_alloc(0);
#endif
    }

    if( a->flags & 4 )
	xfree( a->d );
    else {
#ifdef M_DEBUG
	mpi_debug_free_limb_space(a->d, "alloc_opaque");
#else
	mpi_free_gpg_limb_space(a->d);
#endif
    }

    a->d = p;
    a->alloced = 0;
    a->nlimbs = 0;
    a->nbits = len;
    a->flags = 4;
    return a;
}
Exemple #8
0
static void
test_keys( RSA_secret_key *sk, unsigned nbits )
{
    RSA_public_key pk;
    MPI test = mpi_alloc ( mpi_nlimb_hint_from_nbits (nbits) );
    MPI out1 = mpi_alloc ( mpi_nlimb_hint_from_nbits (nbits) );
    MPI out2 = mpi_alloc ( mpi_nlimb_hint_from_nbits (nbits) );

    pk.n = sk->n;
    pk.e = sk->e;
    {	char *p = get_random_bits( nbits, 0, 0 );
	mpi_set_buffer( test, p, (nbits+7)/8, 0 );
	xfree(p);
    }

    public( out1, test, &pk );
Exemple #9
0
/****************
 * Note: This copy function should not interpret the MPI
 *	 but copy it transparently.
 */
gcry_mpi_t
gcry_mpi_copy( gcry_mpi_t a )
{
    int i;
    gcry_mpi_t b;

    if( a && (a->flags & 4) ) {
	void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
				     : gcry_xmalloc( (a->sign+7)/8 );
	memcpy( p, a->d, (a->sign+7)/8 );
	b = gcry_mpi_set_opaque( NULL, p, a->sign );
    }
    else if( a ) {
	b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
			    : mpi_alloc( a->nlimbs );
	b->nlimbs = a->nlimbs;
	b->sign = a->sign;
	b->flags  = a->flags;
	for(i=0; i < b->nlimbs; i++ )
	    b->d[i] = a->d[i];
    }
    else
	b = NULL;
    return b;
}
Exemple #10
0
/****************
 * To check the validity of the value, recalculate the correspondence
 * between the public value and the secret one.
 */
static int
check_secret_key (ECC_secret_key * sk)
{
  mpi_point_t Q;
  gcry_mpi_t y_2, y2 = mpi_alloc (0);
  mpi_ec_t ctx;

  /* ?primarity test of 'p' */
  /*  (...) //!! */
  /* G in E(F_p) */
  y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
  mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
  if (mpi_cmp (y_2, y2))
    {
      if (DBG_CIPHER)
        log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
      return (1);
    }
  /* G != PaI */
  if (!mpi_cmp_ui (sk->E.G.z, 0))
    {
      if (DBG_CIPHER)
        log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
      return (1);
    }

  point_init (&Q);
  ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
  _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
  if (mpi_cmp_ui (Q.z, 0))
    {
      if (DBG_CIPHER)
        log_debug ("check_secret_key: E is not a curve of order n\n");
      point_free (&Q);
      _gcry_mpi_ec_free (ctx);
      return 1;
    }
  /* pubkey cannot be PaI */
  if (!mpi_cmp_ui (sk->Q.z, 0))
    {
      if (DBG_CIPHER)
        log_debug ("Bad check: Q can not be a Point at Infinity!\n");
      _gcry_mpi_ec_free (ctx);
      return (1);
    }
  /* pubkey = [d]G over E */
  _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
  if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z))
    {
      if (DBG_CIPHER)
        log_debug
          ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
      _gcry_mpi_ec_free (ctx);
      return (1);
    }
  _gcry_mpi_ec_free (ctx);
  point_free (&Q);
  return 0;
}
Exemple #11
0
static gcry_err_code_t
ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
{
  gpg_err_code_t err;
  ECC_secret_key sk;

  (void)algo;

  if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
      || !skey[5] || !skey[6] )
    return GPG_ERR_BAD_MPI;

  sk.E.p = skey[0];
  sk.E.a = skey[1];
  sk.E.b = skey[2];
  point_init (&sk.E.G);
  err = os2ec (&sk.E.G, skey[3]);
  if (err)
    {
      point_free (&sk.E.G);
      return err;
    }
  sk.E.n = skey[4];
  point_init (&sk.Q);
  err = os2ec (&sk.Q, skey[5]);
  if (err)
    {
      point_free (&sk.E.G);
      point_free (&sk.Q);
      return err;
    }
  sk.d = skey[6];

  resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
  resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
  err = sign (data, &sk, resarr[0], resarr[1]);
  if (err)
    {
      mpi_free (resarr[0]);
      mpi_free (resarr[1]);
      resarr[0] = NULL; /* Mark array as released.  */
    }
  point_free (&sk.E.G);
  point_free (&sk.Q);
  return err;
}
Exemple #12
0
gcry_mpi_t
_gcry_mpi_alloc_set_ui( unsigned long u)
{
    gcry_mpi_t w = mpi_alloc(1);
    w->d[0] = u;
    w->nlimbs = u? 1:0;
    w->sign = 0;
    return w;
}
Exemple #13
0
int
elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{
    ELG_public_key pk;

    if( !is_ELGAMAL(algo) )
	return G10ERR_PUBKEY_ALGO;
    if( !data || !pkey[0] || !pkey[1] || !pkey[2] )
	return G10ERR_BAD_MPI;

    pk.p = pkey[0];
    pk.g = pkey[1];
    pk.y = pkey[2];
    resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
    resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
    do_encrypt( resarr[0], resarr[1], data, &pk );
    return 0;
}
Exemple #14
0
MPI mpi_alloc_set_ui(unsigned long u)
{
    MPI w = mpi_alloc(1);
    if (!w)
        return w;
    w->d[0] = u;
    w->nlimbs = u? 1:0;
    w->sign = 0;
    return w;
}
Exemple #15
0
int
mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor )
{
    MPI tmp = mpi_alloc( mpi_get_nlimbs(quot) );
    if (!tmp)
	    return -ENOMEM;
    mpi_fdiv_qr( quot, tmp, dividend, divisor);
    mpi_free(tmp);
    return 0;
}
Exemple #16
0
MPI
do_encode_md(const void *sha_buffer, unsigned nbits)
{
  int nframe = (nbits+7) / 8;
  uint8_t *frame, *fr_pt;
  int i = 0, n;
  size_t asnlen = DIM(asn);
  MPI a = MPI_NULL;

  if(SHA1_DIGEST_LENGTH + asnlen + 4  > nframe )
    printk("MPI: can't encode a %d bit MD into a %d bits frame\n",
	  (int)(SHA1_DIGEST_LENGTH*8), (int)nbits);

  /* We encode the MD in this way:
   *
   *	   0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
   *
   * PAD consists of FF bytes.
   */
//daveti: hack
  //frame = kmalloc(nframe, GFP_KERNEL);
  frame = kmalloc(nframe, GFP_ATOMIC);
  if (!frame)
	  return MPI_NULL;
  n = 0;
  frame[n++] = 0;
  frame[n++] = 1; /* block type */
  i = nframe - SHA1_DIGEST_LENGTH - asnlen -3 ;

  if(i <= 1) {
    printk("MPI: message digest encoding failed\n");
    kfree(frame);
    return a;
  }

  memset( frame+n, 0xff, i ); n += i;
  frame[n++] = 0;
  memcpy( frame+n, &asn, asnlen ); n += asnlen;
  memcpy( frame+n, sha_buffer, SHA1_DIGEST_LENGTH ); n += SHA1_DIGEST_LENGTH;

  i = nframe;
  fr_pt = frame;

  if (n != nframe) {
    printk("MPI: message digest encoding failed, frame length is wrong\n");
    kfree(frame);
    return a;
  }

  a = mpi_alloc( (nframe+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
  mpi_set_buffer( a, frame, nframe, 0 );
  kfree(frame);

  return a;
}
Exemple #17
0
/****************
 * Test whether the secret key is valid.
 * Returns: true if this is a valid key.
 */
static int
check_secret_key( RSA_secret_key *sk )
{
  int rc;
  gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 );
  
  mpi_mul(temp, sk->p, sk->q );
  rc = mpi_cmp( temp, sk->n );
  mpi_free(temp);
  return !rc;
}
Exemple #18
0
/****************
 * Test whether the secret key is valid.
 * Returns: if this is a valid key.
 */
static int
check_secret_key( ELG_secret_key *sk )
{
  int rc;
  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );

  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
  rc = !mpi_cmp( y, sk->y );
  mpi_free( y );
  return rc;
}
Exemple #19
0
/* Accessor for helper variable.  */
static gcry_mpi_t
ec_get_two_inv_p (mpi_ec_t ec)
{
  if (!ec->t.valid.two_inv_p)
    {
      ec->t.valid.two_inv_p = 1;
      if (!ec->t.two_inv_p)
        ec->t.two_inv_p = mpi_alloc (0);
      ec_invm (ec->t.two_inv_p, mpi_const (MPI_C_TWO), ec);
    }
  return ec->t.two_inv_p;
}
Exemple #20
0
static void
sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
{
    gcry_mpi_t k;
    gcry_mpi_t t   = mpi_alloc( mpi_get_nlimbs(a) );
    gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
    gcry_mpi_t p_1 = mpi_copy(skey->p);

   /*
    * b = (t * inv) mod (p-1)
    * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
    * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
    *
    */
    mpi_sub_ui(p_1, p_1, 1);
    k = gen_k( skey->p, 0 /* no small K ! */ );
    gcry_mpi_powm( a, skey->g, k, skey->p );
    mpi_mul(t, skey->x, a );
    mpi_subm(t, input, t, p_1 );
    mpi_invm(inv, k, p_1 );
    mpi_mulm(b, t, inv, p_1 );

#if 0
    if( DBG_CIPHER ) 
      {
	log_mpidump("elg sign p= ", skey->p);
	log_mpidump("elg sign g= ", skey->g);
	log_mpidump("elg sign y= ", skey->y);
	log_mpidump("elg sign x= ", skey->x);
	log_mpidump("elg sign k= ", k);
	log_mpidump("elg sign M= ", input);
	log_mpidump("elg sign a= ", a);
	log_mpidump("elg sign b= ", b);
      }
#endif
    mpi_free(k);
    mpi_free(t);
    mpi_free(inv);
    mpi_free(p_1);
}
Exemple #21
0
MPI
mpi_read_from_buffer(byte *buffer, unsigned int *ret_nread, int secure)
{
    int i, j;
    unsigned nbits, nbytes, nlimbs, nread=0;
    mpi_limb_t a;
    MPI val = NULL;

    if( *ret_nread < 2 )
	goto leave;
    nbits = buffer[0] << 8 | buffer[1];
    if( nbits > MAX_EXTERN_MPI_BITS ) {
	log_info ("mpi too large (%u bits)\n", nbits);
	goto leave;
    }
    buffer += 2;
    nread = 2;

    nbytes = (nbits+7) / 8;
    nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
    val = secure? mpi_alloc_secure( nlimbs )
		: mpi_alloc( nlimbs );
    i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
    i %= BYTES_PER_MPI_LIMB;
    val->nbits = nbits;
    j= val->nlimbs = nlimbs;
    val->sign = 0;
    for( ; j > 0; j-- ) {
	a = 0;
	for(; i < BYTES_PER_MPI_LIMB; i++ ) {
          if( ++nread > *ret_nread ) {
              /* This (as well as the above error condition) may
                 happen if we use this function to parse a decrypted
                 MPI which didn't turn out to be a real MPI - possible
                 because the supplied key was wrong but the OpenPGP
                 checksum didn't caught it. */
		log_info ("mpi larger than buffer\n");
                mpi_free (val);
                val = NULL;
                goto leave;
          }
          a <<= 8;
          a |= *buffer++;
	}
	i = 0;
	val->d[j-1] = a;
    }

  leave:
    *ret_nread = nread;
    return val;
}
Exemple #22
0
MPI
mpi_alloc_set_ui( unsigned long u)
{
#ifdef M_DEBUG
    MPI w = mpi_debug_alloc(1,"alloc_set_ui");
#else
    MPI w = mpi_alloc(1);
#endif
    w->d[0] = u;
    w->nlimbs = u? 1:0;
    w->sign = 0;
    return w;
}
Exemple #23
0
static void
do_gcd(void)
{
    MPI a = mpi_alloc(40);
    if( stackidx < 2 ) {
	fputs("stack underflow\n", stderr);
	return;
    }
    mpi_gcd( a, stack[stackidx-2], stack[stackidx-1] );
    mpi_set(stack[stackidx-2],a);
    mpi_free(a);
    stackidx--;
}
Exemple #24
0
mpi_read(IOBUF inp, unsigned *ret_nread, int secure)
#endif
{
    int c, i, j;
    unsigned nbits, nbytes, nlimbs, nread=0;
    mpi_limb_t a;
    MPI val = MPI_NULL;

    if( (c = iobuf_get(inp)) == -1 )
	goto leave;
    nbits = c << 8;
    if( (c = iobuf_get(inp)) == -1 )
	goto leave;
    nbits |= c;
    if( nbits > MAX_EXTERN_MPI_BITS ) {
	log_error("mpi too large (%u bits)\n", nbits);
	goto leave;
    }
    nread = 2;

    nbytes = (nbits+7) / 8;
    nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
  #ifdef M_DEBUG
    val = secure? mpi_debug_alloc_secure( nlimbs, info )
		: mpi_debug_alloc( nlimbs, info );
  #else
    val = secure? mpi_alloc_secure( nlimbs )
		: mpi_alloc( nlimbs );
  #endif
    i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
    i %= BYTES_PER_MPI_LIMB;
    val->nbits = nbits;
    j= val->nlimbs = nlimbs;
    val->sign = 0;
    for( ; j > 0; j-- ) {
	a = 0;
	for(; i < BYTES_PER_MPI_LIMB; i++ ) {
	    a <<= 8;
	    a |= iobuf_get(inp) & 0xff; nread++;
	}
	i = 0;
	val->d[j-1] = a;
    }

  leave:
    if( nread > *ret_nread )
	log_bug("mpi crosses packet border\n");
    else
	*ret_nread = nread;
    return val;
}
Exemple #25
0
gcry_err_code_t
_gcry_elg_encrypt (int algo, gcry_mpi_t *resarr,
                   gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
  ELG_public_key pk;

  (void)algo;
  (void)flags;

  if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
    err = GPG_ERR_BAD_MPI;
  else
    {
      pk.p = pkey[0];
      pk.g = pkey[1];
      pk.y = pkey[2];
      resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.p));
      resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.p));
      do_encrypt (resarr[0], resarr[1], data, &pk);
    }
  return err;
}
Exemple #26
0
/* Helper used to scan PGP style MPIs.  Returns NULL on failure. */
static gcry_mpi_t
mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
                      int secure)
{
  int i, j;
  unsigned int nbits, nbytes, nlimbs, nread=0;
  mpi_limb_t a;
  gcry_mpi_t val = MPI_NULL;

  if ( *ret_nread < 2 )
    goto leave;
  nbits = buffer[0] << 8 | buffer[1];
  if ( nbits > MAX_EXTERN_MPI_BITS )
    {
/*       log_debug ("mpi too large (%u bits)\n", nbits); */
      goto leave;
    }
  buffer += 2;
  nread = 2;

  nbytes = (nbits+7) / 8;
  nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
  val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
  i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
  i %= BYTES_PER_MPI_LIMB;
  j= val->nlimbs = nlimbs;
  val->sign = 0;
  for ( ; j > 0; j-- )
    {
      a = 0;
      for (; i < BYTES_PER_MPI_LIMB; i++ )
        {
          if ( ++nread > *ret_nread )
            {
/*               log_debug ("mpi larger than buffer"); */
              mpi_free (val);
              val = NULL;
              goto leave;
            }
          a <<= 8;
          a |= *buffer++;
	}
      i = 0;
      val->d[j-1] = a;
    }

 leave:
  *ret_nread = nread;
  return val;
}
Exemple #27
0
static void
do_powm(void)
{
    MPI a;
    if( stackidx < 3 ) {
	fputs("stack underflow\n", stderr);
	return;
    }
    a= mpi_alloc(10);
    mpi_powm( a, stack[stackidx-3], stack[stackidx-2], stack[stackidx-1] );
    mpi_free(stack[stackidx-3]);
    stack[stackidx-3] = a;
    stackidx -= 2;
}
MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
{
	const uint8_t *buffer = xbuffer;
	int i, j;
	unsigned nbits, nbytes, nlimbs, nread = 0;
	mpi_limb_t a;
	MPI val = NULL;

	if (*ret_nread < 2)
		goto leave;
	nbits = buffer[0] << 8 | buffer[1];

	if (nbits > MAX_EXTERN_MPI_BITS) {
		pr_info("MPI: mpi too large (%u bits)\n", nbits);
		goto leave;
	}
	buffer += 2;
	nread = 2;

	nbytes = (nbits + 7) / 8;
	nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
	val = mpi_alloc(nlimbs);
	if (!val)
		return NULL;
	i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
	i %= BYTES_PER_MPI_LIMB;
	val->nbits = nbits;
	j = val->nlimbs = nlimbs;
	val->sign = 0;
	for (; j > 0; j--) {
		a = 0;
		for (; i < BYTES_PER_MPI_LIMB; i++) {
			if (++nread > *ret_nread) {
				printk
				    ("MPI: mpi larger than buffer nread=%d ret_nread=%d\n",
				     nread, *ret_nread);
				goto leave;
			}
			a <<= 8;
			a |= *buffer++;
		}
		i = 0;
		val->d[j - 1] = a;
	}

leave:
	*ret_nread = nread;
	return val;
}
Exemple #29
0
gcry_err_code_t
_gcry_elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
  ELG_secret_key sk;

  (void)algo;

  if ((! data)
      || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
    err = GPG_ERR_BAD_MPI;
  else
    {
      sk.p = skey[0];
      sk.g = skey[1];
      sk.y = skey[2];
      sk.x = skey[3];
      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
      sign (resarr[0], resarr[1], data, &sk);
    }
  
  return err;
}
Exemple #30
0
/****************
 * Barrett reduction: We assume that these conditions are met:
 * Given x =(x_2k-1 ...x_0)_b
 *	 m =(m_k-1 ....m_0)_b	  with m_k-1 != 0
 * Output r = x mod m
 * Before using this function init_barret must be used to calucalte y and k.
 * Returns: false = no error
 *	    true = can't perform barret reduction
 */
static int
calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
{
    int xx = k > 3 ? k-3:0;

    mpi_normalize( x );
    if( mpi_get_nlimbs(x) > 2*k )
	return 1; /* can't do it */

    /* 1. q1 = floor( x / b^k-1)
     *	  q2 = q1 * y
     *	  q3 = floor( q2 / b^k+1 )
     * Actually, we don't need qx, we can work direct on r2
     */
    mpi_set( r2, x );
    mpi_rshift_limbs( r2, k-1 );
    mpi_mul( r2, r2, y );
    mpi_rshift_limbs( r2, k+1 );

    /* 2. r1 = x mod b^k+1
     *	  r2 = q3 * m mod b^k+1
     *	  r  = r1 - r2
     * 3. if r < 0 then  r = r + b^k+1
     */
    mpi_set( r1, x );
    if( r1->nlimbs > k+1 ) /* quick modulo operation */
	r1->nlimbs = k+1;
    mpi_mul( r2, r2, m );
    if( r2->nlimbs > k+1 ) /* quick modulo operation */
	r2->nlimbs = k+1;
    mpi_sub( r, r1, r2 );

    if( mpi_has_sign (r) ) {
	gcry_mpi_t tmp;

	tmp = mpi_alloc( k + 2 );
	mpi_set_ui( tmp, 1 );
	mpi_lshift_limbs( tmp, k+1 );
	mpi_add( r, r, tmp );
	mpi_free(tmp);
    }

    /* 4. while r >= m do r = r - m */
    while( mpi_cmp( r, m ) >= 0 )
	mpi_sub( r, r, m );

    return 0;
}