diff options
author | Jon Spillett <jon.spillett@oracle.com> | 2021-04-28 13:01:48 +1000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-05-07 11:52:07 +0200 |
commit | f71a7453589b29819f2e35b8cf08c8423b0d27a3 (patch) | |
tree | 1a33a69791fac5af68158e6951289075dcb4841d /crypto/ec | |
parent | 592ea4ba94b790a9c366fd12792d88fb9c28ef88 (diff) |
Fixes #14662. Return all EC parameters even for named curves
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15060)
Diffstat (limited to 'crypto/ec')
-rw-r--r-- | crypto/ec/ec_backend.c | 204 |
1 files changed, 130 insertions, 74 deletions
diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index 581c006fd0..6acfa21f69 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -150,61 +150,42 @@ char *ossl_ec_pt_format_id2name(int id) return NULL; } -int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[], OSSL_LIB_CTX *libctx, - const char *propq, - BN_CTX *bnctx, unsigned char **genbuf) +static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], BN_CTX *bnctx, + unsigned char **genbuf) { - int ret = 0, curve_nid, encoding_flag; - const char *field_type, *encoding_name, *pt_form_name; - const BIGNUM *cofactor, *order; - BIGNUM *p = NULL, *a = NULL, *b = NULL; - point_conversion_form_t genform; - const EC_POINT *genpt; - unsigned char *seed = NULL; - size_t genbuf_len, seed_len; - - if (group == NULL) { - ERR_raise(ERR_LIB_EC,EC_R_PASSED_NULL_PARAMETER); - return 0; - } - - genform = EC_GROUP_get_point_conversion_form(group); - pt_form_name = ossl_ec_pt_format_id2name(genform); - if (pt_form_name == NULL - || !ossl_param_build_set_utf8_string( - tmpl, params, - OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, pt_form_name)) { - ECerr(0, EC_R_INVALID_FORM); - return 0; - } - encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE; - encoding_name = ec_param_encoding_id2name(encoding_flag); - if (encoding_name == NULL - || !ossl_param_build_set_utf8_string(tmpl, params, - OSSL_PKEY_PARAM_EC_ENCODING, - encoding_name)) { - ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + int ret = 0, fid; + const char *field_type; + const OSSL_PARAM *param = NULL; + const OSSL_PARAM *param_p = NULL; + const OSSL_PARAM *param_a = NULL; + const OSSL_PARAM *param_b = NULL; + + fid = EC_GROUP_get_field_type(group); + + if (fid == NID_X9_62_prime_field) { + field_type = SN_X9_62_prime_field; + } else if (fid == NID_X9_62_characteristic_two_field) { +#ifdef OPENSSL_NO_EC2M + ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); + goto err; +#else + field_type = SN_X9_62_characteristic_two_field; +#endif + } else { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); return 0; } - curve_nid = EC_GROUP_get_curve_name(group); - if (curve_nid == NID_undef) { - /* explicit curve */ - int fid = EC_GROUP_get_field_type(group); - - if (fid == NID_X9_62_prime_field) { - field_type = SN_X9_62_prime_field; - } else if (fid == NID_X9_62_characteristic_two_field) { - field_type = SN_X9_62_characteristic_two_field; - } else { - ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); - return 0; - } + param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P); + param_a = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A); + param_b = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B); + if (tmpl != NULL || param_p != NULL || param_a != NULL || param_b != NULL) + { + BIGNUM *p = BN_CTX_get(bnctx); + BIGNUM *a = BN_CTX_get(bnctx); + BIGNUM *b = BN_CTX_get(bnctx); - p = BN_CTX_get(bnctx); - a = BN_CTX_get(bnctx); - b = BN_CTX_get(bnctx); if (b == NULL) { ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; @@ -214,13 +195,45 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); goto err; } + if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER); + if (tmpl != NULL || param != NULL) { + const BIGNUM *order = EC_GROUP_get0_order(group); - order = EC_GROUP_get0_order(group); if (order == NULL) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); goto err; } - genpt = EC_GROUP_get0_generator(group); + if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER, + order)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE); + if (tmpl != NULL || param != NULL) { + if (!ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_EC_FIELD_TYPE, + field_type)) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR); + if (tmpl != NULL || param != NULL) { + size_t genbuf_len; + const EC_POINT *genpt = EC_GROUP_get0_generator(group); + point_conversion_form_t genform = EC_GROUP_get_point_conversion_form(group); + if (genpt == NULL) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); goto err; @@ -230,32 +243,31 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); goto err; } - - if (!ossl_param_build_set_utf8_string(tmpl, params, - OSSL_PKEY_PARAM_EC_FIELD_TYPE, - field_type) - || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p) - || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a) - || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b) - || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER, - order) - || !ossl_param_build_set_octet_string(tmpl, params, - OSSL_PKEY_PARAM_EC_GENERATOR, - *genbuf, genbuf_len)) { + if (!ossl_param_build_set_octet_string(tmpl, params, + OSSL_PKEY_PARAM_EC_GENERATOR, + *genbuf, genbuf_len)) { ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR); + if (tmpl != NULL || param != NULL) { + const BIGNUM *cofactor = EC_GROUP_get0_cofactor(group); - cofactor = EC_GROUP_get0_cofactor(group); if (cofactor != NULL && !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) { ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } + } + + param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + if (tmpl != NULL || param != NULL) { + unsigned char *seed = EC_GROUP_get0_seed(group); + size_t seed_len = EC_GROUP_get_seed_len(group); - seed = EC_GROUP_get0_seed(group); - seed_len = EC_GROUP_get_seed_len(group); if (seed != NULL && seed_len > 0 && !ossl_param_build_set_octet_string(tmpl, params, @@ -264,14 +276,58 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); goto err; } -#ifdef OPENSSL_NO_EC2M - if (fid == NID_X9_62_characteristic_two_field) { - ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED); + } + ret = 1; +err: + return ret; +} + +int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *bnctx, unsigned char **genbuf) +{ + int ret = 0, curve_nid, encoding_flag; + const char *encoding_name, *pt_form_name; + point_conversion_form_t genform; + + if (group == NULL) { + ERR_raise(ERR_LIB_EC,EC_R_PASSED_NULL_PARAMETER); + return 0; + } + + genform = EC_GROUP_get_point_conversion_form(group); + pt_form_name = ossl_ec_pt_format_id2name(genform); + if (pt_form_name == NULL + || !ossl_param_build_set_utf8_string( + tmpl, params, + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, pt_form_name)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); + return 0; + } + encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE; + encoding_name = ec_param_encoding_id2name(encoding_flag); + if (encoding_name == NULL + || !ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_EC_ENCODING, + encoding_name)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + + curve_nid = EC_GROUP_get_curve_name(group); + + /* + * Get the explicit parameters in these two cases: + * - We do not have a template, i.e. specific parameters are requested + * - The curve is not a named curve + */ + if (tmpl == NULL || curve_nid == NID_undef) + if (!ec_group_explicit_todata(group, tmpl, params, bnctx, genbuf)) goto err; - } -#endif - } else { - /* named curve */ + + if (curve_nid != NID_undef) { + /* Named curve */ const char *curve_name = ossl_ec_curve_nid2name(curve_nid); if (curve_name == NULL |