Beispiel #1
0
/*
 * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
 * returns one on success. On error it returns zero.
 */
int ec_precompute_mont_data(EC_GROUP *group)
{
    BN_CTX *ctx = BN_CTX_new();
    int ret = 0;

    if (!EC_GROUP_VERSION(group))
        goto err;

    if (group->mont_data) {
        BN_MONT_CTX_free(group->mont_data);
        group->mont_data = NULL;
    }

    if (ctx == NULL)
        goto err;

    group->mont_data = BN_MONT_CTX_new();
    if (!group->mont_data)
        goto err;

    if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) {
        BN_MONT_CTX_free(group->mont_data);
        group->mont_data = NULL;
        goto err;
    }

    ret = 1;

 err:

    if (ctx)
        BN_CTX_free(ctx);
    return ret;
}
Beispiel #2
0
static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
	{
	BN_CTX ctx;
	BN_MONT_CTX *mont;
	BIGNUM *tmp;
	int ret= -1;

	BN_CTX_init(&ctx);
	BN_CTX_start(&ctx);
	tmp = BN_CTX_get(&ctx);
	
	if (dh->priv_key == NULL)
		goto err;

	if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
		{
		if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
				dh->p,&ctx)) goto err;
		}

	mont=(BN_MONT_CTX *)dh->method_mont_p;
	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key,
				dh->priv_key,dh->p,&ctx,mont))
		goto err;

	ret=BN_bn2bin(tmp,key);
err:
	BN_CTX_end(&ctx);
	BN_CTX_free(&ctx);
	return(ret);
	}
Beispiel #3
0
BN_MONT_CTX *
BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, const BIGNUM *mod,
    BN_CTX *ctx)
{
	int got_write_lock = 0;
	BN_MONT_CTX *ret;

	CRYPTO_r_lock(lock);
	if (!*pmont) {
		CRYPTO_r_unlock(lock);
		CRYPTO_w_lock(lock);
		got_write_lock = 1;

		if (!*pmont) {
			ret = BN_MONT_CTX_new();
			if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
				BN_MONT_CTX_free(ret);
			else
				*pmont = ret;
		}
	}

	ret = *pmont;

	if (got_write_lock)
		CRYPTO_w_unlock(lock);
	else
		CRYPTO_r_unlock(lock);

	return ret;
}
Beispiel #4
0
int 
ec_GFp_mont_group_copy(EC_GROUP * dest, const EC_GROUP * src)
{
	BN_MONT_CTX_free(dest->field_data1);
	dest->field_data1 = NULL;
	BN_clear_free(dest->field_data2);
	dest->field_data2 = NULL;

	if (!ec_GFp_simple_group_copy(dest, src))
		return 0;

	if (src->field_data1 != NULL) {
		dest->field_data1 = BN_MONT_CTX_new();
		if (dest->field_data1 == NULL)
			return 0;
		if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
			goto err;
	}
	if (src->field_data2 != NULL) {
		dest->field_data2 = BN_dup(src->field_data2);
		if (dest->field_data2 == NULL)
			goto err;
	}
	return 1;

 err:
	if (dest->field_data1 != NULL) {
		BN_MONT_CTX_free(dest->field_data1);
		dest->field_data1 = NULL;
	}
	return 0;
}
Beispiel #5
0
/*
 * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
 * returns one on success. On error it returns zero.
 */
static int ec_precompute_mont_data(EC_GROUP *group)
{
    BN_CTX *ctx = BN_CTX_new();
    int ret = 0;

    BN_MONT_CTX_free(group->mont_data);
    group->mont_data = NULL;

    if (ctx == NULL)
        goto err;

    group->mont_data = BN_MONT_CTX_new();
    if (group->mont_data == NULL)
        goto err;

    if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) {
        BN_MONT_CTX_free(group->mont_data);
        group->mont_data = NULL;
        goto err;
    }

    ret = 1;

 err:

    BN_CTX_free(ctx);
    return ret;
}
Beispiel #6
0
static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
	{
	BN_CTX *ctx;
	BIGNUM k,*kinv=NULL,*r=NULL;
	int ret=0;

	if (!dsa->p || !dsa->q || !dsa->g)
		{
		DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
		return 0;
		}
	if (ctx_in == NULL)
		{
		if ((ctx=BN_CTX_new()) == NULL) goto err;
		}
	else
		ctx=ctx_in;

	BN_init(&k);
	if ((r=BN_new()) == NULL) goto err;
	kinv=NULL;

	/* Get random k */
	do
		if (!BN_rand_range(&k, dsa->q)) goto err;
	while (BN_is_zero(&k));

	if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
		{
		if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
				dsa->p,ctx)) goto err;
		}

	/* Compute r = (g^k mod p) mod q */
	if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
		(BN_MONT_CTX *)dsa->method_mont_p)) goto err;
	if (!BN_mod(r,r,dsa->q,ctx)) goto err;

	/* Compute  part of 's = inv(k) (m + xr) mod q' */
	if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;

	if (*kinvp != NULL) BN_clear_free(*kinvp);
	*kinvp=kinv;
	kinv=NULL;
	if (*rp != NULL) BN_clear_free(*rp);
	*rp=r;
	ret=1;
err:
	if (!ret)
		{
		DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
		if (kinv != NULL) BN_clear_free(kinv);
		if (r != NULL) BN_clear_free(r);
		}
	if (ctx_in == NULL) BN_CTX_free(ctx);
	if (kinv != NULL) BN_clear_free(kinv);
	BN_clear_free(&k);
	return(ret);
	}
int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
  BN_MONT_CTX_free(dest->mont);
  dest->mont = NULL;
  BN_clear_free(dest->one);
  dest->one = NULL;

  if (!ec_GFp_simple_group_copy(dest, src)) {
    return 0;
  }

  if (src->mont != NULL) {
    dest->mont = BN_MONT_CTX_new();
    if (dest->mont == NULL) {
      return 0;
    }
    if (!BN_MONT_CTX_copy(dest->mont, src->mont)) {
      goto err;
    }
  }
  if (src->one != NULL) {
    dest->one = BN_dup(src->one);
    if (dest->one == NULL) {
      goto err;
    }
  }

  return 1;

err:
  BN_MONT_CTX_free(dest->mont);
  dest->mont = NULL;
  return 0;
}
Beispiel #8
0
int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
                           const BIGNUM *mod, BN_CTX *bn_ctx) {
  CRYPTO_MUTEX_lock_read(lock);
  BN_MONT_CTX *ctx = *pmont;
  CRYPTO_MUTEX_unlock_read(lock);

  if (ctx) {
    return 1;
  }

  CRYPTO_MUTEX_lock_write(lock);
  ctx = *pmont;
  if (ctx) {
    goto out;
  }

  ctx = BN_MONT_CTX_new();
  if (ctx == NULL) {
    goto out;
  }
  if (!BN_MONT_CTX_set(ctx, mod, bn_ctx)) {
    BN_MONT_CTX_free(ctx);
    ctx = NULL;
    goto out;
  }
  *pmont = ctx;

out:
  CRYPTO_MUTEX_unlock_write(lock);
  return ctx != NULL;
}
Beispiel #9
0
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
    BN_CTX *new_ctx = NULL;
    BN_MONT_CTX *mont = NULL;
    BIGNUM *one = NULL;
    int ret = 0;

    if (group->field_data1 != NULL) {
        BN_MONT_CTX_free(group->field_data1);
        group->field_data1 = NULL;
    }
    if (group->field_data2 != NULL) {
        BN_free(group->field_data2);
        group->field_data2 = NULL;
    }

    if (ctx == NULL) {
        ctx = new_ctx = BN_CTX_new();
        if (ctx == NULL)
            return 0;
    }

    mont = BN_MONT_CTX_new();
    if (mont == NULL)
        goto err;
    if (!BN_MONT_CTX_set(mont, p, ctx)) {
        ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
        goto err;
    }
    one = BN_new();
    if (one == NULL)
        goto err;
    if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
        goto err;

    group->field_data1 = mont;
    mont = NULL;
    group->field_data2 = one;
    one = NULL;

    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);

    if (!ret) {
        BN_MONT_CTX_free(group->field_data1);
        group->field_data1 = NULL;
        BN_free(group->field_data2);
        group->field_data2 = NULL;
    }

 err:
    if (new_ctx != NULL)
        BN_CTX_free(new_ctx);
    if (mont != NULL)
        BN_MONT_CTX_free(mont);
    if (one != NULL)
        BN_free(one);
    return ret;
}
Beispiel #10
0
static int generate_key(DH *dh)
	{
	int ok=0;
	int generate_new_key=0;
	unsigned l;
	BN_CTX *ctx;
	BN_MONT_CTX *mont;
	BIGNUM *pub_key=NULL,*priv_key=NULL;

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

	if (dh->priv_key == NULL)
		{
		priv_key=BN_new();
		if (priv_key == NULL) goto err;
		generate_new_key=1;
		}
	else
		priv_key=dh->priv_key;

	if (dh->pub_key == NULL)
		{
		pub_key=BN_new();
		if (pub_key == NULL) goto err;
		}
	else
		pub_key=dh->pub_key;

	if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
		{
		if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
				dh->p,ctx)) goto err;
		}
	mont=(BN_MONT_CTX *)dh->method_mont_p;

	if (generate_new_key)
		{
		l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
		if (!BN_rand(priv_key, l, 0, 0)) goto err;
		}
	if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, priv_key,dh->p,ctx,mont))
		goto err;
		
	dh->pub_key=pub_key;
	dh->priv_key=priv_key;
	ok=1;
err:
	if (ok != 1)
		DHerr(DH_F_DH_GENERATE_KEY,ERR_R_BN_LIB);

	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
	BN_CTX_free(ctx);
	return(ok);
	}
Beispiel #11
0
static void built_in_curve_scalar_field_monts_init(void) {
  unsigned num_built_in_curves;
  for (num_built_in_curves = 0;; num_built_in_curves++) {
    if (OPENSSL_built_in_curves[num_built_in_curves].nid == NID_undef) {
      break;
    }
  }

  assert(0 < num_built_in_curves);

  built_in_curve_scalar_field_monts =
      OPENSSL_malloc(sizeof(BN_MONT_CTX *) * num_built_in_curves);
  if (built_in_curve_scalar_field_monts == NULL) {
    return;
  }

  BIGNUM *order = BN_new();
  BN_CTX *bn_ctx = BN_CTX_new();
  BN_MONT_CTX *mont_ctx = NULL;

  if (bn_ctx == NULL ||
      order == NULL) {
    goto err;
  }

  unsigned i;
  for (i = 0; i < num_built_in_curves; i++) {
    const struct curve_data *curve = OPENSSL_built_in_curves[i].data;
    const unsigned param_len = curve->param_len;
    const uint8_t *params = curve->data;

    mont_ctx = BN_MONT_CTX_new();
    if (mont_ctx == NULL) {
      goto err;
    }

    if (!BN_bin2bn(params + 5 * param_len, param_len, order) ||
        !BN_MONT_CTX_set(mont_ctx, order, bn_ctx)) {
      goto err;
    }

    built_in_curve_scalar_field_monts[i] = mont_ctx;
    mont_ctx = NULL;
  }

  goto out;

err:
  BN_MONT_CTX_free(mont_ctx);
  OPENSSL_free((BN_MONT_CTX**) built_in_curve_scalar_field_monts);
  built_in_curve_scalar_field_monts = NULL;

out:
  BN_free(order);
  BN_CTX_free(bn_ctx);
}
Beispiel #12
0
// built_in_curve_scalar_field_monts contains Montgomery contexts for
// performing inversions in the scalar fields of each of the built-in
// curves. It's protected by |built_in_curve_scalar_field_monts_once|.
DEFINE_LOCAL_DATA(BN_MONT_CTX **, built_in_curve_scalar_field_monts) {
  const struct built_in_curves *const curves = OPENSSL_built_in_curves();

  BN_MONT_CTX **monts =
      OPENSSL_malloc(sizeof(BN_MONT_CTX *) * OPENSSL_NUM_BUILT_IN_CURVES);
  if (monts == NULL) {
    return;
  }

  OPENSSL_memset(monts, 0, sizeof(BN_MONT_CTX *) * OPENSSL_NUM_BUILT_IN_CURVES);

  BIGNUM *order = BN_new();
  BN_CTX *bn_ctx = BN_CTX_new();
  BN_MONT_CTX *mont_ctx = NULL;

  if (bn_ctx == NULL ||
      order == NULL) {
    goto err;
  }

  for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
    const struct built_in_curve *curve = &curves->curves[i];
    const unsigned param_len = curve->param_len;
    const uint8_t *params = curve->params;

    mont_ctx = BN_MONT_CTX_new();
    if (mont_ctx == NULL) {
      goto err;
    }

    if (!BN_bin2bn(params + 5 * param_len, param_len, order) ||
        !BN_MONT_CTX_set(mont_ctx, order, bn_ctx)) {
      goto err;
    }

    monts[i] = mont_ctx;
    mont_ctx = NULL;
  }

  *out = monts;
  goto done;

err:
  BN_MONT_CTX_free(mont_ctx);
  for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
    BN_MONT_CTX_free(monts[i]);
  }
  OPENSSL_free((BN_MONT_CTX**) monts);

done:
  BN_free(order);
  BN_CTX_free(bn_ctx);
}
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  BN_MONT_CTX *mont = NULL;
  BIGNUM *one = NULL;
  int ret = 0;

  BN_MONT_CTX_free(group->mont);
  group->mont = NULL;
  BN_free(group->one);
  group->one = NULL;

  if (ctx == NULL) {
    ctx = new_ctx = BN_CTX_new();
    if (ctx == NULL) {
      return 0;
    }
  }

  mont = BN_MONT_CTX_new();
  if (mont == NULL) {
    goto err;
  }
  if (!BN_MONT_CTX_set(mont, p, ctx)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }
  one = BN_new();
  if (one == NULL || !BN_to_montgomery(one, BN_value_one(), mont, ctx)) {
    goto err;
  }

  group->mont = mont;
  mont = NULL;
  group->one = one;
  one = NULL;

  ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);

  if (!ret) {
    BN_MONT_CTX_free(group->mont);
    group->mont = NULL;
    BN_free(group->one);
    group->one = NULL;
  }

err:
  BN_CTX_free(new_ctx);
  BN_MONT_CTX_free(mont);
  BN_free(one);
  return ret;
}
static int generate_key(DH *dh)
	{
	int ok=0;
	BN_CTX ctx;
	BN_MONT_CTX *mont;
	BIGNUM *pub_key=NULL,*priv_key=NULL;

	BN_CTX_init(&ctx);

	if (dh->priv_key == NULL)
		{
		priv_key=BN_new();
		if (priv_key == NULL) goto err;
		do
			if (!BN_rand_range(priv_key, dh->p)) goto err;
		while (BN_is_zero(priv_key));
		}
	else
		priv_key=dh->priv_key;

	if (dh->pub_key == NULL)
		{
		pub_key=BN_new();
		if (pub_key == NULL) goto err;
		}
	else
		pub_key=dh->pub_key;

	if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
		{
		if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
				dh->p,&ctx)) goto err;
		}
	mont=(BN_MONT_CTX *)dh->method_mont_p;

	if (!dh->meth->bn_mod_exp(dh, pub_key,dh->g,priv_key,dh->p,&ctx,mont))
								goto err;
		
	dh->pub_key=pub_key;
	dh->priv_key=priv_key;
	ok=1;
err:
	if (ok != 1)
		DHerr(DH_F_DH_GENERATE_KEY,ERR_R_BN_LIB);

	if ((pub_key != NULL)  && (dh->pub_key == NULL))  BN_free(pub_key);
	if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
	BN_CTX_free(&ctx);
	return(ok);
	}
Beispiel #15
0
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
					const BIGNUM *mod, BN_CTX *ctx)
	{
	if (*pmont)
		return *pmont;
	CRYPTO_w_lock(lock);
	if (!*pmont)
		{
		BN_MONT_CTX *mtmp;
		mtmp = BN_MONT_CTX_new();
		if (mtmp && !BN_MONT_CTX_set(mtmp, mod, ctx))
			BN_MONT_CTX_free(mtmp);
		else
			*pmont = mtmp;
		}
	CRYPTO_w_unlock(lock);
	return *pmont;
	}
Beispiel #16
0
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
					const BIGNUM *mod, BN_CTX *ctx)
	{
	if (*pmont)
		return *pmont;
	CRYPTO_w_lock(lock);
	if (!*pmont)
		{
		*pmont = BN_MONT_CTX_new();
		if (*pmont && !BN_MONT_CTX_set(*pmont, mod, ctx))
			{
			BN_MONT_CTX_free(*pmont);
			*pmont = NULL;
			}
		}
	CRYPTO_w_unlock(lock);
	return *pmont;
	}
Beispiel #17
0
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
					const BIGNUM *mod, BN_CTX *ctx)
	{
	BN_MONT_CTX *ret;

	CRYPTO_r_lock(lock);
	ret = *pmont;
	CRYPTO_r_unlock(lock);
	if (ret)
		return ret;

	/* We don't want to serialise globally while doing our lazy-init math in
	 * BN_MONT_CTX_set. That punishes threads that are doing independent
	 * things. Instead, punish the case where more than one thread tries to
	 * lazy-init the same 'pmont', by having each do the lazy-init math work
	 * independently and only use the one from the thread that wins the race
	 * (the losers throw away the work they've done). */
	ret = BN_MONT_CTX_new();
	if (!ret)
		return NULL;
	if (!BN_MONT_CTX_set(ret, mod, ctx))
		{
		BN_MONT_CTX_free(ret);
		return NULL;
		}

	/* The locked compare-and-set, after the local work is done. */
	CRYPTO_w_lock(lock);
	if (*pmont)
		{
		BN_MONT_CTX_free(ret);
		ret = *pmont;
		}
	else
		*pmont = ret;
	CRYPTO_w_unlock(lock);
	return ret;
	}
Beispiel #18
0
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
	{
	BN_CTX *ctx;
	BN_MONT_CTX *mont;
	BIGNUM *tmp;
	int ret= -1;

	ctx = BN_CTX_new();
	if (ctx == NULL) goto err;
	BN_CTX_start(ctx);
	tmp = BN_CTX_get(ctx);
	
	if (dh->priv_key == NULL)
		{
		DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
		goto err;
		}
	if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
		{
		if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
			if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
				dh->p,ctx)) goto err;
		}

	mont=(BN_MONT_CTX *)dh->method_mont_p;
	if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
		{
		DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	ret=BN_bn2bin(tmp,key);
err:
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	return(ret);
	}
Beispiel #19
0
int BN_is_prime_fasttest(const BIGNUM *a, int checks,
		void (*callback)(int,int,void *),
		BN_CTX *ctx_passed, void *cb_arg,
		int do_trial_division)
	{
	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))
		return 0;
	if (do_trial_division)
		{
		for (i = 1; i < NUMPRIMES; i++)
			if (BN_mod_word(a, primes[i]) == 0) 
				return 0;
		if (callback != NULL) callback(1, -1, cb_arg);
		}

	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 (callback != NULL) callback(1,i,cb_arg);
		}
	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 #20
0
int FuzzerTestOneInput(const uint8_t *buf, size_t len) {
    int success = 0;
    static BN_CTX *ctx;
    static BN_MONT_CTX *mont;
    static BIGNUM *b1;
    static BIGNUM *b2;
    static BIGNUM *b3;
    static BIGNUM *b4;
    static BIGNUM *b5;

    if (ctx == NULL) {
        b1 = BN_new();
        b2 = BN_new();
        b3 = BN_new();
        b4 = BN_new();
        b5 = BN_new();
        ctx = BN_CTX_new();
        mont = BN_MONT_CTX_new();
    }
    // Divide the input into three parts, using the values of the first two
    // bytes to choose lengths, which generate b1, b2 and b3. Use three bits
    // of the third byte to choose signs for the three numbers.
    size_t l1 = 0, l2 = 0, l3 = 0;
    int s1 = 0, s2 = 0, s3 = 0;
    if (len > 2) {
        len -= 3;
        l1 = (buf[0] * len) / 255;
        ++buf;
        l2 = (buf[0] * (len - l1)) / 255;
        ++buf;
        l3 = len - l1 - l2;

        s1 = buf[0] & 1;
        s2 = buf[0] & 2;
        s3 = buf[0] & 4;
        ++buf;
    }
    OPENSSL_assert(BN_bin2bn(buf, l1, b1) == b1);
    BN_set_negative(b1, s1);
    OPENSSL_assert(BN_bin2bn(buf + l1, l2, b2) == b2);
    BN_set_negative(b2, s2);
    OPENSSL_assert(BN_bin2bn(buf + l1 + l2, l3, b3) == b3);
    BN_set_negative(b3, s3);

    // mod 0 is undefined
    if (BN_is_zero(b3)) {
        success = 1;
        goto done;
    }

    OPENSSL_assert(BN_mod_exp(b4, b1, b2, b3, ctx));
    OPENSSL_assert(BN_mod_exp_simple(b5, b1, b2, b3, ctx));

    success = BN_cmp(b4, b5) == 0;
    if (!success) {
        BN_print_fp(stdout, b1);
        putchar('\n');
        BN_print_fp(stdout, b2);
        putchar('\n');
        BN_print_fp(stdout, b3);
        putchar('\n');
        BN_print_fp(stdout, b4);
        putchar('\n');
        BN_print_fp(stdout, b5);
        putchar('\n');
    }

 done:
    OPENSSL_assert(success);

    return 0;
}
Beispiel #21
0
int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
{
    EC_EXTRA_DATA *d;

    if (dest->meth->group_copy == 0) {
        ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (dest->meth != src->meth) {
        ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
    if (dest == src)
        return 1;

    EC_EX_DATA_free_all_data(&dest->extra_data);

    for (d = src->extra_data; d != NULL; d = d->next) {
        void *t = d->dup_func(d->data);

        if (t == NULL)
            return 0;
        if (!EC_EX_DATA_set_data
            (&dest->extra_data, t, d->dup_func, d->free_func,
             d->clear_free_func))
            return 0;
    }

    if (EC_GROUP_VERSION(src) && src->mont_data != NULL) {
        if (dest->mont_data == NULL) {
            dest->mont_data = BN_MONT_CTX_new();
            if (dest->mont_data == NULL)
                return 0;
        }
        if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
            return 0;
    } else {
        /* src->generator == NULL */
        if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) {
            BN_MONT_CTX_free(dest->mont_data);
            dest->mont_data = NULL;
        }
    }

    if (src->generator != NULL) {
        if (dest->generator == NULL) {
            dest->generator = EC_POINT_new(dest);
            if (dest->generator == NULL)
                return 0;
        }
        if (!EC_POINT_copy(dest->generator, src->generator))
            return 0;
    } else {
        /* src->generator == NULL */
        if (dest->generator != NULL) {
            EC_POINT_clear_free(dest->generator);
            dest->generator = NULL;
        }
    }

    if (!BN_copy(&dest->order, &src->order))
        return 0;
    if (!BN_copy(&dest->cofactor, &src->cofactor))
        return 0;

    dest->curve_name = src->curve_name;
    dest->asn1_flag = src->asn1_flag;
    dest->asn1_form = src->asn1_form;

    if (src->seed) {
        if (dest->seed)
            OPENSSL_free(dest->seed);
        dest->seed = OPENSSL_malloc(src->seed_len);
        if (dest->seed == NULL)
            return 0;
        if (!memcpy(dest->seed, src->seed, src->seed_len))
            return 0;
        dest->seed_len = src->seed_len;
    } else {
        if (dest->seed)
            OPENSSL_free(dest->seed);
        dest->seed = NULL;
        dest->seed_len = 0;
    }

    return dest->meth->group_copy(dest, src);
}
Beispiel #22
0
int test_mont(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM a,b,c,d,A,B;
	BIGNUM n;
	int i;
	BN_MONT_CTX *mont;

	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
	BN_init(&d);
	BN_init(&A);
	BN_init(&B);
	BN_init(&n);

	mont=BN_MONT_CTX_new();

	BN_bntest_rand(&a,100,0,0); /**/
	BN_bntest_rand(&b,100,0,0); /**/
	for (i=0; i<num2; i++)
		{
		int bits = (200*(i+1))/num2;

		if (bits == 0)
			continue;
		BN_bntest_rand(&n,bits,0,1);
		BN_MONT_CTX_set(mont,&n,ctx);

		BN_nnmod(&a,&a,&n,ctx);
		BN_nnmod(&b,&b,&n,ctx);

		BN_to_montgomery(&A,&a,mont,ctx);
		BN_to_montgomery(&B,&b,mont,ctx);

		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
		BN_from_montgomery(&A,&c,mont,ctx);/**/
		if (bp != NULL)
			{
			if (!results)
				{
#ifdef undef
fprintf(stderr,"%d * %d %% %d\n",
BN_num_bits(&a),
BN_num_bits(&b),
BN_num_bits(mont->N));
#endif
				BN_print(bp,&a);
				BIO_puts(bp," * ");
				BN_print(bp,&b);
				BIO_puts(bp," % ");
				BN_print(bp,&(mont->N));
				BIO_puts(bp," - ");
				}
			BN_print(bp,&A);
			BIO_puts(bp,"\n");
			}
		BN_mod_mul(&d,&a,&b,&n,ctx);
		BN_sub(&d,&d,&A);
		if(!BN_is_zero(&d))
		    {
		    fprintf(stderr,"Montgomery multiplication test failed!\n");
		    return 0;
		    }
		}
	BN_MONT_CTX_free(mont);
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
	BN_free(&d);
	BN_free(&A);
	BN_free(&B);
	BN_free(&n);
	return(1);
	}
Beispiel #23
0
/* generates ElGamal key pair. returns 0 when generation went ok, and
 -1 if error occured. 'bits' is the number of bits in p; it should not
 be too low (at least 512 is recommended, 1024 is more realistic number.
 you can use precomputed p,g pairs; set bits to the ordinal of the
 precomputed combination (see table above). generator is either 2 or 5.
 public_key and secret_key will be malloc()ed and contain keys */
int eg_keypair (int bits, int generator, char **public_key, char **secret_key)
{
    BIGNUM       *p, *g, *t1, *t2, *key, *pbk;
    BN_CTX       *ctx2;
    BN_MONT_CTX  *mont;
    char         *buf1, *buf2, *buf3, *buf4, buf[8];
    int          rc;

    // create things needed for work
    ctx2 = BN_CTX_new ();         if (ctx2 == NULL) return -1;
    t1   = BN_new ();             if (t1 == NULL)   return -1;
    t2   = BN_new ();             if (t2 == NULL)   return -1;
    g    = BN_new ();             if (g == NULL)    return -1;
    key  = BN_new ();             if (key == NULL)  return -1;
    pbk  = BN_new ();             if (pbk == NULL)  return -1;
    mont = BN_MONT_CTX_new ();    if (mont == NULL) return -1;

    if (bits < 32)
    {
        if (bits > sizeof(precomp)/sizeof(precomp[0])-1) return -1;
        p = NULL;
        rc = BN_hex2bn (&p, precomp[bits].prime);
        if (rc == 0) return -1;
        // put generator into bignum
        BN_set_word (g, precomp[bits].generator);
    }
    else
    {
        // set values which will be used for checking when generating proper prime
        if (generator == 2)
        {
            BN_set_word (t1,24);
            BN_set_word (t2,11);
        }
        else if (generator == 5)
        {
            BN_set_word (t1,10);
            BN_set_word (t2,3);
            /* BN_set_word(t3,7); just have to miss
             * out on these ones :-( */
        }
        else
            goto err;
    
        // generate proper prime
        p = BN_generate_prime (NULL, bits, 1, t1, t2, NULL, NULL);
        if (p == NULL) goto err;

        // put generator into bignum
        BN_set_word (g, generator);
    }

    // create random private key
    if (!BN_rand (key, BN_num_bits (p)-1, 0, 0)) goto err;

    // create public part of the key
    BN_MONT_CTX_set (mont, p, ctx2);
    if (!BN_mod_exp_mont (pbk, g, key, p, ctx2, mont)) goto err;

    // p, g, key, pbk are ready. secret key: p,g:key, public key: p,g:pbk
    if (bits < 32)
    {
        snprintf1 (buf, sizeof(buf), "%d", bits);
        buf1 = strdup (buf);
    }
    else
    {
        buf1 = BN_bn2hex (p);
    }
    buf2 = BN_bn2hex (key);
    buf3 = BN_bn2hex (pbk);
    buf4 = BN_bn2hex (g);

    *secret_key = malloc (strlen(buf1) + strlen(buf2) + strlen(buf4) + 4);
    *public_key = malloc (strlen(buf1) + strlen(buf3) + strlen(buf4) + 4);

    strcpy (*secret_key, buf1);
    if (bits >= 32)
    {
        strcat (*secret_key, ",");
        strcat (*secret_key, buf4);
    }
    strcat (*secret_key, ":");
    strcat (*secret_key, buf2);
    
    strcpy (*public_key, buf1);
    if (bits >= 32)
    {
        strcat (*public_key, ",");
        strcat (*public_key, buf4);
    }
    strcat (*public_key, ":");
    strcat (*public_key, buf3);
    memset (buf2, 0, strlen (buf2));
    free (buf1); free (buf2); free (buf3);

    // cleanup
    BN_free (p);            BN_free (g);
    BN_clear_free (key);    BN_free (pbk);
    BN_CTX_free (ctx2);
    return 0;
    
err:
    return -1;
}
Beispiel #24
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;

    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++) {
            BN_ULONG mod = BN_mod_word(a, primes[i]);
            if (mod == (BN_ULONG)-1)
                goto err;
            if (mod == 0)
                return BN_is_word(a, primes[i]);
        }
        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);

    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_priv_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);
    }
    BN_MONT_CTX_free(mont);

    return ret;
}
Beispiel #25
0
static int RSA_eay_public_encrypt(int flen, unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	const RSA_METHOD *meth;
	BIGNUM f,ret;
	int i,j,k,num=0,r= -1;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;

	meth = rsa->meth;
	BN_init(&f);
	BN_init(&ret);
	if ((ctx=BN_CTX_new()) == NULL) goto err;
	num=BN_num_bytes(rsa->n);
	if ((buf=(unsigned char *)rtlglue_malloc(num)) == NULL)
		goto err;

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
		break;
	case RSA_SSLV23_PADDING:
		i=RSA_padding_add_SSLv23(buf,num,from,flen);
		break;
	case RSA_NO_PADDING:
		i=RSA_padding_add_none(buf,num,from,flen);
		break;
	default:
		goto err;
		}
	if (i <= 0) goto err;

	if (BN_bin2bn(buf,num,&f) == NULL) goto err;
	
	if (BN_ucmp(&f, rsa->n) >= 0)
		goto err;

	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
		{
		BN_MONT_CTX* bn_mont_ctx;
		if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
			goto err;
		if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
			{
			BN_MONT_CTX_free(bn_mont_ctx);
			goto err;
			}
		if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
			{
			if (rsa->_method_mod_n == NULL)
				{
				rsa->_method_mod_n = bn_mont_ctx;
				bn_mont_ctx = NULL;
				}
			}
		if (bn_mont_ctx)
			BN_MONT_CTX_free(bn_mont_ctx);
		}

	if (!meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
		rsa->_method_mod_n)) goto err;

	/* put in leading 0 bytes if the number is less than the
	 * length of the modulus */
	j=BN_num_bytes(&ret);
	i=BN_bn2bin(&ret,&(to[num-j]));
	for (k=0; k<(num-i); k++)
		to[k]=0;

	r=num;
err:
	if (ctx != NULL) BN_CTX_free(ctx);
	BN_clear_free(&f);
	BN_clear_free(&ret);
	if (buf != NULL) 
		{
		memset(buf, 0, num);
		rtlglue_free(buf);
		}
	return(r);
	}
Beispiel #26
0
int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
{
    if (dest->meth->group_copy == 0) {
        ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (dest->meth != src->meth) {
        ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
    if (dest == src)
        return 1;

    /* Copy precomputed */
    dest->pre_comp_type = src->pre_comp_type;
    switch (src->pre_comp_type) {
    case PCT_none:
        dest->pre_comp.ec = NULL;
        break;
    case PCT_nistz256:
#ifdef ECP_NISTZ256_ASM
        dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256);
#endif
        break;
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
    case PCT_nistp224:
        dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224);
        break;
    case PCT_nistp256:
        dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
        break;
    case PCT_nistp521:
        dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
        break;
#else
    case PCT_nistp224:
    case PCT_nistp256:
    case PCT_nistp521:
        break;
#endif
    case PCT_ec:
        dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec);
        break;
    }

    if (src->mont_data != NULL) {
        if (dest->mont_data == NULL) {
            dest->mont_data = BN_MONT_CTX_new();
            if (dest->mont_data == NULL)
                return 0;
        }
        if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
            return 0;
    } else {
        /* src->generator == NULL */
        BN_MONT_CTX_free(dest->mont_data);
        dest->mont_data = NULL;
    }

    if (src->generator != NULL) {
        if (dest->generator == NULL) {
            dest->generator = EC_POINT_new(dest);
            if (dest->generator == NULL)
                return 0;
        }
        if (!EC_POINT_copy(dest->generator, src->generator))
            return 0;
    } else {
        /* src->generator == NULL */
        EC_POINT_clear_free(dest->generator);
        dest->generator = NULL;
    }

    if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
        if (!BN_copy(dest->order, src->order))
            return 0;
        if (!BN_copy(dest->cofactor, src->cofactor))
            return 0;
    }

    dest->curve_name = src->curve_name;
    dest->asn1_flag = src->asn1_flag;
    dest->asn1_form = src->asn1_form;

    if (src->seed) {
        OPENSSL_free(dest->seed);
        dest->seed = OPENSSL_malloc(src->seed_len);
        if (dest->seed == NULL)
            return 0;
        if (!memcpy(dest->seed, src->seed, src->seed_len))
            return 0;
        dest->seed_len = src->seed_len;
    } else {
        OPENSSL_free(dest->seed);
        dest->seed = NULL;
        dest->seed_len = 0;
    }

    return dest->meth->group_copy(dest, src);
}
Beispiel #27
0
DSA *DSA_generate_parameters(int bits,
		unsigned char *seed_in, int seed_len,
		int *counter_ret, unsigned long *h_ret,
		void (*callback)(int, int, void *),
		void *cb_arg)
	{
	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,*ctx2=NULL,*ctx3=NULL;
	unsigned int h=2;
	DSA *ret=NULL;

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

	if (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);

	if ((ctx=BN_CTX_new()) == NULL) goto err;
	if ((ctx2=BN_CTX_new()) == NULL) goto err;
	if ((ctx3=BN_CTX_new()) == NULL) goto err;
	if ((ret=DSA_new()) == NULL) goto err;

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

	BN_CTX_start(ctx2);
	r0 = BN_CTX_get(ctx2);
	g = BN_CTX_get(ctx2);
	W = BN_CTX_get(ctx2);
	q = BN_CTX_get(ctx2);
	X = BN_CTX_get(ctx2);
	c = BN_CTX_get(ctx2);
	p = BN_CTX_get(ctx2);
	test = BN_CTX_get(ctx2);
	if (test == NULL) goto err;

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

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

			/* step 1 */
			if (callback != NULL) callback(0,m++,cb_arg);

			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(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random);
			if (r > 0)
				break;
			if (r != 0)
				goto err;

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

		if (callback != NULL) callback(2,0,cb_arg);
		if (callback != NULL) callback(3,0,cb_arg);

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

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

		for (;;)
			{
			if (callback != NULL && counter != 0)
				callback(0,counter,cb_arg);

			/* step 7 */
			if (!BN_zero(W)) goto err;
			/* 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(p, DSS_prime_checks, callback, ctx3, cb_arg, 1);
				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 (callback != NULL) callback(2,1,cb_arg);

	/* 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 (callback != NULL) callback(3,1,cb_arg);

	ok=1;
err:
	if (!ok)
		{
		if (ret != NULL) DSA_free(ret);
		}
	else
		{
		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 ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20);
		if (counter_ret != NULL) *counter_ret=counter;
		if (h_ret != NULL) *h_ret=h;
		}
	if (ctx != NULL) BN_CTX_free(ctx);
	if (ctx2 != NULL)
		{
		BN_CTX_end(ctx2);
		BN_CTX_free(ctx2);
		}
	if (ctx3 != NULL) BN_CTX_free(ctx3);
	if (mont != NULL) BN_MONT_CTX_free(mont);
	return(ok?ret:NULL);
	}
static int RSA_eay_public_encrypt(FIPS_RSA_SIZE_T flen, const unsigned char *from,
	     unsigned char *to, RSA *rsa, int padding)
	{
	BIGNUM f,ret;
	int i,j,k,num=0,r= -1;
	unsigned char *buf=NULL;
	BN_CTX *ctx=NULL;

	BN_init(&f);
	BN_init(&ret);

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

	if ((ctx=BN_CTX_new()) == NULL) goto err;
	num=BN_num_bytes(rsa->n);
	if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
		{
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	switch (padding)
		{
	case RSA_PKCS1_PADDING:
		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
		break;
#ifndef OPENSSL_NO_SHA
	case RSA_PKCS1_OAEP_PADDING:
	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
		break;
#endif
	case RSA_SSLV23_PADDING:
		i=RSA_padding_add_SSLv23(buf,num,from,flen);
		break;
	case RSA_NO_PADDING:
		i=RSA_padding_add_none(buf,num,from,flen);
		break;
	default:
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
		goto err;
		}
	if (i <= 0) goto err;

	if (BN_bin2bn(buf,num,&f) == NULL) goto err;
	
	if (BN_ucmp(&f, rsa->n) >= 0)
		{	
		/* usually the padding functions would catch this */
		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
		goto err;
		}

	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
		{
		BN_MONT_CTX* bn_mont_ctx;
		if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
			goto err;
		if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
			{
			BN_MONT_CTX_free(bn_mont_ctx);
			goto err;
			}
		if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
			{
			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
			if (rsa->_method_mod_n == NULL)
				{
				rsa->_method_mod_n = bn_mont_ctx;
				bn_mont_ctx = NULL;
				}
			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
			}
		if (bn_mont_ctx)
			BN_MONT_CTX_free(bn_mont_ctx);
		}
		
	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
		rsa->_method_mod_n)) goto err;

	/* put in leading 0 bytes if the number is less than the
	 * length of the modulus */
	j=BN_num_bytes(&ret);
	i=BN_bn2bin(&ret,&(to[num-j]));
	for (k=0; k<(num-i); k++)
		to[k]=0;

	r=num;
err:
	if (ctx != NULL) BN_CTX_free(ctx);
	BN_clear_free(&f);
	BN_clear_free(&ret);
	if (buf != NULL) 
		{
		OPENSSL_cleanse(buf,num);
		OPENSSL_free(buf);
		}
	return(r);
	}
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 #30
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;
}