Support arbitrary elliptic curve groups.

This change exposes the functions needed to support arbitrary elliptic
curve groups. The Java API[1] doesn't allow a provider to only provide
certain elliptic curve groups. So if BoringSSL is an ECC provider on
Android, we probably need to support arbitrary groups because someone
out there is going to be using it for Bitcoin I'm sure.

Perhaps in time we can remove this support, but not yet.

[1] https://docs.oracle.com/javase/7/docs/api/java/security/spec/ECParameterSpec.html

Change-Id: Ic1d76de96f913c9ca33c46b451cddc08c5b93d80
Reviewed-on: https://boringssl-review.googlesource.com/4740
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
Adam Langley 2015-05-13 14:48:39 -07:00
parent a07c0fc8f2
commit d72e284271
3 changed files with 64 additions and 4 deletions

View File

@ -265,8 +265,8 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) {
return ret;
}
static EC_GROUP *ec_group_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx) {
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx) {
const EC_METHOD *meth = EC_GFp_mont_method();
EC_GROUP *ret;
@ -276,7 +276,7 @@ static EC_GROUP *ec_group_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
}
if (ret->meth->group_set_curve == 0) {
OPENSSL_PUT_ERROR(EC, ec_group_new_curve_GFp,
OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp,
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@ -287,6 +287,44 @@ static EC_GROUP *ec_group_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
return ret;
}
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
const BIGNUM *order, const BIGNUM *cofactor) {
if (group->curve_name != NID_undef) {
/* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
* by |EC_GROUP_new_curve_GFp|. */
return 0;
}
if (group->generator == NULL) {
group->generator = EC_POINT_new(group);
if (group->generator == NULL) {
return 0;
}
}
if (!EC_POINT_copy(group->generator, generator)) {
return 0;
}
if (order != NULL) {
if (!BN_copy(&group->order, order)) {
return 0;
}
} else {
BN_zero(&group->order);
}
if (cofactor != NULL) {
if (!BN_copy(&group->cofactor, cofactor)) {
return 0;
}
} else {
BN_zero(&group->cofactor);
}
return 1;
}
static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
EC_GROUP *group = NULL;
EC_POINT *P = NULL;
@ -322,7 +360,7 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
goto err;
}
} else {
if ((group = ec_group_new_curve_GFp(p, a, b, ctx)) == NULL) {
if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
goto err;
}

View File

@ -3,9 +3,11 @@ EC,function,100,EC_GROUP_copy
EC,function,101,EC_GROUP_get_curve_GFp
EC,function,102,EC_GROUP_get_degree
EC,function,103,EC_GROUP_new_by_curve_name
EC,function,166,EC_GROUP_new_curve_GFp
EC,function,104,EC_KEY_check_key
EC,function,105,EC_KEY_copy
EC,function,106,EC_KEY_generate_key
EC,function,165,EC_KEY_new_by_curve_name
EC,function,107,EC_KEY_new_method
EC,function,108,EC_KEY_set_public_key_affine_coordinates
EC,function,109,EC_POINT_add

View File

@ -286,6 +286,25 @@ OPENSSL_EXPORT int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r,
/* Deprecated functions. */
/* EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based
* on the equation y² = x³ + a·x + b. It returns the new group or NULL on
* error.
*
* |EC_GROUP|s returned by this function will always compare as unequal via
* |EC_GROUP_cmp| (even to themselves). |EC_GROUP_get_curve_name| will always
* return |NID_undef|. */
OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p,
const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx);
/* EC_GROUP_set_generator sets the generator for |group| to |generator|, which
* must have the given order and cofactor. This should only be used with
* |EC_GROUP| objects returned by |EC_GROUP_new_curve_GFp|. */
OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group,
const EC_POINT *generator,
const BIGNUM *order,
const BIGNUM *cofactor);
/* EC_GROUP_set_asn1_flag does nothing. */
OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
@ -381,6 +400,7 @@ OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
#define EC_F_ec_group_copy 163
#define EC_F_nistp256_pre_comp_new 164
#define EC_F_EC_KEY_new_by_curve_name 165
#define EC_F_EC_GROUP_new_curve_GFp 166
#define EC_R_BUFFER_TOO_SMALL 100
#define EC_R_COORDINATES_OUT_OF_RANGE 101
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 102