Exemplo n.º 1
0
/* S = (A * v^u) ^ b % N 
 * this is our shared key (server premaster secret)
 */
mpi_t
_gnutls_calc_srp_S1 (mpi_t A, mpi_t b, mpi_t u, mpi_t v, mpi_t n)
{
  mpi_t tmp1 = NULL, tmp2 = NULL;
  mpi_t S = NULL;

  S = _gnutls_mpi_alloc_like (n);
  if (S == NULL)
    return NULL;

  tmp1 = _gnutls_mpi_alloc_like (n);
  tmp2 = _gnutls_mpi_alloc_like (n);

  if (tmp1 == NULL || tmp2 == NULL)
    goto freeall;

  _gnutls_mpi_powm (tmp1, v, u, n);
  _gnutls_mpi_mulm (tmp2, A, tmp1, n);
  _gnutls_mpi_powm (S, tmp2, b, n);

  _gnutls_mpi_release (&tmp1);
  _gnutls_mpi_release (&tmp2);

  return S;

freeall:
  _gnutls_mpi_release (&tmp1);
  _gnutls_mpi_release (&tmp2);
  return NULL;
}
Exemplo n.º 2
0
/* S = (B - k*g^x) ^ (a + u * x) % N
 * this is our shared key (client premaster secret)
 */
bigint_t
_gnutls_calc_srp_S2 (bigint_t B, bigint_t g, bigint_t x, bigint_t a,
                     bigint_t u, bigint_t n)
{
  bigint_t S = NULL, tmp1 = NULL, tmp2 = NULL;
  bigint_t tmp4 = NULL, tmp3 = NULL, k = NULL;

  S = _gnutls_mpi_alloc_like (n);
  if (S == NULL)
    return NULL;

  tmp1 = _gnutls_mpi_alloc_like (n);
  tmp2 = _gnutls_mpi_alloc_like (n);
  tmp3 = _gnutls_mpi_alloc_like (n);
  if (tmp1 == NULL || tmp2 == NULL || tmp3 == NULL)
    {
      goto freeall;
    }

  k = _gnutls_calc_srp_u (n, g, n);
  if (k == NULL)
    {
      gnutls_assert ();
      goto freeall;
    }

  _gnutls_mpi_powm (tmp1, g, x, n);     /* g^x */
  _gnutls_mpi_mulm (tmp3, tmp1, k, n);  /* k*g^x mod n */
  _gnutls_mpi_subm (tmp2, B, tmp3, n);

  tmp4 = _gnutls_mpi_alloc_like (n);
  if (tmp4 == NULL)
    goto freeall;

  _gnutls_mpi_mul (tmp1, u, x);
  _gnutls_mpi_add (tmp4, a, tmp1);
  _gnutls_mpi_powm (S, tmp2, tmp4, n);

  _gnutls_mpi_release (&tmp1);
  _gnutls_mpi_release (&tmp2);
  _gnutls_mpi_release (&tmp3);
  _gnutls_mpi_release (&tmp4);
  _gnutls_mpi_release (&k);

  return S;

freeall:
  _gnutls_mpi_release (&k);
  _gnutls_mpi_release (&tmp1);
  _gnutls_mpi_release (&tmp2);
  _gnutls_mpi_release (&tmp3);
  _gnutls_mpi_release (&tmp4);
  _gnutls_mpi_release (&S);
  return NULL;
}
Exemplo n.º 3
0
/* returns the blinded c and the inverse of a random
 * number r;
 */
static bigint_t
rsa_blind (bigint_t c, bigint_t e, bigint_t n, bigint_t * _ri)
{
  bigint_t nc = NULL, r = NULL, ri = NULL;

  /* nc = c*(r^e)
   * ri = r^(-1)
   */
  nc = _gnutls_mpi_alloc_like (n);
  if (nc == NULL)
    {
      gnutls_assert ();
      return NULL;
    }

  ri = _gnutls_mpi_alloc_like (n);
  if (nc == NULL)
    {
      gnutls_assert ();
      goto fail;
    }

  r = _gnutls_mpi_randomize (NULL, _gnutls_mpi_get_nbits (n),
                             GNUTLS_RND_NONCE);
  if (r == NULL)
    {
      gnutls_assert ();
      goto fail;
    }

  /* invert r */
  if (mpz_invert (ri, r, n) == 0)
    {
      gnutls_assert ();
      goto fail;
    }

  /* r = r^e */

  _gnutls_mpi_powm (r, r, e, n);

  _gnutls_mpi_mulm (nc, c, r, n);

  *_ri = ri;

  _gnutls_mpi_release (&r);

  return nc;
fail:
  _gnutls_mpi_release (&nc);
  _gnutls_mpi_release (&r);
  return NULL;
}
Exemplo n.º 4
0
int
_gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size)
{
  bigint_t tmp = _gnutls_mpi_alloc_like (params[0]);

  if (params_size < RSA_PRIVATE_PARAMS - 2)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  if (tmp == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* [6] = d % p-1, [7] = d % q-1 */
  _gnutls_mpi_sub_ui (tmp, params[3], 1);
  params[6] = _gnutls_mpi_mod (params[2] /*d */ , tmp);

  _gnutls_mpi_sub_ui (tmp, params[4], 1);
  params[7] = _gnutls_mpi_mod (params[2] /*d */ , tmp);

  _gnutls_mpi_release (&tmp);

  if (params[7] == NULL || params[6] == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  return 0;
}
Exemplo n.º 5
0
/* Checks if b%n==0 which is a fatal srp error.
 * Returns a proper error code in that case, and 0 when
 * all are ok.
 */
inline static int
check_b_mod_n (mpi_t b, mpi_t n)
{
  int ret;
  mpi_t r = _gnutls_mpi_alloc_like (b);

  if (r == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  _gnutls_mpi_mod (r, b, n);
  ret = _gnutls_mpi_cmp_ui (r, 0);

  _gnutls_mpi_release (&r);

  if (ret == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
    }

  return 0;
}
Exemplo n.º 6
0
/* returns the public value (X), and the secret (ret_x).
 */
mpi_t
gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime)
{
  mpi_t e, x;
  int x_size = _gnutls_mpi_get_nbits (prime) - 1;
  /* The size of the secret key is less than
   * prime/2
   */

  if (x_size > MAX_BITS || x_size <= 0)
    {
      gnutls_assert ();
      return NULL;
    }

  x = _gnutls_mpi_new (x_size);
  if (x == NULL)
    {
      gnutls_assert ();
      if (ret_x)
	*ret_x = NULL;

      return NULL;
    }

  /* FIXME: (x_size/8)*8 is there to overcome a bug in libgcrypt
   * which does not really check the bits given but the bytes.
   */
  do
    {
      _gnutls_mpi_randomize (x, (x_size / 8) * 8, GCRY_STRONG_RANDOM);
      /* Check whether x is zero. 
       */
    }
  while (_gnutls_mpi_cmp_ui (x, 0) == 0);

  e = _gnutls_mpi_alloc_like (prime);
  if (e == NULL)
    {
      gnutls_assert ();
      if (ret_x)
	*ret_x = NULL;

      _gnutls_mpi_release (&x);
      return NULL;
    }

  _gnutls_mpi_powm (e, g, x, prime);

  if (ret_x)
    *ret_x = x;
  else
    _gnutls_mpi_release (&x);
  return e;
}
Exemplo n.º 7
0
static bigint_t
wrap_gcry_mpi_mod (const bigint_t a, const bigint_t b)
{
  bigint_t r = _gnutls_mpi_alloc_like (b);

  if (r == NULL)
    return NULL;

  gcry_mpi_mod (r, a, b);

  return r;
}
Exemplo n.º 8
0
static bigint_t
wrap_gcry_mpi_mul_ui (bigint_t w, const bigint_t a, unsigned long b)
{
  if (w == NULL)
    w = _gnutls_mpi_alloc_like (a);

  if (w == NULL)
    return NULL;

  gcry_mpi_mul_ui (w, a, b);

  return w;
}
Exemplo n.º 9
0
/* q = a / b */
static bigint_t
wrap_gcry_mpi_div (bigint_t q, const bigint_t a, const bigint_t b)
{
  if (q == NULL)
    q = _gnutls_mpi_alloc_like (a);

  if (q == NULL)
    return NULL;

  gcry_mpi_div (q, NULL, a, b, 0);

  return q;
}
Exemplo n.º 10
0
static bigint_t
wrap_gcry_mpi_mul (bigint_t w, const bigint_t a, const bigint_t b)
{
  if (w == NULL)
    w = _gnutls_mpi_alloc_like (b);

  if (w == NULL)
    return NULL;

  gcry_mpi_mul (w, a, b);

  return w;
}
Exemplo n.º 11
0
static bigint_t
wrap_gcry_mpi_subm (bigint_t w, const bigint_t a, const bigint_t b,
		    const bigint_t m)
{
  if (w == NULL)
    w = _gnutls_mpi_alloc_like (m);

  if (w == NULL)
    return NULL;

  gcry_mpi_subm (w, a, b, m);

  return w;
}
Exemplo n.º 12
0
int
_gnutls_srp_gx (opaque * text, size_t textsize, opaque ** result,
                bigint_t g, bigint_t prime, gnutls_alloc_function galloc_func)
{
  bigint_t x, e;
  size_t result_size;
  int ret;

  if (_gnutls_mpi_scan_nz (&x, text, textsize))
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  e = _gnutls_mpi_alloc_like (prime);
  if (e == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&x);
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* e = g^x mod prime (n) */
  _gnutls_mpi_powm (e, g, x, prime);
  _gnutls_mpi_release (&x);

  ret = _gnutls_mpi_print (e, NULL, &result_size);
  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
    {
      *result = galloc_func (result_size);
      if ((*result) == NULL)
        return GNUTLS_E_MEMORY_ERROR;

      _gnutls_mpi_print (e, *result, &result_size);
      ret = result_size;
    }
  else
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_PRINT_FAILED;
    }

  _gnutls_mpi_release (&e);

  return ret;

}
Exemplo n.º 13
0
mpi_t
gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime)
{
  mpi_t k;
  int bits;

  bits = _gnutls_mpi_get_nbits (prime);
  if (bits <= 0 || bits > MAX_BITS)
    {
      gnutls_assert ();
      return NULL;
    }

  k = _gnutls_mpi_alloc_like (prime);
  if (k == NULL)
    return NULL;
  _gnutls_mpi_powm (k, f, x, prime);
  return k;
}
Exemplo n.º 14
0
int
_gnutls_srp_gx (opaque * text, size_t textsize, opaque ** result,
		mpi_t g, mpi_t prime, gnutls_alloc_function galloc_func)
{
  mpi_t x, e;
  size_t result_size;

  if (_gnutls_mpi_scan_nz (&x, text, &textsize))
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  e = _gnutls_mpi_alloc_like (prime);
  if (e == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&x);
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* e = g^x mod prime (n) */
  _gnutls_mpi_powm (e, g, x, prime);
  _gnutls_mpi_release (&x);

  _gnutls_mpi_print (NULL, &result_size, e);
  if (result != NULL)
    {
      *result = galloc_func (result_size);
      if ((*result) == NULL)
	return GNUTLS_E_MEMORY_ERROR;

      _gnutls_mpi_print (*result, &result_size, e);
    }

  _gnutls_mpi_release (&e);

  return result_size;

}
Exemplo n.º 15
0
/* Check if N is a prime and G a generator of the
 * group. This is check only done if N is big enough.
 * Otherwise only the included parameters must be used.
 */
static int
group_check_g_n (mpi_t g, mpi_t n)
{
  mpi_t q = NULL, two = NULL, w = NULL;
  int ret;

  if (_gnutls_mpi_get_nbits (n) < 2048)
    {
      gnutls_assert ();
      return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
    }

  /* N must be of the form N=2q+1
   * where q is also a prime.
   */
  if (_gnutls_prime_check (n, 0) != 0)
    {
      _gnutls_dump_mpi ("no prime N: ", n);
      gnutls_assert ();
      return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
    }

  two = _gnutls_mpi_new (4);
  if (two == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  q = _gnutls_mpi_alloc_like (n);
  if (q == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto error;
    }

  /* q = n-1 
   */
  _gnutls_mpi_sub_ui (q, n, 1);

  /* q = q/2, remember that q is divisible by 2 (prime - 1)
   */
  _gnutls_mpi_set_ui (two, 2);
  _gnutls_mpi_div (q, NULL, q, two, 0);

  if (_gnutls_prime_check (q, 0) != 0)
    {
      /* N was not on the form N=2q+1, where q = prime
       */
      _gnutls_dump_mpi ("no prime Q: ", q);
      gnutls_assert ();
      return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
    }

  /* We also check whether g is a generator,
   */

  /* check if g < q < N
   */
  if (_gnutls_mpi_cmp (g, q) >= 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
      goto error;
    }

  w = _gnutls_mpi_alloc_like (q);
  if (w == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto error;
    }

  /* check if g^q mod N == N-1
   * w = g^q mod N
   */
  _gnutls_mpi_powm (w, g, q, n);

  /* w++
   */
  _gnutls_mpi_add_ui (w, w, 1);

  if (_gnutls_mpi_cmp (w, n) != 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
      goto error;
    }

  ret = 0;

error:
  _gnutls_mpi_release (&q);
  _gnutls_mpi_release (&two);
  _gnutls_mpi_release (&w);

  return ret;

}
Exemplo n.º 16
0
Arquivo: pk.c Projeto: dezelin/maily
static int
_rsa_generate_params (bigint_t * resarr, int *resarr_len, int bits)
{

  int ret, i;
  gcry_sexp_t parms, key, list;
  bigint_t tmp;

  if (*resarr_len < RSA_PRIVATE_PARAMS)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret = gcry_sexp_build (&parms, NULL, "(genkey(rsa(nbits %d)))", bits);
  if (ret != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  /* generate the RSA key */
  ret = gcry_pk_genkey (&key, parms);
  gcry_sexp_release (parms);

  if (ret != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  list = gcry_sexp_find_token (key, "n", 0);
  if (list == NULL)
    {
      gnutls_assert ();
      gcry_sexp_release (key);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  resarr[0] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (list);

  list = gcry_sexp_find_token (key, "e", 0);
  if (list == NULL)
    {
      gnutls_assert ();
      gcry_sexp_release (key);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  resarr[1] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (list);

  list = gcry_sexp_find_token (key, "d", 0);
  if (list == NULL)
    {
      gnutls_assert ();
      gcry_sexp_release (key);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  resarr[2] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (list);

  list = gcry_sexp_find_token (key, "p", 0);
  if (list == NULL)
    {
      gnutls_assert ();
      gcry_sexp_release (key);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  resarr[3] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (list);


  list = gcry_sexp_find_token (key, "q", 0);
  if (list == NULL)
    {
      gnutls_assert ();
      gcry_sexp_release (key);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  resarr[4] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  gcry_sexp_release (list);


  list = gcry_sexp_find_token (key, "u", 0);
  if (list == NULL)
    {
      gnutls_assert ();
      gcry_sexp_release (key);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  resarr[5] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);

  gcry_sexp_release (list);
  gcry_sexp_release (key);

  _gnutls_mpi_log ("n: ", resarr[0]);
  _gnutls_mpi_log ("e: ", resarr[1]);
  _gnutls_mpi_log ("d: ", resarr[2]);
  _gnutls_mpi_log ("p: ", resarr[3]);
  _gnutls_mpi_log ("q: ", resarr[4]);
  _gnutls_mpi_log ("u: ", resarr[5]);

  /* generate e1 and e2 */

  *resarr_len = 6;

  tmp = _gnutls_mpi_alloc_like (resarr[0]);
  if (tmp == NULL)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  ret = _gnutls_calc_rsa_exp (resarr, 2 + *resarr_len);
  if (ret < 0)
    {
      gnutls_assert ();
      ret = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  (*resarr_len) += 2;

  return 0;

cleanup:
  for (i = 0; i < *resarr_len; i++)
    _gnutls_mpi_release (&resarr[i]);

  return ret;
}
Exemplo n.º 17
0
static int
wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
			       unsigned int level /*bits */ ,
			       gnutls_pk_params_st * params)
{
	int ret;
	unsigned int i, q_bits;

	memset(params, 0, sizeof(*params));

	switch (algo) {

	case GNUTLS_PK_DSA:
		{
			struct dsa_public_key pub;
			struct dsa_private_key priv;

			dsa_public_key_init(&pub);
			dsa_private_key_init(&priv);

			/* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
			 * but we do NIST DSA here */
			if (level <= 1024)
				q_bits = 160;
			else
				q_bits = 256;

			ret =
			    dsa_generate_keypair(&pub, &priv, NULL,
						 rnd_func, NULL, NULL,
						 level, q_bits);
			if (ret != 1) {
				gnutls_assert();
				ret = GNUTLS_E_INTERNAL_ERROR;
				goto dsa_fail;
			}

			params->params_nr = 0;
			for (i = 0; i < DSA_PRIVATE_PARAMS; i++) {
				params->params[i] =
				    _gnutls_mpi_alloc_like(&pub.p);
				if (params->params[i] == NULL) {
					ret = GNUTLS_E_MEMORY_ERROR;
					goto dsa_fail;
				}
				params->params_nr++;
			}

			ret = 0;
			_gnutls_mpi_set(params->params[0], pub.p);
			_gnutls_mpi_set(params->params[1], pub.q);
			_gnutls_mpi_set(params->params[2], pub.g);
			_gnutls_mpi_set(params->params[3], pub.y);
			_gnutls_mpi_set(params->params[4], priv.x);

		      dsa_fail:
			dsa_private_key_clear(&priv);
			dsa_public_key_clear(&pub);

			if (ret < 0)
				goto fail;

			break;
		}
	case GNUTLS_PK_RSA:
		{
			struct rsa_public_key pub;
			struct rsa_private_key priv;

			rsa_public_key_init(&pub);
			rsa_private_key_init(&priv);

			_gnutls_mpi_set_ui(&pub.e, 65537);

			ret =
			    rsa_generate_keypair(&pub, &priv, NULL,
						 rnd_func, NULL, NULL,
						 level, 0);
			if (ret != 1) {
				gnutls_assert();
				ret = GNUTLS_E_INTERNAL_ERROR;
				goto rsa_fail;
			}

			params->params_nr = 0;
			for (i = 0; i < RSA_PRIVATE_PARAMS; i++) {
				params->params[i] =
				    _gnutls_mpi_alloc_like(&pub.n);
				if (params->params[i] == NULL) {
					ret = GNUTLS_E_MEMORY_ERROR;
					goto rsa_fail;
				}
				params->params_nr++;

			}

			ret = 0;

			_gnutls_mpi_set(params->params[0], pub.n);
			_gnutls_mpi_set(params->params[1], pub.e);
			_gnutls_mpi_set(params->params[2], priv.d);
			_gnutls_mpi_set(params->params[3], priv.p);
			_gnutls_mpi_set(params->params[4], priv.q);
			_gnutls_mpi_set(params->params[5], priv.c);
			_gnutls_mpi_set(params->params[6], priv.a);
			_gnutls_mpi_set(params->params[7], priv.b);

		      rsa_fail:
			rsa_private_key_clear(&priv);
			rsa_public_key_clear(&pub);

			if (ret < 0)
				goto fail;

			break;
		}
	case GNUTLS_PK_EC:
		{
			struct ecc_scalar key;
			struct ecc_point pub;
			const struct ecc_curve *curve;

			curve = get_supported_curve(level);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ecc_scalar_init(&key, curve);
			ecc_point_init(&pub, curve);

			ecdsa_generate_keypair(&pub, &key, NULL, rnd_func);

			params->params[ECC_X] = _gnutls_mpi_new(0);
			params->params[ECC_Y] = _gnutls_mpi_new(0);
			params->params[ECC_K] = _gnutls_mpi_new(0);

			if (params->params[ECC_X] == NULL
			    || params->params[ECC_Y] == NULL
			    || params->params[ECC_K] == NULL) {
				_gnutls_mpi_release(&params->
						    params[ECC_X]);
				_gnutls_mpi_release(&params->
						    params[ECC_Y]);
				_gnutls_mpi_release(&params->
						    params[ECC_K]);
				goto ecc_cleanup;
			}

			params->flags = level;
			params->params_nr = ECC_PRIVATE_PARAMS;

			ecc_point_get(&pub, TOMPZ(params->params[ECC_X]),
				      TOMPZ(params->params[ECC_Y]));
			ecc_scalar_get(&key, TOMPZ(params->params[ECC_K]));

		      ecc_cleanup:
			ecc_point_clear(&pub);
			ecc_scalar_clear(&key);

			break;
		}
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	return 0;

      fail:

	for (i = 0; i < params->params_nr; i++) {
		_gnutls_mpi_release(&params->params[i]);
	}
	params->params_nr = 0;

	return ret;
}
Exemplo n.º 18
0
/****************
 * Choose a random value b and calculate B = (k* v + g^b) % N.
 * where k == SHA1(N|g)
 * Return: B and if ret_b is not NULL b.
 */
mpi_t
_gnutls_calc_srp_B (mpi_t * ret_b, mpi_t g, mpi_t n, mpi_t v)
{
  mpi_t tmpB = NULL, tmpV = NULL;
  mpi_t b = NULL, B = NULL, k = NULL;
  int bits;


  /* calculate:  B = (k*v + g^b) % N 
   */
  bits = _gnutls_mpi_get_nbits (n);
  b = _gnutls_mpi_snew (bits);
  if (b == NULL)
    {
      gnutls_assert ();
      return NULL;
    }

  tmpV = _gnutls_mpi_alloc_like (n);

  if (tmpV == NULL)
    {
      gnutls_assert ();
      goto error;
    }

  _gnutls_mpi_randomize (b, bits, GCRY_STRONG_RANDOM);

  tmpB = _gnutls_mpi_snew (bits);
  if (tmpB == NULL)
    {
      gnutls_assert ();
      goto error;
    }

  B = _gnutls_mpi_snew (bits);
  if (B == NULL)
    {
      gnutls_assert ();
      goto error;
    }

  k = _gnutls_calc_srp_u (n, g, n);
  if (k == NULL)
    {
      gnutls_assert ();
      goto error;
    }

  _gnutls_mpi_mulm (tmpV, k, v, n);
  _gnutls_mpi_powm (tmpB, g, b, n);

  _gnutls_mpi_addm (B, tmpV, tmpB, n);

  _gnutls_mpi_release (&k);
  _gnutls_mpi_release (&tmpB);
  _gnutls_mpi_release (&tmpV);

  if (ret_b)
    *ret_b = b;
  else
    _gnutls_mpi_release (&b);

  return B;

error:
  _gnutls_mpi_release (&b);
  _gnutls_mpi_release (&B);
  _gnutls_mpi_release (&k);
  _gnutls_mpi_release (&tmpB);
  _gnutls_mpi_release (&tmpV);
  return NULL;

}
Exemplo n.º 19
0
Arquivo: pk.c Projeto: intgr/gnutls
static int
wrap_nettle_pk_generate_params (gnutls_pk_algorithm_t algo,
                                unsigned int level /*bits */ ,
                                gnutls_pk_params_st * params)
{
  int ret;
  unsigned int i, q_bits;

  memset(params, 0, sizeof(*params));

  switch (algo)
    {

    case GNUTLS_PK_DSA:
      {
        struct dsa_public_key pub;
        struct dsa_private_key priv;

        dsa_public_key_init (&pub);
        dsa_private_key_init (&priv);

        /* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
         * but we do NIST DSA here */
        if (level <= 1024)
          q_bits = 160;
        else
          q_bits = 256;

        ret =
          dsa_generate_keypair (&pub, &priv, NULL,
                                rnd_func, NULL, NULL, level, q_bits);
        if (ret != 1)
          {
            gnutls_assert ();
            ret = GNUTLS_E_INTERNAL_ERROR;
            goto dsa_fail;
          }

        params->params_nr = 0;
        for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like (&pub.p);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto dsa_fail;
              }
            params->params_nr++;
          }

        ret = 0;
        _gnutls_mpi_set (params->params[0], pub.p);
        _gnutls_mpi_set (params->params[1], pub.q);
        _gnutls_mpi_set (params->params[2], pub.g);
        _gnutls_mpi_set (params->params[3], pub.y);
        _gnutls_mpi_set (params->params[4], priv.x);

dsa_fail:
        dsa_private_key_clear (&priv);
        dsa_public_key_clear (&pub);

        if (ret < 0)
          goto fail;

        break;
      }
    case GNUTLS_PK_RSA:
      {
        struct rsa_public_key pub;
        struct rsa_private_key priv;

        rsa_public_key_init (&pub);
        rsa_private_key_init (&priv);

        _gnutls_mpi_set_ui (&pub.e, 65537);

        ret =
          rsa_generate_keypair (&pub, &priv, NULL,
                                rnd_func, NULL, NULL, level, 0);
        if (ret != 1)
          {
            gnutls_assert ();
            ret = GNUTLS_E_INTERNAL_ERROR;
            goto rsa_fail;
          }

        params->params_nr = 0;
        for (i = 0; i < RSA_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like (&pub.n);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto rsa_fail;
              }
            params->params_nr++;

          }
          
        ret = 0;

        _gnutls_mpi_set (params->params[0], pub.n);
        _gnutls_mpi_set (params->params[1], pub.e);
        _gnutls_mpi_set (params->params[2], priv.d);
        _gnutls_mpi_set (params->params[3], priv.p);
        _gnutls_mpi_set (params->params[4], priv.q);
        _gnutls_mpi_set (params->params[5], priv.c);
        _gnutls_mpi_set (params->params[6], priv.a);
        _gnutls_mpi_set (params->params[7], priv.b);

rsa_fail:
        rsa_private_key_clear (&priv);
        rsa_public_key_clear (&pub);

        if (ret < 0)
          goto fail;

        break;
      }
    case GNUTLS_PK_EC:
      {
        ecc_key key;
        ecc_set_type tls_ecc_set;
        const gnutls_ecc_curve_entry_st *st;

        st = _gnutls_ecc_curve_get_params(level);
        if (st == NULL)
          return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
        
        tls_ecc_set.size = st->size;
        tls_ecc_set.prime = st->prime;
        tls_ecc_set.order = st->order;
        tls_ecc_set.Gx = st->Gx;
        tls_ecc_set.Gy = st->Gy;
        tls_ecc_set.A = st->A;
        tls_ecc_set.B = st->B;

        ret = ecc_make_key(NULL, rnd_func, &key, &tls_ecc_set, st->id);
        if (ret != 0)
          return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

        params->params_nr = 0;
        for (i = 0; i < ECC_PRIVATE_PARAMS; i++)
          {
            params->params[i] = _gnutls_mpi_alloc_like(&key.prime);
            if (params->params[i] == NULL)
              {
                ret = GNUTLS_E_MEMORY_ERROR;
                goto ecc_fail;
              }
            params->params_nr++;
          }
        params->flags = level;

        mpz_set(TOMPZ(params->params[ECC_PRIME]), key.prime);
        mpz_set(TOMPZ(params->params[ECC_ORDER]), key.order);
        mpz_set(TOMPZ(params->params[ECC_A]), key.A);
        mpz_set(TOMPZ(params->params[ECC_B]), key.B);
        mpz_set(TOMPZ(params->params[ECC_GX]), key.Gx);
        mpz_set(TOMPZ(params->params[ECC_GY]), key.Gy);
        mpz_set(TOMPZ(params->params[ECC_X]), key.pubkey.x);
        mpz_set(TOMPZ(params->params[ECC_Y]), key.pubkey.y);
        mpz_set(TOMPZ(params->params[ECC_K]), key.k);
        
ecc_fail:
        ecc_free(&key);
        
        if (ret < 0)
          goto fail;

        break;
      }
    default:
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  return 0;

fail:

  for (i = 0; i < params->params_nr; i++)
    {
      _gnutls_mpi_release (&params->params[i]);
    }
  params->params_nr = 0;

  return ret;
}