Exemple #1
0
static void
check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
            gpg_err_code_t decrypt_fail_code)
{
  gcry_sexp_t plain;
  gcry_mpi_t x;
  int rc;

  /* Create plain text.  */
  x = gcry_mpi_new (nbits_data);
  gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);

  rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
  if (rc)
    die ("converting data for encryption failed: %s\n",
	 gcry_strerror (rc));

  check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
  gcry_sexp_release (plain);
  gcry_mpi_release (x);

  /* Create plain text.  */
  x = gcry_mpi_new (nbits_data);
  gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);

  rc = gcry_sexp_build (&plain, NULL,
                        "(data (flags raw no-blinding) (value %m))", x);
  gcry_mpi_release (x);
  if (rc)
    die ("converting data for encryption failed: %s\n",
	 gcry_strerror (rc));

  check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
  gcry_sexp_release (plain);
}
Exemple #2
0
/* Check that right shifting actually works for an amount larger than
   the number of bits per limb. */
static void
test_rshift (int pass)
{
  gcry_mpi_t a, b;
  char *result, *result2;
  int i;

  wherestr = "test_rshift";
  show ("checking that rshift works as expected (pass %d)\n", pass);

  a = gcry_mpi_new (0);
  b = gcry_mpi_new (0);
  gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);

  for (i=0; i < 75; i++)
    {
      gcry_mpi_rshift (b, a, i);

      result = mpi2bitstr (b, 72);
      result2 = mpi2bitstr (a, 72);
      rshiftbitstring (result2, i);
      if (strcmp (result, result2))
        {
          show ("got =%s\n", result);
          show ("want=%s\n", result2);
          fail ("rshift by %d failed\n", i);
        }
      xfree (result);
      xfree (result2);
    }

  /* Again. This time using in-place operation. */
  gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);

  for (i=0; i < 75; i++)
    {
      gcry_mpi_release (b);
      b = gcry_mpi_copy (a);
      gcry_mpi_rshift (b, b, i);

      result = mpi2bitstr (b, 72);
      result2 = mpi2bitstr (a, 72);
      rshiftbitstring (result2, i);
      if (strcmp (result, result2))
        {
          show ("got =%s\n", result);
          show ("want=%s\n", result2);
          fail ("in-place rshift by %d failed\n", i);
        }
      xfree (result2);
      xfree (result);
    }

  gcry_mpi_release (b);
  gcry_mpi_release (a);
}
ZrtpDH::ZrtpDH(const char* type){

    // Well - the algo type is only 4 char thus cast to int32 and compare
    if (*(int32_t*)type == *(int32_t*)dh2k) {
        pkType = DH2K;
    }
    else if (*(int32_t*)type == *(int32_t*)dh3k) {
        pkType = DH3K;
    }
    else {
        fprintf(stderr, "Unknown pubkey algo: %d\n", pkType);
    }
    ctx = static_cast<void*>(new gcryptCtx);
    gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx);
    tmpCtx->privKey = NULL;
    tmpCtx->pubKey = NULL;

    initializeGcrypt();

    if (!dhinit) {
	gcry_mpi_scan(&bnP2048, GCRYMPI_FMT_USG, P2048, sizeof(P2048), NULL);
        gcry_mpi_scan(&bnP3072, GCRYMPI_FMT_USG, P3072, sizeof(P3072), NULL);
//        gcry_mpi_scan(&bnP4096, GCRYMPI_FMT_USG, P4096, sizeof(P4096), NULL);
        two = gcry_mpi_set_ui(NULL, 2);

        bnP2048MinusOne = gcry_mpi_new(sizeof(P2048)*8);
        gcry_mpi_sub_ui(bnP2048MinusOne, bnP2048, 1);

        bnP3072MinusOne = gcry_mpi_new(sizeof(P3072)*8);
        gcry_mpi_sub_ui(bnP3072MinusOne, bnP3072, 1);

//        bnP4096MinusOne = gcry_mpi_new(sizeof(P4096)*8);
//        gcry_mpi_sub_ui(bnP4096MinusOne, bnP4096, 1);
        dhinit = 1;
    }

    if (pkType == DH3K) {
        tmpCtx->privKey = gcry_mpi_new(256);
        gcry_mpi_randomize(tmpCtx->privKey, 256, GCRY_STRONG_RANDOM);
    }
    else if (pkType == DH2K) {
        tmpCtx->privKey = gcry_mpi_new(512);
        gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM);
    }
//    else {
//        tmpCtx->privKey = gcry_mpi_new(512);
//        gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM);
//    }
}
Exemple #4
0
/* This is to check a bug reported by bpgcrypt at itaparica.org on
   2006-07-31 against libgcrypt 1.2.2.  */
static void
one_bit_only (int highbit)
{
  gcry_mpi_t a;
  char *result;
  int i;

  wherestr = "one_bit_only";
  show ("checking that set_%sbit does only set one bit\n", highbit?"high":"");

  a = gcry_mpi_new (0);
  gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
  gcry_mpi_set_ui (a, 0);

  if (highbit)
    gcry_mpi_set_highbit (a, 42);
  else
    gcry_mpi_set_bit (a, 42);
  if (!gcry_mpi_test_bit (a, 42))
    fail ("failed to set a bit\n");
  gcry_mpi_clear_bit (a, 42);
  if (gcry_mpi_test_bit (a, 42))
    fail ("failed to clear a bit\n");
  result = mpi2bitstr (a, 70);
  assert (strlen (result) == 70);
  for (i=0; result[i]; i++)
    if ( result[i] != '0' )
      break;
  if (result[i])
    fail ("spurious bits detected\n");
  xfree (result);
  gcry_mpi_release (a);
}
Exemple #5
0
/**
 * Generate a random value mod n.
 *
 * @param edc ECC context
 * @return random value mod n.
 */
gcry_mpi_t
GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc)
{
  gcry_mpi_t n;
  unsigned int highbit;
  gcry_mpi_t r;

  n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);

  /* check public key for number of bits, bail out if key is all zeros */
  highbit = 256; /* Curve25519 */
  while ( (! gcry_mpi_test_bit (n, highbit)) &&
          (0 != highbit) )
    highbit--;
  GNUNET_assert (0 != highbit);
  /* generate fact < n (without bias) */
  GNUNET_assert (NULL != (r = gcry_mpi_new (0)));
  do {
    gcry_mpi_randomize (r,
			highbit + 1,
			GCRY_STRONG_RANDOM);
  }
  while (gcry_mpi_cmp (r, n) >= 0);
  gcry_mpi_release (n);
  return r;
}
Exemple #6
0
Fichier : kex.c Projet : gpg/gsti
/* Choose a random value x and calculate e = g^x mod p.  Returns e and
   if ret_x is not NULL x.  */
static gcry_mpi_t
calc_dh_secret (gcry_mpi_t gex_g, gcry_mpi_t gex_p, gcry_mpi_t * ret_x)
{
  gcry_mpi_t e, g, x, prime;
  size_t n = sizeof diffie_hellman_group1_prime;

  if (gex_p)
    prime = gcry_mpi_copy (gex_p);
  else if (gcry_mpi_scan (&prime, GCRYMPI_FMT_STD,
                          diffie_hellman_group1_prime, n, NULL))
    abort ();
  /*_gsti_dump_mpi( "prime=", prime );*/

  if (gex_g)
    g = gcry_mpi_copy (gex_g);
  else
    g = gcry_mpi_set_ui (NULL, 2);

  /* FIXME: we n bits for the private exponent,
     where n is 2*derrived_key_material */
  x = gcry_mpi_snew (200);
  gcry_mpi_randomize (x, 200, GCRY_STRONG_RANDOM);

  n = gcry_mpi_get_nbits (prime);
  e = gcry_mpi_new (n+1);
  gcry_mpi_powm (e, g, x, prime);
  if (ret_x)
    *ret_x = x;
  else
    gcry_mpi_release (x);
  gcry_mpi_release (g);
  gcry_mpi_release (prime);
  return e;
}
Exemple #7
0
nuts_mpi_t nuts_mpi_new_random(const unsigned int nbits) {
  gcry_check();
  gcry_mpi_t mpi = gcry_mpi_new(nbits);

  gcry_mpi_randomize(mpi, nbits, GCRY_STRONG_RANDOM);
  gcry_mpi_set_bit(mpi, nbits - 1);
  gcry_mpi_set_bit(mpi, 0);

  return nuts_mpi_alloc(mpi);
}
Exemple #8
0
gcry_mpi_t get_random_exponent(const struct curve_params *cp)
{
  int bits = gcry_mpi_get_nbits(cp->dp.order);
  gcry_mpi_t a;
  a = gcry_mpi_snew(0);
  do {
    gcry_mpi_randomize(a, bits, GCRY_STRONG_RANDOM);
    gcry_mpi_clear_highbit(a, bits);
  } while (! gcry_mpi_cmp_ui(a, 0) || gcry_mpi_cmp(a, cp->dp.order) >= 0);
  return a;
}
Exemple #9
0
/**
 * Create a blinding key
 *
 * @param len length of the key in bits (i.e. 2048)
 * @return the newly created blinding key
 */
struct GNUNET_CRYPTO_rsa_BlindingKey *
GNUNET_CRYPTO_rsa_blinding_key_create (unsigned int len)
{
  struct GNUNET_CRYPTO_rsa_BlindingKey *blind;

  blind = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
  blind->r = gcry_mpi_new (len);
  gcry_mpi_randomize (blind->r,
                      len,
                      GCRY_STRONG_RANDOM);
  return blind;
}
Exemple #10
0
static void
test_keys( RSA_secret_key *sk, unsigned nbits )
{
  RSA_public_key pk;
  gcry_mpi_t test = gcry_mpi_new ( nbits );
  gcry_mpi_t out1 = gcry_mpi_new ( nbits );
  gcry_mpi_t out2 = gcry_mpi_new ( nbits );

  pk.n = sk->n;
  pk.e = sk->e;
  gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM );

  public( out1, test, &pk );
Exemple #11
0
/* Generate a random secret scalar k with an order of p

   At the beginning this was identical to the code is in elgamal.c.
   Later imporved by mmr.   Further simplified by wk.  */
static gcry_mpi_t
gen_k (gcry_mpi_t p, int security_level)
{
  gcry_mpi_t k;
  unsigned int nbits;

  nbits = mpi_get_nbits (p);
  k = mpi_snew (nbits);
  if (DBG_CIPHER)
    log_debug ("choosing a random k of %u bits\n", nbits);

  gcry_mpi_randomize (k, nbits, security_level);

  mpi_mod (k, k, p);  /*  k = k mod p  */

  return k;
}
Exemple #12
0
gboolean
egg_dh_gen_pair (gcry_mpi_t prime, gcry_mpi_t base, guint bits,
                 gcry_mpi_t *pub, gcry_mpi_t *priv)
{
	guint pbits;

	g_return_val_if_fail (prime, FALSE);
	g_return_val_if_fail (base, FALSE);
	g_return_val_if_fail (pub, FALSE);
	g_return_val_if_fail (priv, FALSE);

	pbits = gcry_mpi_get_nbits (prime);
	g_return_val_if_fail (pbits > 1, FALSE);

	if (bits == 0) {
		bits = pbits;
	} else if (bits > pbits) {
		g_return_val_if_reached (FALSE);
	}

	/*
	 * Generate a strong random number of bits, and not zero.
	 * gcry_mpi_randomize bumps up to the next byte. Since we
	 * need to have a value less than half of prime, we make sure
	 * we bump down.
	 */
	*priv = gcry_mpi_snew (bits);
	g_return_val_if_fail (*priv, FALSE);
	while (gcry_mpi_cmp_ui (*priv, 0) == 0)
		gcry_mpi_randomize (*priv, bits, GCRY_STRONG_RANDOM);

	/* Secret key value must be less than half of p */
	if (gcry_mpi_get_nbits (*priv) > bits)
		gcry_mpi_clear_highbit (*priv, bits);
	if (gcry_mpi_get_nbits (*priv) > pbits - 1)
		gcry_mpi_clear_highbit (*priv, pbits - 1);
	g_assert (gcry_mpi_cmp (prime, *priv) > 0);

	*pub = gcry_mpi_new (gcry_mpi_get_nbits (*priv));
	g_return_val_if_fail (*pub, FALSE);
	gcry_mpi_powm (*pub, base, *priv, prime);

	return TRUE;
}
Exemple #13
0
/****************
 * To verify correct skey it use a random information.
 * First, encrypt and decrypt this dummy value,
 * test if the information is recuperated.
 * Second, test with the sign and verify functions.
 */
static void
test_keys (ECC_secret_key *sk, unsigned int nbits)
{
  ECC_public_key pk;
  gcry_mpi_t test = mpi_new (nbits);
  mpi_point_t R_;
  gcry_mpi_t c = mpi_new (nbits);
  gcry_mpi_t out = mpi_new (nbits);
  gcry_mpi_t r = mpi_new (nbits);
  gcry_mpi_t s = mpi_new (nbits);

  if (DBG_CIPHER)
    log_debug ("Testing key.\n");

  point_init (&R_);

  pk.E = curve_copy (sk->E);
  point_init (&pk.Q);
  point_set (&pk.Q, &sk->Q);

  gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);

  if (sign (test, sk, r, s) )
    log_fatal ("ECDSA operation: sign failed\n");

  if (verify (test, &pk, r, s))
    {
      log_fatal ("ECDSA operation: sign, verify failed\n");
    }

  if (DBG_CIPHER)
    log_debug ("ECDSA operation: sign, verify ok.\n");

  point_free (&pk.Q);
  curve_free (&pk.E);

  point_free (&R_);
  mpi_free (s);
  mpi_free (r);
  mpi_free (out);
  mpi_free (c);
  mpi_free (test);
}
Exemple #14
0
/* Check that a freshly generated key actually works.  Returns 0 on success. */
static int
test_keys (RSA_secret_key *sk, unsigned int nbits)
{
  int result = -1; /* Default to failure.  */
  RSA_public_key pk;
  gcry_mpi_t plaintext = gcry_mpi_new (nbits);
  gcry_mpi_t ciphertext = gcry_mpi_new (nbits);
  gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits);
  gcry_mpi_t signature = gcry_mpi_new (nbits);

  /* Put the relevant parameters into a public key structure.  */
  pk.n = sk->n;
  pk.e = sk->e;

  /* Create a random plaintext.  */
  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);

  /* Encrypt using the public key.  */
  public (ciphertext, plaintext, &pk);
Exemple #15
0
static int
test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
{
  ELG_public_key pk;
  gcry_mpi_t test = gcry_mpi_new ( 0 );
  gcry_mpi_t out1_a = gcry_mpi_new ( nbits );
  gcry_mpi_t out1_b = gcry_mpi_new ( nbits );
  gcry_mpi_t out2 = gcry_mpi_new ( nbits );
  int failed = 0;

  pk.p = sk->p;
  pk.g = sk->g;
  pk.y = sk->y;

  gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );

  do_encrypt ( out1_a, out1_b, test, &pk );
  decrypt ( out2, out1_a, out1_b, sk );
  if ( mpi_cmp( test, out2 ) )
    failed |= 1;

  sign ( out1_a, out1_b, test, sk );
  if ( !verify( out1_a, out1_b, test, &pk ) )
    failed |= 2;

  gcry_mpi_release ( test );
  gcry_mpi_release ( out1_a );
  gcry_mpi_release ( out1_b );
  gcry_mpi_release ( out2 );

  if (failed && !nodie)
    log_fatal ("Elgamal test key for %s %s failed\n",
               (failed & 1)? "encrypt+decrypt":"",
               (failed & 2)? "sign+verify":"");
  if (failed && DBG_CIPHER) 
    log_debug ("Elgamal test key for %s %s failed\n",
               (failed & 1)? "encrypt+decrypt":"",
               (failed & 2)? "sign+verify":"");

  return failed;
}
Exemple #16
0
static void
test_asn1_integers (Test *test, gconstpointer unused)
{
	GNode *asn;
	gcry_mpi_t mpi, mpt;
	GBytes *data;
	gboolean ret;

	asn = egg_asn1x_create (test_asn1_tab, "TestIntegers");
	g_assert ("asn test structure is null" && asn != NULL);

	/* Make a random number */
	mpi = gcry_mpi_new (512);
	g_return_if_fail (mpi);
	gcry_mpi_randomize (mpi, 512, GCRY_WEAK_RANDOM);

	/* Write the mpi out */
	ret = gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "mpi", NULL), mpi);
	g_assert ("couldn't write mpi to asn1" && ret);

	/* Now encode the whole caboodle */
	data = egg_asn1x_encode (asn, NULL);
	g_assert ("encoding asn1 didn't work" && data != NULL);

	egg_asn1x_destroy (asn);

	/* Now decode it all nicely */
	asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data);
	g_assert (asn != NULL);

	ret = gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "mpi", NULL), &mpt);
	egg_asn1x_destroy (asn);
	g_assert ("couldn't read mpi from asn1" && ret);
	g_assert ("mpi returned is null" && mpt != NULL);
	g_assert ("mpi is wrong number" && gcry_mpi_cmp (mpi, mpt) == 0);

	g_bytes_unref (data);
	gcry_mpi_release (mpi);
	gcry_mpi_release (mpt);
}
/*
 * Return true if n is probably a prime
 */
static int
is_prime (gcry_mpi_t n, int steps, unsigned int *count)
{
  gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t z = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t a2 = mpi_alloc_set_ui( 2 );
  gcry_mpi_t q;
  unsigned i, j, k;
  int rc = 0;
  unsigned nbits = mpi_get_nbits( n );

  mpi_sub_ui( nminus1, n, 1 );

  /* Find q and k, so that n = 1 + 2^k * q . */
  q = mpi_copy ( nminus1 );
  k = mpi_trailing_zeros ( q );
  mpi_tdiv_q_2exp (q, q, k);

  for (i=0 ; i < steps; i++ )
    {
      ++*count;
      if( !i )
        {
          mpi_set_ui( x, 2 );
        }
      else
        {
          gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );

          /* Make sure that the number is smaller than the prime and
             keep the randomness of the high bit. */
          if ( mpi_test_bit ( x, nbits-2) )
            {
              mpi_set_highbit ( x, nbits-2); /* Clear all higher bits. */
            }
          else
            {
              mpi_set_highbit( x, nbits-2 );
              mpi_clear_bit( x, nbits-2 );
            }
          assert ( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
	}
      gcry_mpi_powm ( y, x, q, n);
      if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
        {
          for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
            {
              gcry_mpi_powm(y, y, a2, n);
              if( !mpi_cmp_ui( y, 1 ) )
                goto leave; /* Not a prime. */
            }
          if (mpi_cmp( y, nminus1 ) )
            goto leave; /* Not a prime. */
	}
      progress('+');
    }
  rc = 1; /* May be a prime. */

 leave:
  mpi_free( x );
  mpi_free( y );
  mpi_free( z );
  mpi_free( nminus1 );
  mpi_free( q );
  mpi_free( a2 );

  return rc;
}
static gcry_mpi_t
gen_prime (unsigned int nbits, int secret, int randomlevel, 
           int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)
{
  gcry_mpi_t prime, ptest, pminus1, val_2, val_3, result;
  int i;
  unsigned int x, step;
  unsigned int count1, count2;
  int *mods;
  
/*   if (  DBG_CIPHER ) */
/*     log_debug ("generate a prime of %u bits ", nbits ); */

  if (nbits < 16)
    log_fatal ("can't generate a prime with less than %d bits\n", 16);

  mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods );
  /* Make nbits fit into gcry_mpi_t implementation. */
  val_2  = mpi_alloc_set_ui( 2 );
  val_3 = mpi_alloc_set_ui( 3);
  prime  = secret? gcry_mpi_snew ( nbits ): gcry_mpi_new ( nbits );
  result = mpi_alloc_like( prime );
  pminus1= mpi_alloc_like( prime );
  ptest  = mpi_alloc_like( prime );
  count1 = count2 = 0;
  for (;;)
    {  /* try forvever */
      int dotcount=0;
      
      /* generate a random number */
      gcry_mpi_randomize( prime, nbits, randomlevel );
      
      /* Set high order bit to 1, set low order bit to 1.  If we are
         generating a secret prime we are most probably doing that
         for RSA, to make sure that the modulus does have the
         requested key size we set the 2 high order bits. */
      mpi_set_highbit (prime, nbits-1);
      if (secret)
        mpi_set_bit (prime, nbits-2);
      mpi_set_bit(prime, 0);
      
      /* Calculate all remainders. */
      for (i=0; (x = small_prime_numbers[i]); i++ )
        mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
      
      /* Now try some primes starting with prime. */
      for(step=0; step < 20000; step += 2 ) 
        {
          /* Check against all the small primes we have in mods. */
          count1++;
          for (i=0; (x = small_prime_numbers[i]); i++ ) 
            {
              while ( mods[i] + step >= x )
                mods[i] -= x;
              if ( !(mods[i] + step) )
                break;
	    }
          if ( x )
            continue;   /* Found a multiple of an already known prime. */
          
          mpi_add_ui( ptest, prime, step );

          /* Do a fast Fermat test now. */
          count2++;
          mpi_sub_ui( pminus1, ptest, 1);
          gcry_mpi_powm( result, val_2, pminus1, ptest );
          if ( !mpi_cmp_ui( result, 1 ) )
            { 
              /* Not composite, perform stronger tests */
              if (is_prime(ptest, 5, &count2 ))
                {
                  if (!mpi_test_bit( ptest, nbits-1-secret ))
                    {
                      progress('\n');
                      log_debug ("overflow in prime generation\n");
                      break; /* Stop loop, continue with a new prime. */
                    }

                  if (extra_check && extra_check (extra_check_arg, ptest))
                    { 
                      /* The extra check told us that this prime is
                         not of the caller's taste. */
                      progress ('/');
                    }
                  else
                    { 
                      /* Got it. */
                      mpi_free(val_2);
                      mpi_free(val_3);
                      mpi_free(result);
                      mpi_free(pminus1);
                      mpi_free(prime);
                      gcry_free(mods);
                      return ptest; 
                    }
                }
	    }
          if (++dotcount == 10 )
            {
              progress('.');
              dotcount = 0;
	    }
	}
      progress(':'); /* restart with a new random value */
    }
}
Exemple #19
0
char *
irc_sasl_mechanism_dh_blowfish (const char *data_base64,
                                const char *sasl_username,
                                const char *sasl_password)
{
    char *data, *answer, *ptr_answer, *answer_base64;
    unsigned char *ptr_data, *secret_bin, *public_bin;
    unsigned char *password_clear, *password_crypted;
    int length_data, size, num_bits_prime_number, length_key;
    int length_username, length_password, length_answer;
    size_t num_written;
    gcry_mpi_t data_prime_number, data_generator_number, data_server_pub_key;
    gcry_mpi_t pub_key, priv_key, secret_mpi;
    gcry_cipher_hd_t gcrypt_handle;

    data = NULL;
    secret_bin = NULL;
    public_bin = NULL;
    password_clear = NULL;
    password_crypted = NULL;
    answer = NULL;
    answer_base64 = NULL;
    data_prime_number = NULL;
    data_generator_number = NULL;
    data_server_pub_key = NULL;
    pub_key = NULL;
    priv_key = NULL;
    secret_mpi = NULL;

    /* decode data */
    data = malloc (strlen (data_base64) + 1);
    length_data = weechat_string_decode_base64 (data_base64, data);
    ptr_data = (unsigned char *)data;

    /* extract prime number */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto end;
    data_prime_number = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_prime_number, GCRYMPI_FMT_USG, ptr_data, size, NULL);
    num_bits_prime_number = gcry_mpi_get_nbits (data_prime_number);
    ptr_data += size;
    length_data -= size;

    /* extract generator number */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto end;
    data_generator_number = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_generator_number, GCRYMPI_FMT_USG, ptr_data, size, NULL);
    ptr_data += size;
    length_data -= size;

    /* extract server-generated public key */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto end;
    data_server_pub_key = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_server_pub_key, GCRYMPI_FMT_USG, ptr_data, size, NULL);

    /* generate keys */
    pub_key = gcry_mpi_new (num_bits_prime_number);
    priv_key = gcry_mpi_new (num_bits_prime_number);
    gcry_mpi_randomize (priv_key, num_bits_prime_number, GCRY_STRONG_RANDOM);
    /* pub_key = (g ^ priv_key) % p */
    gcry_mpi_powm (pub_key, data_generator_number, priv_key, data_prime_number);

    /* compute secret_bin */
    length_key = num_bits_prime_number / 8;
    secret_bin = malloc (length_key);
    secret_mpi = gcry_mpi_new (num_bits_prime_number);
    /* secret_mpi = (y ^ priv_key) % p */
    gcry_mpi_powm (secret_mpi, data_server_pub_key, priv_key, data_prime_number);
    gcry_mpi_print (GCRYMPI_FMT_USG, secret_bin, length_key,
                    &num_written, secret_mpi);

    /* create public_bin */
    public_bin = malloc (length_key);
    gcry_mpi_print (GCRYMPI_FMT_USG, public_bin, length_key,
                    &num_written, pub_key);

    /* create password buffers (clear and crypted) */
    length_password = strlen (sasl_password) +
        ((8 - (strlen (sasl_password) % 8)) % 8);
    password_clear = malloc (length_password);
    password_crypted = malloc (length_password);
    memset (password_clear, 0, length_password);
    memset (password_crypted, 0, length_password);
    memcpy (password_clear, sasl_password, strlen (sasl_password));

    /* crypt password using blowfish */
    if (gcry_cipher_open (&gcrypt_handle, GCRY_CIPHER_BLOWFISH,
                          GCRY_CIPHER_MODE_ECB, 0) != 0)
        goto end;
    if (gcry_cipher_setkey (gcrypt_handle, secret_bin, length_key) != 0)
        goto end;
    if (gcry_cipher_encrypt (gcrypt_handle,
                             password_crypted, length_password,
                             password_clear, length_password) != 0)
        goto end;

    /*
     * build answer for server, it is concatenation of:
     *   1. key length (2 bytes)
     *   2. public key ('length_key' bytes)
     *   3. sasl_username ('length_username'+1 bytes)
     *   4. encrypted password ('length_password' bytes)
     */
    length_username = strlen (sasl_username);
    length_answer = 2 + length_key + length_username + 1 + length_password;
    answer = malloc (length_answer);
    ptr_answer = answer;
    *((unsigned int *)ptr_answer) = htons(length_key);
    ptr_answer += 2;
    memcpy (ptr_answer, public_bin, length_key);
    ptr_answer += length_key;
    memcpy (ptr_answer, sasl_username, length_username + 1);
    ptr_answer += length_username + 1;
    memcpy (ptr_answer, password_crypted, length_password);

    /* encode answer to base64 */
    answer_base64 = malloc (length_answer * 4);
    if (answer_base64)
        weechat_string_encode_base64 (answer, length_answer, answer_base64);

end:
    if (data)
        free (data);
    if (secret_bin)
        free (secret_bin);
    if (public_bin)
        free (public_bin);
    if (password_clear)
        free (password_clear);
    if (password_crypted)
        free (password_crypted);
    if (answer)
        free (answer);
    if (data_prime_number)
        gcry_mpi_release (data_prime_number);
    if (data_generator_number)
        gcry_mpi_release (data_generator_number);
    if (data_server_pub_key)
        gcry_mpi_release (data_server_pub_key);
    if (pub_key)
        gcry_mpi_release (pub_key);
    if (priv_key)
        gcry_mpi_release (priv_key);
    if (secret_mpi)
        gcry_mpi_release (secret_mpi);

    return answer_base64;
}
Exemple #20
0
/* Check that left shifting works correctly.  */
static void
test_lshift (int pass)
{
  static int size_list[] = {1, 31, 32, 63, 64, 65, 70, 0};
  int size_idx;
  gcry_mpi_t a, b;
  char *tmpstr, *result, *result2;
  int i;

  wherestr = "test_lshift";
  show ("checking that lshift works as expected (pass %d)\n", pass);

  for (size_idx=0; size_list[size_idx]; size_idx++)
    {
      a = gcry_mpi_new (0);
      b = gcry_mpi_new (0);

      /* gcry_mpi_randomize rounds up to full bytes, thus we need to
         use gcry_mpi_clear_highbit to fix that.  */
      gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
      gcry_mpi_clear_highbit (a, size_list[size_idx]);

      for (i=0; i < 75; i++)
        {
          gcry_mpi_lshift (b, a, i);
          
          result = mpi2bitstr_nlz (b);
          tmpstr = mpi2bitstr_nlz (a);
          result2 = lshiftbitstring (tmpstr, i);
          xfree (tmpstr);
          if (strcmp (result, result2))
            {
              show ("got =%s\n", result);
              show ("want=%s\n", result2);
              fail ("lshift by %d failed\n", i);
            }
          xfree (result);
          xfree (result2);
        }
      
      /* Again. This time using in-place operation. */
      gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
      gcry_mpi_clear_highbit (a, size_list[size_idx]);
      
      for (i=0; i < 75; i++)
        {
          gcry_mpi_release (b);
          b = gcry_mpi_copy (a);
          gcry_mpi_lshift (b, b, i);

          result = mpi2bitstr_nlz (b);
          tmpstr = mpi2bitstr_nlz (a);
          result2 = lshiftbitstring (tmpstr, i);
          xfree (tmpstr);
          if (strcmp (result, result2))
            {
              show ("got =%s\n", result);
              show ("want=%s\n", result2);
              fail ("in-place lshift by %d failed\n", i);
            }
          xfree (result2);
          xfree (result);
        }

      gcry_mpi_release (b);
      gcry_mpi_release (a);
    }
}
Exemple #21
0
static void
rsa_bench (int iterations, int print_header, int no_blinding)
{
  gpg_error_t err;
  int p_sizes[] = { 1024, 2048, 3072, 4096 };
  int testno;

  if (print_header)
    printf ("Algorithm         generate %4d*sign %4d*verify\n"
            "------------------------------------------------\n",
            iterations, iterations );
  for (testno=0; testno < DIM (p_sizes); testno++)
    {
      gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
      gcry_mpi_t x;
      gcry_sexp_t data;
      gcry_sexp_t sig = NULL;
      int count;

      printf ("RSA %3d bit    ", p_sizes[testno]);
      fflush (stdout);

      err = gcry_sexp_build (&key_spec, NULL,
                             gcry_fips_mode_active ()
                             ? "(genkey (RSA (nbits %d)))"
                             : "(genkey (RSA (nbits %d)(transient-key)))",
                             p_sizes[testno]);
      if (err)
        die ("creating S-expression failed: %s\n", gcry_strerror (err));

      start_timer ();
      err = gcry_pk_genkey (&key_pair, key_spec);
      if (err)
        die ("creating %d bit RSA key failed: %s\n",
             p_sizes[testno], gcry_strerror (err));

      pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
      if (! pub_key)
        die ("public part missing in key\n");
      sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
      if (! sec_key)
        die ("private part missing in key\n");
      gcry_sexp_release (key_pair);
      gcry_sexp_release (key_spec);

      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      x = gcry_mpi_new (p_sizes[testno]);
      gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
      err = gcry_sexp_build (&data, NULL,
                             "(data (flags raw) (value %m))", x);
      gcry_mpi_release (x);
      if (err)
        die ("converting data failed: %s\n", gcry_strerror (err));

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          gcry_sexp_release (sig);
          err = gcry_pk_sign (&sig, data, sec_key);
          if (err)
            die ("signing failed (%d): %s\n", count, gpg_strerror (err));
        }
      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          err = gcry_pk_verify (sig, data, pub_key);
          if (err)
            {
              putchar ('\n');
              show_sexp ("seckey:\n", sec_key);
              show_sexp ("data:\n", data);
              show_sexp ("sig:\n", sig);
              die ("verify failed (%d): %s\n", count, gpg_strerror (err));
            }
        }
      stop_timer ();
      printf ("     %s", elapsed_time ());

      if (no_blinding)
        {
          fflush (stdout);
          x = gcry_mpi_new (p_sizes[testno]);
          gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
          err = gcry_sexp_build (&data, NULL,
                                 "(data (flags no-blinding) (value %m))", x);
          gcry_mpi_release (x);
          if (err)
            die ("converting data failed: %s\n", gcry_strerror (err));

          start_timer ();
          for (count=0; count < iterations; count++)
            {
              gcry_sexp_release (sig);
              err = gcry_pk_sign (&sig, data, sec_key);
              if (err)
                die ("signing failed (%d): %s\n", count, gpg_strerror (err));
            }
          stop_timer ();
          printf ("   %s", elapsed_time ());
          fflush (stdout);
        }

      putchar ('\n');
      fflush (stdout);

      gcry_sexp_release (sig);
      gcry_sexp_release (data);
      gcry_sexp_release (sec_key);
      gcry_sexp_release (pub_key);
    }
}
Exemple #22
0
static void
dsa_bench (int iterations, int print_header)
{
  gpg_error_t err;
  gcry_sexp_t pub_key[3], sec_key[3];
  int p_sizes[3] = { 1024, 2048, 3072 };
  int q_sizes[3] = { 160, 224, 256 };
  gcry_sexp_t data;
  gcry_sexp_t sig = NULL;
  int i, j;

  err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
                         strlen (sample_public_dsa_key_1024));
  if (!err)
    err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024,
                           strlen (sample_private_dsa_key_1024));
  if (!err)
    err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048,
                           strlen (sample_public_dsa_key_2048));
  if (!err)
    err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048,
                           strlen (sample_private_dsa_key_2048));
  if (!err)
    err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072,
                           strlen (sample_public_dsa_key_3072));
  if (!err)
    err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072,
                           strlen (sample_private_dsa_key_3072));
  if (err)
    {
      fprintf (stderr, PGM ": converting sample keys failed: %s\n",
               gcry_strerror (err));
      exit (1);
    }

  if (print_header)
    printf ("Algorithm         generate %4d*sign %4d*verify\n"
            "------------------------------------------------\n",
            iterations, iterations );
  for (i=0; i < DIM (q_sizes); i++)
    {
      gcry_mpi_t x;

      x = gcry_mpi_new (q_sizes[i]);
      gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM);
      err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
      gcry_mpi_release (x);
      if (err)
        {
          fprintf (stderr, PGM ": converting data failed: %s\n",
                   gcry_strerror (err));
          exit (1);
        }

      printf ("DSA %d/%d             -", p_sizes[i], q_sizes[i]);
      fflush (stdout);

      start_timer ();
      for (j=0; j < iterations; j++)
        {
          gcry_sexp_release (sig);
          err = gcry_pk_sign (&sig, data, sec_key[i]);
          if (err)
            {
              putchar ('\n');
              fprintf (stderr, PGM ": signing failed: %s\n",
                       gpg_strerror (err));
              exit (1);
            }
        }
      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      start_timer ();
      for (j=0; j < iterations; j++)
        {
          err = gcry_pk_verify (sig, data, pub_key[i]);
          if (err)
            {
              putchar ('\n');
              fprintf (stderr, PGM ": verify failed: %s\n",
                       gpg_strerror (err));
              exit (1);
            }
        }
      stop_timer ();
      printf ("     %s\n", elapsed_time ());
      fflush (stdout);

      gcry_sexp_release (sig);
      gcry_sexp_release (data);
      sig = NULL;
    }


  for (i=0; i < DIM (q_sizes); i++)
    {
      gcry_sexp_release (sec_key[i]);
      gcry_sexp_release (pub_key[i]);
    }
}
Exemple #23
0
/*
 * Generate a random number less than p
 * FIXME: takes ages ...
 */
void gen_rand(gcry_mpi_t r, gcry_mpi_t p) {
	do {
		gcry_mpi_randomize(r, gcry_mpi_get_nbits(p), GCRY_STRONG_RANDOM);
		gcry_mpi_clear_highbit(r, gcry_mpi_get_nbits(p) + 1);
	} while (gcry_mpi_cmp(p, r) < 0);
}
Exemple #24
0
int
irc_sasl_dh (const char *data_base64,
             unsigned char **public_bin, unsigned char **secret_bin,
             int *length_key)
{
    char *data;
    unsigned char *ptr_data;
    int length_data, size, num_bits_prime_number, rc;
    size_t num_written;
    gcry_mpi_t data_prime_number, data_generator_number, data_server_pub_key;
    gcry_mpi_t pub_key, priv_key, secret_mpi;

    rc = 0;

    data = NULL;
    data_prime_number = NULL;
    data_generator_number = NULL;
    data_server_pub_key = NULL;
    pub_key = NULL;
    priv_key = NULL;
    secret_mpi = NULL;

    /* decode data */
    data = malloc (strlen (data_base64) + 1);
    length_data = weechat_string_decode_base64 (data_base64, data);
    ptr_data = (unsigned char *)data;

    /* extract prime number */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto dhend;
    data_prime_number = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_prime_number, GCRYMPI_FMT_USG, ptr_data, size, NULL);
    num_bits_prime_number = gcry_mpi_get_nbits (data_prime_number);
    ptr_data += size;
    length_data -= size;

    /* extract generator number */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto dhend;
    data_generator_number = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_generator_number, GCRYMPI_FMT_USG, ptr_data, size, NULL);
    ptr_data += size;
    length_data -= size;

    /* extract server-generated public key */
    size = ntohs ((((unsigned int)ptr_data[1]) << 8) | ptr_data[0]);
    ptr_data += 2;
    length_data -= 2;
    if (size > length_data)
        goto dhend;
    data_server_pub_key = gcry_mpi_new (size * 8);
    gcry_mpi_scan (&data_server_pub_key, GCRYMPI_FMT_USG, ptr_data, size, NULL);

    /* generate keys */
    pub_key = gcry_mpi_new (num_bits_prime_number);
    priv_key = gcry_mpi_new (num_bits_prime_number);
    gcry_mpi_randomize (priv_key, num_bits_prime_number, GCRY_STRONG_RANDOM);
    /* pub_key = (g ^ priv_key) % p */
    gcry_mpi_powm (pub_key, data_generator_number, priv_key, data_prime_number);

    /* compute secret_bin */
    *length_key = num_bits_prime_number / 8;
    *secret_bin = malloc (*length_key);
    secret_mpi = gcry_mpi_new (num_bits_prime_number);
    /* secret_mpi = (y ^ priv_key) % p */
    gcry_mpi_powm (secret_mpi, data_server_pub_key, priv_key, data_prime_number);
    gcry_mpi_print (GCRYMPI_FMT_USG, *secret_bin, *length_key,
                    &num_written, secret_mpi);

    /* create public_bin */
    *public_bin = malloc (*length_key);
    gcry_mpi_print (GCRYMPI_FMT_USG, *public_bin, *length_key,
                    &num_written, pub_key);
    rc = 1;

dhend:
    if (data)
        free (data);
    if (data_prime_number)
        gcry_mpi_release (data_prime_number);
    if (data_generator_number)
        gcry_mpi_release (data_generator_number);
    if (data_server_pub_key)
        gcry_mpi_release (data_server_pub_key);
    if (pub_key)
        gcry_mpi_release (pub_key);
    if (priv_key)
        gcry_mpi_release (priv_key);
    if (secret_mpi)
        gcry_mpi_release (secret_mpi);

    return rc;
}
Exemple #25
0
static void
ecc_bench (int iterations, int print_header)
{
#if USE_ECC
  gpg_error_t err;
  int p_sizes[] = { 192, 224, 256, 384, 521 };
  int testno;

  if (print_header)
    printf ("Algorithm         generate %4d*sign %4d*verify\n"
            "------------------------------------------------\n",
            iterations, iterations );
  for (testno=0; testno < DIM (p_sizes); testno++)
    {
      gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
      gcry_mpi_t x;
      gcry_sexp_t data;
      gcry_sexp_t sig = NULL;
      int count;

      printf ("ECDSA %3d bit ", p_sizes[testno]);
      fflush (stdout);

      err = gcry_sexp_build (&key_spec, NULL,
                             "(genkey (ECDSA (nbits %d)))", p_sizes[testno]);
      if (err)
        die ("creating S-expression failed: %s\n", gcry_strerror (err));

      start_timer ();
      err = gcry_pk_genkey (&key_pair, key_spec);
      if (err)
        die ("creating %d bit ECC key failed: %s\n",
             p_sizes[testno], gcry_strerror (err));

      pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
      if (! pub_key)
        die ("public part missing in key\n");
      sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
      if (! sec_key)
        die ("private part missing in key\n");
      gcry_sexp_release (key_pair);
      gcry_sexp_release (key_spec);

      stop_timer ();
      printf ("     %s", elapsed_time ());
      fflush (stdout);

      x = gcry_mpi_new (p_sizes[testno]);
      gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM);
      err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
      gcry_mpi_release (x);
      if (err)
        die ("converting data failed: %s\n", gcry_strerror (err));

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          gcry_sexp_release (sig);
          err = gcry_pk_sign (&sig, data, sec_key);
          if (err)
            die ("signing failed: %s\n", gpg_strerror (err));
        }
      stop_timer ();
      printf ("   %s", elapsed_time ());
      fflush (stdout);

      start_timer ();
      for (count=0; count < iterations; count++)
        {
          err = gcry_pk_verify (sig, data, pub_key);
          if (err)
            {
              putchar ('\n');
              show_sexp ("seckey:\n", sec_key);
              show_sexp ("data:\n", data);
              show_sexp ("sig:\n", sig);
              die ("verify failed: %s\n", gpg_strerror (err));
            }
        }
      stop_timer ();
      printf ("     %s\n", elapsed_time ());
      fflush (stdout);

      gcry_sexp_release (sig);
      gcry_sexp_release (data);
      gcry_sexp_release (sec_key);
      gcry_sexp_release (pub_key);
    }
#endif /*USE_ECC*/
}