Esempio n. 1
0
int
BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
	int ret = 0;
	BIGNUM *Ri, *R;

	BN_CTX_start(ctx);
	if ((Ri = BN_CTX_get(ctx)) == NULL)
		goto err;
	R = &(mont->RR);				/* grab RR as a temp */
	if (!BN_copy(&(mont->N), mod))
		 goto err;				/* Set N */
	mont->N.neg = 0;

#ifdef MONT_WORD
	{
		BIGNUM tmod;
		BN_ULONG buf[2];

		BN_init(&tmod);
		tmod.d = buf;
		tmod.dmax = 2;
		tmod.neg = 0;

		mont->ri = (BN_num_bits(mod) +
		    (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;

#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
		/* Only certain BN_BITS2<=32 platforms actually make use of
		 * n0[1], and we could use the #else case (with a shorter R
		 * value) for the others.  However, currently only the assembler
		 * files do know which is which. */

		BN_zero(R);
		if (!(BN_set_bit(R, 2 * BN_BITS2)))
			goto err;

		tmod.top = 0;
		if ((buf[0] = mod->d[0]))
			tmod.top = 1;
		if ((buf[1] = mod->top > 1 ? mod->d[1] : 0))
			tmod.top = 2;

		if ((BN_mod_inverse_ct(Ri, R, &tmod, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
			goto err; /* R*Ri */
		if (!BN_is_zero(Ri)) {
			if (!BN_sub_word(Ri, 1))
				goto err;
		}
		else /* if N mod word size == 1 */
		{
			if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
				goto err;
			/* Ri-- (mod double word size) */
			Ri->neg = 0;
			Ri->d[0] = BN_MASK2;
			Ri->d[1] = BN_MASK2;
			Ri->top = 2;
		}
		if (!BN_div_ct(Ri, NULL, Ri, &tmod, ctx))
			goto err;
		/* Ni = (R*Ri-1)/N,
		 * keep only couple of least significant words: */
		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
		mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
#else
		BN_zero(R);
		if (!(BN_set_bit(R, BN_BITS2)))
			goto err;	/* R */

		buf[0] = mod->d[0]; /* tmod = N mod word size */
		buf[1] = 0;
		tmod.top = buf[0] != 0 ? 1 : 0;
		/* Ri = R^-1 mod N*/
		if ((BN_mod_inverse_ct(Ri, R, &tmod, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, BN_BITS2))
			goto err; /* R*Ri */
		if (!BN_is_zero(Ri)) {
			if (!BN_sub_word(Ri, 1))
				goto err;
		}
		else /* if N mod word size == 1 */
		{
			if (!BN_set_word(Ri, BN_MASK2))
				goto err;  /* Ri-- (mod word size) */
		}
		if (!BN_div_ct(Ri, NULL, Ri, &tmod, ctx))
			goto err;
		/* Ni = (R*Ri-1)/N,
		 * keep only least significant word: */
		mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
		mont->n0[1] = 0;
#endif
	}
#else /* !MONT_WORD */
	{ /* bignum version */
		mont->ri = BN_num_bits(&mont->N);
		BN_zero(R);
		if (!BN_set_bit(R, mont->ri))
			goto err;  /* R = 2^ri */
		/* Ri = R^-1 mod N*/
		if ((BN_mod_inverse_ct(Ri, R, &mont->N, ctx)) == NULL)
			goto err;
		if (!BN_lshift(Ri, Ri, mont->ri))
			goto err; /* R*Ri */
		if (!BN_sub_word(Ri, 1))
			goto err;
		/* Ni = (R*Ri-1) / N */
		if (!BN_div_ct(&(mont->Ni), NULL, Ri, &mont->N, ctx))
			goto err;
	}
#endif

	/* setup RR for conversions */
	BN_zero(&(mont->RR));
	if (!BN_set_bit(&(mont->RR), mont->ri*2))
		goto err;
	if (!BN_mod_ct(&(mont->RR), &(mont->RR), &(mont->N), ctx))
		goto err;

	ret = 1;

err:
	BN_CTX_end(ctx);
	return ret;
}
Esempio n. 2
0
static int
ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
	BN_CTX   *ctx = NULL;
	BIGNUM	 *k = NULL, *r = NULL, *order = NULL, *X = NULL;
	EC_POINT *tmp_point = NULL;
	const EC_GROUP *group;
	int 	 ret = 0;

	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
		ECDSAerror(ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}

	if (ctx_in == NULL) {
		if ((ctx = BN_CTX_new()) == NULL) {
			ECDSAerror(ERR_R_MALLOC_FAILURE);
			return 0;
		}
	} else
		ctx = ctx_in;

	k = BN_new();	/* this value is later returned in *kinvp */
	r = BN_new();	/* this value is later returned in *rp    */
	order = BN_new();
	X = BN_new();
	if (!k || !r || !order || !X) {
		ECDSAerror(ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if ((tmp_point = EC_POINT_new(group)) == NULL) {
		ECDSAerror(ERR_R_EC_LIB);
		goto err;
	}
	if (!EC_GROUP_get_order(group, order, ctx)) {
		ECDSAerror(ERR_R_EC_LIB);
		goto err;
	}

	do {
		/* get random k */
		do
			if (!BN_rand_range(k, order)) {
				ECDSAerror(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
				goto err;
			}
		while (BN_is_zero(k));

		/* We do not want timing information to leak the length of k,
		 * so we compute G*k using an equivalent scalar of fixed
		 * bit-length. */
		if (!BN_add(k, k, order))
			goto err;
		if (BN_num_bits(k) <= BN_num_bits(order))
			if (!BN_add(k, k, order))
				goto err;

		BN_set_flags(k, BN_FLG_CONSTTIME);

		/* compute r the x-coordinate of generator * k */
		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
			ECDSAerror(ERR_R_EC_LIB);
			goto err;
		}
		if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
		    NID_X9_62_prime_field) {
			if (!EC_POINT_get_affine_coordinates_GFp(group,
			    tmp_point, X, NULL, ctx)) {
				ECDSAerror(ERR_R_EC_LIB);
				goto err;
			}
		}
#ifndef OPENSSL_NO_EC2M
		else /* NID_X9_62_characteristic_two_field */
		{
			if (!EC_POINT_get_affine_coordinates_GF2m(group,
			    tmp_point, X, NULL, ctx)) {
				ECDSAerror(ERR_R_EC_LIB);
				goto err;
			}
		}
#endif
		if (!BN_nnmod(r, X, order, ctx)) {
			ECDSAerror(ERR_R_BN_LIB);
			goto err;
		}
	} while (BN_is_zero(r));

	/* compute the inverse of k */
	if (!BN_mod_inverse_ct(k, k, order, ctx)) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}
	/* clear old values if necessary */
	BN_clear_free(*rp);
	BN_clear_free(*kinvp);
	/* save the pre-computed values  */
	*rp = r;
	*kinvp = k;
	ret = 1;

err:
	if (!ret) {
		BN_clear_free(k);
		BN_clear_free(r);
	}
	if (ctx_in == NULL)
		BN_CTX_free(ctx);
	BN_free(order);
	EC_POINT_free(tmp_point);
	BN_clear_free(X);
	return (ret);
}
Esempio n. 3
0
static int
ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
    EC_KEY *eckey)
{
	int ret = -1, i;
	BN_CTX   *ctx;
	BIGNUM   *order, *u1, *u2, *m, *X;
	EC_POINT *point = NULL;
	const EC_GROUP *group;
	const EC_POINT *pub_key;

	/* check input values */
	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
	    (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
		ECDSAerror(ECDSA_R_MISSING_PARAMETERS);
		return -1;
	}

	ctx = BN_CTX_new();
	if (!ctx) {
		ECDSAerror(ERR_R_MALLOC_FAILURE);
		return -1;
	}
	BN_CTX_start(ctx);
	order = BN_CTX_get(ctx);
	u1 = BN_CTX_get(ctx);
	u2 = BN_CTX_get(ctx);
	m = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	if (!X) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}

	if (!EC_GROUP_get_order(group, order, ctx)) {
		ECDSAerror(ERR_R_EC_LIB);
		goto err;
	}

	if (BN_is_zero(sig->r)          || BN_is_negative(sig->r) ||
	    BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s)  ||
	    BN_is_negative(sig->s)      || BN_ucmp(sig->s, order) >= 0) {
		ECDSAerror(ECDSA_R_BAD_SIGNATURE);
		ret = 0;	/* signature is invalid */
		goto err;
	}
	/* calculate tmp1 = inv(S) mod order */
	if (!BN_mod_inverse_ct(u2, sig->s, order, ctx)) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}
	/* digest -> m */
	i = BN_num_bits(order);
	/* Need to truncate digest if it is too long: first truncate whole
	 * bytes.
	 */
	if (8 * dgst_len > i)
		dgst_len = (i + 7)/8;
	if (!BN_bin2bn(dgst, dgst_len, m)) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}
	/* If still too long truncate remaining bits with a shift */
	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}
	/* u1 = m * tmp mod order */
	if (!BN_mod_mul(u1, m, u2, order, ctx)) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}
	/* u2 = r * w mod q */
	if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}

	if ((point = EC_POINT_new(group)) == NULL) {
		ECDSAerror(ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
		ECDSAerror(ERR_R_EC_LIB);
		goto err;
	}
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
	    NID_X9_62_prime_field) {
		if (!EC_POINT_get_affine_coordinates_GFp(group,
		    point, X, NULL, ctx)) {
			ECDSAerror(ERR_R_EC_LIB);
			goto err;
		}
	}
#ifndef OPENSSL_NO_EC2M
	else /* NID_X9_62_characteristic_two_field */
	{
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
		    point, X, NULL, ctx)) {
			ECDSAerror(ERR_R_EC_LIB);
			goto err;
		}
	}
#endif
	if (!BN_nnmod(u1, X, order, ctx)) {
		ECDSAerror(ERR_R_BN_LIB);
		goto err;
	}
	/*  if the signature is correct u1 is equal to sig->r */
	ret = (BN_ucmp(u1, sig->r) == 0);

err:
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	EC_POINT_free(point);
	return ret;
}
Esempio n. 4
0
int 
ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP * group, const EC_POINT * point,
    BIGNUM * x, BIGNUM * y, BN_CTX * ctx)
{
	BN_CTX *new_ctx = NULL;
	BIGNUM *Z, *Z_1, *Z_2, *Z_3;
	const BIGNUM *Z_;
	int ret = 0;

	if (EC_POINT_is_at_infinity(group, point) > 0) {
		ECerror(EC_R_POINT_AT_INFINITY);
		return 0;
	}
	if (ctx == NULL) {
		ctx = new_ctx = BN_CTX_new();
		if (ctx == NULL)
			return 0;
	}
	BN_CTX_start(ctx);
	if ((Z = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((Z_1 = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((Z_2 = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((Z_3 = BN_CTX_get(ctx)) == NULL)
		goto err;

	/* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */

	if (group->meth->field_decode) {
		if (!group->meth->field_decode(group, Z, &point->Z, ctx))
			goto err;
		Z_ = Z;
	} else {
		Z_ = &point->Z;
	}

	if (BN_is_one(Z_)) {
		if (group->meth->field_decode) {
			if (x != NULL) {
				if (!group->meth->field_decode(group, x, &point->X, ctx))
					goto err;
			}
			if (y != NULL) {
				if (!group->meth->field_decode(group, y, &point->Y, ctx))
					goto err;
			}
		} else {
			if (x != NULL) {
				if (!BN_copy(x, &point->X))
					goto err;
			}
			if (y != NULL) {
				if (!BN_copy(y, &point->Y))
					goto err;
			}
		}
	} else {
		if (!BN_mod_inverse_ct(Z_1, Z_, &group->field, ctx)) {
			ECerror(ERR_R_BN_LIB);
			goto err;
		}
		if (group->meth->field_encode == 0) {
			/* field_sqr works on standard representation */
			if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
				goto err;
		} else {
			if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
				goto err;
		}

		if (x != NULL) {
			/*
			 * in the Montgomery case, field_mul will cancel out
			 * Montgomery factor in X:
			 */
			if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx))
				goto err;
		}
		if (y != NULL) {
			if (group->meth->field_encode == 0) {
				/* field_mul works on standard representation */
				if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
					goto err;
			} else {
				if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
					goto err;
			}

			/*
			 * in the Montgomery case, field_mul will cancel out
			 * Montgomery factor in Y:
			 */
			if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx))
				goto err;
		}
	}

	ret = 1;

err:
	BN_CTX_end(ctx);
	BN_CTX_free(new_ctx);
	return ret;
}
Esempio n. 5
0
int 
ec_GFp_simple_points_make_affine(const EC_GROUP * group, size_t num, EC_POINT * points[], BN_CTX * ctx)
{
	BN_CTX *new_ctx = NULL;
	BIGNUM *tmp0, *tmp1;
	size_t pow2 = 0;
	BIGNUM **heap = NULL;
	size_t i;
	int ret = 0;

	if (num == 0)
		return 1;

	if (ctx == NULL) {
		ctx = new_ctx = BN_CTX_new();
		if (ctx == NULL)
			return 0;
	}
	BN_CTX_start(ctx);
	if ((tmp0 = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((tmp1 = BN_CTX_get(ctx)) == NULL)
		goto err;

	/*
	 * Before converting the individual points, compute inverses of all Z
	 * values. Modular inversion is rather slow, but luckily we can do
	 * with a single explicit inversion, plus about 3 multiplications per
	 * input value.
	 */

	pow2 = 1;
	while (num > pow2)
		pow2 <<= 1;
	/*
	 * Now pow2 is the smallest power of 2 satifsying pow2 >= num. We
	 * need twice that.
	 */
	pow2 <<= 1;

	heap = reallocarray(NULL, pow2, sizeof heap[0]);
	if (heap == NULL)
		goto err;

	/*
	 * The array is used as a binary tree, exactly as in heapsort:
	 * 
	 * heap[1] heap[2]                     heap[3] heap[4]       heap[5]
	 * heap[6]       heap[7] heap[8]heap[9] heap[10]heap[11]
	 * heap[12]heap[13] heap[14] heap[15]
	 * 
	 * We put the Z's in the last line; then we set each other node to the
	 * product of its two child-nodes (where empty or 0 entries are
	 * treated as ones); then we invert heap[1]; then we invert each
	 * other node by replacing it by the product of its parent (after
	 * inversion) and its sibling (before inversion).
	 */
	heap[0] = NULL;
	for (i = pow2 / 2 - 1; i > 0; i--)
		heap[i] = NULL;
	for (i = 0; i < num; i++)
		heap[pow2 / 2 + i] = &points[i]->Z;
	for (i = pow2 / 2 + num; i < pow2; i++)
		heap[i] = NULL;

	/* set each node to the product of its children */
	for (i = pow2 / 2 - 1; i > 0; i--) {
		heap[i] = BN_new();
		if (heap[i] == NULL)
			goto err;

		if (heap[2 * i] != NULL) {
			if ((heap[2 * i + 1] == NULL) || BN_is_zero(heap[2 * i + 1])) {
				if (!BN_copy(heap[i], heap[2 * i]))
					goto err;
			} else {
				if (BN_is_zero(heap[2 * i])) {
					if (!BN_copy(heap[i], heap[2 * i + 1]))
						goto err;
				} else {
					if (!group->meth->field_mul(group, heap[i],
						heap[2 * i], heap[2 * i + 1], ctx))
						goto err;
				}
			}
		}
	}

	/* invert heap[1] */
	if (!BN_is_zero(heap[1])) {
		if (!BN_mod_inverse_ct(heap[1], heap[1], &group->field, ctx)) {
			ECerror(ERR_R_BN_LIB);
			goto err;
		}
	}
	if (group->meth->field_encode != 0) {
		/*
		 * in the Montgomery case, we just turned  R*H  (representing
		 * H) into  1/(R*H),  but we need  R*(1/H)  (representing
		 * 1/H); i.e. we have need to multiply by the Montgomery
		 * factor twice
		 */
		if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
			goto err;
		if (!group->meth->field_encode(group, heap[1], heap[1], ctx))
			goto err;
	}
	/* set other heap[i]'s to their inverses */
	for (i = 2; i < pow2 / 2 + num; i += 2) {
		/* i is even */
		if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) {
			if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx))
				goto err;
			if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx))
				goto err;
			if (!BN_copy(heap[i], tmp0))
				goto err;
			if (!BN_copy(heap[i + 1], tmp1))
				goto err;
		} else {
			if (!BN_copy(heap[i], heap[i / 2]))
				goto err;
		}
	}

	/*
	 * we have replaced all non-zero Z's by their inverses, now fix up
	 * all the points
	 */
	for (i = 0; i < num; i++) {
		EC_POINT *p = points[i];

		if (!BN_is_zero(&p->Z)) {
			/* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */

			if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx))
				goto err;
			if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx))
				goto err;

			if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx))
				goto err;
			if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx))
				goto err;

			if (group->meth->field_set_to_one != 0) {
				if (!group->meth->field_set_to_one(group, &p->Z, ctx))
					goto err;
			} else {
				if (!BN_one(&p->Z))
					goto err;
			}
			p->Z_is_one = 1;
		}
	}

	ret = 1;

err:
	BN_CTX_end(ctx);
	BN_CTX_free(new_ctx);
	if (heap != NULL) {
		/*
		 * heap[pow2/2] .. heap[pow2-1] have not been allocated
		 * locally!
		 */
		for (i = pow2 / 2 - 1; i > 0; i--) {
			BN_clear_free(heap[i]);
		}
		free(heap);
	}
	return ret;
}
Esempio n. 6
0
int
BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, const BIGNUM *Xp,
    const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
    BN_GENCB *cb)
{
	int ret = 0;

	BIGNUM *t, *p1p2, *pm1;

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

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

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

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

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

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

	/* First set p to value of Rp */

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

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

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

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

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

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

	/* p now equals Rp */

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

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

	/* p now equals Yp0 */

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

	BN_GENCB_call(cb, 3, 0);

	ret = 1;

err:

	BN_CTX_end(ctx);

	return ret;
}