Beispiel #1
0
int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx,
                            int do_trial_division, BN_GENCB *cb) {
  if (BN_cmp(a, BN_value_one()) <= 0) {
    return 0;
  }

  /* first look for small factors */
  if (!BN_is_odd(a)) {
    /* a is even => a is prime if and only if a == 2 */
    return BN_is_word(a, 2);
  }

  /* Enhanced Miller-Rabin does not work for three. */
  if (BN_is_word(a, 3)) {
    return 1;
  }

  if (do_trial_division) {
    for (int i = 1; i < NUMPRIMES; i++) {
      BN_ULONG mod = BN_mod_word(a, primes[i]);
      if (mod == (BN_ULONG)-1) {
        return -1;
      }
      if (mod == 0) {
        return BN_is_word(a, primes[i]);
      }
    }

    if (!BN_GENCB_call(cb, 1, -1)) {
      return -1;
    }
  }

  int ret = -1;
  BN_CTX *ctx_allocated = NULL;
  if (ctx == NULL) {
    ctx_allocated = BN_CTX_new();
    if (ctx_allocated == NULL) {
      return -1;
    }
    ctx = ctx_allocated;
  }

  enum bn_primality_result_t result;
  if (!BN_enhanced_miller_rabin_primality_test(&result, a, checks, ctx, cb)) {
    goto err;
  }

  ret = (result == bn_probably_prime);

err:
  BN_CTX_free(ctx_allocated);
  return ret;
}
Beispiel #2
0
static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
                             BN_GENCB *cb)
{
    int i = 0;
    if (!BN_copy(pi, Xpi))
        return 0;
    if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
        return 0;
    for (;;) {
        i++;
        BN_GENCB_call(cb, 0, i);
        /* NB 27 MR is specificed in X9.31 */
        if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb))
            break;
        if (!BN_add_word(pi, 2))
            return 0;
    }
    BN_GENCB_call(cb, 2, i);
    return 1;
}
Beispiel #3
0
/* See FIPS 186-4 C.3.1 Miller Rabin Probabilistic Primality Test. */
int BN_is_prime_fasttest_ex(const BIGNUM *w, int checks, BN_CTX *ctx_passed,
                            int do_trial_division, BN_GENCB *cb)
{
    int i, status, ret = -1;
    BN_CTX *ctx = NULL;

    /* w must be bigger than 1 */
    if (BN_cmp(w, BN_value_one()) <= 0)
        return 0;

    /* w must be odd */
    if (BN_is_odd(w)) {
        /* Take care of the really small prime 3 */
        if (BN_is_word(w, 3))
            return 1;
    } else {
        /* 2 is the only even prime */
        return BN_is_word(w, 2);
    }

    /* first look for small factors */
    if (do_trial_division) {
        for (i = 1; i < NUMPRIMES; i++) {
            BN_ULONG mod = BN_mod_word(w, primes[i]);
            if (mod == (BN_ULONG)-1)
                return -1;
            if (mod == 0)
                return BN_is_word(w, primes[i]);
        }
        if (!BN_GENCB_call(cb, 1, -1))
            return -1;
    }
    if (ctx_passed != NULL)
        ctx = ctx_passed;
    else if ((ctx = BN_CTX_new()) == NULL)
        goto err;

    ret = bn_miller_rabin_is_prime(w, checks, ctx, cb, 0, &status);
    if (!ret)
        goto err;
    ret = (status == BN_PRIMETEST_PROBABLY_PRIME);
err:
    if (ctx_passed == NULL)
        BN_CTX_free(ctx);
    return ret;
}
Beispiel #4
0
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
	const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
	{
	BIGNUM *t;
	int found=0;
	int i,j,c1=0;
	BN_CTX *ctx;
	int checks = BN_prime_checks_for_size(bits);

	if (bits < 2)
		{
		/* There are no prime numbers this small. */
		BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
		return 0;
		}
	else if (bits == 2 && safe)
		{
		/* The smallest safe prime (7) is three bits. */
		BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
		return 0;
		}

	ctx=BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	t = BN_CTX_get(ctx);
	if(!t) goto err;
loop: 
	/* make a random number and set the top and bottom bits */
	if (add == NULL)
		{
		if (!probable_prime(ret,bits)) goto err;
		}
	else
		{
		if (safe)
			{
			if (!probable_prime_dh_safe(ret,bits,add,rem,ctx))
				 goto err;
			}
		else
			{
			if (!bn_probable_prime_dh(ret,bits,add,rem,ctx))
				goto err;
			}
		}
	/* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
	if(!BN_GENCB_call(cb, 0, c1++))
		/* aborted */
		goto err;

	if (!safe)
		{
		i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb);
		if (i == -1) goto err;
		if (i == 0) goto loop;
		}
	else
		{
		/* for "safe prime" generation,
		 * check that (p-1)/2 is prime.
		 * Since a prime is odd, We just
		 * need to divide by 2 */
		if (!BN_rshift1(t,ret)) goto err;

		for (i=0; i<checks; i++)
			{
			j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb);
			if (j == -1) goto err;
			if (j == 0) goto loop;

			j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb);
			if (j == -1) goto err;
			if (j == 0) goto loop;

			if(!BN_GENCB_call(cb, 2, c1-1))
				goto err;
			/* We have a safe prime test pass */
			}
		}
	/* we have a prime :-) */
	found = 1;
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	bn_check_top(ret);
	return found;
	}
Beispiel #5
0
// generate_prime sets |out| to a prime with length |bits| such that |out|-1 is
// relatively prime to |e|. If |p| is non-NULL, |out| will also not be close to
// |p|. |sqrt2| must be ⌊2^(bits-1)×√2⌋ (or a slightly overestimate for large
// sizes), and |pow2_bits_100| must be 2^(bits-100).
static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e,
                          const BIGNUM *p, const BIGNUM *sqrt2,
                          const BIGNUM *pow2_bits_100, BN_CTX *ctx,
                          BN_GENCB *cb) {
  if (bits < 128 || (bits % BN_BITS2) != 0) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    return 0;
  }
  assert(BN_is_pow2(pow2_bits_100));
  assert(BN_is_bit_set(pow2_bits_100, bits - 100));

  // See FIPS 186-4 appendix B.3.3, steps 4 and 5. Note |bits| here is nlen/2.

  // Use the limit from steps 4.7 and 5.8 for most values of |e|. When |e| is 3,
  // the 186-4 limit is too low, so we use a higher one. Note this case is not
  // reachable from |RSA_generate_key_fips|.
  if (bits >= INT_MAX/32) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
    return 0;
  }
  int limit = BN_is_word(e, 3) ? bits * 32 : bits * 5;

  int ret = 0, tries = 0, rand_tries = 0;
  BN_CTX_start(ctx);
  BIGNUM *tmp = BN_CTX_get(ctx);
  if (tmp == NULL) {
    goto err;
  }

  for (;;) {
    // Generate a random number of length |bits| where the bottom bit is set
    // (steps 4.2, 4.3, 5.2 and 5.3) and the top bit is set (implied by the
    // bound checked below in steps 4.4 and 5.5).
    if (!BN_rand(out, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD) ||
        !BN_GENCB_call(cb, BN_GENCB_GENERATED, rand_tries++)) {
      goto err;
    }

    if (p != NULL) {
      // If |p| and |out| are too close, try again (step 5.4).
      if (!bn_abs_sub_consttime(tmp, out, p, ctx)) {
        goto err;
      }
      if (BN_cmp(tmp, pow2_bits_100) <= 0) {
        continue;
      }
    }

    // If out < 2^(bits-1)×√2, try again (steps 4.4 and 5.5). This is equivalent
    // to out <= ⌊2^(bits-1)×√2⌋, or out <= sqrt2 for FIPS key sizes.
    //
    // For larger keys, the comparison is approximate, leaning towards
    // retrying. That is, we reject a negligible fraction of primes that are
    // within the FIPS bound, but we will never accept a prime outside the
    // bound, ensuring the resulting RSA key is the right size.
    if (BN_cmp(out, sqrt2) <= 0) {
      continue;
    }

    // RSA key generation's bottleneck is discarding composites. If it fails
    // trial division, do not bother computing a GCD or performing Rabin-Miller.
    if (!bn_odd_number_is_obviously_composite(out)) {
      // Check gcd(out-1, e) is one (steps 4.5 and 5.6).
      int relatively_prime;
      if (!BN_sub(tmp, out, BN_value_one()) ||
          !bn_is_relatively_prime(&relatively_prime, tmp, e, ctx)) {
        goto err;
      }
      if (relatively_prime) {
        // Test |out| for primality (steps 4.5.1 and 5.6.1).
        int is_probable_prime;
        if (!BN_primality_test(&is_probable_prime, out, BN_prime_checks, ctx, 0,
                               cb)) {
          goto err;
        }
        if (is_probable_prime) {
          ret = 1;
          goto err;
        }
      }
    }

    // If we've tried too many times to find a prime, abort (steps 4.7 and
    // 5.8).
    tries++;
    if (tries >= limit) {
      OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
      goto err;
    }
    if (!BN_GENCB_call(cb, 2, tries)) {
      goto err;
    }
  }

err:
  BN_CTX_end(ctx);
  return ret;
}
Beispiel #6
0
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
  // See FIPS 186-4 appendix B.3. This function implements a generalized version
  // of the FIPS algorithm. |RSA_generate_key_fips| performs additional checks
  // for FIPS-compliant key generation.

  // Always generate RSA keys which are a multiple of 128 bits. Round |bits|
  // down as needed.
  bits &= ~127;

  // Reject excessively small keys.
  if (bits < 256) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  // Reject excessively large public exponents. Windows CryptoAPI and Go don't
  // support values larger than 32 bits, so match their limits for generating
  // keys. (|check_modulus_and_exponent_sizes| uses a slightly more conservative
  // value, but we don't need to support generating such keys.)
  // https://github.com/golang/go/issues/3161
  // https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx
  if (BN_num_bits(e_value) > 32) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
    return 0;
  }

  int ret = 0;
  int prime_bits = bits / 2;
  BN_CTX *ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto bn_err;
  }
  BN_CTX_start(ctx);
  BIGNUM *totient = BN_CTX_get(ctx);
  BIGNUM *pm1 = BN_CTX_get(ctx);
  BIGNUM *qm1 = BN_CTX_get(ctx);
  BIGNUM *sqrt2 = BN_CTX_get(ctx);
  BIGNUM *pow2_prime_bits_100 = BN_CTX_get(ctx);
  BIGNUM *pow2_prime_bits = BN_CTX_get(ctx);
  if (totient == NULL || pm1 == NULL || qm1 == NULL || sqrt2 == NULL ||
      pow2_prime_bits_100 == NULL || pow2_prime_bits == NULL ||
      !BN_set_bit(pow2_prime_bits_100, prime_bits - 100) ||
      !BN_set_bit(pow2_prime_bits, prime_bits)) {
    goto bn_err;
  }

  // We need the RSA components non-NULL.
  if (!ensure_bignum(&rsa->n) ||
      !ensure_bignum(&rsa->d) ||
      !ensure_bignum(&rsa->e) ||
      !ensure_bignum(&rsa->p) ||
      !ensure_bignum(&rsa->q) ||
      !ensure_bignum(&rsa->dmp1) ||
      !ensure_bignum(&rsa->dmq1)) {
    goto bn_err;
  }

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

  // Compute sqrt2 >= ⌊2^(prime_bits-1)×√2⌋.
  if (!bn_set_words(sqrt2, kBoringSSLRSASqrtTwo, kBoringSSLRSASqrtTwoLen)) {
    goto bn_err;
  }
  int sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2;
  assert(sqrt2_bits == (int)BN_num_bits(sqrt2));
  if (sqrt2_bits > prime_bits) {
    // For key sizes up to 3072 (prime_bits = 1536), this is exactly
    // ⌊2^(prime_bits-1)×√2⌋.
    if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) {
      goto bn_err;
    }
  } else if (prime_bits > sqrt2_bits) {
    // For key sizes beyond 3072, this is approximate. We err towards retrying
    // to ensure our key is the right size and round up.
    if (!BN_add_word(sqrt2, 1) ||
        !BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) {
      goto bn_err;
    }
  }
  assert(prime_bits == (int)BN_num_bits(sqrt2));

  do {
    // Generate p and q, each of size |prime_bits|, using the steps outlined in
    // appendix FIPS 186-4 appendix B.3.3.
    if (!generate_prime(rsa->p, prime_bits, rsa->e, NULL, sqrt2,
                        pow2_prime_bits_100, ctx, cb) ||
        !BN_GENCB_call(cb, 3, 0) ||
        !generate_prime(rsa->q, prime_bits, rsa->e, rsa->p, sqrt2,
                        pow2_prime_bits_100, ctx, cb) ||
        !BN_GENCB_call(cb, 3, 1)) {
      goto bn_err;
    }

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

    // Calculate d = e^(-1) (mod lcm(p-1, q-1)), per FIPS 186-4. This differs
    // from typical RSA implementations which use (p-1)*(q-1).
    //
    // Note this means the size of d might reveal information about p-1 and
    // q-1. However, we do operations with Chinese Remainder Theorem, so we only
    // use d (mod p-1) and d (mod q-1) as exponents. Using a minimal totient
    // does not affect those two values.
    int no_inverse;
    if (!bn_usub_consttime(pm1, rsa->p, BN_value_one()) ||
        !bn_usub_consttime(qm1, rsa->q, BN_value_one()) ||
        !bn_lcm_consttime(totient, pm1, qm1, ctx) ||
        !bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient, ctx)) {
      goto bn_err;
    }

    // Retry if |rsa->d| <= 2^|prime_bits|. See appendix B.3.1's guidance on
    // values for d.
  } while (BN_cmp(rsa->d, pow2_prime_bits) <= 0);

  if (// Calculate n.
      !bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx) ||
      // Calculate d mod (p-1).
      !bn_div_consttime(NULL, rsa->dmp1, rsa->d, pm1, ctx) ||
      // Calculate d mod (q-1)
      !bn_div_consttime(NULL, rsa->dmq1, rsa->d, qm1, ctx)) {
    goto bn_err;
  }
  bn_set_minimal_width(rsa->n);

  // Sanity-check that |rsa->n| has the specified size. This is implied by
  // |generate_prime|'s bounds.
  if (BN_num_bits(rsa->n) != (unsigned)bits) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  // Call |freeze_private_key| to compute the inverse of q mod p, by way of
  // |rsa->mont_p|.
  if (!freeze_private_key(rsa, ctx)) {
    goto bn_err;
  }

  // The key generation process is complex and thus error-prone. It could be
  // disastrous to generate and then use a bad key so double-check that the key
  // makes sense.
  if (!RSA_check_key(rsa)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
    goto err;
  }

  ret = 1;

bn_err:
  if (!ret) {
    OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
  }
err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  return ret;
}
Beispiel #7
0
int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
	unsigned char *seed_out,
	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
	{
	int ok=-1;
	unsigned char *seed = NULL;
	unsigned char md[EVP_MAX_MD_SIZE];
	int mdsize;
	BIGNUM *r0,*W,*X,*c,*test;
	BIGNUM *g=NULL,*q=NULL,*p=NULL;
	BN_MONT_CTX *mont=NULL;
	int i, k, n=0, m=0, qsize = N >> 3;
	int counter=0;
	int r=0;
	BN_CTX *ctx=NULL;
	unsigned int h=2;

#ifdef OPENSSL_FIPS
	if(FIPS_selftest_failed())
	    {
	    FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN2,
		    FIPS_R_FIPS_SELFTEST_FAILED);
	    goto err;
	    }

	if (!fips_check_dsa_prng(ret, L, N))
		goto err;
#endif

	if (evpmd == NULL)
		{
		if (N == 160)
			evpmd = EVP_sha1();
		else if (N == 224)
			evpmd = EVP_sha224();
		else
			evpmd = EVP_sha256();
		}

	mdsize = M_EVP_MD_size(evpmd);

	if (seed_len == 0)
		seed_len = mdsize;

	seed = OPENSSL_malloc(seed_len);

	if (!seed)
		goto err;

	if (seed_in)
		memcpy(seed, seed_in, seed_len);

	if ((ctx=BN_CTX_new()) == NULL)
		goto err;

	if ((mont=BN_MONT_CTX_new()) == NULL)
		goto err;

	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	g = BN_CTX_get(ctx);
	W = BN_CTX_get(ctx);
	q = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	c = BN_CTX_get(ctx);
	p = BN_CTX_get(ctx);
	test = BN_CTX_get(ctx);

	if (!BN_lshift(test,BN_value_one(),L-1))
		goto err;
	for (;;)
		{
		for (;;) /* find q */
			{
			unsigned char *pmd;
			/* step 1 */
			if(!BN_GENCB_call(cb, 0, m++))
				goto err;

			if (!seed_in)
				{
				if (RAND_pseudo_bytes(seed, seed_len) < 0)
					goto err;
				}
			/* step 2 */
			if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
				goto err;
			/* Take least significant bits of md */
			if (mdsize > qsize)
				pmd = md + mdsize - qsize;
			else
				pmd = md;

			if (mdsize < qsize)
				memset(md + mdsize, 0, qsize - mdsize);

			/* step 3 */
			pmd[0] |= 0x80;
			pmd[qsize-1] |= 0x01;
			if (!BN_bin2bn(pmd, qsize, q))
				goto err;

			/* step 4 */
			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
					seed_in ? 1 : 0, cb);
			if (r > 0)
				break;
			if (r != 0)
				goto err;
			/* Provided seed didn't produce a prime: error */
			if (seed_in)
				{
				ok = 0;
				DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
				goto err;
				}

			/* do a callback call */
			/* step 5 */
			}
		/* Copy seed to seed_out before we mess with it */
		if (seed_out)
			memcpy(seed_out, seed, seed_len);

		if(!BN_GENCB_call(cb, 2, 0)) goto err;
		if(!BN_GENCB_call(cb, 3, 0)) goto err;

		/* step 6 */
		counter=0;
		/* "offset = 1" */

		n=(L-1)/(mdsize << 3);

		for (;;)
			{
			if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
				goto err;

			/* step 7 */
			BN_zero(W);
			/* now 'buf' contains "SEED + offset - 1" */
			for (k=0; k<=n; k++)
				{
				/* obtain "SEED + offset + k" by incrementing: */
				for (i = seed_len-1; i >= 0; i--)
					{
					seed[i]++;
					if (seed[i] != 0)
						break;
					}

				if (!EVP_Digest(seed, seed_len, md ,NULL, evpmd,
									NULL))
					goto err;

				/* step 8 */
				if (!BN_bin2bn(md, mdsize, r0))
					goto err;
				if (!BN_lshift(r0,r0,(mdsize << 3)*k)) goto err;
				if (!BN_add(W,W,r0)) goto err;
				}

			/* more of step 8 */
			if (!BN_mask_bits(W,L-1)) goto err;
			if (!BN_copy(X,W)) goto err;
			if (!BN_add(X,X,test)) goto err;

			/* step 9 */
			if (!BN_lshift1(r0,q)) goto err;
			if (!BN_mod(c,X,r0,ctx)) goto err;
			if (!BN_sub(r0,c,BN_value_one())) goto err;
			if (!BN_sub(p,X,r0)) goto err;

			/* step 10 */
			if (BN_cmp(p,test) >= 0)
				{
				/* step 11 */
				r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
						ctx, 1, cb);
				if (r > 0)
						goto end; /* found it */
				if (r != 0)
					goto err;
				}

			/* step 13 */
			counter++;
			/* "offset = offset + n + 1" */

			/* step 14 */
			if (counter >= 4096) break;
			}
		}
end:
	if(!BN_GENCB_call(cb, 2, 1))
		goto err;

	/* We now need to generate g */
	/* Set r0=(p-1)/q */
	if (!BN_sub(test,p,BN_value_one())) goto err;
	if (!BN_div(r0,NULL,test,q,ctx)) goto err;

	if (!BN_set_word(test,h)) goto err;
	if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;

	for (;;)
		{
		/* g=test^r0%p */
		if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
		if (!BN_is_one(g)) break;
		if (!BN_add(test,test,BN_value_one())) goto err;
		h++;
		}

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

	ok=1;
err:
	if (ok == 1)
		{
		if(ret->p) BN_free(ret->p);
		if(ret->q) BN_free(ret->q);
		if(ret->g) BN_free(ret->g);
		ret->p=BN_dup(p);
		ret->q=BN_dup(q);
		ret->g=BN_dup(g);
		if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
			{
			ok=-1;
			goto err;
			}
		if (counter_ret != NULL) *counter_ret=counter;
		if (h_ret != NULL) *h_ret=h;
		}
	if (seed)
		OPENSSL_free(seed);
	if(ctx)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	if (mont != NULL) BN_MONT_CTX_free(mont);
	return ok;
	}
Beispiel #8
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;
	}
Beispiel #9
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;
}
Beispiel #10
0
static int
ltm_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
{
    mp_int el, p, q, n, d, dmp1, dmq1, iqmp, t1, t2, t3;
    int counter, ret, bitsp;

    if (bits < 789)
	return -1;

    bitsp = (bits + 1) / 2;

    ret = -1;

    mp_init_multi(&el, &p, &q, &n, &d,
		  &dmp1, &dmq1, &iqmp,
		  &t1, &t2, &t3, NULL);

    BN2mpz(&el, e);

    /* generate p and q so that p != q and bits(pq) ~ bits */
    counter = 0;
    do {
	BN_GENCB_call(cb, 2, counter++);
	CHECK(random_num(&p, bitsp), 0);
	CHECK(mp_find_prime(&p), MP_YES);

	mp_sub_d(&p, 1, &t1);
	mp_gcd(&t1, &el, &t2);
    } while(mp_cmp_d(&t2, 1) != 0);

    BN_GENCB_call(cb, 3, 0);

    counter = 0;
    do {
	BN_GENCB_call(cb, 2, counter++);
	CHECK(random_num(&q, bits - bitsp), 0);
	CHECK(mp_find_prime(&q), MP_YES);

	if (mp_cmp(&p, &q) == 0) /* don't let p and q be the same */
	    continue;

	mp_sub_d(&q, 1, &t1);
	mp_gcd(&t1, &el, &t2);
    } while(mp_cmp_d(&t2, 1) != 0);

    /* make p > q */
    if (mp_cmp(&p, &q) < 0) {
	mp_int c;
	c = p;
	p = q;
	q = c;
    }

    BN_GENCB_call(cb, 3, 1);

    /* calculate n,  		n = p * q */
    mp_mul(&p, &q, &n);

    /* calculate d, 		d = 1/e mod (p - 1)(q - 1) */
    mp_sub_d(&p, 1, &t1);
    mp_sub_d(&q, 1, &t2);
    mp_mul(&t1, &t2, &t3);
    mp_invmod(&el, &t3, &d);

    /* calculate dmp1		dmp1 = d mod (p-1) */
    mp_mod(&d, &t1, &dmp1);
    /* calculate dmq1		dmq1 = d mod (q-1) */
    mp_mod(&d, &t2, &dmq1);
    /* calculate iqmp 		iqmp = 1/q mod p */
    mp_invmod(&q, &p, &iqmp);

    /* fill in RSA key */

    rsa->e = mpz2BN(&el);
    rsa->p = mpz2BN(&p);
    rsa->q = mpz2BN(&q);
    rsa->n = mpz2BN(&n);
    rsa->d = mpz2BN(&d);
    rsa->dmp1 = mpz2BN(&dmp1);
    rsa->dmq1 = mpz2BN(&dmq1);
    rsa->iqmp = mpz2BN(&iqmp);

    ret = 1;

out:
    mp_clear_multi(&el, &p, &q, &n, &d,
		   &dmp1, &dmq1, &iqmp,
		   &t1, &t2, &t3, NULL);

    return ret;
}
Beispiel #11
0
int BN_enhanced_miller_rabin_primality_test(
    enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations,
    BN_CTX *ctx, BN_GENCB *cb) {
  /* Enhanced Miller-Rabin is only valid on odd integers greater than 3. */
  if (!BN_is_odd(w) || BN_cmp_word(w, 3) <= 0) {
    OPENSSL_PUT_ERROR(BN, BN_R_INVALID_INPUT);
    return 0;
  }

  if (iterations == BN_prime_checks) {
    iterations = BN_prime_checks_for_size(BN_num_bits(w));
  }

  int ret = 0;
  BN_MONT_CTX *mont = NULL;

  BN_CTX_start(ctx);

  BIGNUM *w1 = BN_CTX_get(ctx);
  if (w1 == NULL ||
      !BN_copy(w1, w) ||
      !BN_sub_word(w1, 1)) {
    goto err;
  }

  /* Write w1 as m*2^a (Steps 1 and 2). */
  int a = 0;
  while (!BN_is_bit_set(w1, a)) {
    a++;
  }
  BIGNUM *m = BN_CTX_get(ctx);
  if (m == NULL ||
      !BN_rshift(m, w1, a)) {
    goto err;
  }

  BIGNUM *b = BN_CTX_get(ctx);
  BIGNUM *g = BN_CTX_get(ctx);
  BIGNUM *z = BN_CTX_get(ctx);
  BIGNUM *x = BN_CTX_get(ctx);
  BIGNUM *x1 = BN_CTX_get(ctx);
  if (b == NULL ||
      g == NULL ||
      z == NULL ||
      x == NULL ||
      x1 == NULL) {
    goto err;
  }

  /* Montgomery setup for computations mod A */
  mont = BN_MONT_CTX_new();
  if (mont == NULL ||
      !BN_MONT_CTX_set(mont, w, ctx)) {
    goto err;
  }

  /* The following loop performs in inner iteration of the Enhanced Miller-Rabin
   * Primality test (Step 4). */
  for (int i = 1; i <= iterations; i++) {
    /* Step 4.1-4.2 */
    if (!BN_rand_range_ex(b, 2, w1)) {
      goto err;
    }

    /* Step 4.3-4.4 */
    if (!BN_gcd(g, b, w, ctx)) {
      goto err;
    }
    if (BN_cmp_word(g, 1) > 0) {
      *out_result = bn_composite;
      ret = 1;
      goto err;
    }

    /* Step 4.5 */
    if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) {
      goto err;
    }

    /* Step 4.6 */
    if (BN_is_one(z) || BN_cmp(z, w1) == 0) {
      goto loop;
    }

    /* Step 4.7 */
    for (int j = 1; j < a; j++) {
      if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) {
        goto err;
      }
      if (BN_cmp(z, w1) == 0) {
        goto loop;
      }
      if (BN_is_one(z)) {
        goto composite;
      }
    }

    /* Step 4.8-4.9 */
    if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) {
      goto err;
    }

    /* Step 4.10-4.11 */
    if (!BN_is_one(z) && !BN_copy(x, z)) {
      goto err;
    }

 composite:
    /* Step 4.12-4.14 */
    if (!BN_copy(x1, x) ||
        !BN_sub_word(x1, 1) ||
        !BN_gcd(g, x1, w, ctx)) {
      goto err;
    }
    if (BN_cmp_word(g, 1) > 0) {
      *out_result = bn_composite;
    } else {
      *out_result = bn_non_prime_power_composite;
    }

    ret = 1;
    goto err;

 loop:
    /* Step 4.15 */
    if (!BN_GENCB_call(cb, 1, i)) {
      goto err;
    }
  }

  *out_result = bn_probably_prime;
  ret = 1;

err:
  BN_MONT_CTX_free(mont);
  BN_CTX_end(ctx);

  return ret;
}
Beispiel #12
0
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
  // See FIPS 186-4 appendix B.3. This function implements a generalized version
  // of the FIPS algorithm. |RSA_generate_key_fips| performs additional checks
  // for FIPS-compliant key generation.

  // Always generate RSA keys which are a multiple of 128 bits. Round |bits|
  // down as needed.
  bits &= ~127;

  // Reject excessively small keys.
  if (bits < 256) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  int ret = 0;
  BN_CTX *ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto bn_err;
  }
  BN_CTX_start(ctx);
  BIGNUM *totient = BN_CTX_get(ctx);
  BIGNUM *pm1 = BN_CTX_get(ctx);
  BIGNUM *qm1 = BN_CTX_get(ctx);
  BIGNUM *gcd = BN_CTX_get(ctx);
  BIGNUM *sqrt2 = BN_CTX_get(ctx);
  if (totient == NULL || pm1 == NULL || qm1 == NULL || gcd == NULL ||
      sqrt2 == NULL) {
    goto bn_err;
  }

  // We need the RSA components non-NULL.
  if (!ensure_bignum(&rsa->n) ||
      !ensure_bignum(&rsa->d) ||
      !ensure_bignum(&rsa->e) ||
      !ensure_bignum(&rsa->p) ||
      !ensure_bignum(&rsa->q) ||
      !ensure_bignum(&rsa->dmp1) ||
      !ensure_bignum(&rsa->dmq1)) {
    goto bn_err;
  }

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

  int prime_bits = bits / 2;

  // Compute sqrt2 >= ⌊2^(prime_bits-1)×√2⌋.
  if (!bn_set_words(sqrt2, kBoringSSLRSASqrtTwo, kBoringSSLRSASqrtTwoLen)) {
    goto bn_err;
  }
  int sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2;
  assert(sqrt2_bits == (int)BN_num_bits(sqrt2));
  if (sqrt2_bits > prime_bits) {
    // For key sizes up to 3072 (prime_bits = 1536), this is exactly
    // ⌊2^(prime_bits-1)×√2⌋.
    if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) {
      goto bn_err;
    }
  } else if (prime_bits > sqrt2_bits) {
    // For key sizes beyond 3072, this is approximate. We err towards retrying
    // to ensure our key is the right size and round up.
    if (!BN_add_word(sqrt2, 1) ||
        !BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) {
      goto bn_err;
    }
  }
  assert(prime_bits == (int)BN_num_bits(sqrt2));

  do {
    // Generate p and q, each of size |prime_bits|, using the steps outlined in
    // appendix FIPS 186-4 appendix B.3.3.
    if (!generate_prime(rsa->p, prime_bits, rsa->e, NULL, sqrt2, ctx, cb) ||
        !BN_GENCB_call(cb, 3, 0) ||
        !generate_prime(rsa->q, prime_bits, rsa->e, rsa->p, sqrt2, ctx, cb) ||
        !BN_GENCB_call(cb, 3, 1)) {
      goto bn_err;
    }

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

    // Calculate d = e^(-1) (mod lcm(p-1, q-1)), per FIPS 186-4. This differs
    // from typical RSA implementations which use (p-1)*(q-1).
    //
    // Note this means the size of d might reveal information about p-1 and
    // q-1. However, we do operations with Chinese Remainder Theorem, so we only
    // use d (mod p-1) and d (mod q-1) as exponents. Using a minimal totient
    // does not affect those two values.
    if (!BN_sub(pm1, rsa->p, BN_value_one()) ||
        !BN_sub(qm1, rsa->q, BN_value_one()) ||
        !BN_mul(totient, pm1, qm1, ctx) ||
        !BN_gcd(gcd, pm1, qm1, ctx) ||
        !BN_div(totient, NULL, totient, gcd, ctx) ||
        !BN_mod_inverse(rsa->d, rsa->e, totient, ctx)) {
      goto bn_err;
    }

    // Check that |rsa->d| > 2^|prime_bits| and try again if it fails. See
    // appendix B.3.1's guidance on values for d.
  } while (!rsa_greater_than_pow2(rsa->d, prime_bits));

  if (// Calculate n.
      !BN_mul(rsa->n, rsa->p, rsa->q, ctx) ||
      // Calculate d mod (p-1).
      !BN_mod(rsa->dmp1, rsa->d, pm1, ctx) ||
      // Calculate d mod (q-1)
      !BN_mod(rsa->dmq1, rsa->d, qm1, ctx)) {
    goto bn_err;
  }

  // Sanity-check that |rsa->n| has the specified size. This is implied by
  // |generate_prime|'s bounds.
  if (BN_num_bits(rsa->n) != (unsigned)bits) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  // Call |freeze_private_key| to compute the inverse of q mod p, by way of
  // |rsa->mont_p|.
  if (!freeze_private_key(rsa, ctx)) {
    goto bn_err;
  }

  // The key generation process is complex and thus error-prone. It could be
  // disastrous to generate and then use a bad key so double-check that the key
  // makes sense.
  if (!RSA_check_key(rsa)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
    goto err;
  }

  ret = 1;

bn_err:
  if (!ret) {
    OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
  }
err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  return ret;
}
Beispiel #13
0
/*
 * Refer to FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test.
 * OR C.3.1 Miller-Rabin Probabilistic Primality Test (if enhanced is zero).
 * The Step numbers listed in the code refer to the enhanced case.
 *
 * if enhanced is set, then status returns one of the following:
 *     BN_PRIMETEST_PROBABLY_PRIME
 *     BN_PRIMETEST_COMPOSITE_WITH_FACTOR
 *     BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME
 * if enhanced is zero, then status returns either
 *     BN_PRIMETEST_PROBABLY_PRIME or
 *     BN_PRIMETEST_COMPOSITE
 *
 * returns 0 if there was an error, otherwise it returns 1.
 */
int bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx,
                             BN_GENCB *cb, int enhanced, int *status)
{
    int i, j, a, ret = 0;
    BIGNUM *g, *w1, *w3, *x, *m, *z, *b;
    BN_MONT_CTX *mont = NULL;

    /* w must be odd */
    if (!BN_is_odd(w))
        return 0;

    BN_CTX_start(ctx);
    g = BN_CTX_get(ctx);
    w1 = BN_CTX_get(ctx);
    w3 = BN_CTX_get(ctx);
    x = BN_CTX_get(ctx);
    m = BN_CTX_get(ctx);
    z = BN_CTX_get(ctx);
    b = BN_CTX_get(ctx);

    if (!(b != NULL
            /* w1 := w - 1 */
            && BN_copy(w1, w)
            && BN_sub_word(w1, 1)
            /* w3 := w - 3 */
            && BN_copy(w3, w)
            && BN_sub_word(w3, 3)))
        goto err;

    /* check w is larger than 3, otherwise the random b will be too small */
    if (BN_is_zero(w3) || BN_is_negative(w3))
        goto err;

    /* (Step 1) Calculate largest integer 'a' such that 2^a divides w-1 */
    a = 1;
    while (!BN_is_bit_set(w1, a))
        a++;
    /* (Step 2) m = (w-1) / 2^a */
    if (!BN_rshift(m, w1, a))
        goto err;

    /* Montgomery setup for computations mod a */
    mont = BN_MONT_CTX_new();
    if (mont == NULL || !BN_MONT_CTX_set(mont, w, ctx))
        goto err;

    if (iterations == BN_prime_checks)
        iterations = BN_prime_checks_for_size(BN_num_bits(w));

    /* (Step 4) */
    for (i = 0; i < iterations; ++i) {
        /* (Step 4.1) obtain a Random string of bits b where 1 < b < w-1 */
        if (!BN_priv_rand_range(b, w3) || !BN_add_word(b, 2)) /* 1 < b < w-1 */
            goto err;

        if (enhanced) {
            /* (Step 4.3) */
            if (!BN_gcd(g, b, w, ctx))
                goto err;
            /* (Step 4.4) */
            if (!BN_is_one(g)) {
                *status = BN_PRIMETEST_COMPOSITE_WITH_FACTOR;
                ret = 1;
                goto err;
            }
        }
        /* (Step 4.5) z = b^m mod w */
        if (!BN_mod_exp_mont(z, b, m, w, ctx, mont))
            goto err;
        /* (Step 4.6) if (z = 1 or z = w-1) */
        if (BN_is_one(z) || BN_cmp(z, w1) == 0)
            goto outer_loop;
        /* (Step 4.7) for j = 1 to a-1 */
        for (j = 1; j < a ; ++j) {
            /* (Step 4.7.1 - 4.7.2) x = z. z = x^2 mod w */
            if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx))
                goto err;
            /* (Step 4.7.3) */
            if (BN_cmp(z, w1) == 0)
                goto outer_loop;
            /* (Step 4.7.4) */
            if (BN_is_one(z))
                goto composite;
        }
        /* At this point z = b^((w-1)/2) mod w */
        /* (Steps 4.8 - 4.9) x = z, z = x^2 mod w */
        if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx))
            goto err;
        /* (Step 4.10) */
        if (BN_is_one(z))
            goto composite;
        /* (Step 4.11) x = b^(w-1) mod w */
        if (!BN_copy(x, z))
            goto err;
composite:
        if (enhanced) {
            /* (Step 4.1.2) g = GCD(x-1, w) */
            if (!BN_sub_word(x, 1) || !BN_gcd(g, x, w, ctx))
                goto err;
            /* (Steps 4.1.3 - 4.1.4) */
            if (BN_is_one(g))
                *status = BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME;
            else
                *status = BN_PRIMETEST_COMPOSITE_WITH_FACTOR;
        } else {
            *status = BN_PRIMETEST_COMPOSITE;
        }
        ret = 1;
        goto err;
outer_loop: ;
        /* (Step 4.1.5) */
        if (!BN_GENCB_call(cb, 1, i))
            goto err;
    }
    /* (Step 5) */
    *status = BN_PRIMETEST_PROBABLY_PRIME;
    ret = 1;
err:
    BN_clear(g);
    BN_clear(w1);
    BN_clear(w3);
    BN_clear(x);
    BN_clear(m);
    BN_clear(z);
    BN_clear(b);
    BN_CTX_end(ctx);
    BN_MONT_CTX_free(mont);
    return ret;
}
Beispiel #14
0
static int dsa_builtin_paramgen(DSA *ret, int bits,
                                unsigned char *seed_in, int seed_len,
                                int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
{
    int ok=0;
    unsigned char seed[SHA_DIGEST_LENGTH];
    unsigned char md[SHA_DIGEST_LENGTH];
    unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
    BIGNUM *r0,*W,*X,*c,*test;
    BIGNUM *g=NULL,*q=NULL,*p=NULL;
    BN_MONT_CTX *mont=NULL;
    int k,n=0,i,b,m=0;
    int counter=0;
    int r=0;
    BN_CTX *ctx=NULL;
    unsigned int h=2;

    if(FIPS_selftest_failed())
    {
        FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN,
                FIPS_R_FIPS_SELFTEST_FAILED);
        goto err;
    }

    if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
    {
        DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL);
        goto err;
    }

    if (bits < 512) bits=512;
    bits=(bits+63)/64*64;

    /* NB: seed_len == 0 is special case: copy generated seed to
     * seed_in if it is not NULL.
     */
    if (seed_len && (seed_len < 20))
        seed_in = NULL; /* seed buffer too small -- ignore */
    if (seed_len > 20)
        seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
		                * but our internal buffers are restricted to 160 bits*/
    if ((seed_in != NULL) && (seed_len == 20))
    {
        memcpy(seed,seed_in,seed_len);
        /* set seed_in to NULL to avoid it being copied back */
        seed_in = NULL;
    }

    if ((ctx=BN_CTX_new()) == NULL) goto err;

    if ((mont=BN_MONT_CTX_new()) == NULL) goto err;

    BN_CTX_start(ctx);
    r0 = BN_CTX_get(ctx);
    g = BN_CTX_get(ctx);
    W = BN_CTX_get(ctx);
    q = BN_CTX_get(ctx);
    X = BN_CTX_get(ctx);
    c = BN_CTX_get(ctx);
    p = BN_CTX_get(ctx);
    test = BN_CTX_get(ctx);

    if (!BN_lshift(test,BN_value_one(),bits-1))
        goto err;

    for (;;)
    {
        for (;;) /* find q */
        {
            int seed_is_random;

            /* step 1 */
            if(!BN_GENCB_call(cb, 0, m++))
                goto err;

            if (!seed_len)
            {
                RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH);
                seed_is_random = 1;
            }
            else
            {
                seed_is_random = 0;
                seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
            }
            memcpy(buf,seed,SHA_DIGEST_LENGTH);
            memcpy(buf2,seed,SHA_DIGEST_LENGTH);
            /* precompute "SEED + 1" for step 7: */
            for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
            {
                buf[i]++;
                if (buf[i] != 0) break;
            }

            /* step 2 */
            EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
            EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL);
            for (i=0; i<SHA_DIGEST_LENGTH; i++)
                md[i]^=buf2[i];

            /* step 3 */
            md[0]|=0x80;
            md[SHA_DIGEST_LENGTH-1]|=0x01;
            if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;

            /* step 4 */
            r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
                                        seed_is_random, cb);
            if (r > 0)
                break;
            if (r != 0)
                goto err;

            /* do a callback call */
            /* step 5 */
        }

        if(!BN_GENCB_call(cb, 2, 0)) goto err;
        if(!BN_GENCB_call(cb, 3, 0)) goto err;

        /* step 6 */
        counter=0;
        /* "offset = 2" */

        n=(bits-1)/160;
        b=(bits-1)-n*160;

        for (;;)
        {
            if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
                goto err;

            /* step 7 */
            BN_zero(W);
            /* now 'buf' contains "SEED + offset - 1" */
            for (k=0; k<=n; k++)
            {
                /* obtain "SEED + offset + k" by incrementing: */
                for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
                {
                    buf[i]++;
                    if (buf[i] != 0) break;
                }

                EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);

                /* step 8 */
                if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0))
                    goto err;
                if (!BN_lshift(r0,r0,160*k)) goto err;
                if (!BN_add(W,W,r0)) goto err;
            }

            /* more of step 8 */
            if (!BN_mask_bits(W,bits-1)) goto err;
            if (!BN_copy(X,W)) goto err;
            if (!BN_add(X,X,test)) goto err;

            /* step 9 */
            if (!BN_lshift1(r0,q)) goto err;
            if (!BN_mod(c,X,r0,ctx)) goto err;
            if (!BN_sub(r0,c,BN_value_one())) goto err;
            if (!BN_sub(p,X,r0)) goto err;

            /* step 10 */
            if (BN_cmp(p,test) >= 0)
            {
                /* step 11 */
                r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
                                            ctx, 1, cb);
                if (r > 0)
                    goto end; /* found it */
                if (r != 0)
                    goto err;
            }

            /* step 13 */
            counter++;
            /* "offset = offset + n + 1" */

            /* step 14 */
            if (counter >= 4096) break;
        }
    }
end:
    if(!BN_GENCB_call(cb, 2, 1))
        goto err;

    /* We now need to generate g */
    /* Set r0=(p-1)/q */
    if (!BN_sub(test,p,BN_value_one())) goto err;
    if (!BN_div(r0,NULL,test,q,ctx)) goto err;

    if (!BN_set_word(test,h)) goto err;
    if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;

    for (;;)
    {
        /* g=test^r0%p */
        if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
        if (!BN_is_one(g)) break;
        if (!BN_add(test,test,BN_value_one())) goto err;
        h++;
    }

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

    ok=1;
err:
    if (ok)
    {
        if(ret->p) BN_free(ret->p);
        if(ret->q) BN_free(ret->q);
        if(ret->g) BN_free(ret->g);
        ret->p=BN_dup(p);
        ret->q=BN_dup(q);
        ret->g=BN_dup(g);
        if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
        {
            ok=0;
            goto err;
        }
        if (seed_in != NULL) memcpy(seed_in,seed,20);
        if (counter_ret != NULL) *counter_ret=counter;
        if (h_ret != NULL) *h_ret=h;
    }
    if(ctx)
    {
        BN_CTX_end(ctx);
        BN_CTX_free(ctx);
    }
    if (mont != NULL) BN_MONT_CTX_free(mont);
    return ok;
}
Beispiel #15
0
int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
		int do_trial_division, BN_GENCB *cb)
	{
	int i, j, ret = -1;
	int k;
	BN_CTX *ctx = NULL;
	BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
	BN_MONT_CTX *mont = NULL;
	const BIGNUM *A = NULL;

	if (BN_cmp(a, BN_value_one()) <= 0)
		return 0;
	
	if (checks == BN_prime_checks)
		checks = BN_prime_checks_for_size(BN_num_bits(a));

	/* first look for small factors */
	if (!BN_is_odd(a))
		/* a is even => a is prime if and only if a == 2 */
		return BN_is_word(a, 2);
	if (do_trial_division)
		{
		for (i = 1; i < NUMPRIMES; i++)
			if (BN_mod_word(a, primes[i]) == 0) 
				return 0;
		if(!BN_GENCB_call(cb, 1, -1))
			goto err;
		}

	if (ctx_passed != NULL)
		ctx = ctx_passed;
	else
		if ((ctx=BN_CTX_new()) == NULL)
			goto err;
	BN_CTX_start(ctx);

	/* A := abs(a) */
	if (a->neg)
		{
		BIGNUM *t;
		if ((t = BN_CTX_get(ctx)) == NULL) goto err;
		BN_copy(t, a);
		t->neg = 0;
		A = t;
		}
	else
		A = a;
	A1 = BN_CTX_get(ctx);
	A1_odd = BN_CTX_get(ctx);
	check = BN_CTX_get(ctx);
	if (check == NULL) goto err;

	/* compute A1 := A - 1 */
	if (!BN_copy(A1, A))
		goto err;
	if (!BN_sub_word(A1, 1))
		goto err;
	if (BN_is_zero(A1))
		{
		ret = 0;
		goto err;
		}

	/* write  A1  as  A1_odd * 2^k */
	k = 1;
	while (!BN_is_bit_set(A1, k))
		k++;
	if (!BN_rshift(A1_odd, A1, k))
		goto err;

	/* Montgomery setup for computations mod A */
	mont = BN_MONT_CTX_new();
	if (mont == NULL)
		goto err;
	if (!BN_MONT_CTX_set(mont, A, ctx))
		goto err;
	
	for (i = 0; i < checks; i++)
		{
		if (!BN_pseudo_rand_range(check, A1))
			goto err;
		if (!BN_add_word(check, 1))
			goto err;
		/* now 1 <= check < A */

		j = witness(check, A, A1, A1_odd, k, ctx, mont);
		if (j == -1) goto err;
		if (j)
			{
			ret=0;
			goto err;
			}
		if(!BN_GENCB_call(cb, 1, i))
			goto err;
		}
	ret=1;
err:
	if (ctx != NULL)
		{
		BN_CTX_end(ctx);
		if (ctx_passed == NULL)
			BN_CTX_free(ctx);
		}
	if (mont != NULL)
		BN_MONT_CTX_free(mont);

	return(ret);
	}
Beispiel #16
0
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;
}
Beispiel #17
0
int
BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, const BIGNUM *Xp,
    const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
    BN_GENCB *cb)
{
	int ret = 0;

	BIGNUM *t, *p1p2, *pm1;

	/* Only even e supported */
	if (!BN_is_odd(e))
		return 0;

	BN_CTX_start(ctx);
	if (p1 == NULL) {
		if ((p1 = BN_CTX_get(ctx)) == NULL)
			goto err;
	}
	if (p2 == NULL) {
		if ((p2 = BN_CTX_get(ctx)) == NULL)
			goto err;
	}

	if ((t = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((p1p2 = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((pm1 = BN_CTX_get(ctx)) == NULL)
		goto err;

	if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
		goto err;

	if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
		goto err;

	if (!BN_mul(p1p2, p1, p2, ctx))
		goto err;

	/* First set p to value of Rp */

	if (!BN_mod_inverse(p, p2, p1, ctx))
		goto err;

	if (!BN_mul(p, p, p2, ctx))
		goto err;

	if (!BN_mod_inverse(t, p1, p2, ctx))
		goto err;

	if (!BN_mul(t, t, p1, ctx))
		goto err;

	if (!BN_sub(p, p, t))
		goto err;

	if (p->neg && !BN_add(p, p, p1p2))
		goto err;

	/* p now equals Rp */

	if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
		goto err;

	if (!BN_add(p, p, Xp))
		goto err;

	/* p now equals Yp0 */

	for (;;) {
		int i = 1;
		BN_GENCB_call(cb, 0, i++);
		if (!BN_copy(pm1, p))
			goto err;
		if (!BN_sub_word(pm1, 1))
			goto err;
		if (!BN_gcd(t, pm1, e, ctx))
			goto err;
		if (BN_is_one(t)
		/* X9.31 specifies 8 MR and 1 Lucas test or any prime test
		 * offering similar or better guarantees 50 MR is considerably
		 * better.
		 */
		    && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
			break;
		if (!BN_add(p, p, p1p2))
			goto err;
	}

	BN_GENCB_call(cb, 3, 0);

	ret = 1;

err:

	BN_CTX_end(ctx);

	return ret;
}
Beispiel #18
0
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
                         const BIGNUM *rem, BN_GENCB *cb) {
  BIGNUM *t;
  int found = 0;
  int i, j, c1 = 0;
  BN_CTX *ctx;
  int checks = BN_prime_checks_for_size(bits);

  if (bits < 2) {
    /* There are no prime numbers this small. */
    OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
    return 0;
  } else if (bits == 2 && safe) {
    /* The smallest safe prime (7) is three bits. */
    OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
    return 0;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }
  BN_CTX_start(ctx);
  t = BN_CTX_get(ctx);
  if (!t) {
    goto err;
  }

loop:
  /* make a random number and set the top and bottom bits */
  if (add == NULL) {
    if (!probable_prime(ret, bits)) {
      goto err;
    }
  } else {
    if (safe) {
      if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) {
        goto err;
      }
    } else {
      if (!probable_prime_dh(ret, bits, add, rem, ctx)) {
        goto err;
      }
    }
  }

  if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) {
    /* aborted */
    goto err;
  }

  if (!safe) {
    i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
    if (i == -1) {
      goto err;
    } else if (i == 0) {
      goto loop;
    }
  } else {
    /* for "safe prime" generation, check that (p-1)/2 is prime. Since a prime
     * is odd, We just need to divide by 2 */
    if (!BN_rshift1(t, ret)) {
      goto err;
    }

    for (i = 0; i < checks; i++) {
      j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, NULL);
      if (j == -1) {
        goto err;
      } else if (j == 0) {
        goto loop;
      }

      j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL);
      if (j == -1) {
        goto err;
      } else if (j == 0) {
        goto loop;
      }

      if (!BN_GENCB_call(cb, i, c1 - 1)) {
        goto err;
      }
      /* We have a safe prime test pass */
    }
  }

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

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }

  return found;
}
Beispiel #19
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;
	}
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;
	}
int
dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd,
    const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out,
    int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
{
	int ok = 0;
	unsigned char seed[SHA256_DIGEST_LENGTH];
	unsigned char md[SHA256_DIGEST_LENGTH];
	unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
	BIGNUM *r0, *W, *X, *c, *test;
	BIGNUM *g = NULL, *q = NULL, *p = NULL;
	BN_MONT_CTX *mont = NULL;
	int i, k, n = 0, m = 0, qsize = qbits >> 3;
	int counter = 0;
	int r = 0;
	BN_CTX *ctx = NULL;
	unsigned int h = 2;

	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
	    qsize != SHA256_DIGEST_LENGTH)
		/* invalid q size */
		return 0;

	if (evpmd == NULL)
		/* use SHA1 as default */
		evpmd = EVP_sha1();

	if (bits < 512)
		bits = 512;

	bits = (bits + 63) / 64 * 64;

	/*
	 * NB: seed_len == 0 is special case: copy generated seed to
 	 * seed_in if it is not NULL.
 	 */
	if (seed_len && seed_len < (size_t)qsize)
		seed_in = NULL;		/* seed buffer too small -- ignore */
	/*
	 * App. 2.2 of FIPS PUB 186 allows larger SEED,
	 * but our internal buffers are restricted to 160 bits
	 */
	if (seed_len > (size_t)qsize) 
		seed_len = qsize;
	if (seed_in != NULL)
		memcpy(seed, seed_in, seed_len);

	if ((ctx=BN_CTX_new()) == NULL)
		goto err;

	if ((mont=BN_MONT_CTX_new()) == NULL)
		goto err;

	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	g = BN_CTX_get(ctx);
	W = BN_CTX_get(ctx);
	q = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	c = BN_CTX_get(ctx);
	p = BN_CTX_get(ctx);
	test = BN_CTX_get(ctx);

	if (!BN_lshift(test, BN_value_one(), bits - 1))
		goto err;

	for (;;) {
		for (;;) { /* find q */
			int seed_is_random;

			/* step 1 */
			if (!BN_GENCB_call(cb, 0, m++))
				goto err;

			if (!seed_len) {
				RAND_pseudo_bytes(seed, qsize);
				seed_is_random = 1;
			} else {
				seed_is_random = 0;
				/* use random seed if 'seed_in' turns out
				   to be bad */
				seed_len = 0;
			}
			memcpy(buf, seed, qsize);
			memcpy(buf2, seed, qsize);
			/* precompute "SEED + 1" for step 7: */
			for (i = qsize - 1; i >= 0; i--) {
				buf[i]++;
				if (buf[i] != 0)
					break;
			}

			/* step 2 */
			if (!EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL))
				goto err;
			if (!EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL))
				goto err;
			for (i = 0; i < qsize; i++)
				md[i] ^= buf2[i];

			/* step 3 */
			md[0] |= 0x80;
			md[qsize - 1] |= 0x01;
			if (!BN_bin2bn(md, qsize, q))
				goto err;

			/* step 4 */
			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
			    seed_is_random, cb);
			if (r > 0)
				break;
			if (r != 0)
				goto err;

			/* do a callback call */
			/* step 5 */
		}

		if (!BN_GENCB_call(cb, 2, 0))
			goto err;
		if (!BN_GENCB_call(cb, 3, 0))
			goto err;

		/* step 6 */
		counter = 0;
		/* "offset = 2" */

		n = (bits - 1) / 160;

		for (;;) {
			if (counter != 0 && !BN_GENCB_call(cb, 0, counter))
				goto err;

			/* step 7 */
			BN_zero(W);
			/* now 'buf' contains "SEED + offset - 1" */
			for (k = 0; k <= n; k++) {
				/* obtain "SEED + offset + k" by incrementing: */
				for (i = qsize - 1; i >= 0; i--) {
					buf[i]++;
					if (buf[i] != 0)
						break;
				}

				if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
				    NULL))
					goto err;

				/* step 8 */
				if (!BN_bin2bn(md, qsize, r0))
					goto err;
				if (!BN_lshift(r0, r0, (qsize << 3) * k))
					goto err;
				if (!BN_add(W, W, r0))
					goto err;
			}

			/* more of step 8 */
			if (!BN_mask_bits(W, bits - 1))
				goto err;
			if (!BN_copy(X, W))
				goto err;
			if (!BN_add(X, X, test))
				goto err;

			/* step 9 */
			if (!BN_lshift1(r0, q))
				goto err;
			if (!BN_mod(c, X, r0, ctx))
				goto err;
			if (!BN_sub(r0, c, BN_value_one()))
				goto err;
			if (!BN_sub(p, X, r0))
				goto err;

			/* step 10 */
			if (BN_cmp(p, test) >= 0) {
				/* step 11 */
				r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
				    ctx, 1, cb);
				if (r > 0)
					goto end; /* found it */
				if (r != 0)
					goto err;
			}

			/* step 13 */
			counter++;
			/* "offset = offset + n + 1" */

			/* step 14 */
			if (counter >= 4096)
				break;
		}
	}
end:
	if (!BN_GENCB_call(cb, 2, 1))
		goto err;

	/* We now need to generate g */
	/* Set r0=(p-1)/q */
	if (!BN_sub(test, p, BN_value_one()))
		goto err;
	if (!BN_div(r0, NULL, test, q, ctx))
		goto err;

	if (!BN_set_word(test, h))
		goto err;
	if (!BN_MONT_CTX_set(mont, p, ctx))
		goto err;

	for (;;) {
		/* g=test^r0%p */
		if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
			goto err;
		if (!BN_is_one(g))
			break;
		if (!BN_add(test, test, BN_value_one()))
			goto err;
		h++;
	}

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

	ok = 1;
err:
	if (ok) {
		if (ret->p)
			BN_free(ret->p);
		if (ret->q)
			BN_free(ret->q);
		if (ret->g)
			BN_free(ret->g);
		ret->p = BN_dup(p);
		ret->q = BN_dup(q);
		ret->g = BN_dup(g);
		if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
			ok = 0;
			goto err;
		}
		if (counter_ret != NULL)
			*counter_ret = counter;
		if (h_ret != NULL)
			*h_ret = h;
		if (seed_out)
			memcpy(seed_out, seed, qsize);
	}
	if (ctx) {
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
	}
	if (mont != NULL)
		BN_MONT_CTX_free(mont);
	return ok;
}
Beispiel #22
0
static int
gmp_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
{
    mpz_t el, p, q, n, d, dmp1, dmq1, iqmp, t1, t2, t3;
    int counter, ret;

    if (bits < 789)
	return -1;

    ret = -1;

    mpz_init(el);
    mpz_init(p);
    mpz_init(q);
    mpz_init(n);
    mpz_init(d);
    mpz_init(dmp1);
    mpz_init(dmq1);
    mpz_init(iqmp);
    mpz_init(t1);
    mpz_init(t2);
    mpz_init(t3);

    BN2mpz(el, e);

    /* generate p and q so that p != q and bits(pq) ~ bits */

    counter = 0;
    do {
	BN_GENCB_call(cb, 2, counter++);
	random_num(p, bits / 2 + 1);
	mpz_nextprime(p, p);

	mpz_sub_ui(t1, p, 1);
	mpz_gcd(t2, t1, el);
    } while(mpz_cmp_ui(t2, 1) != 0);

    BN_GENCB_call(cb, 3, 0);

    counter = 0;
    do {
	BN_GENCB_call(cb, 2, counter++);
	random_num(q, bits / 2 + 1);
	mpz_nextprime(q, q);

	mpz_sub_ui(t1, q, 1);
	mpz_gcd(t2, t1, el);
    } while(mpz_cmp_ui(t2, 1) != 0);

    /* make p > q */
    if (mpz_cmp(p, q) < 0)
	mpz_swap(p, q);

    BN_GENCB_call(cb, 3, 1);

    /* calculate n,  		n = p * q */
    mpz_mul(n, p, q);

    /* calculate d, 		d = 1/e mod (p - 1)(q - 1) */
    mpz_sub_ui(t1, p, 1);
    mpz_sub_ui(t2, q, 1);
    mpz_mul(t3, t1, t2);
    mpz_invert(d, el, t3);

    /* calculate dmp1		dmp1 = d mod (p-1) */
    mpz_mod(dmp1, d, t1);
    /* calculate dmq1		dmq1 = d mod (q-1) */
    mpz_mod(dmq1, d, t2);
    /* calculate iqmp 		iqmp = 1/q mod p */
    mpz_invert(iqmp, q, p);

    /* fill in RSA key */

    rsa->e = mpz2BN(el);
    rsa->p = mpz2BN(p);
    rsa->q = mpz2BN(q);
    rsa->n = mpz2BN(n);
    rsa->d = mpz2BN(d);
    rsa->dmp1 = mpz2BN(dmp1);
    rsa->dmq1 = mpz2BN(dmq1);
    rsa->iqmp = mpz2BN(iqmp);

    ret = 1;

    mpz_clear(el);
    mpz_clear(p);
    mpz_clear(q);
    mpz_clear(n);
    mpz_clear(d);
    mpz_clear(dmp1);
    mpz_clear(dmq1);
    mpz_clear(iqmp);
    mpz_clear(t1);
    mpz_clear(t2);
    mpz_clear(t3);

    return ret;
}