static void
test_bignum(const char *hex, unsigned length, const uint8_t *base256)
{
  mpz_t a;
  mpz_t b;
  uint8_t *buf;
  
  mpz_init_set_str(a, hex, 16);
  nettle_mpz_init_set_str_256_s(b, length, base256);

  if (mpz_cmp(a, b))
    FAIL();

  buf = xalloc(length + 1);
  memset(buf, 17, length + 1);

  nettle_mpz_get_str_256(length, buf, a);
  if (!MEMEQ(length, buf, base256))
    FAIL();

  if (buf[length] != 17)
    FAIL();

  mpz_clear(a); mpz_clear(b);
  free(buf);
}
Esempio n. 2
0
static int
extract_digest_info(const struct rsa_public_key *key,
		    gnutls_datum_t * di, uint8_t ** rdi,
		    const mpz_t signature)
{
	unsigned i;
	int ret;
	mpz_t m;
	uint8_t *em;

	if (key->size == 0)
		return 0;

	em = gnutls_malloc(key->size);
	if (em == NULL)
		return 0;

	mpz_init(m);

	mpz_powm(m, signature, key->e, key->n);

	nettle_mpz_get_str_256(key->size, em, m);
	mpz_clear(m);

	if (em[0] != 0 || em[1] != 1) {
		ret = 0;
		goto cleanup;
	}

	for (i = 2; i < key->size; i++) {
		if (em[i] == 0 && i > 2)
			break;

		if (em[i] != 0xff) {
			ret = 0;
			goto cleanup;
		}
	}

	i++;

	*rdi = em;

	di->data = &em[i];
	di->size = key->size - i;

	return 1;

cleanup:
        memset(em, 0, sizeof(key->size));
	gnutls_free(em);

	return ret;
}
Esempio n. 3
0
File: pk.c Progetto: intgr/gnutls
static int
extract_digest_info(const struct rsa_public_key *key,
		 unsigned *length, uint8_t *digest_info,
		 const mpz_t signature)
{
  unsigned i;
  int ret;
  mpz_t m;
  uint8_t *em;

  if (key->size == 0 || *length < key->size)
    return 0;

  em = gnutls_malloc(key->size);
  if (em == NULL)
    return 0;

  mpz_init (m);

  mpz_powm(m, signature, key->e, key->n);

  nettle_mpz_get_str_256(key->size, em, m);
  mpz_clear(m);
  
  if (em[0] != 0 || em[1] != 1)
    {
      ret = 0;
      goto cleanup;
    }
  
  for (i = 2; i < key->size; i++)
    {
      if (em[i] == 0 && i > 2)
        break;
      
      if (em[i] != 0xff)
        {
          ret = 0;
          goto cleanup;
        }
    }

  i++;
  memcpy(digest_info, &em[i], key->size-i);
  *length = key->size-i;
  
  ret = 1;
cleanup:
  gnutls_free(em);

  return ret;
}
int
R_SignFinal(R_SIGNATURE_CTX *ctx,
            uint8_t *signature,
            unsigned *length,
            R_RSA_PRIVATE_KEY *key)
{
  struct rsa_private_key k;
  int res;
  
  nettle_mpz_init_set_str_256_u(k.p,
				MAX_RSA_MODULUS_LEN, key->prime[0]);
  nettle_mpz_init_set_str_256_u(k.q,
				MAX_RSA_MODULUS_LEN, key->prime[1]);
  nettle_mpz_init_set_str_256_u(k.a,
				MAX_RSA_MODULUS_LEN, key->primeExponent[0]);
  nettle_mpz_init_set_str_256_u(k.b,
				MAX_RSA_MODULUS_LEN, key->primeExponent[1]);
  nettle_mpz_init_set_str_256_u(k.c,
				MAX_RSA_MODULUS_LEN, key->coefficient);

  if (rsa_private_key_prepare(&k) && (k.size <= MAX_RSA_MODULUS_LEN))
    {
      mpz_t s;
      mpz_init(s);

      if (rsa_md5_sign(&k, &ctx->hash, s))
	{
	  nettle_mpz_get_str_256(k.size, signature, s);
	  *length = k.size;

	  res = RE_SUCCESS;
	}
      else
	res = RE_PRIVATE_KEY;

      mpz_clear(s);
    }
  else
    res = RE_PRIVATE_KEY;
  
  mpz_clear(k.p);
  mpz_clear(k.q);
  mpz_clear(k.a);
  mpz_clear(k.b);
  mpz_clear(k.c);

  return res;
}
Esempio n. 5
0
int
pkcs1_decrypt (size_t key_size,
	       const mpz_t m,
	       size_t *length, uint8_t *message)
{
  TMP_GMP_DECL(em, uint8_t);
  int ret;

  TMP_GMP_ALLOC(em, key_size);
  nettle_mpz_get_str_256(key_size, em, m);

  ret = _pkcs1_sec_decrypt_variable (length, message, key_size, em);

  TMP_GMP_FREE(em);
  return ret;
}
Esempio n. 6
0
static int
write_bignum(FILE *f, mpz_t x)
{
  unsigned size = nettle_mpz_sizeinbase_256_u(x);
  uint8_t *p;
  int res;
  
  if (!write_uint32(f, size))
    return 0;
  
  p = xalloc(size);
  nettle_mpz_get_str_256(size, p, x);

  res = write_string(f, size, p);
  free(p);
  return res;
}
Esempio n. 7
0
static void
hash(mpz_t x, uint8_t *digest)
{
  mpz_t t;
  uint8_t data[SEED_LENGTH];
  struct sha1_ctx ctx;
  
  mpz_init_set(t, x);
  mpz_fdiv_r_2exp(t, t, SEED_BITS);
  
  nettle_mpz_get_str_256(SEED_LENGTH, data, t);
  mpz_clear(t);

  sha1_init(&ctx);
  sha1_update(&ctx, SEED_LENGTH, data);
  sha1_digest(&ctx, SHA1_DIGEST_SIZE, digest);
}
Esempio n. 8
0
static void
ecc_shared_secret(struct ecc_scalar *private_key,
		  struct ecc_point *public_key, void *out, unsigned size)
{
	struct ecc_point r;
	mpz_t x;

	mpz_init(x);
	ecc_point_init(&r, public_key->ecc);

	ecc_point_mul(&r, private_key, public_key);

	ecc_point_get(&r, x, NULL);
	nettle_mpz_get_str_256(size, out, x);

	mpz_clear(x);
	ecc_point_clear(&r);

	return;
}
Esempio n. 9
0
int
pgp_put_mpi(struct nettle_buffer *buffer, const mpz_t x)
{
  unsigned bits = mpz_sizeinbase(x, 2);
  unsigned octets = (bits + 7) / 8;

  uint8_t *p;

  /* FIXME: What's the correct representation of zero? */
  if (!pgp_put_uint16(buffer, bits))
    return 0;
  
  p = nettle_buffer_space(buffer, octets);

  if (!p)
    return 0;
  
  nettle_mpz_get_str_256(octets, p, x);

  return 1;
}
Esempio n. 10
0
int
pkcs1_decrypt (unsigned key_size,
	       const mpz_t m,
	       unsigned *length, uint8_t *message)
{
  TMP_DECL(em, uint8_t, NETTLE_MAX_BIGNUM_SIZE);
  uint8_t *terminator;
  unsigned padding;
  unsigned message_length;

  TMP_ALLOC(em, key_size);
  nettle_mpz_get_str_256(key_size, em, m);

  /* Check format */
  if (em[0] || em[1] != 2)
    return 0;

  terminator = memchr(em + 2, 0, key_size - 2);

  if (!terminator)
    return 0;
  
  padding = terminator - (em + 2);
  if (padding < 8)
    return 0;

  message_length = key_size - 3 - padding;

  if (*length < message_length)
    return 0;
  
  memcpy(message, terminator + 1, message_length);
  *length = message_length;

  return 1;
}
Esempio n. 11
0
File: mpi.c Progetto: gnutls/gnutls
static int
wrap_nettle_mpi_print(const bigint_t a, void *buffer, size_t * nbytes,
		      gnutls_bigint_format_t format)
{
	unsigned int size;
	mpz_t *p = (void *) a;

	if (format == GNUTLS_MPI_FORMAT_USG) {
		size = nettle_mpz_sizeinbase_256_u(*p);
	} else if (format == GNUTLS_MPI_FORMAT_STD) {
		size = nettle_mpz_sizeinbase_256_s(*p);
#if ENABLE_GOST
	} else if (format == GNUTLS_MPI_FORMAT_ULE) {
		size = nettle_mpz_sizeinbase_256_u_le(*p);
#endif
	} else {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (buffer == NULL || size > *nbytes) {
		*nbytes = size;
		gnutls_assert();
		return GNUTLS_E_SHORT_MEMORY_BUFFER;
	}

#if ENABLE_GOST
	if (format == GNUTLS_MPI_FORMAT_ULE)
		nettle_mpz_get_str_256_u_le(size, buffer, *p);
	else
#endif
		nettle_mpz_get_str_256(size, buffer, *p);
	*nbytes = size;

	return 0;
}
static int
rsa_provable_prime (mpz_t p,
			  unsigned *prime_seed_length, void *prime_seed,
			  unsigned bits,
			  unsigned seed_length, const void *seed,
			  mpz_t e,
			  void *progress_ctx, nettle_progress_func * progress)
{
mpz_t x, t, s, r1, r2, p0, sq;
int ret;
unsigned pcounter = 0;
unsigned iterations;
unsigned storage_length = 0, i;
uint8_t *storage = NULL;
uint8_t pseed[MAX_PVP_SEED_SIZE+1];
unsigned pseed_length = sizeof(pseed), tseed_length;
unsigned max = bits*5;

	mpz_init(p0);
	mpz_init(sq);
	mpz_init(x);
	mpz_init(t);
	mpz_init(s);
	mpz_init(r1);
	mpz_init(r2);

	/* p1 = p2 = 1 */

	ret = st_provable_prime(p0, &pseed_length, pseed,
				NULL, 1+div_ceil(bits,2), seed_length,
				seed, progress_ctx, progress);
	if (ret == 0) {
		goto cleanup;
	}

	iterations = div_ceil(bits, DIGEST_SIZE*8);
	mpz_set_ui(x, 0);

	if (iterations > 0) {
		storage_length = iterations * DIGEST_SIZE;
		storage = malloc(storage_length);
		if (storage == NULL) {
			goto fail;
		}

		nettle_mpz_set_str_256_u(s, pseed_length, pseed);
		for (i = 0; i < iterations; i++) {
			tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length);
			if (tseed_length > sizeof(pseed))
				goto fail;
			nettle_mpz_get_str_256(tseed_length, pseed, s);

			hash(&storage[(iterations - i - 1) * DIGEST_SIZE],
			     tseed_length, pseed);
			mpz_add_ui(s, s, 1);
		}

		nettle_mpz_set_str_256_u(x, storage_length, storage);
	}

	/* x = sqrt(2)*2^(bits-1) + (x mod 2^(bits) - sqrt(2)*2(bits-1)) */

	/* sq = sqrt(2)*2^(bits-1) */
	mpz_set_ui(r1, 1);
	mpz_mul_2exp(r1, r1, 2*bits-1);
	mpz_sqrt(sq, r1);

	/* r2 = 2^bits - sq */
	mpz_set_ui(r2, 1);
	mpz_mul_2exp(r2, r2, bits);
	mpz_sub(r2, r2, sq);

	/* x =  sqrt(2)*2^(bits-1) + (x mod (2^L - sqrt(2)*2^(bits-1)) */
	mpz_mod(x, x, r2);
	mpz_add(x, x, sq);

	/* y = p2 = p1 = 1 */

	/* r1 = (2 y p0 p1) */
	mpz_mul_2exp(r1, p0, 1);

	/* r2 = 2 p0 p1 p2 (p2=y=1) */
	mpz_set(r2, r1);

	/* r1 = (2 y p0 p1) + x */
	mpz_add(r1, r1, x);

	/* t = ((2 y p0 p1) + x) / (2 p0 p1 p2) */
	mpz_cdiv_q(t, r1, r2);

 retry:
	/* p = t p2 - y = t - 1 */
	mpz_sub_ui(p, t, 1);

	/* p = 2(tp2-y)p0p1 */
	mpz_mul(p, p, p0);
	mpz_mul_2exp(p, p, 1);

	/* p = 2(tp2-y)p0p1 + 1*/
	mpz_add_ui(p, p, 1);

	mpz_set_ui(r2, 1);
	mpz_mul_2exp(r2, r2, bits);

	if (mpz_cmp(p, r2) > 0) {
		/* t = (2 y p0 p1) + sqrt(2)*2^(bits-1) / (2p0p1p2) */
		mpz_set(r1, p0);
		/* r1 = (2 y p0 p1) */
		mpz_mul_2exp(r1, r1, 1);

		/* sq =  sqrt(2)*2^(bits-1) */

		/* r1 = (2 y p0 p1) + sq */
		mpz_add(r1, r1, sq);

		/* r2 = 2 p0 p1 p2 */
		mpz_mul_2exp(r2, p0, 1);

		/* t = ((2 y p0 p1) + sq) / (2 p0 p1 p2) */
		mpz_cdiv_q(t, r1, r2);
	}

	pcounter++;

	/* r2 = p - 1 */
	mpz_sub_ui(r2, p, 1);

	/* r1 = GCD(p1, e) */
	mpz_gcd(r1, e, r2);

	if (mpz_cmp_ui(r1, 1) == 0) {
		mpz_set_ui(x, 0); /* a = 0 */
		if (iterations > 0) {
			for (i = 0; i < iterations; i++) {
				tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length);
				if (tseed_length > sizeof(pseed))
					goto fail;
				nettle_mpz_get_str_256(tseed_length, pseed, s);

				hash(&storage[(iterations - i - 1) * DIGEST_SIZE],
				     tseed_length, pseed);
				mpz_add_ui(s, s, 1);
			}

			nettle_mpz_set_str_256_u(x, storage_length, storage);
		}

		/* a = 2 + a mod p-3 */
		mpz_sub_ui(r1, p, 3);	/* p is too large to worry about negatives */
		mpz_mod(x, x, r1);
		mpz_add_ui(x, x, 2);

		/* z = a^(2(tp2-y)p1) mod p */

		/* r1 = (tp2-y) */
		mpz_sub_ui(r1, t, 1);
		/* r1 = 2(tp2-y)p1 */
		mpz_mul_2exp(r1, r1, 1);

		/* z = r2 = a^r1 mod p */
		mpz_powm(r2, x, r1, p);

		mpz_sub_ui(r1, r2, 1);
		mpz_gcd(x, r1, p);

		if (mpz_cmp_ui(x, 1) == 0) {
			mpz_powm(r1, r2, p0, p);
			if (mpz_cmp_ui(r1, 1) == 0) {
				if (prime_seed_length != NULL) {
					tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length);
					if (tseed_length > sizeof(pseed))
						goto fail;

					nettle_mpz_get_str_256(tseed_length, pseed, s);

					if (*prime_seed_length < tseed_length) {
						*prime_seed_length = tseed_length;
						goto fail;
					}
					*prime_seed_length = tseed_length;
					if (prime_seed != NULL)
						memcpy(prime_seed, pseed, tseed_length);
				}
				ret = 1;
				goto cleanup;
			}
		}
	}

	if (pcounter >= max) {
		goto fail;
	}

	mpz_add_ui(t, t, 1);
	goto retry;

fail:
	ret = 0;
cleanup:
	free(storage);
	mpz_clear(p0);
	mpz_clear(sq);
	mpz_clear(r1);
	mpz_clear(r2);
	mpz_clear(x);
	mpz_clear(t);
	mpz_clear(s);

	return ret;
}