Пример #1
0
CHECK_RETVAL_BOOL \
static BOOLEAN selfTestGeneralOps1( void )
	{
	BIGNUM a;

	/* Simple tests that don't need the support of higher-level routines 
	   like importBignum() */
	BN_init( &a );
	if( !BN_zero( &a ) )
		return( FALSE );
	if( !BN_is_zero( &a ) || BN_is_one( &a ) )
		return( FALSE );
	if( !BN_is_word( &a, 0 ) || BN_is_word( &a, 1 ) )
		return( FALSE );
	if( BN_is_odd( &a ) )
		return( FALSE );
	if( BN_get_word( &a ) != 0 )
		return( FALSE );
	if( !BN_one( &a ) )
		return( FALSE );
	if( BN_is_zero( &a ) || !BN_is_one( &a ) )
		return( FALSE );
	if( BN_is_word( &a, 0 ) || !BN_is_word( &a, 1 ) )
		return( FALSE );
	if( !BN_is_odd( &a ) )
		return( FALSE );
	if( BN_num_bytes( &a ) != 1 )
		return( FALSE );
	if( BN_get_word( &a ) != 1 )
		return( FALSE );
	BN_clear( &a );

	return( TRUE );
	}
Пример #2
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;
}
Пример #3
0
int DH_check(const DH *dh, int *ret)
{
    int ok = 0;
    BN_CTX *ctx = NULL;
    BN_ULONG l;
    BIGNUM *q = NULL;

    *ret = 0;
    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;
    q = BN_new();
    if (q == NULL)
        goto err;

    if (BN_is_word(dh->g, DH_GENERATOR_2)) {
        l = BN_mod_word(dh->p, 24);
        if (l != 11)
            *ret |= DH_NOT_SUITABLE_GENERATOR;
    }
# if 0
    else if (BN_is_word(dh->g, DH_GENERATOR_3)) {
        l = BN_mod_word(dh->p, 12);
        if (l != 5)
            *ret |= DH_NOT_SUITABLE_GENERATOR;
    }
# endif
    else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
        l = BN_mod_word(dh->p, 10);
        if ((l != 3) && (l != 7))
            *ret |= DH_NOT_SUITABLE_GENERATOR;
    } else
        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;

    if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
        *ret |= DH_CHECK_P_NOT_PRIME;
    else {
        if (!BN_rshift1(q, dh->p))
            goto err;
        if (!BN_is_prime_ex(q, BN_prime_checks, ctx, NULL))
            *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
    }
    ok = 1;
 err:
    if (ctx != NULL)
        BN_CTX_free(ctx);
    if (q != NULL)
        BN_free(q);
    return (ok);
}
Пример #4
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;
}
Пример #5
0
BIGNUM *BN_mod_inverse(BIGNUM *in,
	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
	{
	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
	BIGNUM *ret=NULL;
	int sign;

	if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
		{
		return BN_mod_inverse_no_branch(in, a, n, ctx);
		}

	bn_check_top(a);
	bn_check_top(n);

	BN_CTX_start(ctx);
	A = BN_CTX_get(ctx);
	B = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	D = BN_CTX_get(ctx);
	M = BN_CTX_get(ctx);
	Y = BN_CTX_get(ctx);
	T = BN_CTX_get(ctx);
	if (T == NULL) goto err;

	if (in == NULL)
		R=BN_new();
	else
		R=in;
	if (R == NULL) goto err;

	BN_one(X);
	BN_zero(Y);
	if (BN_copy(B,a) == NULL) goto err;
	if (BN_copy(A,n) == NULL) goto err;
	A->neg = 0;
	if (B->neg || (BN_ucmp(B, A) >= 0))
		{
		if (!BN_nnmod(B, B, A, ctx)) goto err;
		}
	sign = -1;
	/* From  B = a mod |n|,  A = |n|  it follows that
	 *
	 *      0 <= B < A,
	 *     -sign*X*a  ==  B   (mod |n|),
	 *      sign*Y*a  ==  A   (mod |n|).
	 */

	if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
		{
		/* Binary inversion algorithm; requires odd modulus.
		 * This is faster than the general algorithm if the modulus
		 * is sufficiently small (about 400 .. 500 bits on 32-bit
		 * sytems, but much more on 64-bit systems) */
		int shift;
		
		while (!BN_is_zero(B))
			{
			/*
			 *      0 < B < |n|,
			 *      0 < A <= |n|,
			 * (1) -sign*X*a  ==  B   (mod |n|),
			 * (2)  sign*Y*a  ==  A   (mod |n|)
			 */

			/* Now divide  B  by the maximum possible power of two in the integers,
			 * and divide  X  by the same value mod |n|.
			 * When we're done, (1) still holds. */
			shift = 0;
			while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
				{
				shift++;
				
				if (BN_is_odd(X))
					{
					if (!BN_uadd(X, X, n)) goto err;
					}
				/* now X is even, so we can easily divide it by two */
				if (!BN_rshift1(X, X)) goto err;
				}
			if (shift > 0)
				{
				if (!BN_rshift(B, B, shift)) goto err;
				}


			/* Same for  A  and  Y.  Afterwards, (2) still holds. */
			shift = 0;
			while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
				{
				shift++;
				
				if (BN_is_odd(Y))
					{
					if (!BN_uadd(Y, Y, n)) goto err;
					}
				/* now Y is even */
				if (!BN_rshift1(Y, Y)) goto err;
				}
			if (shift > 0)
				{
				if (!BN_rshift(A, A, shift)) goto err;
				}

			
			/* We still have (1) and (2).
			 * Both  A  and  B  are odd.
			 * The following computations ensure that
			 *
			 *     0 <= B < |n|,
			 *      0 < A < |n|,
			 * (1) -sign*X*a  ==  B   (mod |n|),
			 * (2)  sign*Y*a  ==  A   (mod |n|),
			 *
			 * and that either  A  or  B  is even in the next iteration.
			 */
			if (BN_ucmp(B, A) >= 0)
				{
				/* -sign*(X + Y)*a == B - A  (mod |n|) */
				if (!BN_uadd(X, X, Y)) goto err;
				/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
				 * actually makes the algorithm slower */
				if (!BN_usub(B, B, A)) goto err;
				}
			else
				{
				/*  sign*(X + Y)*a == A - B  (mod |n|) */
				if (!BN_uadd(Y, Y, X)) goto err;
				/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
				if (!BN_usub(A, A, B)) goto err;
				}
			}
		}
	else
		{
		/* general inversion algorithm */

		while (!BN_is_zero(B))
			{
			BIGNUM *tmp;
			
			/*
			 *      0 < B < A,
			 * (*) -sign*X*a  ==  B   (mod |n|),
			 *      sign*Y*a  ==  A   (mod |n|)
			 */
			
			/* (D, M) := (A/B, A%B) ... */
			if (BN_num_bits(A) == BN_num_bits(B))
				{
				if (!BN_one(D)) goto err;
				if (!BN_sub(M,A,B)) goto err;
				}
			else if (BN_num_bits(A) == BN_num_bits(B) + 1)
				{
				/* A/B is 1, 2, or 3 */
				if (!BN_lshift1(T,B)) goto err;
				if (BN_ucmp(A,T) < 0)
					{
					/* A < 2*B, so D=1 */
					if (!BN_one(D)) goto err;
					if (!BN_sub(M,A,B)) goto err;
					}
				else
					{
					/* A >= 2*B, so D=2 or D=3 */
					if (!BN_sub(M,A,T)) goto err;
					if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
					if (BN_ucmp(A,D) < 0)
						{
						/* A < 3*B, so D=2 */
						if (!BN_set_word(D,2)) goto err;
						/* M (= A - 2*B) already has the correct value */
						}
					else
						{
						/* only D=3 remains */
						if (!BN_set_word(D,3)) goto err;
						/* currently  M = A - 2*B,  but we need  M = A - 3*B */
						if (!BN_sub(M,M,B)) goto err;
						}
					}
				}
			else
				{
				if (!BN_div(D,M,A,B,ctx)) goto err;
				}
			
			/* Now
			 *      A = D*B + M;
			 * thus we have
			 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
			 */
			
			tmp=A; /* keep the BIGNUM object, the value does not matter */
			
			/* (A, B) := (B, A mod B) ... */
			A=B;
			B=M;
			/* ... so we have  0 <= B < A  again */
			
			/* Since the former  M  is now  B  and the former  B  is now  A,
			 * (**) translates into
			 *       sign*Y*a  ==  D*A + B    (mod |n|),
			 * i.e.
			 *       sign*Y*a - D*A  ==  B    (mod |n|).
			 * Similarly, (*) translates into
			 *      -sign*X*a  ==  A          (mod |n|).
			 *
			 * Thus,
			 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
			 * i.e.
			 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
			 *
			 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
			 *      -sign*X*a  ==  B   (mod |n|),
			 *       sign*Y*a  ==  A   (mod |n|).
			 * Note that  X  and  Y  stay non-negative all the time.
			 */
			
			/* most of the time D is very small, so we can optimize tmp := D*X+Y */
			if (BN_is_one(D))
				{
				if (!BN_add(tmp,X,Y)) goto err;
				}
			else
				{
				if (BN_is_word(D,2))
					{
					if (!BN_lshift1(tmp,X)) goto err;
					}
				else if (BN_is_word(D,4))
					{
					if (!BN_lshift(tmp,X,2)) goto err;
					}
				else if (D->top == 1)
					{
					if (!BN_copy(tmp,X)) goto err;
					if (!BN_mul_word(tmp,D->d[0])) goto err;
					}
				else
					{
					if (!BN_mul(tmp,D,X,ctx)) goto err;
					}
				if (!BN_add(tmp,tmp,Y)) goto err;
				}
			
			M=Y; /* keep the BIGNUM object, the value does not matter */
			Y=X;
			X=tmp;
			sign = -sign;
			}
		}
		
	/*
	 * The while loop (Euclid's algorithm) ends when
	 *      A == gcd(a,n);
	 * we have
	 *       sign*Y*a  ==  A  (mod |n|),
	 * where  Y  is non-negative.
	 */

	if (sign < 0)
		{
		if (!BN_sub(Y,n,Y)) goto err;
		}
	/* Now  Y*a  ==  A  (mod |n|).  */
	

	if (BN_is_one(A))
		{
		/* Y*a == 1  (mod |n|) */
		if (!Y->neg && BN_ucmp(Y,n) < 0)
			{
			if (!BN_copy(R,Y)) goto err;
			}
		else
			{
			if (!BN_nnmod(R,Y,n,ctx)) goto err;
			}
		}
	else
		{
		BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
		goto err;
		}
	ret=R;
err:
	if ((ret == NULL) && (in == NULL)) BN_free(R);
	BN_CTX_end(ctx);
	bn_check_top(ret);
	return(ret);
	}
Пример #6
0
int DH_check(const DH *dh, int *ret) {
  /* Check that p is a safe prime and if g is 2, 3 or 5, check that it is a
   * suitable generator where:
   *   for 2, p mod 24 == 11
   *   for 3, p mod 12 == 5
   *   for 5, p mod 10 == 3 or 7
   * should hold.
   */
  int ok = 0, r;
  BN_CTX *ctx = NULL;
  BN_ULONG l;
  BIGNUM *t1 = NULL, *t2 = NULL;

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

  if (dh->q) {
    if (BN_cmp(dh->g, BN_value_one()) <= 0) {
      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
    } else if (BN_cmp(dh->g, dh->p) >= 0) {
      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
    } else {
      /* Check g^q == 1 mod p */
      if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx)) {
        goto err;
      }
      if (!BN_is_one(t1)) {
        *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
      }
    }
    r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL);
    if (r < 0) {
      goto err;
    }
    if (!r) {
      *ret |= DH_CHECK_Q_NOT_PRIME;
    }
    /* Check p == 1 mod q  i.e. q divides p - 1 */
    if (!BN_div(t1, t2, dh->p, dh->q, ctx)) {
      goto err;
    }
    if (!BN_is_one(t2)) {
      *ret |= DH_CHECK_INVALID_Q_VALUE;
    }
    if (dh->j && BN_cmp(dh->j, t1)) {
      *ret |= DH_CHECK_INVALID_J_VALUE;
    }
  } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
    l = BN_mod_word(dh->p, 24);
    if (l == (BN_ULONG)-1) {
      goto err;
    }
    if (l != 11) {
      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
    }
  } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
    l = BN_mod_word(dh->p, 10);
    if (l == (BN_ULONG)-1) {
      goto err;
    }
    if (l != 3 && l != 7) {
      *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
    }
  } else {
    *ret |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR;
  }

  r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL);
  if (r < 0) {
    goto err;
  }
  if (!r) {
    *ret |= DH_CHECK_P_NOT_PRIME;
  } else if (!dh->q) {
    if (!BN_rshift1(t1, dh->p)) {
      goto err;
    }
    r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL);
    if (r < 0) {
      goto err;
    }
    if (!r) {
      *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
    }
  }
  ok = 1;

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  return ok;
}
Пример #7
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);
	}
Пример #8
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;
}
Пример #9
0
/* create a new key.  we need a way to specify creation of a key with OAEP
 * padding as well as PKCSv1.5, since signatures will need to be done on
 * data larger than 20 bytes, which is the max size *regardless of key size*
 * for an OAEP key signing using the TPM */
static int tpm_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
{
	TSS_RESULT result;
	TSS_FLAG initFlags = TSS_KEY_TYPE_LEGACY;
	UINT32 encScheme, sigScheme;
	TSS_HKEY hKey;

	/* XXX allow this to be specified through pre commands */
	sigScheme = TSS_SS_RSASSAPKCS1V15_DER;
	encScheme = TSS_ES_RSAESPKCSV15;

	DBG("%s", __FUNCTION__);

	if (!BN_is_word(e, 65537)) {
		TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_INVALID_EXPONENT);
		return 0;
	}

	/* set e in the RSA object as done in the built-in openssl function */
	if (!rsa->e && ((rsa->e = BN_new()) == NULL)) {
		TSSerr(TPM_F_TPM_RSA_KEYGEN, ERR_R_MALLOC_FAILURE);
		return 0;
	}
	BN_copy(rsa->e, e);

	switch (bits) {
		case 512:
			initFlags |= TSS_KEY_SIZE_512;
			break;
		case 1024:
			initFlags |= TSS_KEY_SIZE_1024;
			break;
		case 2048:
			initFlags |= TSS_KEY_SIZE_2048;
			break;
		case 4096:
			initFlags |= TSS_KEY_SIZE_4096;
			break;
		case 8192:
			initFlags |= TSS_KEY_SIZE_8192;
			break;
		case 16384:
			initFlags |= TSS_KEY_SIZE_16384;
			break;
		default:
			TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_INVALID_KEY_SIZE);
			return 0;
	}

	/* Load the parent key (SRK) which will wrap the new key */
	if (!tpm_load_srk(NULL, NULL)) {
		TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_SRK_LOAD_FAILED);
		return 0;
	}

	/* Create the new key object */
	if ((result = Tspi_Context_CreateObject(hContext,
						  TSS_OBJECT_TYPE_RSAKEY,
						  initFlags, &hKey))) {
		TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_REQUEST_FAILED);
		return 0;
	}

	/* set the signature scheme */
	if ((result = Tspi_SetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
					     TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
					     sigScheme))) {
		Tspi_Context_CloseObject(hContext, hKey);
		TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_REQUEST_FAILED);
		return 0;
	}

	/* set the encryption scheme */
	if ((result = Tspi_SetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
					     TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
					     encScheme))) {
		Tspi_Context_CloseObject(hContext, hKey);
		TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_REQUEST_FAILED);
		return 0;
	}

	/* Call create key using the new object */
	if ((result = Tspi_Key_CreateKey(hKey, hSRK, NULL_HPCRS))) {
		Tspi_Context_CloseObject(hContext, hKey);
		TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_REQUEST_FAILED);
		return 0;
	}

	if (!fill_out_rsa_object(rsa, hKey)) {
		Tspi_Context_CloseObject(hContext, hKey);
		TSSerr(TPM_F_TPM_RSA_KEYGEN, TPM_R_REQUEST_FAILED);
		return 0;
	}

	/* Load the key into the chip so other functions don't need to */
	if ((result = Tspi_Key_LoadKey(hKey, hSRK))) {
		Tspi_Context_CloseObject(hContext, hKey);
		TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED);
		return 0;
	}

	return 1;
}
Пример #10
0
soter_status_t soter_engine_specific_to_rsa_priv_key(const soter_engine_specific_rsa_key_t *engine_key, soter_container_hdr_t *key, size_t* key_length)
{
	EVP_PKEY *pkey = (EVP_PKEY *)engine_key;
	RSA *rsa;
	soter_status_t res;
	int rsa_mod_size;
	size_t output_length;
	uint32_t *pub_exp;
	unsigned char *curr_bn = (unsigned char *)(key + 1);

	if (!key_length)
	{
		return SOTER_INVALID_PARAMETER;
	}

	if (EVP_PKEY_RSA != EVP_PKEY_id(pkey))
	{
		return SOTER_INVALID_PARAMETER;
	}

	rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
	if (NULL == rsa)
	{
		return SOTER_FAIL;
	}

	rsa_mod_size = RSA_size(rsa);
	if (!is_mod_size_supported(rsa_mod_size))
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	output_length = rsa_priv_key_size(rsa_mod_size);
	if ((!key) || (output_length > *key_length))
	{
		*key_length = output_length;
		res = SOTER_BUFFER_TOO_SMALL;
		goto err;
	}

	pub_exp = (uint32_t *)(curr_bn + ((rsa_mod_size * 4) + (rsa_mod_size / 2)));
	if (BN_is_word(rsa->e, RSA_F4))
	{
		*pub_exp = htonl(RSA_F4);
	}
	else if (BN_is_word(rsa->e, RSA_3))
	{
		*pub_exp = htonl(RSA_3);
	}
	else
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	/* Private exponent */
	res = bignum_to_bytes(rsa->d, curr_bn, rsa_mod_size);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size;

	/* p */
	res = bignum_to_bytes(rsa->p, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* q */
	res = bignum_to_bytes(rsa->q, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* dp */
	res = bignum_to_bytes(rsa->dmp1, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* dq */
	res = bignum_to_bytes(rsa->dmq1, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* qp */
	res = bignum_to_bytes(rsa->iqmp, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* modulus */
	res = bignum_to_bytes(rsa->n, curr_bn, rsa_mod_size);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}

	memcpy(key->tag, rsa_priv_key_tag(rsa_mod_size), SOTER_CONTAINER_TAG_LENGTH);
	key->size = htonl(output_length);
	soter_update_container_checksum(key);
	*key_length = output_length;
	res = SOTER_SUCCESS;

err:
	/* Free extra reference on RSA object provided by EVP_PKEY_get1_RSA */
	RSA_free(rsa);

//	if (SOTER_SUCCESS != res)
//	{
//		/* Zero output memory to avoid leaking private key information */
//		memset(key, 0, *key_length);
//	}

	return res;
}
Пример #11
0
soter_status_t soter_engine_specific_to_rsa_pub_key(const soter_engine_specific_rsa_key_t *engine_key, soter_container_hdr_t *key, size_t* key_length)
{
	EVP_PKEY *pkey = (EVP_PKEY *)engine_key;
	RSA *rsa;
	soter_status_t res;
	int rsa_mod_size;
	size_t output_length;
	uint32_t *pub_exp;

	if (!key_length)
	{
		return SOTER_INVALID_PARAMETER;
	}

	if (EVP_PKEY_RSA != EVP_PKEY_id(pkey))
	{
		return SOTER_INVALID_PARAMETER;
	}

	rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
	if (NULL == rsa)
	{
		return SOTER_FAIL;
	}

	rsa_mod_size = RSA_size(rsa);
	if (!is_mod_size_supported(rsa_mod_size))
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	output_length = rsa_pub_key_size(rsa_mod_size);
	if ((!key) || (output_length > *key_length))
	{
		*key_length = output_length;
		res = SOTER_BUFFER_TOO_SMALL;
		goto err;
	}

	pub_exp = (uint32_t *)((unsigned char *)(key + 1) + rsa_mod_size);
	if (BN_is_word(rsa->e, RSA_F4))
	{
		*pub_exp = htonl(RSA_F4);
	}
	else if (BN_is_word(rsa->e, RSA_3))
	{
		*pub_exp = htonl(RSA_3);
	}
	else
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	res = bignum_to_bytes(rsa->n, (unsigned char *)(key + 1), rsa_mod_size);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}

	memcpy(key->tag, rsa_pub_key_tag(rsa_mod_size), SOTER_CONTAINER_TAG_LENGTH);
	key->size = htonl(output_length);
	soter_update_container_checksum(key);
	*key_length = output_length;
	res = SOTER_SUCCESS;

err:
	/* Free extra reference on RSA object provided by EVP_PKEY_get1_RSA */
	RSA_free(rsa);

	return res;
}
Пример #12
0
int test_kron(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*b,*r,*t;
	int i;
	int legendre, kronecker;
	int ret = 0;

	a = BN_new();
	b = BN_new();
	r = BN_new();
	t = BN_new();
	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
	
	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
	 * So we generate a random prime  b  and compare these values
	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
	 * primality test to confirm that  b  is prime, except that we
	 * don't want to test whether  b  is prime but whether BN_kronecker
	 * works.) */

	if (!BN_generate_prime(b, 512, 0, NULL, NULL, genprime_cb, NULL)) goto err;
	b->neg = rand_neg();
	putc('\n', stderr);

	for (i = 0; i < num0; i++)
		{
		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
		a->neg = rand_neg();

		/* t := (|b|-1)/2  (note that b is odd) */
		if (!BN_copy(t, b)) goto err;
		t->neg = 0;
		if (!BN_sub_word(t, 1)) goto err;
		if (!BN_rshift1(t, t)) goto err;
		/* r := a^t mod b */
		b->neg=0;
		
		if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
		b->neg=1;

		if (BN_is_word(r, 1))
			legendre = 1;
		else if (BN_is_zero(r))
			legendre = 0;
		else
			{
			if (!BN_add_word(r, 1)) goto err;
			if (0 != BN_ucmp(r, b))
				{
				fprintf(stderr, "Legendre symbol computation failed\n");
				goto err;
				}
			legendre = -1;
			}
		
		kronecker = BN_kronecker(a, b, ctx);
		if (kronecker < -1) goto err;
		/* we actually need BN_kronecker(a, |b|) */
		if (a->neg && b->neg)
			kronecker = -kronecker;
		
		if (legendre != kronecker)
			{
			fprintf(stderr, "legendre != kronecker; a = ");
			BN_print_fp(stderr, a);
			fprintf(stderr, ", b = ");
			BN_print_fp(stderr, b);
			fprintf(stderr, "\n");
			goto err;
			}

		putc('.', stderr);
		fflush(stderr);
		}

	putc('\n', stderr);
	fflush(stderr);
	ret = 1;
 err:
	if (a != NULL) BN_free(a);
	if (b != NULL) BN_free(b);
	if (r != NULL) BN_free(r);
	if (t != NULL) BN_free(t);
	return ret;
	}
Пример #13
0
int DH_check(const DH *dh, int *ret)
{
    int ok = 0;
    BN_CTX *ctx = NULL;
    BN_ULONG l;
    BIGNUM *t1 = NULL, *t2 = NULL;

    *ret = 0;
    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;
    BN_CTX_start(ctx);
    t1 = BN_CTX_get(ctx);
    if (t1 == NULL)
        goto err;
    t2 = BN_CTX_get(ctx);
    if (t2 == NULL)
        goto err;

    if (dh->q) {
        if (BN_cmp(dh->g, BN_value_one()) <= 0)
            *ret |= DH_NOT_SUITABLE_GENERATOR;
        else if (BN_cmp(dh->g, dh->p) >= 0)
            *ret |= DH_NOT_SUITABLE_GENERATOR;
        else {
            /* Check g^q == 1 mod p */
            if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
                goto err;
            if (!BN_is_one(t1))
                *ret |= DH_NOT_SUITABLE_GENERATOR;
        }
        if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL))
            *ret |= DH_CHECK_Q_NOT_PRIME;
        /* Check p == 1 mod q  i.e. q divides p - 1 */
        if (!BN_div(t1, t2, dh->p, dh->q, ctx))
            goto err;
        if (!BN_is_one(t2))
            *ret |= DH_CHECK_INVALID_Q_VALUE;
        if (dh->j && BN_cmp(dh->j, t1))
            *ret |= DH_CHECK_INVALID_J_VALUE;

    } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
        l = BN_mod_word(dh->p, 24);
        if (l != 11)
            *ret |= DH_NOT_SUITABLE_GENERATOR;
    }
#if 0
    else if (BN_is_word(dh->g, DH_GENERATOR_3)) {
        l = BN_mod_word(dh->p, 12);
        if (l != 5)
            *ret |= DH_NOT_SUITABLE_GENERATOR;
    }
#endif
    else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
        l = BN_mod_word(dh->p, 10);
        if ((l != 3) && (l != 7))
            *ret |= DH_NOT_SUITABLE_GENERATOR;
    } else
        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;

    if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
        *ret |= DH_CHECK_P_NOT_PRIME;
    else if (!dh->q) {
        if (!BN_rshift1(t1, dh->p))
            goto err;
        if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL))
            *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
    }
    ok = 1;
 err:
    if (ctx != NULL) {
        BN_CTX_end(ctx);
        BN_CTX_free(ctx);
    }
    return (ok);
}
Пример #14
0
CHECK_RETVAL_BOOL \
static BOOLEAN selfTestGeneralOps2( void )
	{
	BIGNUM a;
	int status;

	/* More complex tests that need higher-level routines like importBignum(),
	   run after the tests of components of importBignum() have concluded */
	BN_init( &a );
#if BN_BITS2 == 64
	status = importBignum( &a, "\x01\x00\x00\x00\x00\x00\x00\x00\x00", 9, 
						   1, 128, NULL, KEYSIZE_CHECK_NONE );
#else
	status = importBignum( &a, "\x01\x00\x00\x00\x00", 5, 1, 128, NULL, 
						   KEYSIZE_CHECK_NONE );
#endif /* 64- vs 32-bit */
	if( cryptStatusError( status ) )
		return( FALSE );
	if( BN_is_zero( &a ) || BN_is_one( &a ) )
		return( FALSE );
	if( BN_is_word( &a, 0 ) || BN_is_word( &a, 1 ) )
		return( FALSE );
	if( BN_is_odd( &a ) )
		return( FALSE );
	if( BN_get_word( &a ) != BN_NAN )
		return( FALSE );
	if( BN_num_bytes( &a ) != ( BN_BITS2 / 8 ) + 1 )
		return( FALSE );
	if( BN_num_bits( &a ) != BN_BITS2 + 1 )
		return( FALSE );
	if( !BN_is_bit_set( &a, BN_BITS2 ) )
		return( FALSE );
	if( BN_is_bit_set( &a, 17 ) || !BN_set_bit( &a, 17 ) || \
		!BN_is_bit_set( &a, 17 ) )
		return( FALSE );
#if BN_BITS2 == 64
	status = importBignum( &a, "\x01\x00\x00\x00\x00\x00\x00\x00\x01", 9, 
						   1, 128, NULL, KEYSIZE_CHECK_NONE );
#else
	status = importBignum( &a,	"\x01\x00\x00\x00\x01", 5, 1, 128, NULL,
						   KEYSIZE_CHECK_NONE );
#endif /* 64- vs 32-bit */
	if( cryptStatusError( status ) )
		return( FALSE );
	if( BN_is_zero( &a ) || BN_is_one( &a ) )
		return( FALSE );
	if( BN_is_word( &a, 0 ) || BN_is_word( &a, 1 ) )
		return( FALSE );
	if( !BN_is_odd( &a ) )
		return( FALSE );
	if( BN_num_bytes( &a ) != ( BN_BITS2 / 8 ) + 1 )
		return( FALSE );
	if( BN_get_word( &a ) != BN_NAN )
		return( FALSE );
	if( BN_num_bits( &a ) != BN_BITS2 + 1 )
		return( FALSE );
	if( !BN_is_bit_set( &a, BN_BITS2 ) )
		return( FALSE );
	if( BN_is_bit_set( &a, BN_BITS2 + 27 ) || \
		!BN_set_bit( &a, BN_BITS2 + 27 ) || \
		!BN_is_bit_set( &a, BN_BITS2 + 27 ) )
		return( FALSE );
	/* Setting a bit off the end of a bignum extends its size, which is why
	   the following value doesn't match the one from a few lines earlier */
	if( BN_num_bytes( &a ) != ( BN_BITS2 / 8 ) + 4 )
		return( FALSE );
	/* The bit index for indexing bits is zero-based (since 1 == 1 << 0) but
	   for counting bits is one-based, which is why the following comparison
	   looks wrong.  Yet another one of OpenSSL's many booby-traps */
	if( BN_num_bits( &a ) != BN_BITS2 + 28 )
		return( FALSE );
	BN_clear( &a );

	return( TRUE );
	}