示例#1
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;

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

}
示例#4
0
/* just read A and put it to session */
int
_gnutls_proc_srp_client_kx (gnutls_session_t session, opaque * data,
			    size_t _data_size)
{
  size_t _n_A;
  ssize_t data_size = _data_size;
  int ret;

  DECR_LEN (data_size, 2);
  _n_A = _gnutls_read_uint16 (&data[0]);

  DECR_LEN (data_size, _n_A);
  if (_gnutls_mpi_scan_nz (&A, &data[2], &_n_A) || A == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  _gnutls_dump_mpi ("SRP A: ", A);
  _gnutls_dump_mpi ("SRP B: ", B);

  /* Checks if A % n == 0.
   */
  if ((ret = check_a_mod_n (A, N)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  /* Start the SRP calculations.
   * - Calculate u 
   */
  session->key->u = _gnutls_calc_srp_u (A, B, N);
  if (session->key->u == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  _gnutls_dump_mpi ("SRP U: ", session->key->u);

  /* S = (A * v^u) ^ b % N 
   */
  S = _gnutls_calc_srp_S1 (A, _b, session->key->u, V, N);
  if (S == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  _gnutls_dump_mpi ("SRP S: ", S);

  _gnutls_mpi_release (&A);
  _gnutls_mpi_release (&_b);
  _gnutls_mpi_release (&V);
  _gnutls_mpi_release (&session->key->u);
  _gnutls_mpi_release (&B);

  ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
  _gnutls_mpi_release (&S);

  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return 0;
}
示例#5
0
/* return A = g^a % N */
int
_gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data)
{
  size_t n_a;
  int ret;
  uint8_t *data_a;
  char *username, *password;
  char buf[64];
  gnutls_srp_client_credentials_t cred;


  cred = (gnutls_srp_client_credentials_t)
    _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL);

  if (cred == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  if (session->internals.srp_username == NULL)
    {
      username = cred->username;
      password = cred->password;
    }
  else
    {
      username = session->internals.srp_username;
      password = session->internals.srp_password;
    }

  if (username == NULL || password == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  /* calc A = g^a % N 
   */
  if (G == NULL || N == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  A = _gnutls_calc_srp_A (&_a, G, N);
  if (A == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* Rest of SRP calculations 
   */

  /* calculate u */
  session->key->u = _gnutls_calc_srp_u (A, B, N);
  if (session->key->u == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  _gnutls_dump_mpi ("SRP U: ", session->key->u);

  /* S = (B - g^x) ^ (a + u * x) % N */
  S = _gnutls_calc_srp_S2 (B, G, session->key->x, _a, session->key->u, N);
  if (S == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  _gnutls_dump_mpi ("SRP B: ", B);

  _gnutls_mpi_release (&_b);
  _gnutls_mpi_release (&V);
  _gnutls_mpi_release (&session->key->u);
  _gnutls_mpi_release (&B);

  ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
  _gnutls_mpi_release (&S);

  if (ret < 0) 
    {
      gnutls_assert();
      return ret;
    }

  if (_gnutls_mpi_print (NULL, &n_a, A) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_PRINT_FAILED;
    }

  (*data) = gnutls_malloc (n_a + 2);
  if ((*data) == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* copy A */
  data_a = (*data);
  if (_gnutls_mpi_print (&data_a[2], &n_a, A) != 0)
    {
      gnutls_free (*data);
      return GNUTLS_E_MPI_PRINT_FAILED;
    }

  _gnutls_hard_log ("INT: SRP A[%d]: %s\n", n_a,
		    _gnutls_bin2hex (&data_a[2], n_a, buf, sizeof (buf)));

  _gnutls_mpi_release (&A);

  _gnutls_write_uint16 (n_a, data_a);

  return n_a + 2;
}
示例#6
0
/* return A = g^a % N */
int
_gnutls_gen_srp_client_kx(gnutls_session_t session,
			  gnutls_buffer_st * data)
{
	int ret;
	char *username, *password;
	gnutls_srp_client_credentials_t cred;
	extension_priv_data_t epriv;
	srp_ext_st *priv;

	ret =
	    _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SRP,
					 &epriv);
	if (ret < 0) {		/* peer didn't send a username */
		gnutls_assert();
		return GNUTLS_E_UNKNOWN_SRP_USERNAME;
	}
	priv = epriv;

	cred = (gnutls_srp_client_credentials_t)
	    _gnutls_get_cred(session, GNUTLS_CRD_SRP);

	if (cred == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	if (priv->username == NULL) {
		username = cred->username;
		password = cred->password;
	} else {

		username = priv->username;
		password = priv->password;
	}

	if (username == NULL || password == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	/* calc A = g^a % N 
	 */
	if (G == NULL || N == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	A = _gnutls_calc_srp_A(&_a, G, N);
	if (A == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	/* Rest of SRP calculations 
	 */

	/* calculate u */
	session->key.u = _gnutls_calc_srp_u(A, B, N);
	if (session->key.u == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	_gnutls_mpi_log("SRP U: ", session->key.u);

	/* S = (B - g^x) ^ (a + u * x) % N */
	S = _gnutls_calc_srp_S2(B, G, session->key.x, _a, session->key.u,
				N);
	if (S == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	_gnutls_mpi_log("SRP B: ", B);

	zrelease_temp_mpi_key(&_b);
	zrelease_temp_mpi_key(&V);
	zrelease_temp_mpi_key(&session->key.u);
	zrelease_temp_mpi_key(&B);

	ret = _gnutls_mpi_dprint(session->key.srp_key, &session->key.key);
	zrelease_temp_mpi_key(&S);

	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_buffer_append_mpi(data, 16, A, 0);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_mpi_log("SRP A: ", A);

	_gnutls_mpi_release(&A);

	return data->length;
}
示例#7
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;
}