diff options
author | Adam Langley <agl@google.com> | 2015-05-14 00:48:39 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2015-05-15 03:59:37 +0300 |
commit | d72e2842715ada993157540e121f8030e158857b (patch) | |
tree | 17bd246260b450deddff49bfb787e6a26f9a5b2f /crypto/ec | |
parent | a07c0fc8f2181d086b1118712e2ceb0d1496fa0b (diff) |
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>
Diffstat (limited to 'crypto/ec')
-rw-r--r-- | crypto/ec/ec.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/crypto/ec/ec.c b/crypto/ec/ec.c index 5426b8ff..f38eba66 100644 --- a/crypto/ec/ec.c +++ b/crypto/ec/ec.c @@ -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; } |