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; } diff --git a/crypto/err/ec.errordata b/crypto/err/ec.errordata index 3b815c8a..252f7ab2 100644 --- a/crypto/err/ec.errordata +++ b/crypto/err/ec.errordata @@ -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 diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 633b11b4..25b45518 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -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