Exemplo n.º 1
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.
 */
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;

}
Exemplo n.º 2
0
Arquivo: mpi.c Projeto: intgr/gnutls
/*
 * Copyright (C) 2007-2012 Free Software Foundation, Inc.
 *
 * Author: Nikos Mavrogiannopoulos, Simon Josefsson
 *
 * This file is part of GnuTLS.
 *
 * GnuTLS is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * GnuTLS is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GnuTLS; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>

#include "utils.h"
#include "../lib/gnutls_int.h"
#include "../lib/gnutls_mpi.h"
#include "../lib/gnutls_errors.h"
#include "../lib/debug.h"

static void
tls_log_func (int level, const char *str)
{
  fprintf (stderr, "|<%d>| %s", level, str);
}

#define RND_BITS 510            /* not multiple of 8 */
void
doit (void)
{
  int rc;
  bigint_t n1, n2, n3, n4;

  gnutls_global_init ();

  gnutls_global_set_log_function (tls_log_func);
  if (debug)
    gnutls_global_set_log_level (99);

  n1 = _gnutls_mpi_new (1000);
  if (n1 == NULL)
    fail ("mpi_new failed\n");

  n2 = _gnutls_mpi_set_ui (NULL, 2);
  if (n2 == NULL)
    fail ("mpi_set_ui failed\n");

  n3 = _gnutls_mpi_set_ui (NULL, 5);
  if (n3 == NULL)
    fail ("mpi_set_ui failed\n");

  _gnutls_mpi_randomize (n1, RND_BITS, GNUTLS_RND_NONCE);

  _gnutls_mpi_log ("rand:", n1);

  rc = _gnutls_mpi_get_nbits (n1);
  if (rc > RND_BITS)
    fail ("mpi_get_nbits failed... returned %d\n", rc);

  n4 = _gnutls_mpi_addm (NULL, n1, n3, n2);
  if (n4 == NULL)
    fail ("mpi_set_ui failed\n");

  if (_gnutls_mpi_cmp_ui (n4, 0) != 0 && _gnutls_mpi_cmp_ui (n4, 1) != 0)
    fail ("mpi_cmp_ui failed\n");

  _gnutls_mpi_release (&n1);
  _gnutls_mpi_release (&n2);
  _gnutls_mpi_release (&n3);
  _gnutls_mpi_release (&n4);

  gnutls_global_deinit ();

  if (debug) success ("mpi ops ok\n");
}
Exemplo n.º 3
0
/* ID should be:
 * 3 for MAC
 * 2 for IV
 * 1 for encryption key
 *
 * Note that this function produces different key for the
 * NULL password, and for the password with zero length.
 */
int
_gnutls_pkcs12_string_to_key(const mac_entry_st * me,
			     unsigned int id, const uint8_t * salt,
			     unsigned int salt_size, unsigned int iter,
			     const char *pw, unsigned int req_keylen,
			     uint8_t * keybuf)
{
	int rc;
	unsigned int i, j;
	digest_hd_st md;
	bigint_t num_b1 = NULL, num_ij = NULL;
	bigint_t mpi512 = NULL;
	unsigned int pwlen;
	uint8_t hash[MAX_HASH_SIZE], buf_b[64], buf_i[MAX_PASS_LEN * 2 + 64], *p;
	uint8_t d[64];
	size_t cur_keylen;
	size_t n, m, p_size, i_size;
	unsigned mac_len;
	const uint8_t buf_512[] =	/* 2^64 */
	{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00
	};

	cur_keylen = 0;

	if (pw == NULL)
		pwlen = 0;
	else
		pwlen = strlen(pw);

	if (pwlen > MAX_PASS_LEN) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if ((rc = _pkcs12_check_pass(pw, pwlen)) < 0) {
		gnutls_assert();
		return rc;
	}

	rc = _gnutls_mpi_init_scan(&mpi512, buf_512, sizeof(buf_512));
	if (rc < 0) {
		gnutls_assert();
		return rc;
	}

	/* Store salt and password in BUF_I */
	p_size = ((pwlen / 64) * 64) + 64;

	if (p_size > sizeof(buf_i) - 64)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	p = buf_i;
	for (i = 0; i < 64; i++)
		*p++ = salt[i % salt_size];
	if (pw) {
		for (i = j = 0; i < p_size; i += 2) {
			*p++ = 0;
			*p++ = pw[j];
			if (++j > pwlen)	/* Note, that we include the trailing (0) */
				j = 0;
		}
	} else
		memset(p, 0, p_size);

	i_size = 64 + p_size;
	mac_len = _gnutls_mac_get_algo_len(me);

	for (;;) {
		rc = _gnutls_hash_init(&md, me);
		if (rc < 0) {
			gnutls_assert();
			goto cleanup;
		}
		memset(d, id & 0xff, 64);
		_gnutls_hash(&md, d, 64);
		_gnutls_hash(&md, buf_i, pw ? i_size : 64);
		_gnutls_hash_deinit(&md, hash);
		for (i = 1; i < iter; i++) {
			rc = _gnutls_hash_fast(me->id, hash, mac_len,
					       hash);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}
		}
		for (i = 0; i < mac_len && cur_keylen < req_keylen; i++)
			keybuf[cur_keylen++] = hash[i];
		if (cur_keylen == req_keylen) {
			rc = 0;	/* ready */
			goto cleanup;
		}

		/* need more bytes. */
		for (i = 0; i < 64; i++)
			buf_b[i] = hash[i % mac_len];
		n = 64;
		rc = _gnutls_mpi_init_scan(&num_b1, buf_b, n);
		if (rc < 0) {
			gnutls_assert();
			goto cleanup;
		}

		rc = _gnutls_mpi_add_ui(num_b1, num_b1, 1);
		if (rc < 0) {
			gnutls_assert();
			goto cleanup;
		}
		
		for (i = 0; i < 128; i += 64) {
			n = 64;
			rc = _gnutls_mpi_init_scan(&num_ij, buf_i + i, n);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}

			rc = _gnutls_mpi_addm(num_ij, num_ij, num_b1, mpi512);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}

			n = 64;
#ifndef PKCS12_BROKEN_KEYGEN
			m = (_gnutls_mpi_get_nbits(num_ij) + 7) / 8;
#else
			m = n;
#endif
			memset(buf_i + i, 0, n - m);
			rc = _gnutls_mpi_print(num_ij, buf_i + i + n - m,
					       &n);
			if (rc < 0) {
				gnutls_assert();
				goto cleanup;
			}
			_gnutls_mpi_release(&num_ij);
		}
	}
      cleanup:
	_gnutls_mpi_release(&num_ij);
	_gnutls_mpi_release(&num_b1);
	_gnutls_mpi_release(&mpi512);

	return rc;
}
Exemplo n.º 4
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.º 5
0
/* ID should be:
 * 3 for MAC
 * 2 for IV
 * 1 for encryption key
 */
int
_gnutls_pkcs12_string_to_key (unsigned int id, const opaque * salt,
			      unsigned int salt_size, unsigned int iter,
			      const char *pw, unsigned int req_keylen,
			      opaque * keybuf)
{
  int rc;
  unsigned int i, j;
  digest_hd_st md;
  bigint_t num_b1 = NULL, num_ij = NULL;
  bigint_t mpi512 = NULL;
  unsigned int pwlen;
  opaque hash[20], buf_b[64], buf_i[128], *p;
  size_t cur_keylen;
  size_t n;
  const opaque buf_512[] =	/* 2^64 */
  { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

  cur_keylen = 0;

  if (pw == NULL)
    pwlen = 0;
  else
    pwlen = strlen (pw);

  if (pwlen > 63 / 2)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if ((rc = _pkcs12_check_pass (pw, pwlen)) < 0)
    {
      gnutls_assert ();
      return rc;
    }

  rc = _gnutls_mpi_scan (&mpi512, buf_512, sizeof (buf_512));
  if (rc < 0)
    {
      gnutls_assert ();
      return rc;
    }

  /* Store salt and password in BUF_I */
  p = buf_i;
  for (i = 0; i < 64; i++)
    *p++ = salt[i % salt_size];
  if (pw)
    {
      for (i = j = 0; i < 64; i += 2)
	{
	  *p++ = 0;
	  *p++ = pw[j];
	  if (++j > pwlen)	/* Note, that we include the trailing zero */
	    j = 0;
	}
    }
  else
    memset (p, 0, 64);

  for (;;)
    {
      rc = _gnutls_hash_init (&md, GNUTLS_MAC_SHA1);
      if (rc < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
      for (i = 0; i < 64; i++)
	{
	  unsigned char lid = id & 0xFF;
	  _gnutls_hash (&md, &lid, 1);
	}
      _gnutls_hash (&md, buf_i, pw ? 128 : 64);
      _gnutls_hash_deinit (&md, hash);
      for (i = 1; i < iter; i++)
	{
	  rc = _gnutls_hash_init (&md, GNUTLS_MAC_SHA1);
	  if (rc < 0)
	    {
	      gnutls_assert ();
	      goto cleanup;
	    }
	  _gnutls_hash (&md, hash, 20);
	  _gnutls_hash_deinit (&md, hash);
	}
      for (i = 0; i < 20 && cur_keylen < req_keylen; i++)
	keybuf[cur_keylen++] = hash[i];
      if (cur_keylen == req_keylen)
	{
	  rc = 0;		/* ready */
	  goto cleanup;
	}

      /* need more bytes. */
      for (i = 0; i < 64; i++)
	buf_b[i] = hash[i % 20];
      n = 64;
      rc = _gnutls_mpi_scan (&num_b1, buf_b, n);
      if (rc < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}
      _gnutls_mpi_add_ui (num_b1, num_b1, 1);
      for (i = 0; i < 128; i += 64)
	{
	  n = 64;
	  rc = _gnutls_mpi_scan (&num_ij, buf_i + i, n);
	  if (rc < 0)
	    {
	      gnutls_assert ();
	      goto cleanup;
	    }
	  _gnutls_mpi_addm (num_ij, num_ij, num_b1, mpi512);
	  n = 64;
	  rc = _gnutls_mpi_print (num_ij, buf_i + i, &n);
	  if (rc < 0)
	    {
	      gnutls_assert ();
	      goto cleanup;
	    }
	  _gnutls_mpi_release (&num_ij);
	}
    }
cleanup:
  _gnutls_mpi_release (&num_ij);
  _gnutls_mpi_release (&num_b1);
  _gnutls_mpi_release (&mpi512);

  return rc;
}