Пример #1
0
/*
 * Set the coordinates of an EC_POINT using affine coordinates. Note that
 * the simple implementation only uses affine coordinates.
 */
int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
                                                EC_POINT *point,
                                                const BIGNUM *x,
                                                const BIGNUM *y, BN_CTX *ctx)
{
    int ret = 0;
    if (x == NULL || y == NULL) {
        ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES,
              ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (!BN_copy(&point->X, x))
        goto err;
    BN_set_negative(&point->X, 0);
    if (!BN_copy(&point->Y, y))
        goto err;
    BN_set_negative(&point->Y, 0);
    if (!BN_copy(&point->Z, BN_value_one()))
        goto err;
    BN_set_negative(&point->Z, 0);
    point->Z_is_one = 1;
    ret = 1;

 err:
    return ret;
}
Пример #2
0
/* Gets the affine coordinates of an EC_POINT. 
 * Note that the simple implementation only uses affine coordinates.
 */
int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
	BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
	{
	int ret = 0;

	if (EC_POINT_is_at_infinity(group, point))
		{
		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
		return 0;
		}

	if (BN_cmp(&point->Z, BN_value_one())) 
		{
		ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		return 0;
		}
	if (x != NULL)
		{
		if (!BN_copy(x, &point->X)) goto err;
		BN_set_negative(x, 0);
		}
	if (y != NULL)
		{
		if (!BN_copy(y, &point->Y)) goto err;
		BN_set_negative(y, 0);
		}
	ret = 1;
		
 err:
	return ret;
	}
Пример #3
0
static int test_bad_key(void) {
  RSA *key = RSA_new();
  BIGNUM e;

  BN_init(&e);
  BN_set_word(&e, RSA_F4);

  if (!RSA_generate_key_ex(key, 512, &e, NULL)) {
    fprintf(stderr, "RSA_generate_key_ex failed.\n");
    ERR_print_errors_fp(stderr);
    return 0;
  }

  if (!BN_add(key->p, key->p, BN_value_one())) {
    fprintf(stderr, "BN error.\n");
    ERR_print_errors_fp(stderr);
    return 0;
  }

  if (RSA_check_key(key)) {
    fprintf(stderr, "RSA_check_key passed with invalid key!\n");
    return 0;
  }

  ERR_clear_error();
  BN_free(&e);
  RSA_free(key);
  return 1;
}
Пример #4
0
/* The secret integers s0 and s1 must be in the range 0 < s < n for
   some n, and must be relatively prime to that n.  We know a priori
   that n is of the form 2**k * p for some small integer k and prime
   p.  Therefore, it suffices to choose a random integer in the range
   [0, n/2), multiply by two and add one (enforcing oddness), and then
   reject values which are divisible by p.  */
static BIGNUM *
random_s(const BIGNUM *n, const BIGNUM *p, BN_CTX *c)
{
  BIGNUM h, m, *r;

  BN_init(&h);
  BN_init(&m);
  FAILZ(r = BN_new());
  FAILZ(BN_copy(&h, n));
  FAILZ(BN_rshift1(&h, &h));

  do {
    FAILZ(BN_rand_range(r, &h));
    FAILZ(BN_lshift1(r, r));
    FAILZ(BN_add(r, r, BN_value_one()));
    FAILZ(BN_nnmod(&m, r, p, c));
  } while (BN_is_zero(&m));

  BN_clear(&h);
  BN_clear(&m);
  return r;

 fail:
  BN_clear(&h);
  BN_clear(&m);
  if (r) BN_clear_free(r);
  return 0;
}
Пример #5
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;
}
Пример #6
0
int
dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
{
	int i;
	int n = BN_num_bits(dh_pub);
	int bits_set = 0;
	BIGNUM *tmp;
	const BIGNUM *p;

	if (BN_is_negative(dh_pub)) {
		logit("invalid public DH value: negative");
		return 0;
	}
	if (BN_cmp(dh_pub, BN_value_one()) != 1) {	/* pub_exp <= 1 */
		logit("invalid public DH value: <= 1");
		return 0;
	}

	if ((tmp = BN_new()) == NULL) {
		error("%s: BN_new failed", __func__);
		return 0;
	}
	DH_get0_pqg(dh, &p, NULL, NULL);
	if (!BN_sub(tmp, p, BN_value_one()) ||
	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
		BN_clear_free(tmp);
		logit("invalid public DH value: >= p-1");
		return 0;
	}
	BN_clear_free(tmp);

	for (i = 0; i <= n; i++)
		if (BN_is_bit_set(dh_pub, i))
			bits_set++;
	debug2("bits set: %d/%d", bits_set, BN_num_bits(p));

	/*
	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
	 */
	if (bits_set < 4) {
		logit("invalid public DH value (%d/%d)",
		   bits_set, BN_num_bits(p));
		return 0;
	}
	return 1;
}
Пример #7
0
a1int &a1int::operator ++ (void)
{
	BIGNUM *bn = ASN1_INTEGER_to_BN(in, NULL);
	BN_add(bn, bn, BN_value_one());
	BN_to_ASN1_INTEGER(bn, in);
	BN_free(bn);
	return *this;
}
Пример #8
0
void test_lehmer_thm(void)
{
  BIGNUM
    *v = BN_new(),
    *v2 = BN_new(),
    *h = BN_new(),
    *n = BN_new(),
    *p = BN_new(),
    *q = BN_new(),
    *g = BN_new();
  BN_CTX *ctx = BN_CTX_new();

  BN_dec2bn(&v, "2");
  BN_dec2bn(&p,
            "181857351165158586099319592412492032999818333818932850952491024"
            "131283899677766672100915923041329384157985577418702469610834914"
            "6296393743554494871840505599");
  BN_dec2bn(&q,
            "220481921324130321200060036818685031159071785249502660004347524"
            "831733577485433929892260897846567483448177204481081755191897197"
            "38283711758138566145322943999");
  BN_mul(n, p, q, ctx);
  /* p + 1 */
  BN_dec2bn(&h,
            "181857351165158586099319592412492032999818333818932850952491024"
            "131283899677766672100915923041329384157985577418702469610834914"
            "6296393743554494871840505600");
  lucas(v, h, n, ctx);
  BN_sub(v2, v, BN_value_two());
  BN_gcd(g, v2, n, ctx);
  assert(!BN_is_one(g));

  /* another test */
  BN_dec2bn(&v, "3");
  BN_dec2bn(&p,
            "181857351165158586099319592412492032999818333818932850952491024"
            "131283899677766672100915923041329384157985577418702469610834914"
            "62963937435544948718405055999");
  BN_generate_prime(q, 512, 1, NULL, NULL, NULL, NULL);
  BN_mul(n, p, q, ctx);

  BN_sub(h, p, BN_value_one());
  BN_mul(h, h, BN_value_two(), ctx);
  lucas(v, h, n, ctx);

  BN_mod_sub(v2, v, BN_value_two(), n, ctx);
  BN_gcd(g, v2, n, ctx);
  assert(!BN_is_one(g));
  assert(BN_cmp(g, n));

  BN_free(q);
  BN_free(p);
  BN_free(v);
  BN_free(v2);
  BN_free(h);

  BN_CTX_free(ctx);
}
Пример #9
0
static int
old_dsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
{
	DSA *dsa;
	BN_CTX *ctx = NULL;
	BIGNUM *j, *p1, *newp1;

	if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) {
		DSAerror(ERR_R_DSA_LIB);
		return 0;
	}

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

	/*
	 * Check that p and q are consistent with each other.
	 */

	j = BN_CTX_get(ctx);
	p1 = BN_CTX_get(ctx);
	newp1 = BN_CTX_get(ctx);
	if (j == NULL || p1 == NULL || newp1 == NULL)
		goto err;
	/* p1 = p - 1 */
	if (BN_sub(p1, dsa->p, BN_value_one()) == 0)
		goto err;
	/* j = (p - 1) / q */
	if (BN_div_ct(j, NULL, p1, dsa->q, ctx) == 0)
		goto err;
	/* q * j should == p - 1 */
	if (BN_mul(newp1, dsa->q, j, ctx) == 0)
		goto err;
	if (BN_cmp(newp1, p1) != 0) {
		DSAerror(DSA_R_BAD_Q_VALUE);
		goto err;
	}

	/*
	 * Check that q is not a composite number.
	 */

	if (BN_is_prime_ex(dsa->q, BN_prime_checks, ctx, NULL) <= 0) {
		DSAerror(DSA_R_BAD_Q_VALUE);
		goto err;
	}

	BN_CTX_free(ctx);

	EVP_PKEY_assign_DSA(pkey, dsa);
	return 1;

 err:
	BN_CTX_free(ctx);
	DSA_free(dsa);
	return 0;
}
Пример #10
0
int 
ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP * group, EC_POINT * point,
    const BIGNUM * x, const BIGNUM * y, BN_CTX * ctx)
{
	if (x == NULL || y == NULL) {
		/* unlike for projective coordinates, we do not tolerate this */
		ECerror(ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}
	return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx);
}
Пример #11
0
/* calculate p-1 and q-1 */
void
rsa_generate_additional_parameters(RSA *rsa)
{
	BIGNUM *aux;
	BN_CTX *ctx;

	if ((aux = BN_new()) == NULL)
		fatal("rsa_generate_additional_parameters: BN_new failed");
	if ((ctx = BN_CTX_new()) == NULL)
		fatal("rsa_generate_additional_parameters: BN_CTX_new failed");

	if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
	    (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
		fatal("rsa_generate_additional_parameters: BN_sub/mod failed");

	BN_clear_free(aux);
	BN_CTX_free(ctx);
}
Пример #12
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;
}
Пример #13
0
uint8_t sane_key(RSA *rsa) { // checks sanity of a RSA key (PKCS#1 v2.1)
    uint8_t sane = 1;

    BN_CTX *ctx = BN_CTX_new();
    BN_CTX_start(ctx);
    BIGNUM *p1     = BN_CTX_get(ctx), // p - 1
            *q1     = BN_CTX_get(ctx), // q - 1
             *chk    = BN_CTX_get(ctx), // storage to run checks with
              *gcd    = BN_CTX_get(ctx), // GCD(p - 1, q - 1)
               *lambda = BN_CTX_get(ctx); // LCM(p - 1, q - 1)

    BN_sub(p1, rsa->p, BN_value_one()); // p - 1
    BN_sub(q1, rsa->q, BN_value_one()); // q - 1
    BN_gcd(gcd, p1, q1, ctx);           // gcd(p - 1, q - 1)
    BN_lcm(lambda, p1, q1, gcd, ctx);   // lambda(n)

    BN_gcd(chk, lambda, rsa->e, ctx); // check if e is coprime to lambda(n)
    if(!BN_is_one(chk))
        sane = 0;

    // check if public exponent e is less than n - 1
    BN_sub(chk, rsa->e, rsa->n); // subtract n from e to avoid checking BN_is_zero
    if(!chk->neg)
        sane = 0;

    BN_mod_inverse(rsa->d, rsa->e, lambda, ctx);    // d
    BN_mod(rsa->dmp1, rsa->d, p1, ctx);             // d mod (p - 1)
    BN_mod(rsa->dmq1, rsa->d, q1, ctx);             // d mod (q - 1)
    BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx); // q ^ -1 mod p
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);

    // this is excessive but you're better off safe than (very) sorry
    // in theory this should never be true unless I made a mistake ;)
    if((RSA_check_key(rsa) != 1) && sane) {
        fprintf(stderr, "WARNING: Key looked okay, but OpenSSL says otherwise!\n");
        sane = 0;
    }

    return sane;
}
Пример #14
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;

  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;
}
Пример #15
0
/* calculate p-1 and q-1 */
static void rsa_generate_additional_parameters(RSA *rsa)
{
	BIGNUM *aux = NULL;
	BN_CTX *ctx = NULL;

	if ((aux = BN_new()) == NULL)
		goto error;
	if ((ctx = BN_CTX_new()) == NULL)
		goto error;

	if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
	    (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
	    (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0))
		goto error;

error:
	if (aux)
		BN_clear_free(aux);
	if (ctx)
		BN_CTX_free(ctx);
}
Пример #16
0
BOOL rsautil_quickimport(RSA *rsa, BIGNUM *e_value, BIGNUM *p_value, BIGNUM *q_value, OPTIONAL BIGNUM *n_value)
{
	BIGNUM *r0, *r1, *r2;
	BN_CTX *ctx;

	ctx = BN_CTX_new();
	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
	r1 = BN_CTX_get(ctx);
	r2 = BN_CTX_get(ctx);

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

	BN_copy(rsa->e, e_value);
	BN_copy(rsa->p, p_value);
	BN_copy(rsa->q, q_value);
	if(n_value)
		BN_copy(rsa->n, n_value);
	else
		BN_mul(rsa->n, rsa->p, rsa->q, ctx);
	BN_sub(r1, rsa->p, BN_value_one());
	BN_sub(r2, rsa->q, BN_value_one());
	BN_mul(r0, r1, r2, ctx);
	BN_mod_inverse(rsa->d, rsa->e, r0, ctx);
	BN_mod(rsa->dmp1, rsa->d, r1, ctx);
	BN_mod(rsa->dmq1, rsa->d, r2, ctx);
	BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx);

	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	return (RSA_check_key(rsa) == 1);
}
Пример #17
0
static void
schnorr_selftest(void)
{
	BIGNUM *x;
	struct modp_group *grp;
	u_int i;
	char *hh;

	grp = jpake_default_group();
	if ((x = BN_new()) == NULL)
		fatal("%s: BN_new", __func__);
	SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__));
	SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__));
	SCHNORR_DEBUG_BN((grp->g, "%s: grp->g = ", __func__));

	/* [1, 20) */
	for (i = 1; i < 20; i++) {
		printf("x = %u\n", i);
		fflush(stdout);
		if (BN_set_word(x, i) != 1)
			fatal("%s: set x word", __func__);
		schnorr_selftest_one(grp->p, grp->q, grp->g, x);
	}

	/* 100 x random [0, p) */
	for (i = 0; i < 100; i++) {
		if (BN_rand_range(x, grp->p) != 1)
			fatal("%s: BN_rand_range", __func__);
		hh = BN_bn2hex(x);
		printf("x = (random) 0x%s\n", hh);
		free(hh);
		fflush(stdout);
		schnorr_selftest_one(grp->p, grp->q, grp->g, x);
	}

	/* [q-20, q) */
	if (BN_set_word(x, 20) != 1)
		fatal("%s: BN_set_word (x = 20)", __func__);
	if (BN_sub(x, grp->q, x) != 1)
		fatal("%s: BN_sub (q - x)", __func__);
	for (i = 0; i < 19; i++) {
		hh = BN_bn2hex(x);
		printf("x = (q - %d) 0x%s\n", 20 - i, hh);
		free(hh);
		fflush(stdout);
		schnorr_selftest_one(grp->p, grp->q, grp->g, x);
		if (BN_add(x, x, BN_value_one()) != 1)
			fatal("%s: BN_add (x + 1)", __func__);
	}
	BN_free(x);
}
Пример #18
0
BIGNUM *
DH_get_order(const DH *dh, BN_CTX *ctx)
{
    BIGNUM *order = NULL, *bn = NULL;
    const BIGNUM *p, *g;

    check(dh && ctx, "Invalid argument");

    BN_CTX_start(ctx);

    DH_get0_pqg(dh, &p, NULL, &g);

    /* suppose the order of g is q-1 */
    order = DH_get_q(dh, ctx);
    bn = BN_CTX_get(ctx);
    if (!bn || !order || !BN_sub_word(order, 1)
          || !BN_mod_exp(bn, g, order, p, ctx))
        goto err;

    if (BN_cmp(bn, BN_value_one()) != 0) {
        /* if bn != 1, then q-1 is not the order of g, but p-1 should be */
        if (!BN_sub(order, p, BN_value_one()) ||
              !BN_mod_exp(bn, g, order, p, ctx))
           goto err;
        check(BN_cmp(bn, BN_value_one()) == 0, "Unable to get order");
    }

    BN_CTX_end(ctx);

    return order;

err:
    if (order)
        BN_clear_free(order);
    BN_CTX_end(ctx);

    return NULL;
}
Пример #19
0
static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
                                  const BIGNUM *q, BN_CTX *ctx)
{
    BIGNUM *ret = NULL, *r0, *r1, *r2;

    if (d == NULL || p == NULL || q == NULL)
        return NULL;

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

    if (!BN_sub(r1, p, BN_value_one())) goto err;
    if (!BN_sub(r2, q, BN_value_one())) goto err;
    if (!BN_mul(r0, r1, r2, ctx)) goto err;

    ret = BN_mod_inverse(NULL, d, r0, ctx);
err:
    BN_CTX_end(ctx);
    return ret;
}
Пример #20
0
static int test_check_public_exponent(void)
{
    int ret = 0;
    BIGNUM *e = NULL;

    ret = TEST_ptr(e = BN_new())
          /* e is too small */
          && TEST_true(BN_set_word(e, 65535))
          && TEST_false(rsa_check_public_exponent(e))
          /* e is even will fail */
          && TEST_true(BN_set_word(e, 65536))
          && TEST_false(rsa_check_public_exponent(e))
          /* e is ok */
          && TEST_true(BN_set_word(e, 65537))
          && TEST_true(rsa_check_public_exponent(e))
          /* e = 2^256 is too big */
          && TEST_true(BN_lshift(e, BN_value_one(), 256))
          && TEST_false(rsa_check_public_exponent(e))
          /* e = 2^256-1 is odd and in range */
          && TEST_true(BN_sub(e, e, BN_value_one()))
          && TEST_true(rsa_check_public_exponent(e));
    BN_free(e);
    return ret;
}
Пример #21
0
/* encrypts (or decrypts) with private key, not sensitive to
   timing attacks (blind encryption)
*/
void rsa_encrypt_secure(BIGNUM* m, const BIGNUM* d,
                        const BIGNUM* e, const BIGNUM* n,
                        const unsigned char * r_bin, int r_len) {
  BN_CTX *ctx;
  BIGNUM *tmp = BN_new();
  BIGNUM *r = BN_new();
  BIGNUM *r_inv = BN_new();

  ctx = BN_CTX_new();
  BN_bin2bn(r_bin, r_len, r);
  BN_mod(r, r, n, ctx); /* r = r % n */

  /*
  printf(" r input: ");BN_print_fp(stdout, r);
  printf(" n: ");BN_print_fp(stdout, n);
  printf("\n");
  */

  BN_mod(tmp, n, r, ctx);
  /*printf("r=");BN_print_fp(stdout, r); printf("; tmp=");BN_print_fp(stdout, tmp);*/
  while (BN_is_zero(tmp)) { /*  */
    BN_mod_add(r, r, BN_value_one(), n, ctx);
    BN_mod(tmp, n, r, ctx);
    /*printf("r=");BN_print_fp(stdout, r); printf("; tmp=");BN_print_fp(stdout, tmp);*/
  }
  /*printf("\n");*/

  BN_mod_inverse(r_inv, r, n, ctx);

  /*
  printf(" r = ");BN_print_fp(stdout, r);
  printf(" r_inv = ");BN_print_fp(stdout, r_inv);
  printf(" n = ");BN_print_fp(stdout, n);
  printf("\n");
  */

  BN_mod_exp(r, r, e, n, ctx);  /* r = r^e % n */
  BN_mod_mul(m, m, r, n, ctx);  /* m = m * r % n */

  rsa_encrypt(m, d, n);

  BN_mod_mul(m, m, r_inv, n, ctx);

  BN_free(r);
  BN_free(r_inv);
  BN_free(tmp);
  BN_CTX_free(ctx);
}
Пример #22
0
int
MKEM_generate_message(const MKEM *kp, uint8_t *secret, uint8_t *message)
{
  BIGNUM u;
  uint8_t pad;
  int rv = -1;
  BN_init(&u);
  if (BN_rand_range(&u, kp->params->maxu) &&
      BN_add(&u, &u, BN_value_one()) &&
      RAND_bytes(&pad, 1) &&
      !MKEM_generate_message_u(kp, &u, pad, secret, message))
    rv = 0;

  BN_clear(&u);
  return rv;
}
Пример #23
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;
}
int example_EC_POINT_mul() {
  /* This example ensures that 10×∞ + G = G, in P-256. */
  EC_GROUP *group = NULL;
  EC_POINT *p = NULL, *result = NULL;
  BIGNUM *n = NULL;
  int ret = 0;
  const EC_POINT *generator;

  group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
  p = EC_POINT_new(group);
  result = EC_POINT_new(group);
  n = BN_new();

  if (p == NULL ||
      result == NULL ||
      group == NULL ||
      n == NULL ||
      !EC_POINT_set_to_infinity(group, p) ||
      !BN_set_word(n, 10)) {
    goto err;
  }

  /* First check that 10×∞ = ∞. */
  if (!EC_POINT_mul(group, result, NULL, p, n, NULL) ||
      !EC_POINT_is_at_infinity(group, result)) {
    goto err;
  }

  generator = EC_GROUP_get0_generator(group);

  /* Now check that 10×∞ + G = G. */
  if (!EC_POINT_mul(group, result, BN_value_one(), p, n, NULL) ||
      EC_POINT_cmp(group, result, generator, NULL) != 0) {
    goto err;
  }

  ret = 1;

err:
  BN_free(n);
  EC_POINT_free(result);
  EC_POINT_free(p);
  EC_GROUP_free(group);

  return ret;
}
EC_POINT *embed(const polypseud_ctx *ctx, const unsigned char *data, const size_t len) {
   BIGNUM *t1 = BN_bin2bn(data, len, NULL);
   BIGNUM *x = BN_new();
   BN_mod(x, t1, ctx->p, ctx->bn_ctx);

   EC_POINT *point = EC_POINT_new(ctx->ec_group);
   unsigned char counter = 0;
   int success = 0;
   while(!success) {
       success = EC_POINT_set_compressed_coordinates_GFp(ctx->ec_group, point, x, 1, ctx->bn_ctx);
       if(!success) {
           if(counter == 0) {
               BN_lshift(x, x, 8);
           }
           BN_add(x, x, BN_value_one());
       }
   }
   BN_free(x);
   BN_free(t1);
   return point;
}
Пример #26
0
int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
                                               EC_POINT *point, const BIGNUM *x,
                                               const BIGNUM *y, BN_CTX *ctx) {
  if (x == NULL || y == NULL) {
    /* unlike for projective coordinates, we do not tolerate this */
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  if (!ec_point_set_Jprojective_coordinates_GFp(group, point, x, y,
                                                BN_value_one(), ctx)) {
    return 0;
  }

  if (!ec_GFp_simple_is_on_curve(group, point, ctx)) {
    OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
    return 0;
  }

  return 1;
}
Пример #27
0
static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
                          BN_CTX *ctx)
{
    BIGNUM *rem = NULL;
    if (BN_num_bits(p) != nmod)
        return 0;
    if (BN_num_bits(q) != 160)
        return 0;
    if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
        return 0;
    if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
        return 0;
    rem = BN_new();
    if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
            || (BN_cmp(g, BN_value_one()) <= 0)
            || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) {
        BN_free(rem);
        return 0;
    }
    /* Todo: check g */
    BN_free(rem);
    return 1;
}
Пример #28
0
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;
}
Пример #29
0
int
process_peer_commit (pwd_session_t *sess, uint8_t *commit, BN_CTX *bnctx)
{
    uint8_t *ptr;
    BIGNUM *x = NULL, *y = NULL, *cofactor = NULL;
    EC_POINT *K = NULL, *point = NULL;
    int res = 1;

    if (((sess->peer_scalar = BN_new()) == NULL) ||
	((sess->k = BN_new()) == NULL) ||
	((cofactor = BN_new()) == NULL) ||
	((x = BN_new()) == NULL) ||
	((y = BN_new()) == NULL) ||
	((point = EC_POINT_new(sess->group)) == NULL) ||
	((K = EC_POINT_new(sess->group)) == NULL) ||
	((sess->peer_element = EC_POINT_new(sess->group)) == NULL)) {
	DEBUG2("pwd: failed to allocate room to process peer's commit");
	goto fin;
    }

    if (!EC_GROUP_get_cofactor(sess->group, cofactor, NULL)) {
	DEBUG2("pwd: unable to get group co-factor");
	goto fin;
    }

    /* element, x then y, followed by scalar */
    ptr = (uint8_t *)commit;
    BN_bin2bn(ptr, BN_num_bytes(sess->prime), x);
    ptr += BN_num_bytes(sess->prime);
    BN_bin2bn(ptr, BN_num_bytes(sess->prime), y);
    ptr += BN_num_bytes(sess->prime);
    BN_bin2bn(ptr, BN_num_bytes(sess->order), sess->peer_scalar);
    if (!EC_POINT_set_affine_coordinates_GFp(sess->group,
					     sess->peer_element, x, y,
					     bnctx)) {
	DEBUG2("pwd: unable to get coordinates of peer's element");
	goto fin;
    }

    /* check to ensure peer's element is not in a small sub-group */
    if (BN_cmp(cofactor, BN_value_one())) {
	if (!EC_POINT_mul(sess->group, point, NULL,
			  sess->peer_element, cofactor, NULL)) {
	    DEBUG2("pwd: unable to multiply element by co-factor");
	    goto fin;
	}
	if (EC_POINT_is_at_infinity(sess->group, point)) {
	    DEBUG2("pwd: peer's element is in small sub-group");
	    goto fin;
	}
    }

    /* compute the shared key, k */
    if ((!EC_POINT_mul(sess->group, K, NULL, sess->pwe,
		       sess->peer_scalar, bnctx)) ||
	(!EC_POINT_add(sess->group, K, K, sess->peer_element,
		       bnctx)) ||
	(!EC_POINT_mul(sess->group, K, NULL, K, sess->private_value,
		       bnctx))) {
	DEBUG2("pwd: unable to compute shared key, k");
	goto fin;
    }

    /* ensure that the shared key isn't in a small sub-group */
    if (BN_cmp(cofactor, BN_value_one())) {
	if (!EC_POINT_mul(sess->group, K, NULL, K, cofactor,
			  NULL)) {
	    DEBUG2("pwd: unable to multiply k by co-factor");
	    goto fin;
	}
    }

    /*
     * This check is strictly speaking just for the case above where
     * co-factor > 1 but it was suggested that even though this is probably
     * never going to happen it is a simple and safe check "just to be
     * sure" so let's be safe.
     */
    if (EC_POINT_is_at_infinity(sess->group, K)) {
	DEBUG2("pwd: k is point-at-infinity!");
	goto fin;
    }
    if (!EC_POINT_get_affine_coordinates_GFp(sess->group, K, sess->k,
					     NULL, bnctx)) {
	DEBUG2("pwd: unable to get shared secret from K");
	goto fin;
    }
    res = 0;

  fin:
    EC_POINT_free(K);
    EC_POINT_free(point);
    BN_free(cofactor);
    BN_free(x);
    BN_free(y);

    return res;
}
Пример #30
0
int
compute_password_element (pwd_session_t *sess, uint16_t grp_num,
			  char *password, int password_len,
			  char *id_server, int id_server_len,
			  char *id_peer, int id_peer_len,
			  uint32_t *token)
{
    BIGNUM *x_candidate = NULL, *rnd = NULL, *cofactor = NULL;
    HMAC_CTX ctx;
    uint8_t pwe_digest[SHA256_DIGEST_LENGTH], *prfbuf = NULL, ctr;
    int nid, is_odd, primebitlen, primebytelen, ret = 0;

    switch (grp_num) { /* from IANA registry for IKE D-H groups */
	case 19:
	    nid = NID_X9_62_prime256v1;
	    break;
	case 20:
	    nid = NID_secp384r1;
	    break;
	case 21:
	    nid = NID_secp521r1;
	    break;
	case 25:
	    nid = NID_X9_62_prime192v1;
	    break;
	case 26:
	    nid = NID_secp224r1;
	    break;
	default:
	    DEBUG("unknown group %d", grp_num);
	    goto fail;
    }

    sess->pwe = NULL;
    sess->order = NULL;
    sess->prime = NULL;

    if ((sess->group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
	DEBUG("unable to create EC_GROUP");
	goto fail;
    }

    if (((rnd = BN_new()) == NULL) ||
	((cofactor = BN_new()) == NULL) ||
	((sess->pwe = EC_POINT_new(sess->group)) == NULL) ||
	((sess->order = BN_new()) == NULL) ||
	((sess->prime = BN_new()) == NULL) ||
	((x_candidate = BN_new()) == NULL)) {
	DEBUG("unable to create bignums");
	goto fail;
    }

    if (!EC_GROUP_get_curve_GFp(sess->group, sess->prime, NULL, NULL, NULL))
    {
	DEBUG("unable to get prime for GFp curve");
	goto fail;
    }
    if (!EC_GROUP_get_order(sess->group, sess->order, NULL)) {
	DEBUG("unable to get order for curve");
	goto fail;
    }
    if (!EC_GROUP_get_cofactor(sess->group, cofactor, NULL)) {
	DEBUG("unable to get cofactor for curve");
	goto fail;
    }
    primebitlen = BN_num_bits(sess->prime);
    primebytelen = BN_num_bytes(sess->prime);
    if ((prfbuf = talloc_zero_array(sess, uint8_t, primebytelen)) == NULL) {
	DEBUG("unable to alloc space for prf buffer");
	goto fail;
    }
    ctr = 0;
    while (1) {
	if (ctr > 10) {
	    DEBUG("unable to find random point on curve for group %d, something's fishy", grp_num);
	    goto fail;
	}
	ctr++;

	/*
	 * compute counter-mode password value and stretch to prime
	 *    pwd-seed = H(token | peer-id | server-id | password |
	 *		   counter)
	 */
	H_Init(&ctx);
	H_Update(&ctx, (uint8_t *)token, sizeof(*token));
	H_Update(&ctx, (uint8_t *)id_peer, id_peer_len);
	H_Update(&ctx, (uint8_t *)id_server, id_server_len);
	H_Update(&ctx, (uint8_t *)password, password_len);
	H_Update(&ctx, (uint8_t *)&ctr, sizeof(ctr));
	H_Final(&ctx, pwe_digest);

	BN_bin2bn(pwe_digest, SHA256_DIGEST_LENGTH, rnd);
	eap_pwd_kdf(pwe_digest, SHA256_DIGEST_LENGTH,
		    "EAP-pwd Hunting And Pecking",
		    strlen("EAP-pwd Hunting And Pecking"),
		    prfbuf, primebitlen);

	BN_bin2bn(prfbuf, primebytelen, x_candidate);
	/*
	 * eap_pwd_kdf() returns a string of bits 0..primebitlen but
	 * BN_bin2bn will treat that string of bits as a big endian
	 * number. If the primebitlen is not an even multiple of 8
	 * then excessive bits-- those _after_ primebitlen-- so now
	 * we have to shift right the amount we masked off.
	 */
	if (primebitlen % 8) {
	    BN_rshift(x_candidate, x_candidate, (8 - (primebitlen % 8)));
	}
	if (BN_ucmp(x_candidate, sess->prime) >= 0) {
	    continue;
	}
	/*
	 * need to unambiguously identify the solution, if there is
	 * one...
	 */
	if (BN_is_odd(rnd)) {
	    is_odd = 1;
	} else {
	    is_odd = 0;
	}
	/*
	 * solve the quadratic equation, if it's not solvable then we
	 * don't have a point
	 */
	if (!EC_POINT_set_compressed_coordinates_GFp(sess->group,
						     sess->pwe,
						     x_candidate,
						     is_odd, NULL)) {
	    continue;
	}
	/*
	 * If there's a solution to the equation then the point must be
	 * on the curve so why check again explicitly? OpenSSL code
	 * says this is required by X9.62. We're not X9.62 but it can't
	 * hurt just to be sure.
	 */
	if (!EC_POINT_is_on_curve(sess->group, sess->pwe, NULL)) {
	    DEBUG("EAP-pwd: point is not on curve");
	    continue;
	}

	if (BN_cmp(cofactor, BN_value_one())) {
	    /* make sure the point is not in a small sub-group */
	    if (!EC_POINT_mul(sess->group, sess->pwe, NULL, sess->pwe,
			      cofactor, NULL)) {
		DEBUG("EAP-pwd: cannot multiply generator by order");
		continue;
	    }
	    if (EC_POINT_is_at_infinity(sess->group, sess->pwe)) {
		DEBUG("EAP-pwd: point is at infinity");
		continue;
	    }
	}
	/* if we got here then we have a new generator. */
	break;
    }
    sess->group_num = grp_num;
    if (0) {
fail:				/* DON'T free sess, it's in handler->opaque */
	ret = -1;
    }
    /* cleanliness and order.... */
    BN_free(cofactor);
    BN_free(x_candidate);
    BN_free(rnd);
    talloc_free(prfbuf);

    return ret;
}