Exemplo n.º 1
0
/*
 * 	generate_p_q
 *	Generates two prime numbers of bit_length bit length, p and q
 *	inputs: 	int bit_length
 *	outputs:	BIGNUM* p
 * 			BIGNUM* q
 *
 *	return value:	0 if failure
 *			1 if success
 */
int generate_p_q(int bit_length, BIGNUM* p, BIGNUM* q){
	int res1 = BN_generate_prime_ex(p, bit_length, 0, NULL, NULL, NULL);
	int res2 = BN_generate_prime_ex(q, bit_length + 3, 0, NULL, NULL, NULL);
	if ( res1 == 0 || res2 == 0 )
		return 0;
	else
		return 1;
}
Exemplo n.º 2
0
BIGNUM *
BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
    const BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg)
{
	BN_GENCB cb;
	BIGNUM *rnd = NULL;
	int found = 0;

	BN_GENCB_set_old(&cb, callback, cb_arg);

	if (ret == NULL) {
		if ((rnd = BN_new()) == NULL)
			goto err;
	} else
		rnd = ret;
	if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
		goto err;

	/* we have a prime :-) */
	found = 1;

err:
	if (!found && (ret == NULL) && (rnd != NULL))
		BN_free(rnd);
	return (found ? rnd : NULL);
}
Exemplo n.º 3
0
NON_EMPTY_TRANSLATION_UNIT
#else

# include <stdio.h>
# include <time.h>
# include "internal/cryptlib.h"
# include "bn_lcl.h"

BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
                          const BIGNUM *add, const BIGNUM *rem,
                          void (*callback) (int, int, void *), void *cb_arg)
{
    BN_GENCB cb;
    BIGNUM *rnd = NULL;

    BN_GENCB_set_old(&cb, callback, cb_arg);

    if (ret == NULL) {
        if ((rnd = BN_new()) == NULL)
            goto err;
    } else
        rnd = ret;
    if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
        goto err;

    /* we have a prime :-) */
    return ret;
 err:
    BN_free(rnd);
    return NULL;
}
Exemplo n.º 4
0
/**
 * Generate a prime number
 *
 * The internal CPRNG is seeded using the provided seed value.
 *
 * @param prime Pointer for storage of prime number
 * @param s Secret to share
 * @param bits Bit size of prime
 * @param rngSeed Seed value for CPRNG
 * @param rngSeedLength Length of Seed value for CPRNG
 *
 */
static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigned char *rngSeed, const unsigned int rngSeedLength)
{
	int max_rounds = 1000;

	// Seed the RNG
	RAND_seed(rngSeed, rngSeedLength);

	// Clear the prime value
	BN_clear(prime);

	do {
		// Generate random prime
#if OPENSSL_VERSION_NUMBER  >= 0x00908000L /* last parm is BN_GENCB which is null in our case */
		BN_generate_prime_ex(prime, bits, 1, NULL, NULL, NULL);
#else
		BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL );
#endif

	} while ((BN_ucmp(prime, s) == -1) && (max_rounds-- > 0));	// If prime < s or not reached 1000 tries

	if (max_rounds > 0)
		return 0;
	else
		return -1; // We could not find a prime number
}
Exemplo n.º 5
0
extern "C" void Java_java_math_NativeBN_BN_1generate_1prime_1ex(JNIEnv* env, jclass, jlong ret, int bits,
                                          jboolean safe, jlong add, jlong rem, jlong cb) {
  if (!oneValidHandle(env, ret)) return;
  BN_generate_prime_ex(toBigNum(ret), bits, safe, toBigNum(add), toBigNum(rem),
                       reinterpret_cast<BN_GENCB*>(cb));
  throwExceptionIfNecessary(env);
}
Exemplo n.º 6
0
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
	{
	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
	BIGNUM local_r0,local_d,local_p;
	BIGNUM *pr0,*d,*p;
	int bitsp,bitsq,ok= -1,n=0;
	BN_CTX *ctx=NULL;

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	r1 = BN_CTX_get(ctx);
	r2 = BN_CTX_get(ctx);
	r3 = BN_CTX_get(ctx);
	if (r3 == NULL) goto err;

	bitsp=(bits+1)/2;
	bitsq=bits-bitsp;

	/* We need the RSA components non-NULL */
	if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
	if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
	if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
	if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
	if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
	if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
	if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
	if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;

	BN_copy(rsa->e, e_value);

	/* generate p and q */
	for (;;)
		{
		if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
			goto err;
		if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1)) break;
		if(!BN_GENCB_call(cb, 2, n++))
			goto err;
		}
	if(!BN_GENCB_call(cb, 3, 0))
		goto err;
	for (;;)
		{
		/* When generating ridiculously small keys, we can get stuck
		 * continually regenerating the same prime values. Check for
		 * this and bail if it happens 3 times. */
		unsigned int degenerate = 0;
		do
			{
			if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
				goto err;
			} while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
		if(degenerate == 3)
			{
			ok = 0; /* we set our own err */
			RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
			goto err;
			}
		if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1))
			break;
		if(!BN_GENCB_call(cb, 2, n++))
			goto err;
		}
	if(!BN_GENCB_call(cb, 3, 1))
		goto err;
	if (BN_cmp(rsa->p,rsa->q) < 0)
		{
		tmp=rsa->p;
		rsa->p=rsa->q;
		rsa->q=tmp;
		}

	/* calculate n */
	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;

	/* calculate d */
	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		  pr0 = &local_r0;
		  BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
		}
	else
	  pr0 = r0;
	if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;	/* d */

	/* set up d for correct BN_FLG_CONSTTIME flag */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		d = &local_d;
		BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
		}
	else
		d = rsa->d;
	/* calculate d mod (p-1) */
	if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;

	/* calculate d mod (q-1) */
	if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;

	/* calculate inverse of q mod p */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		p = &local_p;
		BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
		}
	else
		p = rsa->p;
	if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;

	ok=1;
err:
	if (ok == -1)
		{
		RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
		ok=0;
		}
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}

	return ok;
	}
Exemplo n.º 7
0
/* Actually there is no reason to insist that 'generator' be a generator.
 * It's just as OK (and in some sense better) to use a generator of the
 * order-q subgroup.
 */
static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
	{
	BIGNUM *t1,*t2;
	int g,ok= -1;
	BN_CTX *ctx=NULL;

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	t1 = BN_CTX_get(ctx);
	t2 = BN_CTX_get(ctx);
	if (t1 == NULL || t2 == NULL) goto err;

	/* Make sure 'ret' has the necessary elements */
	if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
	if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
	
	if (generator <= 1)
		{
		DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
		goto err;
		}
	if (generator == DH_GENERATOR_2)
		{
		if (!BN_set_word(t1,24)) goto err;
		if (!BN_set_word(t2,11)) goto err;
		g=2;
		}
#if 0 /* does not work for safe primes */
	else if (generator == DH_GENERATOR_3)
		{
		if (!BN_set_word(t1,12)) goto err;
		if (!BN_set_word(t2,5)) goto err;
		g=3;
		}
#endif
	else if (generator == DH_GENERATOR_5)
		{
		if (!BN_set_word(t1,10)) goto err;
		if (!BN_set_word(t2,3)) goto err;
		/* BN_set_word(t3,7); just have to miss
		 * out on these ones :-( */
		g=5;
		}
	else
		{
		/* in the general case, don't worry if 'generator' is a
		 * generator or not: since we are using safe primes,
		 * it will generate either an order-q or an order-2q group,
		 * which both is OK */
		if (!BN_set_word(t1,2)) goto err;
		if (!BN_set_word(t2,1)) goto err;
		g=generator;
		}
	
	if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
	if(!BN_GENCB_call(cb, 3, 0)) goto err;
	if (!BN_set_word(ret->g,g)) goto err;
	ok=1;
err:
	if (ok == -1)
		{
		DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
		ok=0;
		}

	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return ok;
	}
Exemplo n.º 8
0
int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
                                   BIGNUM *e_value, BN_GENCB *cb) {
  BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
  BIGNUM local_r0, local_d, local_p;
  BIGNUM *pr0, *d, *p;
  int prime_bits, ok = -1, n = 0, i, j;
  BN_CTX *ctx = NULL;
  STACK_OF(RSA_additional_prime) *additional_primes = NULL;

  if (num_primes < 2) {
    ok = 0; /* we set our own err */
    OPENSSL_PUT_ERROR(RSA, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES);
    goto err;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }
  BN_CTX_start(ctx);
  r0 = BN_CTX_get(ctx);
  r1 = BN_CTX_get(ctx);
  r2 = BN_CTX_get(ctx);
  r3 = BN_CTX_get(ctx);
  if (r0 == NULL || r1 == NULL || r2 == NULL || r3 == NULL) {
    goto err;
  }

  if (num_primes > 2) {
    additional_primes = sk_RSA_additional_prime_new_null();
    if (additional_primes == NULL) {
      goto err;
    }
  }

  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime));
    if (ap == NULL) {
      goto err;
    }
    memset(ap, 0, sizeof(RSA_additional_prime));
    ap->prime = BN_new();
    ap->exp = BN_new();
    ap->coeff = BN_new();
    ap->r = BN_new();
    if (ap->prime == NULL ||
        ap->exp == NULL ||
        ap->coeff == NULL ||
        ap->r == NULL ||
        !sk_RSA_additional_prime_push(additional_primes, ap)) {
      RSA_additional_prime_free(ap);
      goto err;
    }
  }

  /* We need the RSA components non-NULL */
  if (!rsa->n && ((rsa->n = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->d && ((rsa->d = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->e && ((rsa->e = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->p && ((rsa->p = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->q && ((rsa->q = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) {
    goto err;
  }
  if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) {
    goto err;
  }

  if (!BN_copy(rsa->e, e_value)) {
    goto err;
  }

  /* generate p and q */
  prime_bits = (bits + (num_primes - 1)) / num_primes;
  for (;;) {
    if (!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb) ||
        !BN_sub(r2, rsa->p, BN_value_one()) ||
        !BN_gcd(r1, r2, rsa->e, ctx)) {
      goto err;
    }
    if (BN_is_one(r1)) {
      break;
    }
    if (!BN_GENCB_call(cb, 2, n++)) {
      goto err;
    }
  }
  if (!BN_GENCB_call(cb, 3, 0)) {
    goto err;
  }
  prime_bits = ((bits - prime_bits) + (num_primes - 2)) / (num_primes - 1);
  for (;;) {
    /* When generating ridiculously small keys, we can get stuck
     * continually regenerating the same prime values. Check for
     * this and bail if it happens 3 times. */
    unsigned int degenerate = 0;
    do {
      if (!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) {
        goto err;
      }
    } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
    if (degenerate == 3) {
      ok = 0; /* we set our own err */
      OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
      goto err;
    }
    if (!BN_sub(r2, rsa->q, BN_value_one()) ||
        !BN_gcd(r1, r2, rsa->e, ctx)) {
      goto err;
    }
    if (BN_is_one(r1)) {
      break;
    }
    if (!BN_GENCB_call(cb, 2, n++)) {
      goto err;
    }
  }

  if (!BN_GENCB_call(cb, 3, 1) ||
      !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
    goto err;
  }

  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap =
        sk_RSA_additional_prime_value(additional_primes, i - 2);
    prime_bits = ((bits - BN_num_bits(rsa->n)) + (num_primes - (i + 1))) /
                 (num_primes - i);

    for (;;) {
      if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) {
        goto err;
      }
      if (BN_cmp(rsa->p, ap->prime) == 0 ||
          BN_cmp(rsa->q, ap->prime) == 0) {
        continue;
      }

      for (j = 0; j < i - 2; j++) {
        if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime,
                   ap->prime) == 0) {
          break;
        }
      }
      if (j != i - 2) {
        continue;
      }

      if (!BN_sub(r2, ap->prime, BN_value_one()) ||
          !BN_gcd(r1, r2, rsa->e, ctx)) {
        goto err;
      }

      if (!BN_is_one(r1)) {
        continue;
      }
      if (i != num_primes - 1) {
        break;
      }

      /* For the last prime we'll check that it makes n large enough. In the
       * two prime case this isn't a problem because we generate primes with
       * the top two bits set and so the product is always of the expected
       * size. In the multi prime case, this doesn't follow. */
      if (!BN_mul(r1, rsa->n, ap->prime, ctx)) {
        goto err;
      }
      if (BN_num_bits(r1) == (unsigned) bits) {
        break;
      }

      if (!BN_GENCB_call(cb, 2, n++)) {
        goto err;
      }
    }

    /* ap->r is is the product of all the primes prior to the current one
     * (including p and q). */
    if (!BN_copy(ap->r, rsa->n)) {
      goto err;
    }
    if (i == num_primes - 1) {
      /* In the case of the last prime, we calculated n as |r1| in the loop
       * above. */
      if (!BN_copy(rsa->n, r1)) {
        goto err;
      }
    } else if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) {
      goto err;
    }

    if (!BN_GENCB_call(cb, 3, 1)) {
      goto err;
    }
  }

  if (BN_cmp(rsa->p, rsa->q) < 0) {
    tmp = rsa->p;
    rsa->p = rsa->q;
    rsa->q = tmp;
  }

  /* calculate d */
  if (!BN_sub(r1, rsa->p, BN_value_one())) {
    goto err; /* p-1 */
  }
  if (!BN_sub(r2, rsa->q, BN_value_one())) {
    goto err; /* q-1 */
  }
  if (!BN_mul(r0, r1, r2, ctx)) {
    goto err; /* (p-1)(q-1) */
  }
  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap =
        sk_RSA_additional_prime_value(additional_primes, i - 2);
    if (!BN_sub(r3, ap->prime, BN_value_one()) ||
        !BN_mul(r0, r0, r3, ctx)) {
      goto err;
    }
  }
  pr0 = &local_r0;
  BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
  if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
    goto err; /* d */
  }

  /* set up d for correct BN_FLG_CONSTTIME flag */
  d = &local_d;
  BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);

  /* calculate d mod (p-1) */
  if (!BN_mod(rsa->dmp1, d, r1, ctx)) {
    goto err;
  }

  /* calculate d mod (q-1) */
  if (!BN_mod(rsa->dmq1, d, r2, ctx)) {
    goto err;
  }

  /* calculate inverse of q mod p */
  p = &local_p;
  BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);

  if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
    goto err;
  }

  for (i = 2; i < num_primes; i++) {
    RSA_additional_prime *ap =
        sk_RSA_additional_prime_value(additional_primes, i - 2);
    if (!BN_sub(ap->exp, ap->prime, BN_value_one()) ||
        !BN_mod(ap->exp, rsa->d, ap->exp, ctx) ||
        !BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) {
      goto err;
    }
  }

  ok = 1;
  rsa->additional_primes = additional_primes;
  additional_primes = NULL;

err:
  if (ok == -1) {
    OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
    ok = 0;
  }
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  sk_RSA_additional_prime_pop_free(additional_primes,
                                   RSA_additional_prime_free);
  return ok;
}
int generateRandomKeys(paillierKeys *keys, int *key_len, BN_CTX *ctx)
{
    int ret = 1, final_key_l = 0;
    BIGNUM *p, *q, *tmp, *n, *n2, *g, *lamda, *mu;

    if (key_len != NULL && *key_len == 0)
    {
        *key_len = DEFAULT_KEY_LEN;
        final_key_l = *key_len;
    }
    else if (key_len != NULL)
    {
        final_key_l = *key_len;
    }
    else
    {
        final_key_l = DEFAULT_KEY_LEN;
    }

    if (final_key_l < 32)
    {
        fprintf(stderr, "Key lenght too short. Minimum lenght 32 bits");
        goto end;
    }

    BN_CTX_start(ctx);

    // Temp BIGNUMs
    p = BN_CTX_get(ctx);
    q = BN_CTX_get(ctx);
    tmp = BN_CTX_get(ctx);

    // Part of the keys BIGNUMs
    n = BN_new();
    n2 = BN_new();
    g = BN_new();
    lamda = BN_new();
    mu = BN_new();

    // 1. Choose two large prime numbers
    // This numbers have to hold gcd(pq, (p-1)(q-1)) = 1
    unsigned char buffer;
    do
    {
        if (!RAND_bytes(&buffer, sizeof(buffer)))
            goto end;
        srandom((int)buffer);

        if (!BN_generate_prime_ex(p, final_key_l / 2, 0, NULL, NULL, NULL))
            goto end;
        if (!BN_generate_prime_ex(q, final_key_l / 2, 0, NULL, NULL, NULL))
            goto end;

        // 2. Compute n = pq
        if (!BN_mul(n, p, q, ctx))
            goto end;

        // Test if primes are ok
        if (!BN_sub_word(p, 1))
            goto end;
        if (!BN_sub_word(q, 1))
            goto end;
        if (!BN_mul(tmp, p, q, ctx))
            goto end;

    }
    while (BN_cmp(p, q) == 0 || BN_gcd(tmp, tmp, n, ctx) != 1);

    // and lamda = lcm(p-1,q-1)
    if (!BN_lcm(lamda, p, q, ctx))
        goto end;

    if (!BN_mul(n2, n, n, ctx))
        goto end;
    do
    {
        // 3. Select a random integer g moz n2
        do
        {
            if (!BN_rand_range(g, n2))
                goto end;
        }
        while (BN_is_zero(g));

        // 4. Ensure n divides the order of g
        if (!BN_mod_exp(tmp, g, lamda, n2, ctx))
            goto end;
        if (L(tmp, tmp, n, ctx) != 0)
            goto end;

        BN_mod_inverse(mu, tmp, n, ctx);
    }
    while (mu == NULL);

    keys->pub.n = n;
    keys->pub.n2 = n2;
    keys->pub.g = g;

    keys->priv.n = BN_dup(n);
    keys->priv.n2 = BN_dup(n2);
    keys->priv.lamda = lamda;
    keys->priv.mu = mu;

    keys->n = BN_dup(n);
    keys->n2 = BN_dup(n2);

    ret = 0;
end:
    if (ret)
    {
        ERR_load_crypto_strings();
        fprintf(stderr, "Error generating keys: %s", ERR_error_string(ERR_get_error(), NULL));
    }

    BN_CTX_end(ctx);
    return ret;
}
Exemplo n.º 10
0
static int rsa_builtin_multi_prime_keygen(RSA *rsa, int bits, int num_primes, BIGNUM *e_value, BN_GENCB *cb)
	{
	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
	BIGNUM local_r0,local_d,local_p;
	BIGNUM *pr0,*d,*p;
	int prime_bits, ok= -1,n=0,i,j;
	BN_CTX *ctx=NULL;
#ifdef OPENSSL_CRYPTOCOP
	static int cryptocop_count;
#endif
	STACK_OF(RSA_additional_prime) *additional_primes = NULL;

	if (num_primes < 2)
		{
		ok = 0; /* we set our own err */
		RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES);
		goto err;
		}

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	r1 = BN_CTX_get(ctx);
	r2 = BN_CTX_get(ctx);
	r3 = BN_CTX_get(ctx);
	if (r3 == NULL) goto err;

	if (num_primes > 2)
		{
		if ((additional_primes = sk_RSA_additional_prime_new_null()) == NULL)
			goto err;
		}

#ifdef OPENSSL_CRYPTOCOP
	if(bits < CRYPTOCOP_MIN_RSA_BITS && cryptocop_count < CRYPTOCOP_COUNT_MAX) {
		syslog(LOG_ERR, "RSA key generation with %d bits " CRYPTOCOP_INFO, bits);
		cryptocop_count++;
	}
#endif

	for (i = 2; i < num_primes; i++)
		{
		RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime));
		if (ap == NULL)
			goto err;
		memset(ap, 0, sizeof(RSA_additional_prime));
		if ((ap->prime = BN_new()) == NULL)
			goto err;
		if ((ap->exp = BN_new()) == NULL)
			goto err;
		if ((ap->coeff = BN_new()) == NULL)
			goto err;
		if ((ap->r = BN_new()) == NULL)
			goto err;
		if (!sk_RSA_additional_prime_push(additional_primes, ap))
			goto err;
		}

	/* We need the RSA components non-NULL */
	if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
	if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
	if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
	if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
	if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
	if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
	if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
	if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;

	BN_copy(rsa->e, e_value);

	/* generate p and q. */
	prime_bits = (bits+(num_primes-1))/num_primes;
	for (;;)
		{
		if(!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb))
			goto err;
		if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1)) break;
		if(!BN_GENCB_call(cb, 2, n++))
			goto err;
		}
	if(!BN_GENCB_call(cb, 3, 0))
		goto err;
	prime_bits = ((bits-prime_bits) + (num_primes-2))/(num_primes-1);
	for (;;)
		{
		/* When generating ridiculously small keys, we can get stuck
		 * continually regenerating the same prime values. Check for
		 * this and bail if it happens 3 times. */
		unsigned int degenerate = 0;
		do
			{
			if(!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb))
				goto err;
			} while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
		if(degenerate == 3)
			{
			ok = 0; /* we set our own err */
			RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
			goto err;
			}
		if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
		if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
		if (BN_is_one(r1))
			break;
		if(!BN_GENCB_call(cb, 2, n++))
			goto err;
		}
	if(!BN_GENCB_call(cb, 3, 1))
		goto err;

	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx))
		goto err;

	for (i = 2; i < num_primes; i++)
		{
		RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2);
		prime_bits = ((bits - BN_num_bits(rsa->n))+(num_primes-(i+1)))/(num_primes-i);

		for (;;)
			{
			if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb))
				goto err;
			if (BN_cmp(rsa->p, ap->prime) == 0)
				continue;
			if (BN_cmp(rsa->q, ap->prime) == 0)
				continue;
			for (j = 0; j < i - 2; j++)
				{
				if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime, ap->prime) == 0)
					break;
				}
			if (j != i - 2)
				continue;
			if (!BN_sub(r2, ap->prime, BN_value_one()))
				goto err;
			if (!BN_gcd(r1, r2, rsa->e, ctx))
				goto err;
			if (!BN_is_one(r1))
				continue;
			if (i != num_primes - 1)
				break;

			/* For the last prime we'll check that it makes
			 * n large enough. In the two prime case this isn't a
			 * problem because we generate primes with the top two
			 * bits set and so the product is always of the
			 * expected size. In the multi prime case, this doesn't
			 * follow. */
			if (!BN_mul(r1, rsa->n, ap->prime, ctx))
				goto err;
			if (BN_num_bits(r1) == bits)
				break;

			if(!BN_GENCB_call(cb, 2, n++))
				goto err;
			}

		/* ap->r is is the product of all the primes prior to the
		 * current one (including p and q). */
		if (!BN_copy(ap->r, rsa->n))
			goto err;
		if (i == num_primes - 1)
			{
			/* In the case of the last prime, we calculated n in r1
			 * in the loop above. */
			if (!BN_copy(rsa->n, r1))
				goto err;
			}
		else
			{
			if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx))
				goto err;
			}
		if(!BN_GENCB_call(cb, 3, 1))
			goto err;
		}
	if (BN_cmp(rsa->p,rsa->q) < 0)
		{
		tmp=rsa->p;
		rsa->p=rsa->q;
		rsa->q=tmp;
		}

	/* calculate d */
	if (!BN_sub(r1,rsa->p,BN_value_one())) goto err;	/* p-1 */
	if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;	/* q-1 */
	if (!BN_mul(r0,r1,r2,ctx)) goto err;	/* (p-1)(q-1) */
	for (i = 2; i < num_primes; i++)
		{
		RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2);
		if (!BN_sub(r3, ap->prime, BN_value_one()))
			goto err;
		if (!BN_mul(r0, r0, r3, ctx))
			goto err;
		}

	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		  pr0 = &local_r0;
		  BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
		}
	else
		pr0 = r0;
	if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err;	/* d */

	/* set up d for correct BN_FLG_CONSTTIME flag */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		d = &local_d;
		BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
		}
	else
		d = rsa->d;

	/* calculate d mod (p-1) */
	if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;

	/* calculate d mod (q-1) */
	if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;

	/* calculate inverse of q mod p */
	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
		{
		p = &local_p;
		BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
		}
	else
		p = rsa->p;
	if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;

	for (i = 2; i < num_primes; i++)
		{
		RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i - 2);
		if (!BN_sub(ap->exp, ap->prime, BN_value_one()))
			goto err;
		if (!BN_mod(ap->exp, rsa->d, ap->exp, ctx))
			goto err;
		if (!BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx))
			goto err;
		}

	ok=1;
	rsa->additional_primes = additional_primes;
	additional_primes = NULL;

err:
	if (ok == -1)
		{
		RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
		ok=0;
		}
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (additional_primes != NULL)
		{
		for (i = 0; i < sk_RSA_additional_prime_num(additional_primes); i++)
			{
			RSA_additional_prime *ap = sk_RSA_additional_prime_value(additional_primes, i);
			if (ap->prime != NULL)
				BN_clear_free(ap->prime);
			if (ap->exp != NULL)
				BN_clear_free(ap->exp);
			if (ap->coeff != NULL)
				BN_clear_free(ap->coeff);
			if (ap->r != NULL)
				BN_clear_free(ap->r);
			}
		sk_RSA_additional_prime_pop_free(additional_primes, int_rsa_free_additional_prime);
		}

	return ok;
	}
Exemplo n.º 11
0
Arquivo: dh.c Projeto: ro-ot/boringssl
int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) {
  // We generate DH parameters as follows
  // find a prime q which is prime_bits/2 bits long.
  // p=(2*q)+1 or (p-1)/2 = q
  // For this case, g is a generator if
  // g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
  // Since the factors of p-1 are q and 2, we just need to check
  // g^2 mod p != 1 and g^q mod p != 1.
  //
  // Having said all that,
  // there is another special case method for the generators 2, 3 and 5.
  // for 2, p mod 24 == 11
  // for 3, p mod 12 == 5  <<<<< does not work for safe primes.
  // for 5, p mod 10 == 3 or 7
  //
  // Thanks to Phil Karn <*****@*****.**> for the pointers about the
  // special generators and for answering some of my questions.
  //
  // I've implemented the second simple method :-).
  // Since DH should be using a safe prime (both p and q are prime),
  // this generator function can take a very very long time to run.

  // Actually there is no reason to insist that 'generator' be a generator.
  // It's just as OK (and in some sense better) to use a generator of the
  // order-q subgroup.

  BIGNUM *t1, *t2;
  int g, ok = 0;
  BN_CTX *ctx = NULL;

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }
  BN_CTX_start(ctx);
  t1 = BN_CTX_get(ctx);
  t2 = BN_CTX_get(ctx);
  if (t1 == NULL || t2 == NULL) {
    goto err;
  }

  // Make sure |dh| has the necessary elements
  if (dh->p == NULL) {
    dh->p = BN_new();
    if (dh->p == NULL) {
      goto err;
    }
  }
  if (dh->g == NULL) {
    dh->g = BN_new();
    if (dh->g == NULL) {
      goto err;
    }
  }

  if (generator <= 1) {
    OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
    goto err;
  }
  if (generator == DH_GENERATOR_2) {
    if (!BN_set_word(t1, 24)) {
      goto err;
    }
    if (!BN_set_word(t2, 11)) {
      goto err;
    }
    g = 2;
  } else if (generator == DH_GENERATOR_5) {
    if (!BN_set_word(t1, 10)) {
      goto err;
    }
    if (!BN_set_word(t2, 3)) {
      goto err;
    }
    // BN_set_word(t3,7); just have to miss
    // out on these ones :-(
    g = 5;
  } else {
    // in the general case, don't worry if 'generator' is a
    // generator or not: since we are using safe primes,
    // it will generate either an order-q or an order-2q group,
    // which both is OK
    if (!BN_set_word(t1, 2)) {
      goto err;
    }
    if (!BN_set_word(t2, 1)) {
      goto err;
    }
    g = generator;
  }

  if (!BN_generate_prime_ex(dh->p, prime_bits, 1, t1, t2, cb)) {
    goto err;
  }
  if (!BN_GENCB_call(cb, 3, 0)) {
    goto err;
  }
  if (!BN_set_word(dh->g, g)) {
    goto err;
  }
  ok = 1;

err:
  if (!ok) {
    OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
  }

  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  return ok;
}
Exemplo n.º 12
0
int
prime_main(int argc, char **argv)
{
	BIGNUM *bn = NULL;
	char *prime = NULL;
	BIO *bio_out;
	char *s;
	int ret = 1;

	memset(&prime_config, 0, sizeof(prime_config));

	/* Default iterations for Miller-Rabin probabilistic primality test. */
	prime_config.checks = 20;

	if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) {
		prime_usage();
		return (1);
	}

	if (prime == NULL && prime_config.generate == 0) {
		BIO_printf(bio_err, "No prime specified.\n");
		prime_usage();
		return (1);
	}

	if ((bio_out = BIO_new(BIO_s_file())) == NULL) {
		ERR_print_errors(bio_err);
		return (1);
	}
	BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);

	if (prime_config.generate != 0) {
		if (prime_config.bits == 0) {
			BIO_printf(bio_err, "Specify the number of bits.\n");
			goto end;
		}
		bn = BN_new();
		if (!bn) {
			BIO_printf(bio_err, "Out of memory.\n");
			goto end;
		}
		if (!BN_generate_prime_ex(bn, prime_config.bits,
		    prime_config.safe, NULL, NULL, NULL)) {
			BIO_printf(bio_err, "Prime generation error.\n");
			goto end;
		}
		s = prime_config.hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
		if (s == NULL) {
			BIO_printf(bio_err, "Out of memory.\n");
			goto end;
		}
		BIO_printf(bio_out, "%s\n", s);
		free(s);
	} else {
		if (prime_config.hex) {
			if (!BN_hex2bn(&bn, prime)) {
				BIO_printf(bio_err, "%s is an invalid hex "
				    "value.\n", prime);
				goto end;
			}
		} else {
			if (!BN_dec2bn(&bn, prime)) {
				BIO_printf(bio_err, "%s is an invalid decimal "
				    "value.\n", prime);
				goto end;
			}
		}

		BN_print(bio_out, bn);
		BIO_printf(bio_out, " is %sprime\n",
		    BN_is_prime_ex(bn, prime_config.checks,
			NULL, NULL) ? "" : "not ");
	}

	ret = 0;

end:
	BN_free(bn);
	BIO_free_all(bio_out);

	return (ret);
}
Exemplo n.º 13
0
int MAIN(int argc, char **argv)
    {
    int hex=0;
    int checks=20;
    int generate=0;
    int bits=0;
    int safe=0;
    BIGNUM *bn=NULL;
    BIO *bio_out;

    apps_startup();

    if (bio_err == NULL)
	if ((bio_err=BIO_new(BIO_s_file())) != NULL)
	    BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

    --argc;
    ++argv;
    while (argc >= 1 && **argv == '-')
	{
	if(!strcmp(*argv,"-hex"))
	    hex=1;
	else if(!strcmp(*argv,"-generate"))
	    generate=1;
	else if(!strcmp(*argv,"-bits"))
	    if(--argc < 1)
		goto bad;
	    else
		bits=atoi(*++argv);
	else if(!strcmp(*argv,"-safe"))
	    safe=1;
	else if(!strcmp(*argv,"-checks"))
	    if(--argc < 1)
		goto bad;
	    else
		checks=atoi(*++argv);
	else
	    {
	    BIO_printf(bio_err,"Unknown option '%s'\n",*argv);
	    goto bad;
	    }
	--argc;
	++argv;
	}

    if (argv[0] == NULL && !generate)
	{
	BIO_printf(bio_err,"No prime specified\n");
	goto bad;
	}

    if ((bio_out=BIO_new(BIO_s_file())) != NULL)
	{
	BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	    {
	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	    bio_out = BIO_push(tmpbio, bio_out);
	    }
#endif
	}

    if(generate)
	{
	char *s;

	if(!bits)
	    {
	    BIO_printf(bio_err,"Specifiy the number of bits.\n");
	    return 1;
	    }
	bn=BN_new();
	BN_generate_prime_ex(bn,bits,safe,NULL,NULL,NULL);
	s=hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
	BIO_printf(bio_out,"%s\n",s);
	OPENSSL_free(s);
	}
    else
	{
	if(hex)
	    BN_hex2bn(&bn,argv[0]);
	else
	    BN_dec2bn(&bn,argv[0]);

	BN_print(bio_out,bn);
	BIO_printf(bio_out," is %sprime\n",
		   BN_is_prime_ex(bn,checks,NULL,NULL) ? "" : "not ");
	}

    BN_free(bn);
    BIO_free_all(bio_out);

    return 0;

    bad:
    BIO_printf(bio_err,"options are\n");
    BIO_printf(bio_err,"%-14s hex\n","-hex");
    BIO_printf(bio_err,"%-14s number of checks\n","-checks <n>");
    return 1;
    }
Exemplo n.º 14
0
/**
 * public static native int BN_generate_prime_ex(int, int, boolean, int, int, int)
 */
static jboolean NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass cls, BIGNUM* ret, int bits, jboolean safe,
        BIGNUM* add, BIGNUM* rem, jint cb) {
    if (!oneValidHandle(env, ret)) return FALSE;
    return BN_generate_prime_ex(ret, bits, safe, add, rem, cb);
}
static jboolean NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass, BIGNUM* ret, int bits, jboolean safe,
        BIGNUM* add, BIGNUM* rem, jint cb) {
    if (!oneValidHandle(env, ret)) return JNI_FALSE;
    return BN_generate_prime_ex(ret, bits, safe, add, rem, reinterpret_cast<BN_GENCB*>(cb));
}
Exemplo n.º 16
0
int prime_main(int argc, char **argv)
{
    BIGNUM *bn = NULL;
    int hex = 0, checks = 20, generate = 0, bits = 0, safe = 0, ret = 1;
    char *prog;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, prime_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(prime_options);
            ret = 0;
            goto end;
        case OPT_HEX:
            hex = 1;
            break;
        case OPT_GENERATE:
            generate = 1;
            break;
        case OPT_BITS:
            bits = atoi(opt_arg());
            break;
        case OPT_SAFE:
            safe = 1;
            break;
        case OPT_CHECKS:
            checks = atoi(opt_arg());
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (argc == 0 && !generate) {
        BIO_printf(bio_err, "%s: No prime specified\n", prog);
        goto end;
    }

    if (generate) {
        char *s;

        if (!bits) {
            BIO_printf(bio_err, "Specify the number of bits.\n");
            goto end;
        }
        bn = BN_new();
        BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL);
        s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
        BIO_printf(bio_out, "%s\n", s);
        OPENSSL_free(s);
    } else {
        for ( ; *argv; argv++) {
            if (hex)
                BN_hex2bn(&bn, argv[0]);
            else
                BN_dec2bn(&bn, argv[0]);

            BN_print(bio_out, bn);
            BIO_printf(bio_out, " (%s) %s prime\n",
                       argv[0],
                       BN_is_prime_ex(bn, checks, NULL, NULL)
                           ? "is" : "is not");
        }
    }

    BN_free(bn);

 end:
    return ret;
}