diff options
Diffstat (limited to 'src/crypto/ec/ec.c')
-rw-r--r-- | src/crypto/ec/ec.c | 159 |
1 files changed, 50 insertions, 109 deletions
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c index 3117f16..ec01766 100644 --- a/src/crypto/ec/ec.c +++ b/src/crypto/ec/ec.c @@ -218,15 +218,25 @@ static const struct curve_data P521 = { 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}}; +/* MSan appears to have a bug that causes code to be miscompiled in opt mode. + * While that is being looked at, don't run the uint128_t code under MSan. */ +#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \ + !defined(MEMORY_SANITIZER) +#define BORINGSSL_USE_INT128_CODE +#endif + const struct built_in_curve OPENSSL_built_in_curves[] = { - {NID_secp224r1, &P224, 0}, + { + NID_secp224r1, &P224, +#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL) + EC_GFp_nistp224_method, +#else + 0, +#endif + }, { NID_X9_62_prime256v1, &P256, - /* MSAN appears to have a bug that causes this P-256 code to be miscompiled - * in opt mode. While that is being looked at, don't run the uint128_t - * P-256 code under MSAN for now. */ -#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \ - !defined(MEMORY_SANITIZER) +#if defined(BORINGSSL_USE_INT128_CODE) EC_GFp_nistp256_method, #else 0, @@ -549,30 +559,17 @@ int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, BIGNUM *out_b, BN_CTX *ctx) { - if (group->meth->group_get_curve == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx); + return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx); } int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } -int EC_GROUP_get_degree(const EC_GROUP *group) { - if (group->meth->group_get_degree == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_get_degree(group); +unsigned EC_GROUP_get_degree(const EC_GROUP *group) { + return ec_GFp_simple_group_get_degree(group); } int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { - if (group->meth->mul == 0) { - /* use default */ - return ec_wNAF_precompute_mult(group, ctx); - } - - if (group->meth->precompute_mult != 0) { + if (group->meth->precompute_mult != NULL) { return group->meth->precompute_mult(group, ctx); } @@ -580,16 +577,10 @@ int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { } int EC_GROUP_have_precompute_mult(const EC_GROUP *group) { - if (group->meth->mul == 0) { - /* use default */ - return ec_wNAF_have_precompute_mult(group); - } - - if (group->meth->have_precompute_mult != 0) { - return group->meth->have_precompute_mult(group); + if (group->pre_comp != NULL) { + return 1; } - - return 0; /* cannot tell whether precomputation has been performed */ + return 0; } EC_POINT *EC_POINT_new(const EC_GROUP *group) { @@ -599,10 +590,6 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return NULL; } - if (group->meth->point_init == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return NULL; - } ret = OPENSSL_malloc(sizeof *ret); if (ret == NULL) { @@ -612,7 +599,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) { ret->meth = group->meth; - if (!ret->meth->point_init(ret)) { + if (!ec_GFp_simple_point_init(ret)) { OPENSSL_free(ret); return NULL; } @@ -625,9 +612,8 @@ void EC_POINT_free(EC_POINT *point) { return; } - if (point->meth->point_finish != 0) { - point->meth->point_finish(point); - } + ec_GFp_simple_point_finish(point); + OPENSSL_free(point); } @@ -636,20 +622,13 @@ void EC_POINT_clear_free(EC_POINT *point) { return; } - if (point->meth->point_clear_finish != 0) { - point->meth->point_clear_finish(point); - } else if (point->meth->point_finish != 0) { - point->meth->point_finish(point); - } + ec_GFp_simple_point_clear_finish(point); + OPENSSL_cleanse(point, sizeof *point); OPENSSL_free(point); } int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { - if (dest->meth->point_copy == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (dest->meth != src->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; @@ -657,7 +636,7 @@ int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { if (dest == src) { return 1; } - return dest->meth->point_copy(dest, src); + return ec_GFp_simple_point_copy(dest, src); } EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { @@ -683,82 +662,58 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { } int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { - if (group->meth->point_set_to_infinity == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (group->meth != point->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->point_set_to_infinity(group, point); + return ec_GFp_simple_point_set_to_infinity(group, point); } int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { - if (group->meth->is_at_infinity == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (group->meth != point->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->is_at_infinity(group, point); + return ec_GFp_simple_is_at_infinity(group, point); } int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) { - if (group->meth->is_on_curve == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (group->meth != point->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->is_on_curve(group, point, ctx); + return ec_GFp_simple_is_on_curve(group, point, ctx); } int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { - if (group->meth->point_cmp == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return -1; - } if ((group->meth != a->meth) || (a->meth != b->meth)) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return -1; } - return group->meth->point_cmp(group, a, b, ctx); + return ec_GFp_simple_cmp(group, a, b, ctx); } int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { - if (group->meth->make_affine == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (group->meth != point->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->make_affine(group, point, ctx); + return ec_GFp_simple_make_affine(group, point, ctx); } int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) { size_t i; - if (group->meth->points_make_affine == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } for (i = 0; i < num; i++) { if (group->meth != points[i]->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } } - return group->meth->points_make_affine(group, num, points, ctx); + return ec_GFp_simple_points_make_affine(group, num, points, ctx); } int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, @@ -778,56 +733,40 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { - if (group->meth->point_set_affine_coordinates == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (group->meth != point->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); + return ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx); } int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { - if (group->meth->add == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->add(group, r, a, b, ctx); + return ec_GFp_simple_add(group, r, a, b, ctx); } int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) { - if (group->meth->dbl == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if ((group->meth != r->meth) || (r->meth != a->meth)) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->dbl(group, r, a, ctx); + return ec_GFp_simple_dbl(group, r, a, ctx); } int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { - if (group->meth->invert == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (group->meth != a->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->invert(group, a, ctx); + return ec_GFp_simple_invert(group, a, ctx); } int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, @@ -847,9 +786,15 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { - if (group->meth->mul == 0) { - /* use default. Warning, not constant-time. */ - return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + size_t i; + for (i = 0; i < num; i++) { + if (points[i]->meth != r->meth) { + break; + } + } + if (i != num) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; } return group->meth->mul(group, r, scalar, num, points, scalars, ctx); @@ -858,16 +803,12 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) { - if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } if (group->meth != point->meth) { OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, - z, ctx); + return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z, + ctx); } void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} |