Commit b14e6015 authored by Matt Caswell's avatar Matt Caswell
Browse files

Improve compatibility of point and curve checks



We check that the curve name associated with the point is the same as that
for the curve.

Fixes #6302

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6323)
parent 2de108df
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -311,6 +311,7 @@ int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
    if (!BN_copy(dest->Z, src->Z))
        return 0;
    dest->Z_is_one = src->Z_is_one;
    dest->curve_name = src->curve_name;

    return 1;
}
+2 −2
Original line number Diff line number Diff line
@@ -3066,6 +3066,8 @@ static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
    }
#endif

    EC_GROUP_set_curve_name(group, curve.nid);

    if ((P = EC_POINT_new(group)) == NULL) {
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
        goto err;
@@ -3131,8 +3133,6 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
        return NULL;
    }

    EC_GROUP_set_curve_name(ret, nid);

    return ret;
}

+16 −0
Original line number Diff line number Diff line
@@ -276,6 +276,8 @@ struct ec_key_st {

struct ec_point_st {
    const EC_METHOD *meth;
    /* NID for the curve if known */
    int curve_name;
    /*
     * All members except 'meth' are handled by the method functions, even if
     * they appear generic
@@ -288,6 +290,20 @@ struct ec_point_st {
                                 * special case */
};


static ossl_inline int ec_point_is_compat(const EC_POINT *point,
                                          const EC_GROUP *group)
{
    if (group->meth != point->meth
        || (group->curve_name != 0
            && point->curve_name != 0
            && group->curve_name != point->curve_name))
        return 0;

    return 1;
}


NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
+22 −17
Original line number Diff line number Diff line
@@ -140,6 +140,8 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
    if (dest == src)
        return 1;

    dest->curve_name = src->curve_name;

    /* Copy precomputed */
    dest->pre_comp_type = src->pre_comp_type;
    switch (src->pre_comp_type) {
@@ -207,7 +209,6 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
            return 0;
    }

    dest->curve_name = src->curve_name;
    dest->asn1_flag = src->asn1_flag;
    dest->asn1_form = src->asn1_form;

@@ -572,6 +573,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group)
    }

    ret->meth = group->meth;
    ret->curve_name = group->curve_name;

    if (!ret->meth->point_init(ret)) {
        OPENSSL_free(ret);
@@ -609,7 +611,10 @@ int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
        ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (dest->meth != src->meth) {
    if (dest->meth != src->meth
            || (dest->curve_name != src->curve_name
                && dest->curve_name != 0
                && src->curve_name != 0)) {
        ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -666,7 +671,7 @@ int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
              EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
@@ -685,7 +690,7 @@ int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
              EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
@@ -703,7 +708,7 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
              EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
@@ -729,7 +734,7 @@ int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
              EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
@@ -755,7 +760,7 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
              EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
@@ -773,7 +778,7 @@ int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
              EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
@@ -789,8 +794,8 @@ int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
        ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if ((group->meth != r->meth) || (r->meth != a->meth)
        || (a->meth != b->meth)) {
    if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)
        || !ec_point_is_compat(b, group)) {
        ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -804,7 +809,7 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
        ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if ((group->meth != r->meth) || (r->meth != a->meth)) {
    if (!ec_point_is_compat(r, group) || !ec_point_is_compat(a, group)) {
        ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -817,7 +822,7 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
        ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != a->meth) {
    if (!ec_point_is_compat(a, group)) {
        ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -831,7 +836,7 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -852,7 +857,7 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
        ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -866,7 +871,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
        ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return -1;
    }
    if ((group->meth != a->meth) || (a->meth != b->meth)) {
    if (!ec_point_is_compat(a, group) || !ec_point_is_compat(b, group)) {
        ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
        return -1;
    }
@@ -879,7 +884,7 @@ int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
        ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }
    if (group->meth != point->meth) {
    if (!ec_point_is_compat(point, group)) {
        ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -896,7 +901,7 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
        return 0;
    }
    for (i = 0; i < num; i++) {
        if (group->meth != points[i]->meth) {
        if (!ec_point_is_compat(points[i], group)) {
            ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
            return 0;
        }
+2 −2
Original line number Diff line number Diff line
@@ -368,7 +368,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
                                 * precomputation is not available */
    int ret = 0;

    if (group->meth != r->meth) {
    if (!ec_point_is_compat(r, group)) {
        ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
        return 0;
    }
@@ -404,7 +404,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
    }

    for (i = 0; i < num; i++) {
        if (group->meth != points[i]->meth) {
        if (!ec_point_is_compat(points[i], group)) {
            ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
            return 0;
        }
Loading