예제 #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;
}
예제 #2
0
파일: gnutls_srp.c 프로젝트: ares89/vlc
/* 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;
}
예제 #3
0
파일: gnutls_srp.c 프로젝트: ares89/vlc
/* A = g^a % N 
 * returns A and a (which is random)
 */
bigint_t
_gnutls_calc_srp_A (bigint_t * a, bigint_t g, bigint_t n)
{
  bigint_t tmpa;
  bigint_t A;
  int bits;

  bits = _gnutls_mpi_get_nbits (n);
  tmpa = _gnutls_mpi_randomize (NULL, bits, GNUTLS_RND_RANDOM);

  A = _gnutls_mpi_new (bits);
  if (A == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&tmpa);
      return NULL;
    }
  _gnutls_mpi_powm (A, g, tmpa, n);

  if (a != NULL)
    *a = tmpa;
  else
    _gnutls_mpi_release (&tmpa);

  return A;
}
예제 #4
0
/* A = g^a % N 
 * returns A and a (which is random)
 */
mpi_t
_gnutls_calc_srp_A (mpi_t * a, mpi_t g, mpi_t n)
{
  mpi_t tmpa;
  mpi_t A;
  int bits;

  bits = _gnutls_mpi_get_nbits (n);
  tmpa = _gnutls_mpi_snew (bits);
  if (tmpa == NULL)
    {
      gnutls_assert ();
      return NULL;
    }

  _gnutls_mpi_randomize (tmpa, bits, GCRY_STRONG_RANDOM);

  A = _gnutls_mpi_snew (bits);
  if (A == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&tmpa);
      return NULL;
    }
  _gnutls_mpi_powm (A, g, tmpa, n);

  if (a != NULL)
    *a = tmpa;
  else
    _gnutls_mpi_release (&tmpa);

  return A;
}
예제 #5
0
파일: srp.c 프로젝트: attilamolnar/gnutls
/* A = g^a % N 
 * returns A and a (which is random)
 */
bigint_t _gnutls_calc_srp_A(bigint_t * a, bigint_t g, bigint_t n)
{
	bigint_t tmpa;
	bigint_t A;
	int ret;

	ret = _gnutls_mpi_init_multi(&A, &tmpa, NULL);
	if (ret < 0) {
		gnutls_assert();
		return NULL;
	}

	_gnutls_mpi_random_modp(tmpa, n, GNUTLS_RND_RANDOM);

	ret = _gnutls_mpi_powm(A, g, tmpa, n);
	if (ret < 0)
		goto error;

	if (a != NULL)
		*a = tmpa;
	else
		_gnutls_mpi_release(&tmpa);

	return A;
error:
	_gnutls_mpi_release(&tmpa);
	_gnutls_mpi_release(&A);
	return NULL;
}
예제 #6
0
파일: srp.c 프로젝트: attilamolnar/gnutls
/****************
 * 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.
 */
bigint_t
_gnutls_calc_srp_B(bigint_t * ret_b, bigint_t g, bigint_t n, bigint_t v)
{
	bigint_t tmpB = NULL, tmpV = NULL;
	bigint_t b = NULL, B = NULL, k = NULL;
	int ret;

	/* calculate:  B = (k*v + g^b) % N 
	 */
	ret = _gnutls_mpi_init_multi(&tmpV, &tmpB, &B, &b, NULL);
	if (ret < 0)
		return NULL;

	_gnutls_mpi_random_modp(b, n, GNUTLS_RND_RANDOM);

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

	ret = _gnutls_mpi_mulm(tmpV, k, v, n);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls_mpi_powm(tmpB, g, b, n);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls_mpi_addm(B, tmpV, tmpB, n);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	_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;

}
예제 #7
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;
}
예제 #8
0
파일: pk.c 프로젝트: philippe-goetz/gnutls
/* 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;
}
예제 #9
0
파일: srp.c 프로젝트: attilamolnar/gnutls
/* S = (A * v^u) ^ b % N 
 * this is our shared key (server premaster secret)
 */
bigint_t
_gnutls_calc_srp_S1(bigint_t A, bigint_t b, bigint_t u, bigint_t v,
		    bigint_t n)
{
	bigint_t tmp1 = NULL, tmp2 = NULL;
	bigint_t S = NULL;
	int ret;

	ret = _gnutls_mpi_init_multi(&S, &tmp1, &tmp2, NULL);
	if (ret < 0)
		return NULL;

	ret = _gnutls_mpi_powm(tmp1, v, u, n);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls_mpi_mulm(tmp2, A, tmp1, n);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	_gnutls_mpi_powm(S, tmp2, b, n);

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

	return S;

error:
	_gnutls_mpi_release(&S);
	_gnutls_mpi_release(&tmp1);
	_gnutls_mpi_release(&tmp2);
	return NULL;
}
예제 #10
0
파일: gnutls_srp.c 프로젝트: ares89/vlc
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;

}
예제 #11
0
파일: srp.c 프로젝트: attilamolnar/gnutls
static int
_gnutls_srp_gx(uint8_t * text, size_t textsize, uint8_t ** result,
	       bigint_t g, bigint_t prime)
{
	bigint_t x, e = NULL;
	size_t result_size;
	int ret;

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

	ret = _gnutls_mpi_init(&e);
	if (ret < 0)
		goto cleanup;

	/* e = g^x mod prime (n) */
	ret = _gnutls_mpi_powm(e, g, x, prime);
	if (ret < 0)
		goto cleanup;

	ret = _gnutls_mpi_print(e, NULL, &result_size);
	if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
		*result = gnutls_malloc(result_size);
		if ((*result) == NULL) {
			ret = GNUTLS_E_MEMORY_ERROR;
			goto cleanup;
		}

		ret = _gnutls_mpi_print(e, *result, &result_size);
		if (ret < 0)
			goto cleanup;

		ret = result_size;
	} else {
		gnutls_assert();
		ret = GNUTLS_E_MPI_PRINT_FAILED;
	}

cleanup:
	_gnutls_mpi_release(&e);
	_gnutls_mpi_release(&x);

	return ret;

}
예제 #12
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;
}
예제 #13
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;

}
예제 #14
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;

}
예제 #15
0
파일: pk.c 프로젝트: randombit/hacrypto
static int
wrap_nettle_pk_verify_params(gnutls_pk_algorithm_t algo,
			     const gnutls_pk_params_st * params)
{
	int ret;

	switch (algo) {
	case GNUTLS_PK_RSA:
		{
			bigint_t t1 = NULL, t2 = NULL;

			if (params->params_nr != RSA_PRIVATE_PARAMS)
				return
				    gnutls_assert_val
				    (GNUTLS_E_INVALID_REQUEST);

			t1 = _gnutls_mpi_new(256);
			if (t1 == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);

			_gnutls_mpi_mulm(t1, params->params[RSA_PRIME1],
					 params->params[RSA_PRIME2],
					 params->params[RSA_MODULUS]);
			if (_gnutls_mpi_cmp_ui(t1, 0) != 0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ILLEGAL_PARAMETER);
				goto rsa_cleanup;
			}

			mpz_invert(TOMPZ(t1),
				   TOMPZ(params->params[RSA_PRIME2]),
				   TOMPZ(params->params[RSA_PRIME1]));
			if (_gnutls_mpi_cmp(t1, params->params[RSA_COEF])
			    != 0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ILLEGAL_PARAMETER);
				goto rsa_cleanup;
			}

			/* [RSA_PRIME1] = d % p-1, [RSA_PRIME2] = d % q-1 */
			_gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME1],
					   1);
			t2 = _gnutls_mpi_mod(params->params[RSA_PRIV], t1);
			if (t2 == NULL) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);
				goto rsa_cleanup;
			}

			if (_gnutls_mpi_cmp(params->params[RSA_E1], t2) !=
			    0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ILLEGAL_PARAMETER);
				goto rsa_cleanup;
			}

			_gnutls_mpi_sub_ui(t1, params->params[RSA_PRIME2],
					   1);
			_gnutls_mpi_release(&t2);

			t2 = _gnutls_mpi_mod(params->params[RSA_PRIV], t1);
			if (t2 == NULL) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);
				goto rsa_cleanup;
			}

			if (_gnutls_mpi_cmp(params->params[RSA_E2], t2) !=
			    0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ILLEGAL_PARAMETER);
				goto rsa_cleanup;
			}

			ret = 0;

		      rsa_cleanup:
			_gnutls_mpi_release(&t1);
			_gnutls_mpi_release(&t2);
		}

		break;
	case GNUTLS_PK_DSA:
		{
			bigint_t t1 = NULL;

			if (params->params_nr != DSA_PRIVATE_PARAMS)
				return
				    gnutls_assert_val
				    (GNUTLS_E_INVALID_REQUEST);

			t1 = _gnutls_mpi_new(256);
			if (t1 == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);

			_gnutls_mpi_powm(t1, params->params[DSA_G],
					 params->params[DSA_X],
					 params->params[DSA_P]);

			if (_gnutls_mpi_cmp(t1, params->params[DSA_Y]) !=
			    0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ILLEGAL_PARAMETER);
				goto dsa_cleanup;
			}

			ret = 0;

		      dsa_cleanup:
			_gnutls_mpi_release(&t1);
		}

		break;
	case GNUTLS_PK_EC:
		{
			struct ecc_point r, pub;
			struct ecc_scalar priv;
			mpz_t x1, y1, x2, y2;
			const struct ecc_curve *curve;

			if (params->params_nr != ECC_PRIVATE_PARAMS)
				return
				    gnutls_assert_val
				    (GNUTLS_E_INVALID_REQUEST);

			curve = get_supported_curve(params->flags);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ret = _ecc_params_to_pubkey(params, &pub, curve);
			if (ret < 0)
				return gnutls_assert_val(ret);

			ret = _ecc_params_to_privkey(params, &priv, curve);
			if (ret < 0) {
				ecc_point_clear(&pub);
				return gnutls_assert_val(ret);
			}

			ecc_point_init(&r, curve);
			/* verify that x,y lie on the curve */
			ret =
			    ecc_point_set(&r, TOMPZ(params->params[ECC_X]),
					  TOMPZ(params->params[ECC_Y]));
			if (ret == 0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ILLEGAL_PARAMETER);
				goto ecc_cleanup;
			}
			ecc_point_clear(&r);

			ecc_point_init(&r, curve);
			ecc_point_mul_g(&r, &priv);

			mpz_init(x1);
			mpz_init(y1);
			ecc_point_get(&r, x1, y1);
			ecc_point_clear(&r);

			mpz_init(x2);
			mpz_init(y2);
			ecc_point_get(&pub, x2, y2);

			/* verify that k*(Gx,Gy)=(x,y) */
			if (mpz_cmp(x1, x2) != 0 || mpz_cmp(y1, y2) != 0) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_ILLEGAL_PARAMETER);
				goto ecc_cleanup;
			}

			ret = 0;

		      ecc_cleanup:
			ecc_scalar_clear(&priv);
			ecc_point_clear(&pub);
		}
		break;
	default:
		ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
	}

	return ret;
}
예제 #16
0
파일: pk.c 프로젝트: Drakey83/steamlink-sdk
/* This is used for DH or ECDH key derivation. In DH for example
 * it is given the peers Y and our x, and calculates Y^x 
 */
static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo,
				  gnutls_datum_t * out,
				  const gnutls_pk_params_st * priv,
				  const gnutls_pk_params_st * pub)
{
	int ret;

	switch (algo) {
	case GNUTLS_PK_DH: {
		bigint_t f, x, prime;
		bigint_t k = NULL, ff = NULL;
		unsigned int bits;

		f = pub->params[DH_Y];
		x = priv->params[DH_X];
		prime = priv->params[DH_P];

		ret = _gnutls_mpi_init_multi(&k, &ff, NULL);
		if (ret < 0)
			return gnutls_assert_val(ret);

		ret = _gnutls_mpi_modm(ff, f, prime);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = _gnutls_mpi_add_ui(ff, ff, 1);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		/* check if f==0,1,p-1. 
		 * or (ff=f+1) equivalently ff==1,2,p */
		if ((_gnutls_mpi_cmp_ui(ff, 2) == 0)
		    || (_gnutls_mpi_cmp_ui(ff, 1) == 0)
		    || (_gnutls_mpi_cmp(ff, prime) == 0)) {
			gnutls_assert();
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			goto dh_cleanup;
		}

		/* prevent denial of service */
		bits = _gnutls_mpi_get_nbits(prime);
		if (bits == 0 || bits > MAX_DH_BITS) {
			gnutls_assert();
			ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
			goto dh_cleanup;
		}


		ret = _gnutls_mpi_powm(k, f, x, prime);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = _gnutls_mpi_dprint(k, out);
		if (ret < 0) {
			gnutls_assert();
			goto dh_cleanup;
		}

		ret = 0;
dh_cleanup:
		_gnutls_mpi_release(&ff);
		zrelease_temp_mpi_key(&k);
		if (ret < 0)
			goto cleanup;

		break;
	}
	case GNUTLS_PK_EC:
		{
			struct ecc_scalar ecc_priv;
			struct ecc_point ecc_pub;
			const struct ecc_curve *curve;

			out->data = NULL;

			curve = get_supported_curve(priv->flags);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ret = _ecc_params_to_pubkey(pub, &ecc_pub, curve);
			if (ret < 0)
				return gnutls_assert_val(ret);

			ret =
			    _ecc_params_to_privkey(priv, &ecc_priv, curve);
			if (ret < 0) {
				ecc_point_clear(&ecc_pub);
				return gnutls_assert_val(ret);
			}

			out->size = gnutls_ecc_curve_get_size(priv->flags);
			/*ecc_size(curve)*sizeof(mp_limb_t); */
			out->data = gnutls_malloc(out->size);
			if (out->data == NULL) {
				ret =
				    gnutls_assert_val
				    (GNUTLS_E_MEMORY_ERROR);
				goto ecc_cleanup;
			}

			ecc_shared_secret(&ecc_priv, &ecc_pub, out->data,
					  out->size);

		      ecc_cleanup:
			ecc_point_clear(&ecc_pub);
			ecc_scalar_zclear(&ecc_priv);
			if (ret < 0)
				goto cleanup;
			break;
		}
	default:
		gnutls_assert();
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto cleanup;
	}

	ret = 0;

      cleanup:

	return ret;
}
예제 #17
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;

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

	if (_gnutls_mpi_get_nbits(n) < (session->internals.srp_prime_bits
					? session->internals.srp_prime_bits
					: 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) {
		_gnutls_mpi_log("no prime N: ", n);
		gnutls_assert();
		return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
	}

	ret = _gnutls_mpi_init_multi(&two, &q, &w, NULL);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	/* q = n-1 
	 */
	ret = _gnutls_mpi_sub_ui(q, n, 1);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	/* q = q/2, remember that q is divisible by 2 (prime - 1)
	 */
	ret = _gnutls_mpi_set_ui(two, 2);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls_mpi_div(q, q, two);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

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

	/* 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;
	}

	/* check if g^q mod N == N-1
	 * w = g^q mod N
	 */
	ret = _gnutls_mpi_powm(w, g, q, n);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	/* w++
	 */
	ret = _gnutls_mpi_add_ui(w, w, 1);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	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;

}
예제 #19
0
파일: pk.c 프로젝트: intgr/gnutls
static int
wrap_nettle_pk_verify_params (gnutls_pk_algorithm_t algo,
                              const gnutls_pk_params_st * params)
{
  int ret;

  switch (algo)
    {
    case GNUTLS_PK_RSA:
      {
        bigint_t t1 = NULL, t2 = NULL;

        if (params->params_nr != RSA_PRIVATE_PARAMS)
          return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        
        t1 = _gnutls_mpi_new (256);
        if (t1 == NULL)
          return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

        _gnutls_mpi_mulm (t1, params->params[RSA_PRIME1], params->params[RSA_PRIME2], params->params[RSA_MODULUS]);
        if (_gnutls_mpi_cmp_ui(t1, 0) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto rsa_cleanup;
          }

        mpz_invert (TOMPZ(t1), TOMPZ (params->params[RSA_PRIME2]), TOMPZ (params->params[RSA_PRIME1]));
        if (_gnutls_mpi_cmp(t1, params->params[RSA_COEF]) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto rsa_cleanup;
          }

        /* [RSA_PRIME1] = d % p-1, [RSA_PRIME2] = d % q-1 */
        _gnutls_mpi_sub_ui (t1, params->params[RSA_PRIME1], 1);
        t2 = _gnutls_mpi_mod (params->params[RSA_PRIV], t1);
        if (t2 == NULL)
          {
            ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
            goto rsa_cleanup;
          }
  
        if (_gnutls_mpi_cmp(params->params[RSA_E1], t2) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto rsa_cleanup;
          }
        
        _gnutls_mpi_sub_ui (t1, params->params[RSA_PRIME2], 1);
        _gnutls_mpi_release(&t2);

        t2 = _gnutls_mpi_mod (params->params[RSA_PRIV], t1);
        if (t2 == NULL)
          {
            ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
            goto rsa_cleanup;
          }
  
        if (_gnutls_mpi_cmp(params->params[RSA_E2], t2) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto rsa_cleanup;
          }
        
        ret = 0;

rsa_cleanup:
        _gnutls_mpi_release(&t1);
        _gnutls_mpi_release(&t2);
      }

      break;
    case GNUTLS_PK_DSA:
      {
        bigint_t t1 = NULL;

        if (params->params_nr != DSA_PRIVATE_PARAMS)
          return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        
        t1 = _gnutls_mpi_new (256);
        if (t1 == NULL)
          return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

        _gnutls_mpi_powm (t1, params->params[DSA_G], params->params[DSA_X], params->params[DSA_P]);

        if (_gnutls_mpi_cmp(t1, params->params[DSA_Y]) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto dsa_cleanup;
          }

        ret = 0;

dsa_cleanup:
        _gnutls_mpi_release(&t1);
      }

      break;
    case GNUTLS_PK_EC:
      {
        int curve = params->flags;
        ecc_key ecc_priv;
        ecc_point *R;
        ecc_point zero;

        if (params->params_nr != ECC_PRIVATE_PARAMS)
          return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

        if (is_supported_curve(curve) == 0)
          return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);

        _ecc_params_to_privkey(params, &ecc_priv);
        R = ecc_new_point();

        /* verify that x,y lie on the curve */
        ret = ecc_projective_check_point(&ecc_priv.pubkey, TOMPZ(params->params[ECC_B]), params->params[ECC_PRIME]);
        if (ret != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto ecc_cleanup;
          }

        memcpy(&zero.x, ecc_priv.Gx, sizeof(mpz_t));
        memcpy(&zero.y, ecc_priv.Gy, sizeof(mpz_t));
        memcpy(&zero.z, ecc_priv.pubkey.z, sizeof(mpz_t)); /* z = 1 */

        /* verify that k*(Gx,Gy)=(x,y) */
        ret = ecc_mulmod_cached(ecc_priv.k, curve, R, TOMPZ(params->params[ECC_A]), TOMPZ(params->params[ECC_PRIME]), 1);
        if (ret != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto ecc_cleanup;
          }

        if (mpz_cmp(ecc_priv.pubkey.x, R->x) != 0 || mpz_cmp(ecc_priv.pubkey.y, R->y) != 0)
          {
            ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
            goto ecc_cleanup;
          }
        
        ret = 0;

ecc_cleanup:
        _ecc_params_clear(&ecc_priv);
        ecc_del_point(R);
      }  
      break;
    default:
      ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
    }

  return ret;
}
예제 #20
0
/* Decodes an DSA privateKey and params from a PKCS8 structure.
 */
static int
_decode_pkcs8_dsa_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey)
{
	int ret;
	gnutls_datum_t tmp = {NULL, 0};

	gnutls_pk_params_init(&pkey->params);

	ret = _gnutls_x509_read_value(pkcs8_asn, "privateKey", &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_x509_read_der_int(tmp.data, tmp.size,
				      &pkey->params.params[4]);
	_gnutls_free_key_datum(&tmp);

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_x509_read_value(pkcs8_asn,
				    "privateKeyAlgorithm.parameters",
				    &tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_x509_read_pubkey_params(GNUTLS_PK_DSA, tmp.data,
					    tmp.size, &pkey->params);
	_gnutls_free_datum(&tmp);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (_gnutls_mpi_cmp_ui(pkey->params.params[0], 0) == 0) {
		gnutls_assert();
		ret = GNUTLS_E_ILLEGAL_PARAMETER;
		goto error;
	}

	/* the public key can be generated as g^x mod p */
	ret = _gnutls_mpi_init(&pkey->params.params[3]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = _gnutls_mpi_powm(pkey->params.params[3], pkey->params.params[2],
			 pkey->params.params[4], pkey->params.params[0]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->params.algo = GNUTLS_PK_DSA;
	pkey->params.params_nr = DSA_PRIVATE_PARAMS;

	ret =
	    _gnutls_asn1_encode_privkey(&pkey->key,
					&pkey->params);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	return 0;

 error:
	if (pkey->params.params_nr != DSA_PRIVATE_PARAMS)
		_gnutls_mpi_release(&pkey->params.params[4]);
	return ret;
}
예제 #21
0
파일: srp.c 프로젝트: attilamolnar/gnutls
/* 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;
	int ret;

	ret = _gnutls_mpi_init_multi(&S, &tmp1, &tmp2, &tmp3, &tmp4, NULL);
	if (ret < 0)
		return NULL;

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

	ret = _gnutls_mpi_powm(tmp1, g, x, n);	/* g^x */
	if (ret < 0) {
		gnutls_assert();
		goto freeall;
	}

	ret = _gnutls_mpi_mulm(tmp3, tmp1, k, n);	/* k*g^x mod n */
	if (ret < 0) {
		gnutls_assert();
		goto freeall;
	}

	ret = _gnutls_mpi_subm(tmp2, B, tmp3, n);
	if (ret < 0) {
		gnutls_assert();
		goto freeall;
	}

	ret = _gnutls_mpi_mul(tmp1, u, x);
	if (ret < 0) {
		gnutls_assert();
		goto freeall;
	}

	ret = _gnutls_mpi_add(tmp4, a, tmp1);
	if (ret < 0) {
		gnutls_assert();
		goto freeall;
	}

	ret = _gnutls_mpi_powm(S, tmp2, tmp4, n);
	if (ret < 0) {
		gnutls_assert();
		goto freeall;
	}

	_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;
}