예제 #1
0
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
                                   unsigned int *k2, unsigned int *k3)
{
    if (group == NULL)
        return 0;

    if (EC_GROUP_method_of(group)->group_set_curve !=
        ec_GF2m_simple_group_set_curve || !((group->poly[0] != 0)
                                            && (group->poly[1] != 0)
                                            && (group->poly[2] != 0)
                                            && (group->poly[3] != 0)
                                            && (group->poly[4] == 0))) {
        ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }

    if (k1)
        *k1 = group->poly[3];
    if (k2)
        *k2 = group->poly[2];
    if (k3)
        *k3 = group->poly[1];

    return 1;
}
예제 #2
0
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
                                   unsigned int *k2, unsigned int *k3)
{
    if (group == NULL)
        return 0;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
            NID_X9_62_characteristic_two_field
            || !((group->poly[0] != 0) && (group->poly[1] != 0)
                 && (group->poly[2] != 0) && (group->poly[3] != 0)
                 && (group->poly[4] == 0))) {
        ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }

    if (k1)
        *k1 = group->poly[3];
    if (k2)
        *k2 = group->poly[2];
    if (k3)
        *k3 = group->poly[1];

    return 1;
}
예제 #3
0
EC_KEY *
EC_KEY_copy(EC_KEY * dest, const EC_KEY * src)
{
	EC_EXTRA_DATA *d;

	if (dest == NULL || src == NULL) {
		ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
		return NULL;
	}
	/* copy the parameters */
	if (src->group) {
		const EC_METHOD *meth = EC_GROUP_method_of(src->group);
		/* clear the old group */
		EC_GROUP_free(dest->group);
		dest->group = EC_GROUP_new(meth);
		if (dest->group == NULL)
			return NULL;
		if (!EC_GROUP_copy(dest->group, src->group))
			return NULL;
	}
	/* copy the public key */
	if (src->pub_key && src->group) {
		EC_POINT_free(dest->pub_key);
		dest->pub_key = EC_POINT_new(src->group);
		if (dest->pub_key == NULL)
			return NULL;
		if (!EC_POINT_copy(dest->pub_key, src->pub_key))
			return NULL;
	}
	/* copy the private key */
	if (src->priv_key) {
		if (dest->priv_key == NULL) {
			dest->priv_key = BN_new();
			if (dest->priv_key == NULL)
				return NULL;
		}
		if (!BN_copy(dest->priv_key, src->priv_key))
			return NULL;
	}
	/* copy method/extra data */
	EC_EX_DATA_free_all_data(&dest->method_data);

	for (d = src->method_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->method_data, t, d->dup_func,
		    d->free_func, d->clear_free_func))
			return 0;
	}

	/* copy the rest */
	dest->enc_flag = src->enc_flag;
	dest->conv_form = src->conv_form;
	dest->version = src->version;
	dest->flags = src->flags;

	return dest;
}
예제 #4
0
static int ec_get_pubkey(EC_KEY *key, BIGNUM *x, BIGNUM *y)
{
    const EC_POINT *pt;
    const EC_GROUP *grp;
    const EC_METHOD *meth;
    int rv;
    BN_CTX *ctx;
    ctx = BN_CTX_new();
    if (!ctx)
        return 0;
    grp = EC_KEY_get0_group(key);
    pt = EC_KEY_get0_public_key(key);
    meth = EC_GROUP_method_of(grp);
    if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
        rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, x, y, ctx);
    else
# ifdef OPENSSL_NO_EC2M
    {
        fprintf(stderr, "ERROR: GF2m not supported\n");
        exit(1);
    }
# else
        rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, x, y, ctx);
# endif

    BN_CTX_free(ctx);

    return rv;

}
예제 #5
0
int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
	{
	if (group == NULL)
		return 0;

	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
		{
		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		return 0;
		}

	if (k)
		*k = group->poly[1];

	return 1;
	}
예제 #6
0
int 
EC_GROUP_get_trinomial_basis(const EC_GROUP * group, unsigned int *k)
{
	if (group == NULL)
		return 0;

	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
	    NID_X9_62_characteristic_two_field
	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) {
		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		return 0;
	}
	if (k)
		*k = group->poly[1];

	return 1;
}
예제 #7
0
파일: t1_lib.c 프로젝트: bbbrumley/openbsd
/* For an EC key set TLS ID and required compression based on parameters. */
static int
tls1_set_ec_id(uint16_t *curve_id, uint8_t *comp_id, EC_KEY *ec)
{
	const EC_GROUP *grp;
	const EC_METHOD *meth;
	int is_prime = 0;
	int nid, id;

	if (ec == NULL)
		return (0);

	/* Determine if it is a prime field. */
	if ((grp = EC_KEY_get0_group(ec)) == NULL)
		return (0);
	if ((meth = EC_GROUP_method_of(grp)) == NULL)
		return (0);
	if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
		is_prime = 1;

	/* Determine curve ID. */
	nid = EC_GROUP_get_curve_name(grp);
	id = tls1_ec_nid2curve_id(nid);

	/* If we have an ID set it, otherwise set arbitrary explicit curve. */
	if (id != 0)
		*curve_id = id;
	else
		*curve_id = is_prime ? 0xff01 : 0xff02;

	/* Specify the compression identifier. */
	if (comp_id != NULL) {
		if (EC_KEY_get0_public_key(ec) == NULL)
			return (0);

		if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
			*comp_id = is_prime ?
			    TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime :
			    TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
		} else {
			*comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
		}
	}
	return (1);
}
예제 #8
0
int EC_GROUP_get_basis_type(const EC_GROUP *group)
{
    int i = 0;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
            NID_X9_62_characteristic_two_field)
        /* everything else is currently not supported */
        return 0;

    while (group->poly[i] != 0)
        i++;

    if (i == 4)
        return NID_X9_62_ppBasis;
    else if (i == 2)
        return NID_X9_62_tpBasis;
    else
        /* everything else is currently not supported */
        return 0;
}
예제 #9
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)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}

	if (ctx_in == NULL) 
	{
		if ((ctx = BN_CTX_new()) == NULL)
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,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)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if ((tmp_point = EC_POINT_new(group)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
		goto err;
	}
	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
		goto err;
	}
	
	do
	{
		/* get random k */	
		do
			if (!BN_rand_range(k, order))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
				 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);	
				goto err;
			}
		while (BN_is_zero(k));

		/* compute r the x-coordinate of generator * k */
		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 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))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
				goto err;
			}
		}
		else /* NID_X9_62_characteristic_two_field */
		{
			if (!EC_POINT_get_affine_coordinates_GF2m(group,
				tmp_point, X, NULL, ctx))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
				goto err;
			}
		}
		if (!BN_nnmod(r, X, order, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
			goto err;
		}
	}
	while (BN_is_zero(r));

	/* compute the inverse of k */
	if (!BN_mod_inverse(k, k, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
		goto err;	
	}
	/* clear old values if necessary */
	if (*rp != NULL)
		BN_clear_free(*rp);
	if (*kinvp != NULL) 
		BN_clear_free(*kinvp);
	/* save the pre-computed values  */
	*rp    = r;
	*kinvp = k;
	ret = 1;
err:
	if (!ret)
	{
		if (k != NULL) BN_clear_free(k);
		if (r != NULL) BN_clear_free(r);
	}
	if (ctx_in == NULL) 
		BN_CTX_free(ctx);
	if (order != NULL)
		BN_free(order);
	if (tmp_point != NULL) 
		EC_POINT_free(tmp_point);
	if (X)
		BN_clear_free(X);
	return(ret);
}
예제 #10
0
파일: ecs_ossl.c 프로젝트: LucidOne/Rovio
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
		const ECDSA_SIG *sig, EC_KEY *eckey)
{
	int ret = -1;
	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)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
		return -1;
	}

	ctx = BN_CTX_new();
	if (!ctx)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	
	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}
	if (8 * dgst_len > BN_num_bits(order))
	{
		/* XXX
		 * 
		 * Should provide for optional hash truncation:
		 * Keep the BN_num_bits(order) leftmost bits of dgst
		 * (see March 2006 FIPS 186-3 draft, which has a few
		 * confusing errors in this part though)
		 */

		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY,
			ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
		ret = 0;
		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)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
		ret = 0;	/* signature is invalid */
		goto err;
	}
	/* calculate tmp1 = inv(S) mod order */
	if (!BN_mod_inverse(u2, sig->s, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* digest -> m */
	if (!BN_bin2bn(dgst, dgst_len, m))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* u1 = m * tmp mod order */
	if (!BN_mod_mul(u1, m, u2, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* u2 = r * w mod q */
	if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}

	if ((point = EC_POINT_new(group)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
	else /* NID_X9_62_characteristic_two_field */
	{
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
			point, X, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
	
	if (!BN_nnmod(u1, X, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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);
	if (point)
		EC_POINT_free(point);
	return ret;
}
예제 #11
0
static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) {

	printf("in ecdh test\n");
	EC_KEY *a = NULL;    //EC_KEY is a structure
	EC_KEY *b = NULL;
	BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL;
	char buf[12];
	unsigned char *abuf = NULL, *bbuf = NULL;
	int i, alen, blen, aout, bout, ret = 0;
	const EC_GROUP *group;

	a = EC_KEY_new_by_curve_name(nid);
// creates a new key according to the curve specified
//it fills in the EC_KEY structure // use function called EC_KEY *EC_KEY_new(void)
//also use a function called EC_GROUP_new_by_curve_name() creates a EC_GROUP structure specified by a curve name (in form of a NID) */
// the group returned is set in the EC_KEY structure.

	b = EC_KEY_new_by_curve_name(nid);
	if (a == NULL || b == NULL)
		goto err;

	group = EC_KEY_get0_group(a); //returns the EC_GROUP structure created by the EC_KEY structure
//EC_GROUP structure is present in the EC_KEY structure.

	if ((x_a = BN_new()) == NULL)
		goto err;
	//BN_new returns a pointer to the bignum
	if ((y_a = BN_new()) == NULL)
		goto err;
	if ((x_b = BN_new()) == NULL)
		goto err;
	if ((y_b = BN_new()) == NULL)
		goto err;

	BIO_puts(out, "Testing key generation with ");
	BIO_puts(out, text);

#ifdef NOISY
	printf ("noisy");
	BIO_puts(out,"\n");
	BIO_puts(out,"\n");
	BIO_puts(out,"\n");
#else
	BIO_flush(out);
#endif

//public key number one is created here

	if (!EC_KEY_generate_key(a))
		goto err;
	//pass the filled EC_KEY structure and it will create a public or private ec key.
//it places the key in a->priv_key a->pub_key   /// PUBLIC AND PVT KEYS ARE GENERATED BY THE SCALAR MULTIPLICATION
	printf("\n1 ) generating keys\n");

	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group))
			== NID_X9_62_prime_field) {
		if (!EC_POINT_get_affine_coordinates_GFp(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}
	//returns the public key
	else {
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}

	//BN_print_fp(stdout, a->pub_key);
	printf("private key is : ");
	BN_print_fp(stdout, EC_KEY_get0_private_key(a));
	printf("\nAffine cordinates x:");
	BN_print_fp(stdout, x_a);
	printf("\nAffine cordinates y:");
	BN_print_fp(stdout, y_a);

	printf(
			"\n2 ) generated keys , generated affine points x and y , and also determided the primse brinary case\n");

#ifdef NOISY
	printf("no generation");
	BIO_puts(out,"  pri 1=");
	BN_print(out,a->priv_key);
	BIO_puts(out,"\n  pub 1=");
	BN_print(out,x_a);
	BIO_puts(out,",");
	BN_print(out,y_a);
	BIO_puts(out,"\n");
#else
	BIO_printf(out, " .");
	BIO_flush(out);
#endif

//public key number two is created here

	if (!EC_KEY_generate_key(b))
		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,
				EC_KEY_get0_public_key(b), x_b, y_b, ctx))
			goto err;
		// not well
	} else {
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
				EC_KEY_get0_public_key(b), x_b, y_b, ctx))
			goto err;
	}

	//	printf("public key is : ");
	//	BN_print_fp(stdout, EC_KEY_get0_private_key(b));
	//  for public key they will exchange the whole EC_POINT structure
	printf("private key is : ");
	BN_print_fp(stdout, EC_KEY_get0_private_key(b));
	printf("\nAffine cordinates x");
	BN_print_fp(stdout, x_b);
	printf("\nAffine cordinates y");
	BN_print_fp(stdout, y_b);

#ifdef NOISY
	BIO_puts(out,"  pri 2=");
	BN_print(out,b->priv_key);
	BIO_puts(out,"\n  pub 2=");
	BN_print(out,x_b);
	BIO_puts(out,",");
	BN_print(out,y_b);
	BIO_puts(out,"\n");
#else
	BIO_printf(out, ".");
	BIO_flush(out);
#endif

	alen = KDF1_SHA1_len; ///it is a static constant integer.
	abuf = (unsigned char *) OPENSSL_malloc(alen);
	aout = ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a,
			KDF1_SHA1); //generating session key
	//      BN_print(out, abuf);
	//BIO_puts(out,"\n");

#ifdef NOISY
	BIO_puts(out,"  key1 =");
	for (i=0; i<aout; i++)
	{
		sprintf(buf,"%02X",abuf[i]);
		BIO_puts(out,buf);
	}
	BIO_puts(out,"\n");
#else
	BIO_printf(out, ".");
	BIO_flush(out);
#endif

	blen = KDF1_SHA1_len;
	bbuf = (unsigned char *) OPENSSL_malloc(blen);
	bout = ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b,
			KDF1_SHA1);
//	BN_print(out, bbuf);
//	BIO_puts(out,"\n");
#ifdef NOISY
	BIO_puts(out,"  key2 =");
	for (i=0; i<bout; i++)
	{
		sprintf(buf,"%02X",bbuf[i]);
		BIO_puts(out,buf);
	}
	BIO_puts(out,"\n");
#else
	BIO_printf(out, ".");
	BIO_flush(out);
#endif

	if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
#ifndef NOISY
		BIO_printf(out, " failed\n\n");
		BIO_printf(out, "key a:\n");
		BIO_printf(out, "private key: ");
		BN_print(out, EC_KEY_get0_private_key(a));
		BIO_printf(out, "\n");
		BIO_printf(out, "public key (x,y): ");
		BN_print(out, x_a);
		BIO_printf(out, ",");
		BN_print(out, y_a);
		BIO_printf(out, "\nkey b:\n");
		BIO_printf(out, "private key: ");
		BN_print(out, EC_KEY_get0_private_key(b));
		BIO_printf(out, "\n");
		BIO_printf(out, "public key (x,y): ");
		BN_print(out, x_b);
		BIO_printf(out, ",");
		BN_print(out, y_b);
		BIO_printf(out, "\n");
		BIO_printf(out, "generated key a: ");
		for (i = 0; i < bout; i++) {
			sprintf(buf, "%02X", bbuf[i]);
			BIO_puts(out, buf);
		}
		BIO_printf(out, "\n");
		BIO_printf(out, "generated key b: ");
		for (i = 0; i < aout; i++) {
			sprintf(buf, "%02X", abuf[i]);
			BIO_puts(out, buf);
		}
		BIO_printf(out, "\n");
#endif
		fprintf(stderr, "Error in ECDH routines\n");
		ret = 0;
	} else {
#ifndef NOISY
		BIO_printf(out, " ok\n");
#endif
		ret = 1;
	}
	err: ERR_print_errors_fp(stderr);

	if (abuf != NULL)
		OPENSSL_free(abuf);
	if (bbuf != NULL)
		OPENSSL_free(bbuf);
	if (x_a)
		BN_free(x_a);
	if (y_a)
		BN_free(y_a);
	if (x_b)
		BN_free(x_b);
	if (y_b)
		BN_free(y_b);
	if (b)
		EC_KEY_free(b);
	if (a)
		EC_KEY_free(a);
	return (ret);
}
예제 #12
0
/*-
 * This implementation is based on the following primitives in the IEEE 1363 standard:
 *  - ECKAS-DH1
 *  - ECSVDP-DH
 */
int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
                            const EC_POINT *pub_key, const EC_KEY *ecdh)
{
    BN_CTX *ctx;
    EC_POINT *tmp = NULL;
    BIGNUM *x = NULL, *y = NULL;
    const BIGNUM *priv_key;
    const EC_GROUP *group;
    int ret = 0;
    size_t buflen, len;
    unsigned char *buf = NULL;

    if ((ctx = BN_CTX_new()) == NULL)
        goto err;
    BN_CTX_start(ctx);
    x = BN_CTX_get(ctx);
    y = BN_CTX_get(ctx);

    priv_key = EC_KEY_get0_private_key(ecdh);
    if (priv_key == NULL) {
        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE);
        goto err;
    }

    group = EC_KEY_get0_group(ecdh);

    if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) {
        if (!EC_GROUP_get_cofactor(group, x, NULL) ||
            !BN_mul(x, x, priv_key, ctx)) {
            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        priv_key = x;
    }

    if ((tmp = EC_POINT_new(group)) == NULL) {
        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
        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, x, y, ctx)) {
            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
            goto err;
        }
    }
#ifndef OPENSSL_NO_EC2M
    else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) {
            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
            goto err;
        }
    }
#endif

    buflen = (EC_GROUP_get_degree(group) + 7) / 8;
    len = BN_num_bytes(x);
    if (len > buflen) {
        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    if ((buf = OPENSSL_malloc(buflen)) == NULL) {
        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    memset(buf, 0, buflen - len);
    if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB);
        goto err;
    }

    *pout = buf;
    *poutlen = buflen;
    buf = NULL;

    ret = 1;

 err:
    EC_POINT_free(tmp);
    if (ctx)
        BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    OPENSSL_free(buf);
    return ret;
}
예제 #13
0
파일: ecs_ossl.c 프로젝트: izick/eme
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)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}

	if (ctx_in == NULL) 
	{
		if ((ctx = BN_CTX_new()) == NULL)
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,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)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if ((tmp_point = EC_POINT_new(group)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
		goto err;
	}
	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
		goto err;
	}

#ifdef OPENSSL_FIPS
	if (!fips_check_ec_prng(eckey))
		goto err;
#endif
	
	do
	{
		/* get random k */	
		do
			if (!BN_rand_range(k, order))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
				 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);	
				goto err;
			}
		while (BN_is_zero(k));

#ifdef ECDSA_POINT_MUL_NO_CONSTTIME
		/* 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;
#endif /* def(ECDSA_POINT_MUL_NO_CONSTTIME) */

		/* compute r the x-coordinate of generator * k */
		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 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))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,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))
			{
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
				goto err;
			}
		}
#endif
		if (!BN_nnmod(r, X, order, ctx))
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
			goto err;
		}
	}
	while (BN_is_zero(r));

	/* compute the inverse of k */
	if (!BN_mod_inverse(k, k, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
		goto err;	
	}
	/* clear old values if necessary */
	if (*rp != NULL)
		BN_clear_free(*rp);
	if (*kinvp != NULL) 
		BN_clear_free(*kinvp);
	/* save the pre-computed values  */
	*rp    = r;
	*kinvp = k;
	ret = 1;
err:
	if (!ret)
	{
		if (k != NULL) BN_clear_free(k);
		if (r != NULL) BN_clear_free(r);
	}
	if (ctx_in == NULL) 
		BN_CTX_free(ctx);
	if (order != NULL)
		BN_free(order);
	if (tmp_point != NULL) 
		EC_POINT_free(tmp_point);
	if (X)
		BN_clear_free(X);
	return(ret);
}
예제 #14
0
파일: ec_lib.c 프로젝트: LucidOne/Rovio
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
	{
	int    r = 0;
	BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
	BN_CTX *ctx_new = NULL;

	/* compare the field types*/
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
		return 1;
	/* compare the curve name (if present) */
	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
	    EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b))
		return 0;

	if (!ctx)
		ctx_new = ctx = BN_CTX_new();
	if (!ctx)
		return -1;
	
	BN_CTX_start(ctx);
	a1 = BN_CTX_get(ctx);
	a2 = BN_CTX_get(ctx);
	a3 = BN_CTX_get(ctx);
	b1 = BN_CTX_get(ctx);
	b2 = BN_CTX_get(ctx);
	b3 = BN_CTX_get(ctx);
	if (!b3)
		{
		BN_CTX_end(ctx);
		if (ctx_new)
			BN_CTX_free(ctx);
		return -1;
		}

	/* XXX This approach assumes that the external representation
	 * of curves over the same field type is the same.
	 */
	if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
	    !b->meth->group_get_curve(b, b1, b2, b3, ctx))
		r = 1;

	if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
		r = 1;

	/* XXX EC_POINT_cmp() assumes that the methods are equal */
	if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
	    EC_GROUP_get0_generator(b), ctx))
		r = 1;

	if (!r)
		{
		/* compare the order and cofactor */
		if (!EC_GROUP_get_order(a, a1, ctx) ||
		    !EC_GROUP_get_order(b, b1, ctx) ||
		    !EC_GROUP_get_cofactor(a, a2, ctx) ||
		    !EC_GROUP_get_cofactor(b, b2, ctx))
			{
			BN_CTX_end(ctx);
			if (ctx_new)
				BN_CTX_free(ctx);
			return -1;
			}
		if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
			r = 1;
		}

	BN_CTX_end(ctx);
	if (ctx_new)
		BN_CTX_free(ctx);

	return r;
	}
예제 #15
0
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
{
    if (dest == NULL || src == NULL) {
        ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }
    if (src->meth != dest->meth) {
        if (dest->meth->finish != NULL)
            dest->meth->finish(dest);
        if (dest->group && dest->group->meth->keyfinish)
            dest->group->meth->keyfinish(dest);
#ifndef OPENSSL_NO_ENGINE
        if (ENGINE_finish(dest->engine) == 0)
            return 0;
        dest->engine = NULL;
#endif
    }
    /* copy the parameters */
    if (src->group != NULL) {
        const EC_METHOD *meth = EC_GROUP_method_of(src->group);
        /* clear the old group */
        EC_GROUP_free(dest->group);
        dest->group = EC_GROUP_new(meth);
        if (dest->group == NULL)
            return NULL;
        if (!EC_GROUP_copy(dest->group, src->group))
            return NULL;

        /*  copy the public key */
        if (src->pub_key != NULL) {
            EC_POINT_free(dest->pub_key);
            dest->pub_key = EC_POINT_new(src->group);
            if (dest->pub_key == NULL)
                return NULL;
            if (!EC_POINT_copy(dest->pub_key, src->pub_key))
                return NULL;
        }
        /* copy the private key */
        if (src->priv_key != NULL) {
            if (dest->priv_key == NULL) {
                dest->priv_key = BN_new();
                if (dest->priv_key == NULL)
                    return NULL;
            }
            if (!BN_copy(dest->priv_key, src->priv_key))
                return NULL;
            if (src->group->meth->keycopy
                && src->group->meth->keycopy(dest, src) == 0)
                return NULL;
        }
    }


    /* copy the rest */
    dest->enc_flag = src->enc_flag;
    dest->conv_form = src->conv_form;
    dest->version = src->version;
    dest->flags = src->flags;
    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
                            &dest->ex_data, &src->ex_data))
        return NULL;

    if (src->meth != dest->meth) {
#ifndef OPENSSL_NO_ENGINE
        if (src->engine != NULL && ENGINE_init(src->engine) == 0)
            return NULL;
        dest->engine = src->engine;
#endif
        dest->meth = src->meth;
    }

    if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
        return NULL;

    return dest;
}
예제 #16
0
/*
 * NIST SP800-56A co-factor ECDH tests.
 * KATs taken from NIST documents with parameters:
 *
 * - (QCAVSx,QCAVSy) is the public key for CAVS.
 * - dIUT is the private key for IUT.
 * - (QIUTx,QIUTy) is the public key for IUT.
 * - ZIUT is the shared secret KAT.
 *
 * CAVS: Cryptographic Algorithm Validation System
 * IUT: Implementation Under Test
 *
 * This function tests two things:
 *
 * 1. dIUT * G = (QIUTx,QIUTy)
 *    i.e. public key for IUT computes correctly.
 * 2. x-coord of cofactor * dIUT * (QCAVSx,QCAVSy) = ZIUT
 *    i.e. co-factor ECDH key computes correctly.
 *
 * returns zero on failure or unsupported curve. One otherwise.
 */
static int ecdh_cavs_kat(BIO *out, const ecdh_cavs_kat_t *kat)
{
    int rv = 0, is_char_two = 0;
    EC_KEY *key1 = NULL;
    EC_POINT *pub = NULL;
    const EC_GROUP *group = NULL;
    BIGNUM *bnz = NULL, *x = NULL, *y = NULL;
    unsigned char *Ztmp = NULL, *Z = NULL;
    size_t Ztmplen, Zlen;
    BIO_puts(out, "Testing ECC CDH Primitive SP800-56A with ");
    BIO_puts(out, OBJ_nid2sn(kat->nid));

    /* dIUT is IUT's private key */
    if ((key1 = mk_eckey(kat->nid, kat->dIUT)) == NULL)
        goto err;
    /* these are cofactor ECDH KATs */
    EC_KEY_set_flags(key1, EC_FLAG_COFACTOR_ECDH);

    if ((group = EC_KEY_get0_group(key1)) == NULL)
        goto err;
    if ((pub = EC_POINT_new(group)) == NULL)
        goto err;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_characteristic_two_field)
        is_char_two = 1;

    /* (QIUTx, QIUTy) is IUT's public key */
    if(!BN_hex2bn(&x, kat->QIUTx))
        goto err;
    if(!BN_hex2bn(&y, kat->QIUTy))
        goto err;
    if (is_char_two) {
#ifdef OPENSSL_NO_EC2M
        goto err;
#else
        if (!EC_POINT_set_affine_coordinates_GF2m(group, pub, x, y, NULL))
            goto err;
#endif
    }
    else {
        if (!EC_POINT_set_affine_coordinates_GFp(group, pub, x, y, NULL))
            goto err;
    }
    /* dIUT * G = (QIUTx, QIUTy) should hold */
    if (EC_POINT_cmp(group, EC_KEY_get0_public_key(key1), pub, NULL))
        goto err;

    /* (QCAVSx, QCAVSy) is CAVS's public key */
    if(!BN_hex2bn(&x, kat->QCAVSx))
        goto err;
    if(!BN_hex2bn(&y, kat->QCAVSy))
        goto err;
    if (is_char_two) {
#ifdef OPENSSL_NO_EC2M
        goto err;
#else
        if (!EC_POINT_set_affine_coordinates_GF2m(group, pub, x, y, NULL))
            goto err;
#endif
    }
    else {
        if (!EC_POINT_set_affine_coordinates_GFp(group, pub, x, y, NULL))
            goto err;
    }

    /* ZIUT is the shared secret */
    if(!BN_hex2bn(&bnz, kat->ZIUT))
        goto err;
    Ztmplen = (EC_GROUP_get_degree(EC_KEY_get0_group(key1)) + 7) / 8;
    Zlen = BN_num_bytes(bnz);
    if (Zlen > Ztmplen)
        goto err;
    if((Ztmp = OPENSSL_zalloc(Ztmplen)) == NULL)
        goto err;
    if((Z = OPENSSL_zalloc(Ztmplen)) == NULL)
        goto err;
    if(!BN_bn2binpad(bnz, Z, Ztmplen))
        goto err;
    if (!ECDH_compute_key(Ztmp, Ztmplen, pub, key1, 0))
        goto err;
    /* shared secrets should be identical */
    if (memcmp(Ztmp, Z, Ztmplen))
        goto err;
    rv = 1;
 err:
    EC_KEY_free(key1);
    EC_POINT_free(pub);
    BN_free(bnz);
    BN_free(x);
    BN_free(y);
    OPENSSL_free(Ztmp);
    OPENSSL_free(Z);
    if (rv) {
        BIO_puts(out, " ok\n");
    }
    else {
        fprintf(stderr, "Error in ECC CDH routines\n");
        ERR_print_errors_fp(stderr);
    }
    return rv;
}
예제 #17
0
파일: ec_lib.c 프로젝트: Castaglia/openssl
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
{
    int r = 0;
    BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
    BN_CTX *ctx_new = NULL;

    /* compare the field types */
    if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
        EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
        return 1;
    /* compare the curve name (if present in both) */
    if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
        EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
        return 1;
    if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
        return 0;

    if (ctx == NULL)
        ctx_new = ctx = BN_CTX_new();
    if (ctx == NULL)
        return -1;

    BN_CTX_start(ctx);
    a1 = BN_CTX_get(ctx);
    a2 = BN_CTX_get(ctx);
    a3 = BN_CTX_get(ctx);
    b1 = BN_CTX_get(ctx);
    b2 = BN_CTX_get(ctx);
    b3 = BN_CTX_get(ctx);
    if (b3 == NULL) {
        BN_CTX_end(ctx);
        BN_CTX_free(ctx_new);
        return -1;
    }

    /*
     * XXX This approach assumes that the external representation of curves
     * over the same field type is the same.
     */
    if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
        !b->meth->group_get_curve(b, b1, b2, b3, ctx))
        r = 1;

    if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
        r = 1;

    /* XXX EC_POINT_cmp() assumes that the methods are equal */
    if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
                          EC_GROUP_get0_generator(b), ctx))
        r = 1;

    if (!r) {
        const BIGNUM *ao, *bo, *ac, *bc;
        /* compare the order and cofactor */
        ao = EC_GROUP_get0_order(a);
        bo = EC_GROUP_get0_order(b);
        ac = EC_GROUP_get0_cofactor(a);
        bc = EC_GROUP_get0_cofactor(b);
        if (ao == NULL || bo == NULL) {
            BN_CTX_end(ctx);
            BN_CTX_free(ctx_new);
            return -1;
        }
        if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
            r = 1;
    }

    BN_CTX_end(ctx);
    BN_CTX_free(ctx_new);

    return r;
}
예제 #18
0
builtin_curves::builtin_curves()
{
	int i, num_curves = EC_get_builtin_curves(NULL, 0);
	EC_builtin_curve *curves = (EC_builtin_curve*)OPENSSL_malloc(
		(int)(sizeof(EC_builtin_curve) *num_curves));

	check_oom(curves);

	BIGNUM *order = BN_new();
	check_oom(order);

	EC_get_builtin_curves(curves, num_curves);

	for (i=0; i< num_curves; i++) {
		size_t j;
		int flag = 0, nid = curves[i].nid;
		unsigned long type = 0;

		for (j=0; j<ARRAY_SIZE(x962_curve_nids); j++) {
			if (x962_curve_nids[j] == nid) {
				flag = CURVE_X962;
				break;
			}
		}
		if (!flag) {
			for (j=0; j<ARRAY_SIZE(other_curve_nids); j++) {
				if (other_curve_nids[j] == nid) {
					flag = CURVE_OTHER;
					break;
				}
			}
		}
		if (!flag)
			continue;

		EC_GROUP *group = EC_GROUP_new_by_curve_name(nid);
		EC_GROUP_get_order(group, order, NULL);

		switch (EC_METHOD_get_field_type(EC_GROUP_method_of(group))) {
		case NID_X9_62_prime_field:
			type = CKF_EC_F_P;
			break;
		case NID_X9_62_characteristic_two_field:
			type = CKF_EC_F_2M;
			break;
		default:
			continue;
		}
#undef PRINT_KNOWN_CURVES
#ifdef PRINT_KNOWN_CURVES
		fprintf(stderr, "%50s %27s %20s %s\n",
			curves[i].comment, OBJ_nid2sn(nid),
			CCHAR(OBJ_obj2QString(OBJ_nid2obj(nid), 1)),
			type == CKF_EC_F_P ? "Fp" : "F2m");
#endif
		append(builtin_curve(nid, QString(curves[i].comment),
			BN_num_bits(order), flag, type));
                EC_GROUP_free(group);
	}
	BN_free(order);
}
예제 #19
0
int 
ECPKParameters_print(BIO * bp, const EC_GROUP * x, int off)
{
	unsigned char *buffer = NULL;
	size_t buf_len = 0, i;
	int ret = 0, reason = ERR_R_BIO_LIB;
	BN_CTX *ctx = NULL;
	const EC_POINT *point = NULL;
	BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, *order = NULL,
	*cofactor = NULL;
	const unsigned char *seed;
	size_t seed_len = 0;
	const char *nname;

	static const char *gen_compressed = "Generator (compressed):";
	static const char *gen_uncompressed = "Generator (uncompressed):";
	static const char *gen_hybrid = "Generator (hybrid):";

	if (!x) {
		reason = ERR_R_PASSED_NULL_PARAMETER;
		goto err;
	}
	ctx = BN_CTX_new();
	if (ctx == NULL) {
		reason = ERR_R_MALLOC_FAILURE;
		goto err;
	}
	if (EC_GROUP_get_asn1_flag(x)) {
		/* the curve parameter are given by an asn1 OID */
		int nid;

		if (!BIO_indent(bp, off, 128))
			goto err;

		nid = EC_GROUP_get_curve_name(x);
		if (nid == 0)
			goto err;

		if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
			goto err;
		if (BIO_printf(bp, "\n") <= 0)
			goto err;

		nname = EC_curve_nid2nist(nid);
		if (nname) {
			if (!BIO_indent(bp, off, 128))
				goto err;
			if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
				goto err;
		}
	} else {
		/* explicit parameters */
		int is_char_two = 0;
		point_conversion_form_t form;
		int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));

		if (tmp_nid == NID_X9_62_characteristic_two_field)
			is_char_two = 1;

		if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
		    (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
		    (cofactor = BN_new()) == NULL) {
			reason = ERR_R_MALLOC_FAILURE;
			goto err;
		}
#ifndef OPENSSL_NO_EC2M
		if (is_char_two) {
			if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
				reason = ERR_R_EC_LIB;
				goto err;
			}
		} else		/* prime field */
#endif
		{
			if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
				reason = ERR_R_EC_LIB;
				goto err;
			}
		}

		if ((point = EC_GROUP_get0_generator(x)) == NULL) {
			reason = ERR_R_EC_LIB;
			goto err;
		}
		if (!EC_GROUP_get_order(x, order, NULL) ||
		    !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
			reason = ERR_R_EC_LIB;
			goto err;
		}
		form = EC_GROUP_get_point_conversion_form(x);

		if ((gen = EC_POINT_point2bn(x, point,
			    form, NULL, ctx)) == NULL) {
			reason = ERR_R_EC_LIB;
			goto err;
		}
		buf_len = (size_t) BN_num_bytes(p);
		if (buf_len < (i = (size_t) BN_num_bytes(a)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(b)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(gen)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(order)))
			buf_len = i;
		if (buf_len < (i = (size_t) BN_num_bytes(cofactor)))
			buf_len = i;

		if ((seed = EC_GROUP_get0_seed(x)) != NULL)
			seed_len = EC_GROUP_get_seed_len(x);

		buf_len += 10;
		if ((buffer = malloc(buf_len)) == NULL) {
			reason = ERR_R_MALLOC_FAILURE;
			goto err;
		}
		if (!BIO_indent(bp, off, 128))
			goto err;

		/* print the 'short name' of the field type */
		if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
		    <= 0)
			goto err;

		if (is_char_two) {
			/* print the 'short name' of the base type OID */
			int basis_type = EC_GROUP_get_basis_type(x);
			if (basis_type == 0)
				goto err;

			if (!BIO_indent(bp, off, 128))
				goto err;

			if (BIO_printf(bp, "Basis Type: %s\n",
				OBJ_nid2sn(basis_type)) <= 0)
				goto err;

			/* print the polynomial */
			if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
				off))
				goto err;
		} else {
			if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
				goto err;
		}
		if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, buffer, off))
			goto err;
		if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, buffer, off))
			goto err;
		if (form == POINT_CONVERSION_COMPRESSED) {
			if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
				buffer, off))
				goto err;
		} else if (form == POINT_CONVERSION_UNCOMPRESSED) {
			if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
				buffer, off))
				goto err;
		} else {	/* form == POINT_CONVERSION_HYBRID */
			if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
				buffer, off))
				goto err;
		}
		if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
			buffer, off))
			goto err;
		if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
			buffer, off))
			goto err;
		if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
			goto err;
	}
	ret = 1;
err:
	if (!ret)
		ECerror(reason);
	BN_free(p);
	BN_free(a);
	BN_free(b);
	BN_free(gen);
	BN_free(order);
	BN_free(cofactor);
	BN_CTX_free(ctx);
	free(buffer);
	return (ret);
}
예제 #20
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;
    int order_bits;

    if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
        ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (ctx_in == NULL) {
        if ((ctx = BN_CTX_new()) == NULL) {
            ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 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) {
        ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if ((tmp_point = EC_POINT_new(group)) == NULL) {
        ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        goto err;
    }
    if (!EC_GROUP_get_order(group, order, ctx)) {
        ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        goto err;
    }

    /* Preallocate space */
    order_bits = BN_num_bits(order);
    if (!BN_set_bit(k, order_bits)
        || !BN_set_bit(r, order_bits)
        || !BN_set_bit(X, order_bits))
        goto err;

    do {
        /* get random k */
        do
            if (!BN_rand_range(k, order)) {
                ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
                         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.
         *
         * We unconditionally perform both of these additions to prevent a
         * small timing information leakage.  We then choose the sum that is
         * one bit longer than the order.  This guarantees the code
         * path used in the constant time implementations elsewhere.
         *
         * TODO: revisit the BN_copy aiming for a memory access agnostic
         * conditional copy.
         */
        if (!BN_add(r, k, order)
            || !BN_add(X, r, order)
            || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X))
            goto err;

        /* compute r the x-coordinate of generator * k */
        if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
            ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 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)) {
                ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, 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)) {
                ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
                goto err;
            }
        }
#endif
        if (!BN_nnmod(r, X, order, ctx)) {
            ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    }
    while (BN_is_zero(r));

    /* compute the inverse of k */
    if (EC_GROUP_get_mont_data(group) != NULL) {
        /*
         * We want inverse in constant time, therefore we utilize the fact
         * order must be prime and use Fermats Little Theorem instead.
         */
        if (!BN_set_word(X, 2)) {
            ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
        if (!BN_mod_sub(X, order, X, order, ctx)) {
            ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
        BN_set_flags(X, BN_FLG_CONSTTIME);
        if (!BN_mod_exp_mont_consttime
            (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
            ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    } else {
        if (!BN_mod_inverse(k, k, order, ctx)) {
            ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    }

    /* clear old values if necessary */
    if (*rp != NULL)
        BN_clear_free(*rp);
    if (*kinvp != NULL)
        BN_clear_free(*kinvp);
    /* save the pre-computed values  */
    *rp = r;
    *kinvp = k;
    ret = 1;
 err:
    if (!ret) {
        if (k != NULL)
            BN_clear_free(k);
        if (r != NULL)
            BN_clear_free(r);
    }
    if (ctx_in == NULL)
        BN_CTX_free(ctx);
    if (order != NULL)
        BN_free(order);
    if (tmp_point != NULL)
        EC_POINT_free(tmp_point);
    if (X)
        BN_clear_free(X);
    return (ret);
}
예제 #21
0
파일: ecparam.c 프로젝트: 375670450/openssl
int ecparam_main(int argc, char **argv)
{
    BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
    BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL;
    BIO *in = NULL, *out = NULL;
    EC_GROUP *group = NULL;
    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
    char *curve_name = NULL, *inrand = NULL;
    char *infile = NULL, *outfile = NULL, *prog;
    unsigned char *buffer = NULL;
    OPTION_CHOICE o;
    int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret =
        1;
    int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
    int text = 0, i, need_rand = 0, genkey = 0;

    prog = opt_init(argc, argv, ecparam_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(ecparam_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_C:
            C = 1;
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_LIST_CURVES:
            list_curves = 1;
            break;
        case OPT_NO_SEED:
            no_seed = 1;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_NAME:
            curve_name = opt_arg();
            break;
        case OPT_CONV_FORM:
            if (!opt_pair(opt_arg(), forms, &new_form))
                goto opthelp;
            form = new_form;
            new_form = 1;
            break;
        case OPT_PARAM_ENC:
            if (!opt_pair(opt_arg(), encodings, &asn1_flag))
                goto opthelp;
            new_asn1_flag = 1;
            break;
        case OPT_GENKEY:
            genkey = need_rand = 1;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            need_rand = 1;
            break;
        case OPT_ENGINE:
            (void)setup_engine(opt_arg(), 0);
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    in = bio_open_default(infile, RB(informat));
    if (in == NULL)
        goto end;
    out = bio_open_default(outfile, WB(outformat));
    if (out == NULL)
        goto end;

    if (list_curves) {
        EC_builtin_curve *curves = NULL;
        size_t crv_len = EC_get_builtin_curves(NULL, 0);
        size_t n;

        curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves");
        if (!EC_get_builtin_curves(curves, crv_len)) {
            OPENSSL_free(curves);
            goto end;
        }

        for (n = 0; n < crv_len; n++) {
            const char *comment;
            const char *sname;
            comment = curves[n].comment;
            sname = OBJ_nid2sn(curves[n].nid);
            if (comment == NULL)
                comment = "CURVE DESCRIPTION NOT AVAILABLE";
            if (sname == NULL)
                sname = "";

            BIO_printf(out, "  %-10s: ", sname);
            BIO_printf(out, "%s\n", comment);
        }

        OPENSSL_free(curves);
        ret = 0;
        goto end;
    }

    if (curve_name != NULL) {
        int nid;

        /*
         * workaround for the SECG curve names secp192r1 and secp256r1 (which
         * are the same as the curves prime192v1 and prime256v1 defined in
         * X9.62)
         */
        if (strcmp(curve_name, "secp192r1") == 0) {
            BIO_printf(bio_err, "using curve name prime192v1 "
                       "instead of secp192r1\n");
            nid = NID_X9_62_prime192v1;
        } else if (strcmp(curve_name, "secp256r1") == 0) {
            BIO_printf(bio_err, "using curve name prime256v1 "
                       "instead of secp256r1\n");
            nid = NID_X9_62_prime256v1;
        } else
            nid = OBJ_sn2nid(curve_name);

        if (nid == 0)
            nid = EC_curve_nist2nid(curve_name);

        if (nid == 0) {
            BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name);
            goto end;
        }

        group = EC_GROUP_new_by_curve_name(nid);
        if (group == NULL) {
            BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name);
            goto end;
        }
        EC_GROUP_set_asn1_flag(group, asn1_flag);
        EC_GROUP_set_point_conversion_form(group, form);
    } else if (informat == FORMAT_ASN1)
        group = d2i_ECPKParameters_bio(in, NULL);
    else
        group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
    if (group == NULL) {
        BIO_printf(bio_err, "unable to load elliptic curve parameters\n");
        ERR_print_errors(bio_err);
        goto end;
    }

    if (new_form)
        EC_GROUP_set_point_conversion_form(group, form);

    if (new_asn1_flag)
        EC_GROUP_set_asn1_flag(group, asn1_flag);

    if (no_seed) {
        EC_GROUP_set_seed(group, NULL, 0);
    }

    if (text) {
        if (!ECPKParameters_print(out, group, 0))
            goto end;
    }

    if (check) {
        if (group == NULL)
            BIO_printf(bio_err, "no elliptic curve parameters\n");
        BIO_printf(bio_err, "checking elliptic curve parameters: ");
        if (!EC_GROUP_check(group, NULL)) {
            BIO_printf(bio_err, "failed\n");
            ERR_print_errors(bio_err);
        } else
            BIO_printf(bio_err, "ok\n");

    }

    if (C) {
        size_t buf_len = 0, tmp_len = 0;
        const EC_POINT *point;
        int is_prime, len = 0;
        const EC_METHOD *meth = EC_GROUP_method_of(group);

        if ((ec_p = BN_new()) == NULL
                || (ec_a = BN_new()) == NULL
                || (ec_b = BN_new()) == NULL
                || (ec_gen = BN_new()) == NULL
                || (ec_order = BN_new()) == NULL
                || (ec_cofactor = BN_new()) == NULL) {
            perror("Can't allocate BN");
            goto end;
        }

        is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field);
        if (!is_prime) {
            BIO_printf(bio_err, "Can only handle X9.62 prime fields\n");
            goto end;
        }

        if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL))
            goto end;

        if ((point = EC_GROUP_get0_generator(group)) == NULL)
            goto end;
        if (!EC_POINT_point2bn(group, point,
                               EC_GROUP_get_point_conversion_form(group),
                               ec_gen, NULL))
            goto end;
        if (!EC_GROUP_get_order(group, ec_order, NULL))
            goto end;
        if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
            goto end;

        if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor)
            goto end;

        len = BN_num_bits(ec_order);

        if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
            buf_len = tmp_len;

        buffer = app_malloc(buf_len, "BN buffer");

        BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len);
        print_bignum_var(out, ec_p, "ec_p", len, buffer);
        print_bignum_var(out, ec_a, "ec_a", len, buffer);
        print_bignum_var(out, ec_b, "ec_b", len, buffer);
        print_bignum_var(out, ec_gen, "ec_gen", len, buffer);
        print_bignum_var(out, ec_order, "ec_order", len, buffer);
        print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer);
        BIO_printf(out, "    int ok = 0;\n"
                        "    EC_GROUP *group = NULL;\n"
                        "    EC_POINT *point = NULL;\n"
                        "    BIGNUM *tmp_1 = NULL;\n"
                        "    BIGNUM *tmp_2 = NULL;\n"
                        "    BIGNUM *tmp_3 = NULL;\n"
                        "\n");

        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n"
                        "        goto err;\n"
                        "\n");
        BIO_printf(out, "    /* build generator */\n");
        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n");
        BIO_printf(out, "    if (point == NULL)\n"
                        "        goto err;\n");
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n"
                        "        goto err;\n"
                        "ok = 1;"
                        "\n");
        BIO_printf(out, "err:\n"
                        "    BN_free(tmp_1);\n"
                        "    BN_free(tmp_2);\n"
                        "    BN_free(tmp_3);\n"
                        "    EC_POINT_free(point);\n"
                        "    if (!ok) {\n"
                        "        EC_GROUP_free(group);\n"
                        "        return NULL;\n"
                        "    }\n"
                        "    return (group);\n"
                        "}\n");
    }

    if (!noout) {
        if (outformat == FORMAT_ASN1)
            i = i2d_ECPKParameters_bio(out, group);
        else
            i = PEM_write_bio_ECPKParameters(out, group);
        if (!i) {
            BIO_printf(bio_err, "unable to write elliptic "
                       "curve parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (need_rand) {
        app_RAND_load_file(NULL, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }

    if (genkey) {
        EC_KEY *eckey = EC_KEY_new();

        if (eckey == NULL)
            goto end;

        assert(need_rand);

        if (EC_KEY_set_group(eckey, group) == 0)
            goto end;

        if (!EC_KEY_generate_key(eckey)) {
            EC_KEY_free(eckey);
            goto end;
        }
        if (outformat == FORMAT_ASN1)
            i = i2d_ECPrivateKey_bio(out, eckey);
        else
            i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
                                           NULL, 0, NULL, NULL);
        EC_KEY_free(eckey);
    }

    if (need_rand)
        app_RAND_write_file(NULL);

    ret = 0;
 end:
    BN_free(ec_p);
    BN_free(ec_a);
    BN_free(ec_b);
    BN_free(ec_gen);
    BN_free(ec_order);
    BN_free(ec_cofactor);
    OPENSSL_free(buffer);
    BIO_free(in);
    BIO_free_all(out);
    EC_GROUP_free(group);
    return (ret);
}
예제 #22
0
static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
{
    EC_KEY *a = NULL;
    EC_KEY *b = NULL;
    BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL;
    char buf[12];
    unsigned char *abuf = NULL, *bbuf = NULL;
    int i, alen, blen, aout, bout, ret = 0;
    const EC_GROUP *group;

    a = EC_KEY_new_by_curve_name(nid);
    b = EC_KEY_new_by_curve_name(nid);
    if (a == NULL || b == NULL)
        goto err;

    group = EC_KEY_get0_group(a);

    if ((x_a = BN_new()) == NULL)
        goto err;
    if ((y_a = BN_new()) == NULL)
        goto err;
    if ((x_b = BN_new()) == NULL)
        goto err;
    if ((y_b = BN_new()) == NULL)
        goto err;

    BIO_puts(out, "Testing key generation with ");
    BIO_puts(out, text);
# ifdef NOISY
    BIO_puts(out, "\n");
# else
    (void)BIO_flush(out);
# endif

    if (!EC_KEY_generate_key(a))
        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, EC_KEY_get0_public_key(a), x_a, y_a, ctx))
            goto err;
    }
# ifndef OPENSSL_NO_EC2M
    else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group,
                                                  EC_KEY_get0_public_key(a),
                                                  x_a, y_a, ctx))
            goto err;
    }
# endif
# ifdef NOISY
    BIO_puts(out, "  pri 1=");
    BN_print(out, a->priv_key);
    BIO_puts(out, "\n  pub 1=");
    BN_print(out, x_a);
    BIO_puts(out, ",");
    BN_print(out, y_a);
    BIO_puts(out, "\n");
# else
    BIO_printf(out, " .");
    (void)BIO_flush(out);
# endif

    if (!EC_KEY_generate_key(b))
        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, EC_KEY_get0_public_key(b), x_b, y_b, ctx))
            goto err;
    }
# ifndef OPENSSL_NO_EC2M
    else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group,
                                                  EC_KEY_get0_public_key(b),
                                                  x_b, y_b, ctx))
            goto err;
    }
# endif

# ifdef NOISY
    BIO_puts(out, "  pri 2=");
    BN_print(out, b->priv_key);
    BIO_puts(out, "\n  pub 2=");
    BN_print(out, x_b);
    BIO_puts(out, ",");
    BN_print(out, y_b);
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    alen = KDF1_SHA1_len;
    abuf = (unsigned char *)OPENSSL_malloc(alen);
    aout =
        ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1);

# ifdef NOISY
    BIO_puts(out, "  key1 =");
    for (i = 0; i < aout; i++) {
        sprintf(buf, "%02X", abuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    blen = KDF1_SHA1_len;
    bbuf = (unsigned char *)OPENSSL_malloc(blen);
    bout =
        ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1);

# ifdef NOISY
    BIO_puts(out, "  key2 =");
    for (i = 0; i < bout; i++) {
        sprintf(buf, "%02X", bbuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
# ifndef NOISY
        BIO_printf(out, " failed\n\n");
        BIO_printf(out, "key a:\n");
        BIO_printf(out, "private key: ");
        BN_print(out, EC_KEY_get0_private_key(a));
        BIO_printf(out, "\n");
        BIO_printf(out, "public key (x,y): ");
        BN_print(out, x_a);
        BIO_printf(out, ",");
        BN_print(out, y_a);
        BIO_printf(out, "\nkey b:\n");
        BIO_printf(out, "private key: ");
        BN_print(out, EC_KEY_get0_private_key(b));
        BIO_printf(out, "\n");
        BIO_printf(out, "public key (x,y): ");
        BN_print(out, x_b);
        BIO_printf(out, ",");
        BN_print(out, y_b);
        BIO_printf(out, "\n");
        BIO_printf(out, "generated key a: ");
        for (i = 0; i < bout; i++) {
            sprintf(buf, "%02X", bbuf[i]);
            BIO_puts(out, buf);
        }
        BIO_printf(out, "\n");
        BIO_printf(out, "generated key b: ");
        for (i = 0; i < aout; i++) {
            sprintf(buf, "%02X", abuf[i]);
            BIO_puts(out, buf);
        }
        BIO_printf(out, "\n");
# endif
        fprintf(stderr, "Error in ECDH routines\n");
        ret = 0;
    } else {
# ifndef NOISY
        BIO_printf(out, " ok\n");
# endif
        ret = 1;
    }
 err:
    ERR_print_errors_fp(stderr);

    if (abuf != NULL)
        OPENSSL_free(abuf);
    if (bbuf != NULL)
        OPENSSL_free(bbuf);
    if (x_a)
        BN_free(x_a);
    if (y_a)
        BN_free(y_a);
    if (x_b)
        BN_free(x_b);
    if (y_b)
        BN_free(y_b);
    if (b)
        EC_KEY_free(b);
    if (a)
        EC_KEY_free(a);
    return (ret);
}
예제 #23
0
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
                                             BIGNUM *y)
{
    BN_CTX *ctx = NULL;
    BIGNUM *tx, *ty;
    EC_POINT *point = NULL;
    int ok = 0;
#ifndef OPENSSL_NO_EC2M
    int tmp_nid, is_char_two = 0;
#endif

    if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
              ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    ctx = BN_CTX_new();
    if (ctx == NULL)
        return 0;

    BN_CTX_start(ctx);
    point = EC_POINT_new(key->group);

    if (point == NULL)
        goto err;

    tx = BN_CTX_get(ctx);
    ty = BN_CTX_get(ctx);
    if (ty == NULL)
        goto err;

#ifndef OPENSSL_NO_EC2M
    tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));

    if (tmp_nid == NID_X9_62_characteristic_two_field)
        is_char_two = 1;

    if (is_char_two) {
        if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
                                                  x, y, ctx))
            goto err;
        if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
                                                  tx, ty, ctx))
            goto err;
    } else
#endif
    {
        if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
                                                 x, y, ctx))
            goto err;
        if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
                                                 tx, ty, ctx))
            goto err;
    }
    /*
     * Check if retrieved coordinates match originals and are less than field
     * order: if not values are out of range.
     */
    if (BN_cmp(x, tx) || BN_cmp(y, ty)
        || (BN_cmp(x, key->group->field) >= 0)
        || (BN_cmp(y, key->group->field) >= 0)) {
        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
              EC_R_COORDINATES_OUT_OF_RANGE);
        goto err;
    }

    if (!EC_KEY_set_public_key(key, point))
        goto err;

    if (EC_KEY_check_key(key) == 0)
        goto err;

    ok = 1;

 err:
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    EC_POINT_free(point);
    return ok;

}
예제 #24
0
void char2_field_tests()
	{	
	BN_CTX *ctx = NULL;
	BIGNUM *p, *a, *b;
	EC_GROUP *group;
	EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = NULL, *C2_K571 = NULL;
	EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = NULL, *C2_B571 = NULL;
	EC_POINT *P, *Q, *R;
	BIGNUM *x, *y, *z, *cof;
	unsigned char buf[100];
	size_t i, len;
	int k;
	
#if 1 /* optional */
	ctx = BN_CTX_new();
	if (!ctx) ABORT;
#endif

	p = BN_new();
	a = BN_new();
	b = BN_new();
	if (!p || !a || !b) ABORT;

	if (!BN_hex2bn(&p, "13")) ABORT;
	if (!BN_hex2bn(&a, "3")) ABORT;
	if (!BN_hex2bn(&b, "1")) ABORT;
	
	group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use EC_GROUP_new_curve_GF2m
	                                                * so that the library gets to choose the EC_METHOD */
	if (!group) ABORT;
	if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT;

	{
		EC_GROUP *tmp;
		tmp = EC_GROUP_new(EC_GROUP_method_of(group));
		if (!tmp) ABORT;
		if (!EC_GROUP_copy(tmp, group)) ABORT;
		EC_GROUP_free(group);
		group = tmp;
	}
	
	if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) ABORT;

	fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");
	BN_print_fp(stdout, p);
	fprintf(stdout, ")\n     a = 0x");
	BN_print_fp(stdout, a);
	fprintf(stdout, "\n     b = 0x");
	BN_print_fp(stdout, b);
	fprintf(stdout, "\n(0x... means binary polynomial)\n");

	P = EC_POINT_new(group);
	Q = EC_POINT_new(group);
	R = EC_POINT_new(group);
	if (!P || !Q || !R) ABORT;
	
	if (!EC_POINT_set_to_infinity(group, P)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

	buf[0] = 0;
	if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;

	if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

	x = BN_new();
	y = BN_new();
	z = BN_new();
	cof = BN_new();
	if (!x || !y || !z || !cof) ABORT;

	if (!BN_hex2bn(&x, "6")) ABORT;
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
	if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) ABORT;
#else
	if (!BN_hex2bn(&y, "8")) ABORT;
	if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
#endif
	if (!EC_POINT_is_on_curve(group, Q, ctx))
		{
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
		if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
#endif
		fprintf(stderr, "Point is not on curve: x = 0x");
		BN_print_fp(stderr, x);
		fprintf(stderr, ", y = 0x");
		BN_print_fp(stderr, y);
		fprintf(stderr, "\n");
		ABORT;
		}

	fprintf(stdout, "A cyclic subgroup:\n");
	k = 100;
	do
		{
		if (k-- == 0) ABORT;

		if (EC_POINT_is_at_infinity(group, P))
			fprintf(stdout, "     point at infinity\n");
		else
			{
			if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT;

			fprintf(stdout, "     x = 0x");
			BN_print_fp(stdout, x);
			fprintf(stdout, ", y = 0x");
			BN_print_fp(stdout, y);
			fprintf(stdout, "\n");
			}
		
		if (!EC_POINT_copy(R, P)) ABORT;
		if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
		}
	while (!EC_POINT_is_at_infinity(group, P));

	if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, P)) ABORT;

/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "Generator as octet string, compressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
#endif
	
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
	
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
	len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
	if (len == 0) ABORT;
	if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
	fprintf(stdout, "\nGenerator as octet string, hybrid form:\n     ");
	for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
#endif

	fprintf(stdout, "\n");
	
	if (!EC_POINT_invert(group, P, ctx)) ABORT;
	if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;


	/* Curve K-163 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-163",
		"0800000000000000000000000000000000000000C9",
		"1",
		"1",
		"02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
		"0289070FB05D38FF58321F2E800536D538CCDAA3D9",
		1,
		"04000000000000000000020108A2E0CC0D99F8A5EF",
		"2",
		163,
		C2_K163
		);

	/* Curve B-163 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-163",
		"0800000000000000000000000000000000000000C9",
		"1",
		"020A601907B8C953CA1481EB10512F78744A3205FD",
		"03F0EBA16286A2D57EA0991168D4994637E8343E36",
		"00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
		1,
		"040000000000000000000292FE77E70C12A4234C33",
		"2",
		163,
		C2_B163
		);

	/* Curve K-233 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-233",
		"020000000000000000000000000000000000000004000000000000000001",
		"0",
		"1",
		"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
		"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
		0,
		"008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
		"4",
		233,
		C2_K233
		);

	/* Curve B-233 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-233",
		"020000000000000000000000000000000000000004000000000000000001",
		"000000000000000000000000000000000000000000000000000000000001",
		"0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
		"00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
		"01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
		1,
		"01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
		"2",
		233,
		C2_B233
		);

	/* Curve K-283 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-283",
		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
		"0",
		"1",
		"0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
		"01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
		0,
		"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
		"4",
		283,
		C2_K283
		);

	/* Curve B-283 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-283",
		"0800000000000000000000000000000000000000000000000000000000000000000010A1",
		"000000000000000000000000000000000000000000000000000000000000000000000001",
		"027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
		"05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
		"03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
		1,
		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
		"2",
		283,
		C2_B283
		);

	/* Curve K-409 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-409",
		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
		"0",
		"1",
		"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
		"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
		1,
		"007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
		"4",
		409,
		C2_K409
		);

	/* Curve B-409 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-409",
		"02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
		"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
		"0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
		"015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
		"0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
		1,
		"010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
		"2",
		409,
		C2_B409
		);

	/* Curve K-571 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve K-571",
		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
		"0",
		"1",
		"026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
		"0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
		0,
		"020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
		"4",
		571,
		C2_K571
		);

	/* Curve B-571 (FIPS PUB 186-2, App. 6) */
	CHAR2_CURVE_TEST
		(
		"NIST curve B-571",
		"80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
		"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
		"02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
		"0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
		"037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
		1,
		"03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
		"2",
		571,
		C2_B571
		);

	/* more tests using the last curve */

	if (!EC_POINT_copy(Q, P)) ABORT;
	if (EC_POINT_is_at_infinity(group, Q)) ABORT;
	if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
	if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
	if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */

	if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
	if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
	if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */

	{
		const EC_POINT *points[3];
		const BIGNUM *scalars[3];
	
		if (EC_POINT_is_at_infinity(group, Q)) ABORT;
		points[0] = Q;
		points[1] = Q;
		points[2] = Q;

		if (!BN_add(y, z, BN_value_one())) ABORT;
		if (BN_is_odd(y)) ABORT;
		if (!BN_rshift1(y, y)) ABORT;
		scalars[0] = y; /* (group order + 1)/2,  so  y*Q + y*Q = Q */
		scalars[1] = y;

		fprintf(stdout, "combined multiplication ...");
		fflush(stdout);

		/* z is still the group order */
		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
		if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
		if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
		if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;

		fprintf(stdout, ".");
		fflush(stdout);

		if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
		if (!BN_add(z, z, y)) ABORT;
		BN_set_negative(z, 1);
		scalars[0] = y;
		scalars[1] = z; /* z = -(order + y) */

		if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
		if (!EC_POINT_is_at_infinity(group, P)) ABORT;

		fprintf(stdout, ".");
		fflush(stdout);

		if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
		if (!BN_add(z, x, y)) ABORT;
		BN_set_negative(z, 1);
		scalars[0] = x;
		scalars[1] = y;
		scalars[2] = z; /* z = -(x+y) */

		if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
		if (!EC_POINT_is_at_infinity(group, P)) ABORT;

		fprintf(stdout, " ok\n\n");
	}


#if 0
	timings(C2_K163, TIMING_BASE_PT, ctx);
	timings(C2_K163, TIMING_RAND_PT, ctx);
	timings(C2_K163, TIMING_SIMUL, ctx);
	timings(C2_B163, TIMING_BASE_PT, ctx);
	timings(C2_B163, TIMING_RAND_PT, ctx);
	timings(C2_B163, TIMING_SIMUL, ctx);
	timings(C2_K233, TIMING_BASE_PT, ctx);
	timings(C2_K233, TIMING_RAND_PT, ctx);
	timings(C2_K233, TIMING_SIMUL, ctx);
	timings(C2_B233, TIMING_BASE_PT, ctx);
	timings(C2_B233, TIMING_RAND_PT, ctx);
	timings(C2_B233, TIMING_SIMUL, ctx);
	timings(C2_K283, TIMING_BASE_PT, ctx);
	timings(C2_K283, TIMING_RAND_PT, ctx);
	timings(C2_K283, TIMING_SIMUL, ctx);
	timings(C2_B283, TIMING_BASE_PT, ctx);
	timings(C2_B283, TIMING_RAND_PT, ctx);
	timings(C2_B283, TIMING_SIMUL, ctx);
	timings(C2_K409, TIMING_BASE_PT, ctx);
	timings(C2_K409, TIMING_RAND_PT, ctx);
	timings(C2_K409, TIMING_SIMUL, ctx);
	timings(C2_B409, TIMING_BASE_PT, ctx);
	timings(C2_B409, TIMING_RAND_PT, ctx);
	timings(C2_B409, TIMING_SIMUL, ctx);
	timings(C2_K571, TIMING_BASE_PT, ctx);
	timings(C2_K571, TIMING_RAND_PT, ctx);
	timings(C2_K571, TIMING_SIMUL, ctx);
	timings(C2_B571, TIMING_BASE_PT, ctx);
	timings(C2_B571, TIMING_RAND_PT, ctx);
	timings(C2_B571, TIMING_SIMUL, ctx);
#endif


	if (ctx)
		BN_CTX_free(ctx);
	BN_free(p); BN_free(a);	BN_free(b);
	EC_GROUP_free(group);
	EC_POINT_free(P);
	EC_POINT_free(Q);
	EC_POINT_free(R);
	BN_free(x); BN_free(y); BN_free(z); BN_free(cof);

	if (C2_K163) EC_GROUP_free(C2_K163);
	if (C2_B163) EC_GROUP_free(C2_B163);
	if (C2_K233) EC_GROUP_free(C2_K233);
	if (C2_B233) EC_GROUP_free(C2_B233);
	if (C2_K283) EC_GROUP_free(C2_K283);
	if (C2_B283) EC_GROUP_free(C2_B283);
	if (C2_K409) EC_GROUP_free(C2_K409);
	if (C2_B409) EC_GROUP_free(C2_B409);
	if (C2_K571) EC_GROUP_free(C2_K571);
	if (C2_B571) EC_GROUP_free(C2_B571);

	}
예제 #25
0
파일: ecparam.c 프로젝트: benwh4/libressl
int 
ecparam_main(int argc, char **argv)
{
	EC_GROUP *group = NULL;
	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
	int new_form = 0;
	int asn1_flag = OPENSSL_EC_NAMED_CURVE;
	int new_asn1_flag = 0;
	char *curve_name = NULL, *inrand = NULL;
	int list_curves = 0, no_seed = 0, check = 0, badops = 0, text = 0,
	 i, genkey = 0;
	char *infile = NULL, *outfile = NULL, *prog;
	BIO *in = NULL, *out = NULL;
	int informat, outformat, noout = 0, C = 0, ret = 1;
	char *engine = NULL;

	BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL,
	*ec_order = NULL, *ec_cofactor = NULL;
	unsigned char *buffer = NULL;

	if (!load_config(bio_err, NULL))
		goto end;

	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-text") == 0)
			text = 1;
		else if (strcmp(*argv, "-C") == 0)
			C = 1;
		else if (strcmp(*argv, "-check") == 0)
			check = 1;
		else if (strcmp(*argv, "-name") == 0) {
			if (--argc < 1)
				goto bad;
			curve_name = *(++argv);
		} else if (strcmp(*argv, "-list_curves") == 0)
			list_curves = 1;
		else if (strcmp(*argv, "-conv_form") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_form = 1;
			if (strcmp(*argv, "compressed") == 0)
				form = POINT_CONVERSION_COMPRESSED;
			else if (strcmp(*argv, "uncompressed") == 0)
				form = POINT_CONVERSION_UNCOMPRESSED;
			else if (strcmp(*argv, "hybrid") == 0)
				form = POINT_CONVERSION_HYBRID;
			else
				goto bad;
		} else if (strcmp(*argv, "-param_enc") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_asn1_flag = 1;
			if (strcmp(*argv, "named_curve") == 0)
				asn1_flag = OPENSSL_EC_NAMED_CURVE;
			else if (strcmp(*argv, "explicit") == 0)
				asn1_flag = 0;
			else
				goto bad;
		} else if (strcmp(*argv, "-no_seed") == 0)
			no_seed = 1;
		else if (strcmp(*argv, "-noout") == 0)
			noout = 1;
		else if (strcmp(*argv, "-genkey") == 0) {
			genkey = 1;
		} else if (strcmp(*argv, "-rand") == 0) {
			if (--argc < 1)
				goto bad;
			inrand = *(++argv);
		} else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		} else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg       input format - "
		    "default PEM (DER or PEM)\n");
		BIO_printf(bio_err, " -outform arg      output format - "
		    "default PEM\n");
		BIO_printf(bio_err, " -in  arg          input file  - "
		    "default stdin\n");
		BIO_printf(bio_err, " -out arg          output file - "
		    "default stdout\n");
		BIO_printf(bio_err, " -noout            do not print the "
		    "ec parameter\n");
		BIO_printf(bio_err, " -text             print the ec "
		    "parameters in text form\n");
		BIO_printf(bio_err, " -check            validate the ec "
		    "parameters\n");
		BIO_printf(bio_err, " -C                print a 'C' "
		    "function creating the parameters\n");
		BIO_printf(bio_err, " -name arg         use the "
		    "ec parameters with 'short name' name\n");
		BIO_printf(bio_err, " -list_curves      prints a list of "
		    "all currently available curve 'short names'\n");
		BIO_printf(bio_err, " -conv_form arg    specifies the "
		    "point conversion form \n");
		BIO_printf(bio_err, "                   possible values:"
		    " compressed\n");
		BIO_printf(bio_err, "                                   "
		    " uncompressed (default)\n");
		BIO_printf(bio_err, "                                   "
		    " hybrid\n");
		BIO_printf(bio_err, " -param_enc arg    specifies the way"
		    " the ec parameters are encoded\n");
		BIO_printf(bio_err, "                   in the asn1 der "
		    "encoding\n");
		BIO_printf(bio_err, "                   possible values:"
		    " named_curve (default)\n");
		BIO_printf(bio_err, "                                   "
		    " explicit\n");
		BIO_printf(bio_err, " -no_seed          if 'explicit'"
		    " parameters are chosen do not"
		    " use the seed\n");
		BIO_printf(bio_err, " -genkey           generate ec"
		    " key\n");
		BIO_printf(bio_err, " -rand file        files to use for"
		    " random number input\n");
		BIO_printf(bio_err, " -engine e         use engine e, "
		    "possibly a hardware device\n");
		goto end;
	}
	ERR_load_crypto_strings();

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, infile) <= 0) {
			perror(infile);
			goto end;
		}
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	if (list_curves) {
		EC_builtin_curve *curves = NULL;
		size_t crv_len = 0;
		size_t n = 0;

		crv_len = EC_get_builtin_curves(NULL, 0);

		curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));

		if (curves == NULL)
			goto end;

		if (!EC_get_builtin_curves(curves, crv_len)) {
			free(curves);
			goto end;
		}
		for (n = 0; n < crv_len; n++) {
			const char *comment;
			const char *sname;
			comment = curves[n].comment;
			sname = OBJ_nid2sn(curves[n].nid);
			if (comment == NULL)
				comment = "CURVE DESCRIPTION NOT AVAILABLE";
			if (sname == NULL)
				sname = "";

			BIO_printf(out, "  %-10s: ", sname);
			BIO_printf(out, "%s\n", comment);
		}

		free(curves);
		ret = 0;
		goto end;
	}
	if (curve_name != NULL) {
		int nid;

		/*
		 * workaround for the SECG curve names secp192r1 and
		 * secp256r1 (which are the same as the curves prime192v1 and
		 * prime256v1 defined in X9.62)
		 */
		if (!strcmp(curve_name, "secp192r1")) {
			BIO_printf(bio_err, "using curve name prime192v1 "
			    "instead of secp192r1\n");
			nid = NID_X9_62_prime192v1;
		} else if (!strcmp(curve_name, "secp256r1")) {
			BIO_printf(bio_err, "using curve name prime256v1 "
			    "instead of secp256r1\n");
			nid = NID_X9_62_prime256v1;
		} else
			nid = OBJ_sn2nid(curve_name);

		if (nid == 0) {
			BIO_printf(bio_err, "unknown curve name (%s)\n",
			    curve_name);
			goto end;
		}
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL) {
			BIO_printf(bio_err, "unable to create curve (%s)\n",
			    curve_name);
			goto end;
		}
		EC_GROUP_set_asn1_flag(group, asn1_flag);
		EC_GROUP_set_point_conversion_form(group, form);
	} else if (informat == FORMAT_ASN1) {
		group = d2i_ECPKParameters_bio(in, NULL);
	} else if (informat == FORMAT_PEM) {
		group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
	} else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}

	if (group == NULL) {
		BIO_printf(bio_err,
		    "unable to load elliptic curve parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (new_form)
		EC_GROUP_set_point_conversion_form(group, form);

	if (new_asn1_flag)
		EC_GROUP_set_asn1_flag(group, asn1_flag);

	if (no_seed) {
		EC_GROUP_set_seed(group, NULL, 0);
	}
	if (text) {
		if (!ECPKParameters_print(out, group, 0))
			goto end;
	}
	if (check) {
		if (group == NULL)
			BIO_printf(bio_err, "no elliptic curve parameters\n");
		BIO_printf(bio_err, "checking elliptic curve parameters: ");
		if (!EC_GROUP_check(group, NULL)) {
			BIO_printf(bio_err, "failed\n");
			ERR_print_errors(bio_err);
		} else
			BIO_printf(bio_err, "ok\n");

	}
	if (C) {
		size_t buf_len = 0, tmp_len = 0;
		const EC_POINT *point;
		int is_prime, len = 0;
		const EC_METHOD *meth = EC_GROUP_method_of(group);

		if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
		    (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
		    (ec_order = BN_new()) == NULL ||
		    (ec_cofactor = BN_new()) == NULL) {
			perror("malloc");
			goto end;
		}
		is_prime = (EC_METHOD_get_field_type(meth) ==
		    NID_X9_62_prime_field);

		if (is_prime) {
			if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
				ec_b, NULL))
				goto end;
		} else {
			/* TODO */
			goto end;
		}

		if ((point = EC_GROUP_get0_generator(group)) == NULL)
			goto end;
		if (!EC_POINT_point2bn(group, point,
			EC_GROUP_get_point_conversion_form(group), ec_gen,
			NULL))
			goto end;
		if (!EC_GROUP_get_order(group, ec_order, NULL))
			goto end;
		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
			goto end;

		if (!ec_p || !ec_a || !ec_b || !ec_gen ||
		    !ec_order || !ec_cofactor)
			goto end;

		len = BN_num_bits(ec_order);

		if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len)
			buf_len = tmp_len;

		buffer = (unsigned char *) malloc(buf_len);

		if (buffer == NULL) {
			perror("malloc");
			goto end;
		}
		ecparam_print_var(out, ec_p, "ec_p", len, buffer);
		ecparam_print_var(out, ec_a, "ec_a", len, buffer);
		ecparam_print_var(out, ec_b, "ec_b", len, buffer);
		ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
		ecparam_print_var(out, ec_order, "ec_order", len, buffer);
		ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
		    buffer);

		BIO_printf(out, "\n\n");

		BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
		BIO_printf(out, "\tint ok=0;\n");
		BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
		BIO_printf(out, "\tEC_POINT *point = NULL;\n");
		BIO_printf(out, "\tBIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, "
		    "*tmp_3 = NULL;\n\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
		    "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
		    "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
		    "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		if (is_prime) {
			BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
			    "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
			    "\n\t\tgoto err;\n\n");
		} else {
			/* TODO */
			goto end;
		}
		BIO_printf(out, "\t/* build generator */\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
		    "sizeof(ec_gen_%d), tmp_1)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
		    "NULL, NULL);\n");
		BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
		    "sizeof(ec_order_%d), tmp_2)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
		    "sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
		    " tmp_2, tmp_3))\n\t\tgoto err;\n");
		BIO_printf(out, "\n\tok=1;\n");
		BIO_printf(out, "err:\n");
		BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
		BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
		BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
		BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
		BIO_printf(out, "\tif (!ok)\n");
		BIO_printf(out, "\t\t{\n");
		BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
		BIO_printf(out, "\t\tgroup = NULL;\n");
		BIO_printf(out, "\t\t}\n");
		BIO_printf(out, "\treturn(group);\n\t}\n");
	}
	if (!noout) {
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPKParameters_bio(out, group);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPKParameters(out, group);
		else {
			BIO_printf(bio_err, "bad output format specified for"
			    " outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write elliptic "
			    "curve parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (genkey) {
		EC_KEY *eckey = EC_KEY_new();

		if (eckey == NULL)
			goto end;

		if (EC_KEY_set_group(eckey, group) == 0)
			goto end;

		if (!EC_KEY_generate_key(eckey)) {
			EC_KEY_free(eckey);
			goto end;
		}
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPrivateKey_bio(out, eckey);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
			    NULL, 0, NULL, NULL);
		else {
			BIO_printf(bio_err, "bad output format specified "
			    "for outfile\n");
			EC_KEY_free(eckey);
			goto end;
		}
		EC_KEY_free(eckey);
	}
	ret = 0;
end:
	if (ec_p)
		BN_free(ec_p);
	if (ec_a)
		BN_free(ec_a);
	if (ec_b)
		BN_free(ec_b);
	if (ec_gen)
		BN_free(ec_gen);
	if (ec_order)
		BN_free(ec_order);
	if (ec_cofactor)
		BN_free(ec_cofactor);
	free(buffer);
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (group != NULL)
		EC_GROUP_free(group);
	
	return (ret);
}
예제 #26
0
/* This implementation is based on the following primitives in the IEEE 1363 standard:
 *  - ECKAS-DH1
 *  - ECSVDP-DH
 * Finally an optional KDF is applied.
 */
static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
	EC_KEY *ecdh,
	void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
	{
	BN_CTX *ctx;
	EC_POINT *tmp=NULL;
	BIGNUM *x=NULL, *y=NULL;
	const BIGNUM *priv_key;
	const EC_GROUP* group;
	int ret= -1;
	size_t buflen, len;
	unsigned char *buf=NULL;

	if (outlen > INT_MAX)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */
		return -1;
		}

	if ((ctx = BN_CTX_new()) == NULL) goto err;
	BN_CTX_start(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	
	priv_key = EC_KEY_get0_private_key(ecdh);
	if (priv_key == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
		goto err;
		}

	group = EC_KEY_get0_group(ecdh);
	if ((tmp=EC_POINT_new(group)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) 
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
		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, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#ifndef OPENSSL_NO_EC2M
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) 
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
			goto err;
			}
		}
#endif

	buflen = (EC_GROUP_get_degree(group) + 7)/8;
	len = BN_num_bytes(x);
	if (len > buflen)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_INTERNAL_ERROR);
		goto err;
		}
	if ((buf = malloc(buflen)) == NULL)
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	
	memset(buf, 0, buflen - len);
	if (len != (size_t)BN_bn2bin(x, buf + buflen - len))
		{
		ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_BN_LIB);
		goto err;
		}

	if (KDF != 0)
		{
		if (KDF(buf, buflen, out, &outlen) == NULL)
			{
			ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_KDF_FAILED);
			goto err;
			}
		ret = outlen;
		}
	else
		{
		/* no KDF, just copy as much as we can */
		if (outlen > buflen)
			outlen = buflen;
		memcpy(out, buf, outlen);
		ret = outlen;
		}
	
err:
	EC_POINT_free(tmp);
	if (ctx)
		BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	free(buf);
	return(ret);
	}
예제 #27
0
파일: ecs_ossl.c 프로젝트: izick/eme
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)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
		return -1;
	}

	ctx = BN_CTX_new();
	if (!ctx)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	
	if (!EC_GROUP_get_order(group, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
		ret = 0;	/* signature is invalid */
		goto err;
	}
	/* calculate tmp1 = inv(S) mod order */
	if (!BN_mod_inverse(u2, sig->s, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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)))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* u1 = m * tmp mod order */
	if (!BN_mod_mul(u1, m, u2, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	/* u2 = r * w mod q */
	if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}

	if ((point = EC_POINT_new(group)) == NULL)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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))
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
#endif	
	if (!BN_nnmod(u1, X, order, ctx))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, 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);
	if (point)
		EC_POINT_free(point);
	return ret;
}
예제 #28
0
	return NULL;
#endif
}

int main(void) {

	unsigned char *abuf = NULL;
	//const EC_POINT *public_key;
	int i, alen, aout, jj = 0;
	int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
	struct sockaddr_in my_addr;    // my address information
	struct sockaddr_in their_addr; // connector's address information
	socklen_t sin_size;
	int yes = 1, numbytes;
	char buf[MAXDATASIZE];
	/*//////////////////////////////////////////////////////////////Generating Keys/////////////////////////////////////*/

	BN_CTX *ctx = NULL;
	int nid;
	BIO *out;
	CRYPTO_malloc_debug_init();
	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
	const char *text = "NIST Prime-Curve P-192";

#ifdef OPENSSL_SYS_WIN32
	CRYPTO_malloc_init();
#endif

	RAND_seed(rnd_seed, sizeof rnd_seed);
	out = BIO_new(BIO_s_file());
	if (out == NULL)
		EXIT(1);
	BIO_set_fp(out, stdout, BIO_NOCLOSE);

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

	EC_KEY *a = NULL;    //EC_KEY is a structure
	BIGNUM *x_a = NULL, *y_a = NULL;
	const BIGNUM *BIG = NULL;
	char *buff;
	//unsigned char *abuf=NULL,*bbuf=NULL;

	const EC_GROUP *group;

	a = EC_KEY_new_by_curve_name(nid);
	if (a == NULL)
		goto err;

	group = EC_KEY_get0_group(a);
	//	aa=EC_POINT_new(group);

	if ((x_a = BN_new()) == NULL)
		goto err;
	//BN_new returns a pointer to the bignum
	if ((y_a = BN_new()) == NULL)
		goto err;
	//	if ((BIG=BN_new()) == NULL) goto err;

	BIO_puts(out, "Testing key generation with ");
	BIO_puts(out, text);

	if (!EC_KEY_generate_key(a))
		goto err;
	printf("\n1 ) generating keys\n");

	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group))
			== NID_X9_62_prime_field) {
		if (!EC_POINT_get_affine_coordinates_GFp(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}
	//returns the public key
	else {
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}

	BIO_puts(out, "  pri 1=");
	BN_print(out, EC_KEY_get0_private_key(a));
	BIO_puts(out, "\n  pub 1=");
	BN_print(out, x_a);
	BIO_puts(out, ",");
	BN_print(out, y_a);
	BIO_puts(out, "\n");

	/*
	 printf("importnt work\n");
	 //BN_print(out,x_a);
	 buff=BN_bn2dec(x_a);
	 printf("%s\n",buff);
	 BN_dec2bn(&(x_a),buff);
	 printf("%s\n",buff);
	 BN_print(out,x_a);
	 */

	/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/

	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("socket");
		exit(1);
	}

	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
		perror("setsockopt");
		exit(1);
	}

	my_addr.sin_family = AF_INET;         // host byte order
	my_addr.sin_port = htons(MYPORT);     // short, network byte order
	my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
	memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);

	if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof my_addr) == -1) {
		perror("bind");
		exit(1);
	}

	if (listen(sockfd, BACKLOG) == -1) {
		perror("listen");
		exit(1);
	}

	while (1) {  // main accept() loop
		sin_size = sizeof their_addr;
		if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &sin_size))
				== -1) {
			perror("accept");
			continue;
		}
		printf("server: got connection from %s\n",
				inet_ntoa(their_addr.sin_addr));

		if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
			perror("send");

		//	BN_print(out,x_a);
		//  if ((jj=send(new_fd, &aa, sizeof(BIGNUM), 0)) == -1)
		//  perror("send");
		//////////////////////////////////////////////////////////////////////////////
		//printf("side %d\n",sizeof(EC_POINT*));
		//aa= EC_KEY_get0_public_key(a);
		//printf("side %d\n",sizeof(aa));
		// if ((jj=send(new_fd, &aa, sizeof(EC_POINT*), 0)) == -1)
		//perror("send");

		//printf("\nbytes send %d\n",jj);
		////////////////////////////////////////////////////////////////////////////////
		//x_a=(BIGNUM*)&buff;
		//BN_print(out,x_a);
		//printf("%d",sizeof(EC_POINT));
		//buff=(char*)&x_a;
		//if (send(new_fd, &x_a, sizeof(x_a), 0) == -1)
		//perror("send");
		//buff[10]='\0';
		//BIG =EC_KEY_get0_private_key(a);
		//BN_print(out,BIG);
		/*
		 buff=BN_bn2dec(x_a);
		 //	BN_print(out,BIG);
		 buff=(char*)&x_a;
		 //buff[10]='\0';
		 printf("%s\n",buff);
		 x_a=(BIGNUM*)&buff;
		 BN_dec2bn(&(y_a),buff);
		 printf("%s",buff);
		 */
		//sprintf(buff,"%u",EC_KEY_get0_private_key(a));
		//printf("send: %d\n",BIG);
		//printf("%s",buff);
		//printf("%d",strlen(buff));
		// float data1;
		//char  data2[64];
		//BIG=(BIGNUM*)(buff);
		//BIO_puts(out,BIG);
		//memcpy((void*)buff, (void*)EC_KEY_get0_private_key(a), 20);
		//printf("%s",buff);
		//for (i=0; i<10; i++)
		//{
		//printf("%c",buff[i]);
		//BIO_puts(out,buff);
		//}
		//if (send(new_fd,buff,strlen(buff), 0) == -1)
		//      {
		//      perror("send");
		//  }
		//printf("\npublic key send\n");
		/*
		 //EC_POINT *bb;
		 if ((numbytes=recv(new_fd,(char*)&bb,500, 0)) == -1) {
		 perror("recv");
		 exit(1);
		 }
		 printf("\npublic key received\n");
		 */
		/*  if ((numbytes=recv(new_fd, buf, MAXDATASIZE-1, 0)) == -1) {
		 perror("recv");
		 exit(1);
		 }
		 */
		//    buf[numbytes] = '\0';
		/*  printf("Received: %d",numbytes);
		 printf("working\n");
		 alen=KDF1_SHA1_len; ///it is a static constant integer.
		 printf("working\n");
		 abuf=(unsigned char *)OPENSSL_malloc(alen);
		 printf("working\n");
		 if(abuf==NULL || bb==NULL || a==NULL)
		 printf("i hate you error\n");
		 aout=ECDH_compute_key(abuf,alen,bb,a,KDF1_SHA1); //generating session key
		 printf("working\n");
		 //      BN_print(out, abuf);
		 //BIO_puts(out,"\n");
		 BIO_puts(out,"  key1 =");
		 for (i=0; i<aout; i++)
		 {
		 sprintf(buf,"%02X",abuf[i]);
		 BIO_puts(out,buf);
		 }
		 BIO_puts(out,"\n");
		 */
		close(new_fd);
		exit(0);
		close(new_fd);  // parent doesn't need this
	}
	err: ERR_print_errors_fp(stderr);
	if (x_a)
		BN_free(x_a);
	if (y_a)
		BN_free(y_a);
	if (a)
		EC_KEY_free(a);
	if (ctx)
		BN_CTX_free(ctx);
	BIO_free(out);
	CRYPTO_cleanup_all_ex_data();
	ERR_remove_state(0);
예제 #29
0
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
                            BIGNUM **kinvp, BIGNUM **rp,
                            const unsigned char *dgst, int dlen)
{
    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) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (ctx_in == NULL) {
        if ((ctx = BN_CTX_new()) == NULL) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, 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 == NULL || r == NULL || order == NULL || X == NULL) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if ((tmp_point = EC_POINT_new(group)) == NULL) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        goto err;
    }
    if (!EC_GROUP_get_order(group, order, ctx)) {
        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
        goto err;
    }

    do {
        /* get random k */
        do
            if (dgst != NULL) {
                if (!BN_generate_dsa_nonce
                    (k, order, EC_KEY_get0_private_key(eckey), dgst, dlen,
                     ctx)) {
                    ECerr(EC_F_ECDSA_SIGN_SETUP,
                             EC_R_RANDOM_NUMBER_GENERATION_FAILED);
                    goto err;
                }
            } else {
                if (!BN_rand_range(k, order)) {
                    ECerr(EC_F_ECDSA_SIGN_SETUP,
                             EC_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;

        /* compute r the x-coordinate of generator * k */
        if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, 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)) {
                ECerr(EC_F_ECDSA_SIGN_SETUP, 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)) {
                ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
                goto err;
            }
        }
#endif
        if (!BN_nnmod(r, X, order, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    }
    while (BN_is_zero(r));

    /* compute the inverse of k */
    if (EC_GROUP_get_mont_data(group) != NULL) {
        /*
         * We want inverse in constant time, therefore we utilize the fact
         * order must be prime and use Fermats Little Theorem instead.
         */
        if (!BN_set_word(X, 2)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
        if (!BN_mod_sub(X, order, X, order, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
        BN_set_flags(X, BN_FLG_CONSTTIME);
        if (!BN_mod_exp_mont_consttime
            (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
            goto err;
        }
    } else {
        if (!BN_mod_inverse(k, k, order, ctx)) {
            ECerr(EC_F_ECDSA_SIGN_SETUP, 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 != ctx_in)
        BN_CTX_free(ctx);
    BN_free(order);
    EC_POINT_free(tmp_point);
    BN_clear_free(X);
    return (ret);
}
예제 #30
0
int main(int argc, char *argv[]) {
	void *bb;
	BN_CTX *ctx = NULL;
	int nid;
	BIO *out;
	CRYPTO_malloc_debug_init();
	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
	const char *text = "NIST Prime-Curve P-192";

#ifdef OPENSSL_SYS_WIN32
	CRYPTO_malloc_init();
#endif

	RAND_seed(rnd_seed, sizeof rnd_seed);
	out = BIO_new(BIO_s_file());
	if (out == NULL)
		EXIT(1);
	BIO_set_fp(out, stdout, BIO_NOCLOSE);

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

	//EC_POINT *bb;
	EC_KEY *a = NULL;    //EC_KEY is a structure
	BIGNUM *x_a = NULL, *y_a = NULL;

	char buf[12];
	//unsigned char *abuf=NULL,*bbuf=NULL;
	int i, alen, blen, aout, bout;
	const EC_GROUP *group;

	a = EC_KEY_new_by_curve_name(nid);
	if (a == NULL)
		goto err;

	group = EC_KEY_get0_group(a);

	if ((x_a = BN_new()) == NULL)
		goto err;
	//BN_new returns a pointer to the bignum
	if ((y_a = BN_new()) == NULL)
		goto err;

	BIO_puts(out, "Testing key generation with ");
	BIO_puts(out, text);

	if (!EC_KEY_generate_key(a))
		goto err;
	printf("\n1 ) generating keys\n");

	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group))
			== NID_X9_62_prime_field) {
		if (!EC_POINT_get_affine_coordinates_GFp(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}
	//returns the public key
	else {
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}

	BIO_puts(out, "  pri 1=");
	BN_print(out, EC_KEY_get0_private_key(a));
	BIO_puts(out, "\n  pub 1=");
	BN_print(out, x_a);
	BIO_puts(out, ",");
	BN_print(out, y_a);
	BIO_puts(out, "\n");

	func(EC_KEY_get0_public_key(a));

	err: ERR_print_errors_fp(stderr);

	if (x_a)
		BN_free(x_a);
	if (y_a)
		BN_free(y_a);
	if (a)
		EC_KEY_free(a);
	if (ctx)
		BN_CTX_free(ctx);
	BIO_free(out);
	CRYPTO_cleanup_all_ex_data();
	ERR_remove_state(0);
	CRYPTO_mem_leaks_fp(stderr);
	return 0;

}