From 1f65bd719a8b625ceac6dbee17d3eaac5fe81de4 Mon Sep 17 00:00:00 2001 From: jsing Date: Tue, 11 Apr 2023 18:58:20 +0000 Subject: [PATCH] Handle BN_CTX at the EC API boundary. The EC API allows callers to optionally pass in a BN_CTX, which means that any code needing a BN_CTX has to check if one was provided, allocate one if not, then free it again. Rather than doing this dance throughout the EC code, handle the BN_CTX existance at the EC API boundary. This means that lower level implementation code can simply assume that the BN_CTX is available. ok tb@ --- lib/libcrypto/ec/ec2_mult.c | 14 +- lib/libcrypto/ec/ec2_oct.c | 59 ++--- lib/libcrypto/ec/ec2_smpl.c | 78 ++----- lib/libcrypto/ec/ec_check.c | 31 +-- lib/libcrypto/ec/ec_lib.c | 452 +++++++++++++++++++++++++++--------- lib/libcrypto/ec/ec_mult.c | 22 +- lib/libcrypto/ec/ec_oct.c | 70 ++++-- lib/libcrypto/ec/ecp_mont.c | 12 +- lib/libcrypto/ec/ecp_nist.c | 58 +---- lib/libcrypto/ec/ecp_oct.c | 62 ++--- lib/libcrypto/ec/ecp_smpl.c | 186 +++++---------- 11 files changed, 553 insertions(+), 491 deletions(-) diff --git a/lib/libcrypto/ec/ec2_mult.c b/lib/libcrypto/ec/ec2_mult.c index d32b7442c40..d7cbd933f2a 100644 --- a/lib/libcrypto/ec/ec2_mult.c +++ b/lib/libcrypto/ec/ec2_mult.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec2_mult.c,v 1.16 2023/03/27 10:25:02 tb Exp $ */ +/* $OpenBSD: ec2_mult.c,v 1.17 2023/04/11 18:58:20 jsing Exp $ */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -375,17 +375,11 @@ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; - int ret = 0; - size_t i; EC_POINT *p = NULL; EC_POINT *acc = NULL; + size_t i; + int ret = 0; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } /* * This implementation is more efficient than the wNAF implementation * for 2 or fewer points. Use the ec_wNAF_mul implementation for 3 @@ -432,7 +426,7 @@ ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, err: EC_POINT_free(p); EC_POINT_free(acc); - BN_CTX_free(new_ctx); + return ret; } diff --git a/lib/libcrypto/ec/ec2_oct.c b/lib/libcrypto/ec/ec2_oct.c index d3fbc127496..6cb7259824b 100644 --- a/lib/libcrypto/ec/ec2_oct.c +++ b/lib/libcrypto/ec/ec2_oct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec2_oct.c,v 1.19 2022/11/26 16:08:52 tb Exp $ */ +/* $OpenBSD: ec2_oct.c,v 1.20 2023/04/11 18:58:20 jsing Exp $ */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -94,21 +94,17 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x_, int y_bit, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *tmp, *x, *y, *z; - int ret = 0, z0; + int z0; + int ret = 0; /* clear error queue */ ERR_clear_error(); - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } y_bit = (y_bit != 0) ? 1 : 0; BN_CTX_start(ctx); + if ((tmp = BN_CTX_get(ctx)) == NULL) goto err; if ((x = BN_CTX_get(ctx)) == NULL) @@ -163,7 +159,7 @@ ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } @@ -177,18 +173,17 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx) { - size_t ret; - BN_CTX *new_ctx = NULL; - int used_ctx = 0; BIGNUM *x, *y, *yxi; size_t field_len, i, skip; + size_t ret; - if ((form != POINT_CONVERSION_COMPRESSED) - && (form != POINT_CONVERSION_UNCOMPRESSED) - && (form != POINT_CONVERSION_HYBRID)) { + if (form != POINT_CONVERSION_COMPRESSED && + form != POINT_CONVERSION_UNCOMPRESSED && + form != POINT_CONVERSION_HYBRID) { ECerror(EC_R_INVALID_FORM); - goto err; + return 0; } + if (EC_POINT_is_at_infinity(group, point) > 0) { /* encodes to a single 0 octet */ if (buf != NULL) { @@ -200,6 +195,9 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, } return 1; } + + BN_CTX_start(ctx); + /* ret := required output buffer length */ field_len = (EC_GROUP_get_degree(group) + 7) / 8; ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : @@ -211,13 +209,7 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, ECerror(EC_R_BUFFER_TOO_SMALL); goto err; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - BN_CTX_start(ctx); - used_ctx = 1; + if ((x = BN_CTX_get(ctx)) == NULL) goto err; if ((y = BN_CTX_get(ctx)) == NULL) @@ -271,18 +263,12 @@ ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, goto err; } } - if (used_ctx) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - return ret; err: - if (used_ctx) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - return 0; -} + BN_CTX_end(ctx); + return ret; +} /* * Converts an octet string representation to an EC_POINT. @@ -294,7 +280,6 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, { point_conversion_form_t form; int y_bit; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y, *yxi; size_t field_len, enc_len; int ret = 0; @@ -349,12 +334,8 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, return 0; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } BN_CTX_start(ctx); + if ((x = BN_CTX_get(ctx)) == NULL) goto err; if ((y = BN_CTX_get(ctx)) == NULL) @@ -415,7 +396,7 @@ ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } #endif diff --git a/lib/libcrypto/ec/ec2_smpl.c b/lib/libcrypto/ec/ec2_smpl.c index 1ad339cbd78..850159cb25a 100644 --- a/lib/libcrypto/ec/ec2_smpl.c +++ b/lib/libcrypto/ec/ec2_smpl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec2_smpl.c,v 1.34 2023/03/27 10:25:02 tb Exp $ */ +/* $OpenBSD: ec2_smpl.c,v 1.35 2023/04/11 18:58:20 jsing Exp $ */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -216,18 +216,11 @@ ec_GF2m_simple_group_get_degree(const EC_GROUP *group) static int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) { - int ret = 0; BIGNUM *b; - BN_CTX *new_ctx = NULL; + int ret = 0; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) { - ECerror(ERR_R_MALLOC_FAILURE); - goto err; - } - } BN_CTX_start(ctx); + if ((b = BN_CTX_get(ctx)) == NULL) goto err; @@ -244,9 +237,8 @@ ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) ret = 1; err: - if (ctx != NULL) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); + return ret; } @@ -368,7 +360,6 @@ static int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; int ret = 0; @@ -382,12 +373,9 @@ ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, return 0; return 1; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } + BN_CTX_start(ctx); + if ((x0 = BN_CTX_get(ctx)) == NULL) goto err; if ((y0 = BN_CTX_get(ctx)) == NULL) @@ -475,7 +463,7 @@ ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } @@ -517,11 +505,10 @@ ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) static int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) { - int ret = -1; - BN_CTX *new_ctx = NULL; - BIGNUM *lh, *y2; int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + BIGNUM *lh, *y2; + int ret = -1; if (EC_POINT_is_at_infinity(group, point) > 0) return 1; @@ -533,12 +520,8 @@ ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX if (!point->Z_is_one) return -1; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } BN_CTX_start(ctx); + if ((y2 = BN_CTX_get(ctx)) == NULL) goto err; if ((lh = BN_CTX_get(ctx)) == NULL) @@ -563,11 +546,12 @@ ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX goto err; if (!BN_GF2m_add(lh, lh, y2)) goto err; + ret = BN_is_zero(lh); + err: - if (ctx) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); + return ret; } @@ -583,24 +567,19 @@ ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { BIGNUM *aX, *aY, *bX, *bY; - BN_CTX *new_ctx = NULL; int ret = -1; - if (EC_POINT_is_at_infinity(group, a) > 0) { + if (EC_POINT_is_at_infinity(group, a) > 0) return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1; - } + if (EC_POINT_is_at_infinity(group, b) > 0) return 1; - if (a->Z_is_one && b->Z_is_one) { + if (a->Z_is_one && b->Z_is_one) return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; - } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } + BN_CTX_start(ctx); + if ((aX = BN_CTX_get(ctx)) == NULL) goto err; if ((aY = BN_CTX_get(ctx)) == NULL) @@ -617,9 +596,8 @@ ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1; err: - if (ctx) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); + return ret; } @@ -627,19 +605,14 @@ ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, static int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; int ret = 0; if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0) return 1; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } BN_CTX_start(ctx); + if ((x = BN_CTX_get(ctx)) == NULL) goto err; if ((y = BN_CTX_get(ctx)) == NULL) @@ -657,9 +630,8 @@ ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) ret = 1; err: - if (ctx) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); + return ret; } diff --git a/lib/libcrypto/ec/ec_check.c b/lib/libcrypto/ec/ec_check.c index 5c6165e1290..4e065c739a5 100644 --- a/lib/libcrypto/ec/ec_check.c +++ b/lib/libcrypto/ec/ec_check.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_check.c,v 1.12 2022/11/26 16:08:52 tb Exp $ */ +/* $OpenBSD: ec_check.c,v 1.13 2023/04/11 18:58:20 jsing Exp $ */ /* ==================================================================== * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. * @@ -57,21 +57,20 @@ #include int -EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) +EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx_in) { - int ret = 0; + BN_CTX *ctx; BIGNUM *order; - BN_CTX *new_ctx = NULL; EC_POINT *point = NULL; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) { - ECerror(ERR_R_MALLOC_FAILURE); - goto err; - } - } BN_CTX_start(ctx); + if ((order = BN_CTX_get(ctx)) == NULL) goto err; @@ -104,12 +103,16 @@ EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) ECerror(EC_R_INVALID_GROUP_ORDER); goto err; } + ret = 1; err: - if (ctx != NULL) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); + + if (ctx != ctx_in) + BN_CTX_free(ctx); + EC_POINT_free(point); + return ret; } diff --git a/lib/libcrypto/ec/ec_lib.c b/lib/libcrypto/ec/ec_lib.c index 38ddd7af9f8..bc472b73b77 100644 --- a/lib/libcrypto/ec/ec_lib.c +++ b/lib/libcrypto/ec/ec_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_lib.c,v 1.52 2023/03/27 10:25:02 tb Exp $ */ +/* $OpenBSD: ec_lib.c,v 1.53 2023/04/11 18:58:20 jsing Exp $ */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -487,24 +487,52 @@ EC_GROUP_get_seed_len(const EC_GROUP *group) int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) + const BIGNUM *b, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->group_set_curve == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } - return group->meth->group_set_curve(group, p, a, b, ctx); + ret = group->meth->group_set_curve(group, p, a, b, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, - BN_CTX *ctx) + BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->group_get_curve == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - return group->meth->group_get_curve(group, p, a, b, ctx); + ret = group->meth->group_get_curve(group, p, a, b, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int @@ -549,13 +577,27 @@ EC_GROUP_get_degree(const EC_GROUP *group) int -EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) +EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->group_check_discriminant == 0) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } return group->meth->group_check_discriminant(group, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } @@ -803,9 +845,6 @@ EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data) *ex_data = NULL; } - -/* functions for EC_POINT objects */ - EC_POINT * EC_POINT_new(const EC_GROUP *group) { @@ -867,7 +906,6 @@ EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) return dest->meth->point_copy(dest, src); } - EC_POINT * EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { @@ -888,18 +926,16 @@ EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) return t; } - const EC_METHOD * EC_POINT_method_of(const EC_POINT *point) { return point->meth; } - int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { - if (group->meth->point_set_to_infinity == 0) { + if (group->meth->point_set_to_infinity == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -912,40 +948,70 @@ EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) int EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, - const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->point_set_Jprojective_coordinates == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } if (!group->meth->point_set_Jprojective_coordinates(group, point, x, y, z, ctx)) - return 0; + goto err; + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { ECerror(EC_R_POINT_IS_NOT_ON_CURVE); - return 0; + goto err; } - return 1; + + ret = 1; + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, - const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) + const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->point_get_Jprojective_coordinates == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } - return group->meth->point_get_Jprojective_coordinates(group, point, + ret = group->meth->point_get_Jprojective_coordinates(group, point, x, y, z, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int @@ -964,23 +1030,39 @@ EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, - const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->point_set_affine_coordinates == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) - return 0; + goto err; + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { ECerror(EC_R_POINT_IS_NOT_ON_CURVE); - return 0; + goto err; } - return 1; + + ret = 1; + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int @@ -1001,8 +1083,16 @@ EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point, int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, - BIGNUM *x, BIGNUM *y, BN_CTX *ctx) + BIGNUM *x, BIGNUM *y, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->point_get_affine_coordinates == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -1011,7 +1101,13 @@ EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, ECerror(EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); + ret = group->meth->point_get_affine_coordinates(group, point, x, y, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int @@ -1032,38 +1128,74 @@ EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *poin int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) + const EC_POINT *b, BN_CTX *ctx_in) { - if (group->meth->add == 0) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->add == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } - if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) { + if (group->meth != r->meth || group->meth != a->meth || + group->meth != b->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } - return group->meth->add(group, r, a, b, ctx); -} + ret = group->meth->add(group, r, a, b, ctx); + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} int -EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) +EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx_in) { - if (group->meth->dbl == 0) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->dbl == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } - if ((group->meth != r->meth) || (r->meth != a->meth)) { + if (group->meth != r->meth || r->meth != a->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->dbl(group, r, a, ctx); -} + ret = group->meth->dbl(group, r, a, ctx); + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} int -EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) +EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->invert == 0) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -1073,13 +1205,18 @@ EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) return 0; } return group->meth->invert(group, a, ctx); -} + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { - if (group->meth->is_at_infinity == 0) { + if (group->meth->is_at_infinity == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -1090,114 +1227,184 @@ EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) return group->meth->is_at_infinity(group, point); } - int -EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) +EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx_in) { - if (group->meth->is_on_curve == 0) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->is_on_curve == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } - return group->meth->is_on_curve(group, point, ctx); -} + ret = group->meth->is_on_curve(group, point, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + return ret; +} int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, - BN_CTX *ctx) + BN_CTX *ctx_in) { - if (group->meth->point_cmp == 0) { + BN_CTX *ctx; + int ret = -1; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->point_cmp == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return -1; + goto err; } - if ((group->meth != a->meth) || (a->meth != b->meth)) { + if (group->meth != a->meth || a->meth != b->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return -1; + goto err; } - return group->meth->point_cmp(group, a, b, ctx); -} + ret = group->meth->point_cmp(group, a, b, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + return ret; +} int -EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx_in) { - if (group->meth->make_affine == 0) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->make_affine == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } - return group->meth->make_affine(group, point, ctx); -} + ret = group->meth->make_affine(group, point, ctx); + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], - BN_CTX *ctx) + BN_CTX *ctx_in) { + BN_CTX *ctx; size_t i; + int ret = 0; - if (group->meth->points_make_affine == 0) { + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (group->meth->points_make_affine == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } for (i = 0; i < num; i++) { if (group->meth != points[i]->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } } - return group->meth->points_make_affine(group, num, points, ctx); -} + ret = group->meth->points_make_affine(group, num, points, ctx); + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; +} -/* Functions for point multiplication */ 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) + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *ctx_in) { - /* - * The function pointers must be set, and only support num == 0 and - * num == 1. - */ + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + /* Only num == 0 and num == 1 is supported. */ if (group->meth->mul_generator_ct == NULL || group->meth->mul_single_ct == NULL || group->meth->mul_double_nonct == NULL || num > 1) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } - /* Either bP or aG + bP, this is sane. */ - if (num == 1 && points != NULL && scalars != NULL) - return EC_POINT_mul(group, r, scalar, points[0], scalars[0], - ctx); + if (num == 1 && points != NULL && scalars != NULL) { + /* Either bP or aG + bP, this is sane. */ + ret = EC_POINT_mul(group, r, scalar, points[0], scalars[0], ctx); + } else if (scalar != NULL && points == NULL && scalars == NULL) { + /* aG, this is sane */ + ret = EC_POINT_mul(group, r, scalar, NULL, NULL, ctx); + } else { + /* anything else is an error */ + ECerror(ERR_R_EC_LIB); + goto err; + } - /* aG, this is sane */ - if (scalar != NULL && points == NULL && scalars == NULL) - return EC_POINT_mul(group, r, scalar, NULL, NULL, ctx); + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); - /* anything else is an error */ - ECerror(ERR_R_EC_LIB); - return 0; + return ret; } int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, - const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) + const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->mul_generator_ct == NULL || group->meth->mul_single_ct == NULL || group->meth->mul_double_nonct == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } + if (g_scalar != NULL && point == NULL && p_scalar == NULL) { /* * In this case we want to compute g_scalar * GeneratorPoint: @@ -1207,52 +1414,69 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, * secret. This is why we ignore if BN_FLG_CONSTTIME is actually * set and we always call the constant time version. */ - return group->meth->mul_generator_ct(group, r, g_scalar, ctx); - } - if (g_scalar == NULL && point != NULL && p_scalar != NULL) { - /* In this case we want to compute p_scalar * GenericPoint: + ret = group->meth->mul_generator_ct(group, r, g_scalar, ctx); + } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) { + /* + * In this case we want to compute p_scalar * GenericPoint: * this codepath is reached most prominently by the second half * of ECDH, where the secret scalar is multiplied by the peer's * public point. To protect the secret scalar, we ignore if * BN_FLG_CONSTTIME is actually set and we always call the * constant time version. */ - return group->meth->mul_single_ct(group, r, p_scalar, point, - ctx); - } - if (g_scalar != NULL && point != NULL && p_scalar != NULL) { + ret = group->meth->mul_single_ct(group, r, p_scalar, point, ctx); + } else if (g_scalar != NULL && point != NULL && p_scalar != NULL) { /* * In this case we want to compute * g_scalar * GeneratorPoint + p_scalar * GenericPoint: * this codepath is reached most prominently by ECDSA signature * verification. So we call the non-ct version. */ - return group->meth->mul_double_nonct(group, r, g_scalar, + ret = group->meth->mul_double_nonct(group, r, g_scalar, p_scalar, point, ctx); + } else { + /* Anything else is an error. */ + ECerror(ERR_R_EC_LIB); + goto err; } - /* Anything else is an error. */ - ECerror(ERR_R_EC_LIB); - return 0; + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int -EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx_in) { - if (group->meth->precompute_mult != 0) - return group->meth->precompute_mult(group, ctx); - else - return 1; /* nothing to do, so report success */ + BN_CTX *ctx; + int ret = 0; + + if (group->meth->precompute_mult == NULL) + return 1; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + ret = group->meth->precompute_mult(group, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int EC_GROUP_have_precompute_mult(const EC_GROUP *group) { - if (group->meth->have_precompute_mult != 0) - return group->meth->have_precompute_mult(group); - else - return 0; /* cannot tell whether precomputation has - * been performed */ + if (group->meth->have_precompute_mult == NULL) + return 0; + + return group->meth->have_precompute_mult(group); } int diff --git a/lib/libcrypto/ec/ec_mult.c b/lib/libcrypto/ec/ec_mult.c index c7927256612..b70e60a1b4b 100644 --- a/lib/libcrypto/ec/ec_mult.c +++ b/lib/libcrypto/ec/ec_mult.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_mult.c,v 1.28 2023/03/08 05:45:31 jsing Exp $ */ +/* $OpenBSD: ec_mult.c,v 1.29 2023/04/11 18:58:20 jsing Exp $ */ /* * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. */ @@ -335,7 +335,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; const EC_POINT *generator = NULL; EC_POINT *tmp = NULL; size_t totalnum; @@ -375,11 +374,6 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - } if (scalar != NULL) { generator = EC_GROUP_get0_generator(group); if (generator == NULL) { @@ -679,7 +673,6 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, ret = 1; err: - BN_CTX_free(new_ctx); EC_POINT_free(tmp); free(wsize); free(wNAF_len); @@ -726,7 +719,6 @@ ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { const EC_POINT *generator; EC_POINT *tmp_point = NULL, *base = NULL, **var; - BN_CTX *new_ctx = NULL; BIGNUM *order; size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; @@ -745,12 +737,9 @@ ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) ECerror(EC_R_UNDEFINED_GENERATOR); goto err; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - } + BN_CTX_start(ctx); + if ((order = BN_CTX_get(ctx)) == NULL) goto err; @@ -857,10 +846,9 @@ ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) pre_comp = NULL; ret = 1; + err: - if (ctx != NULL) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); ec_pre_comp_free(pre_comp); if (points) { EC_POINT **p; diff --git a/lib/libcrypto/ec/ec_oct.c b/lib/libcrypto/ec/ec_oct.c index ef17ec59a59..b1c9e6a6340 100644 --- a/lib/libcrypto/ec/ec_oct.c +++ b/lib/libcrypto/ec/ec_oct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_oct.c,v 1.10 2023/03/08 04:50:27 jsing Exp $ */ +/* $OpenBSD: ec_oct.c,v 1.11 2023/04/11 18:58:20 jsing Exp $ */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -72,18 +72,32 @@ int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, - const BIGNUM *x, int y_bit, BN_CTX *ctx) + const BIGNUM *x, int y_bit, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->point_set_compressed_coordinates == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } - return group->meth->point_set_compressed_coordinates(group, point, + ret = group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int @@ -104,31 +118,59 @@ EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point, size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *ctx) + point_conversion_form_t form, unsigned char *buf, size_t len, + BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->point2oct == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } - return group->meth->point2oct(group, point, form, buf, len, ctx); + ret = group->meth->point2oct(group, point, form, buf, len, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, - const unsigned char *buf, size_t len, BN_CTX *ctx) + const unsigned char *buf, size_t len, BN_CTX *ctx_in) { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = ctx_in) == NULL) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + if (group->meth->oct2point == NULL) { ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; + goto err; } if (group->meth != point->meth) { ECerror(EC_R_INCOMPATIBLE_OBJECTS); - return 0; + goto err; } - return group->meth->oct2point(group, point, buf, len, ctx); + ret = group->meth->oct2point(group, point, buf, len, ctx); + + err: + if (ctx != ctx_in) + BN_CTX_free(ctx); + + return ret; } diff --git a/lib/libcrypto/ec/ecp_mont.c b/lib/libcrypto/ec/ecp_mont.c index 915cf15f720..b1138556039 100644 --- a/lib/libcrypto/ec/ecp_mont.c +++ b/lib/libcrypto/ec/ecp_mont.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecp_mont.c,v 1.28 2023/03/27 10:25:02 tb Exp $ */ +/* $OpenBSD: ecp_mont.c,v 1.29 2023/04/11 18:58:20 jsing Exp $ */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -127,18 +127,12 @@ static int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BN_MONT_CTX *mont = NULL; BIGNUM *one = NULL; int ret = 0; ec_GFp_mont_group_clear(group); - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } mont = BN_MONT_CTX_new(); if (mont == NULL) goto err; @@ -158,14 +152,13 @@ ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, one = NULL; ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); - if (!ret) ec_GFp_mont_group_clear(group); err: - BN_CTX_free(new_ctx); BN_MONT_CTX_free(mont); BN_free(one); + return ret; } @@ -222,6 +215,7 @@ ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx) } if (!bn_copy(r, group->mont_one)) return 0; + return 1; } diff --git a/lib/libcrypto/ec/ecp_nist.c b/lib/libcrypto/ec/ecp_nist.c index c736526a66f..9478b4dc6e4 100644 --- a/lib/libcrypto/ec/ecp_nist.c +++ b/lib/libcrypto/ec/ecp_nist.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecp_nist.c,v 1.25 2023/04/11 18:53:20 jsing Exp $ */ +/* $OpenBSD: ecp_nist.c,v 1.26 2023/04/11 18:58:20 jsing Exp $ */ /* * Written by Nils Larsch for the OpenSSL project. */ @@ -80,15 +80,6 @@ static int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - int ret = 0; - BN_CTX *new_ctx = NULL; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - - BN_CTX_start(ctx); - if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) group->field_mod_func = BN_nist_mod_192; else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) @@ -101,67 +92,40 @@ ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, group->field_mod_func = BN_nist_mod_521; else { ECerror(EC_R_NOT_A_NIST_PRIME); - goto err; + return 0; } - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); - - err: - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - return ret; + return ec_GFp_simple_group_set_curve(group, p, a, b, ctx); } static int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - int ret = 0; - BN_CTX *ctx_new = NULL; - - if (!group || !r || !a || !b) { + if (group == NULL || r == NULL || a == NULL || b == NULL) { ECerror(ERR_R_PASSED_NULL_PARAMETER); - goto err; + return 0; } - if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) - goto err; if (!BN_mul(r, a, b, ctx)) - goto err; - if (!group->field_mod_func(r, r, &group->field, ctx)) - goto err; + return 0; - ret = 1; - err: - BN_CTX_free(ctx_new); - return ret; + return group->field_mod_func(r, r, &group->field, ctx); } static int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { - int ret = 0; - BN_CTX *ctx_new = NULL; - - if (!group || !r || !a) { + if (group == NULL || r == NULL || a == NULL) { ECerror(EC_R_PASSED_NULL_PARAMETER); - goto err; + return 0; } - if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) - goto err; if (!BN_sqr(r, a, ctx)) - goto err; - if (!group->field_mod_func(r, r, &group->field, ctx)) - goto err; + return 0; - ret = 1; - err: - BN_CTX_free(ctx_new); - return ret; + return group->field_mod_func(r, r, &group->field, ctx); } static const EC_METHOD ec_GFp_nist_method = { diff --git a/lib/libcrypto/ec/ecp_oct.c b/lib/libcrypto/ec/ecp_oct.c index f2f1929e849..8cdf544bf1f 100644 --- a/lib/libcrypto/ec/ecp_oct.c +++ b/lib/libcrypto/ec/ecp_oct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecp_oct.c,v 1.19 2022/11/26 16:08:52 tb Exp $ */ +/* $OpenBSD: ecp_oct.c,v 1.20 2023/04/11 18:58:20 jsing Exp $ */ /* Includes code written by Lenka Fibikova * for the OpenSSL project. * Includes code written by Bodo Moeller for the OpenSSL project. @@ -70,21 +70,16 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x_, int y_bit, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *tmp1, *tmp2, *x, *y; int ret = 0; /* clear error queue */ ERR_clear_error(); - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } y_bit = (y_bit != 0); BN_CTX_start(ctx); + if ((tmp1 = BN_CTX_get(ctx)) == NULL) goto err; if ((tmp2 = BN_CTX_get(ctx)) == NULL) @@ -179,27 +174,25 @@ ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } - size_t -ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *ctx) +ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx) { - size_t ret; - BN_CTX *new_ctx = NULL; - int used_ctx = 0; BIGNUM *x, *y; size_t field_len, i, skip; + size_t ret = 0; - if ((form != POINT_CONVERSION_COMPRESSED) - && (form != POINT_CONVERSION_UNCOMPRESSED) - && (form != POINT_CONVERSION_HYBRID)) { + if (form != POINT_CONVERSION_COMPRESSED && + form != POINT_CONVERSION_UNCOMPRESSED && + form != POINT_CONVERSION_HYBRID) { ECerror(EC_R_INVALID_FORM); - goto err; + return 0; } + if (EC_POINT_is_at_infinity(group, point) > 0) { /* encodes to a single 0 octet */ if (buf != NULL) { @@ -211,23 +204,20 @@ ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conv } return 1; } + /* ret := required output buffer length */ field_len = BN_num_bytes(&group->field); ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + BN_CTX_start(ctx); + /* if 'buf' is NULL, just return required length */ if (buf != NULL) { if (len < ret) { ECerror(EC_R_BUFFER_TOO_SMALL); goto err; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - BN_CTX_start(ctx); - used_ctx = 1; + if ((x = BN_CTX_get(ctx)) == NULL) goto err; if ((y = BN_CTX_get(ctx)) == NULL) @@ -276,18 +266,12 @@ ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conv goto err; } } - if (used_ctx) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - return ret; err: - if (used_ctx) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - return 0; -} + BN_CTX_end(ctx); + return ret; +} int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, @@ -295,7 +279,6 @@ ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, { point_conversion_form_t form; int y_bit; - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; size_t field_len, enc_len; int ret = 0; @@ -331,12 +314,9 @@ ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, ECerror(EC_R_INVALID_ENCODING); return 0; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } + BN_CTX_start(ctx); + if ((x = BN_CTX_get(ctx)) == NULL) goto err; if ((y = BN_CTX_get(ctx)) == NULL) @@ -380,6 +360,6 @@ ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } diff --git a/lib/libcrypto/ec/ecp_smpl.c b/lib/libcrypto/ec/ecp_smpl.c index 90330652e49..1162d89ca50 100644 --- a/lib/libcrypto/ec/ecp_smpl.c +++ b/lib/libcrypto/ec/ecp_smpl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecp_smpl.c,v 1.43 2023/03/27 10:25:02 tb Exp $ */ +/* $OpenBSD: ecp_smpl.c,v 1.44 2023/04/11 18:58:20 jsing Exp $ */ /* Includes code written by Lenka Fibikova * for the OpenSSL project. * Includes code written by Bodo Moeller for the OpenSSL project. @@ -118,21 +118,17 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - int ret = 0; - BN_CTX *new_ctx = NULL; BIGNUM *tmp_a; + int ret = 0; /* p must be a prime > 3 */ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { ECerror(EC_R_INVALID_FIELD); return 0; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } + BN_CTX_start(ctx); + if ((tmp_a = BN_CTX_get(ctx)) == NULL) goto err; @@ -166,51 +162,38 @@ ec_GFp_simple_group_set_curve(EC_GROUP *group, err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { - int ret = 0; - BN_CTX *new_ctx = NULL; - if (p != NULL) { if (!bn_copy(p, &group->field)) return 0; } - if (a != NULL || b != NULL) { - if (group->meth->field_decode) { - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - if (a != NULL) { - if (!group->meth->field_decode(group, a, &group->a, ctx)) - goto err; - } - if (b != NULL) { - if (!group->meth->field_decode(group, b, &group->b, ctx)) - goto err; - } - } else { - if (a != NULL) { - if (!bn_copy(a, &group->a)) - goto err; - } - if (b != NULL) { - if (!bn_copy(b, &group->b)) - goto err; - } + if (group->meth->field_decode != NULL) { + if (a != NULL) { + if (!group->meth->field_decode(group, a, &group->a, ctx)) + return 0; + } + if (b != NULL) { + if (!group->meth->field_decode(group, b, &group->b, ctx)) + return 0; + } + } else { + if (a != NULL) { + if (!bn_copy(a, &group->a)) + return 0; + } + if (b != NULL) { + if (!bn_copy(b, &group->b)) + return 0; } } - ret = 1; - err: - BN_CTX_free(new_ctx); - return ret; + return 1; } int @@ -222,19 +205,12 @@ ec_GFp_simple_group_get_degree(const EC_GROUP *group) int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) { - int ret = 0; BIGNUM *a, *b, *order, *tmp_1, *tmp_2; const BIGNUM *p = &group->field; - BN_CTX *new_ctx = NULL; + int ret = 0; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) { - ECerror(ERR_R_MALLOC_FAILURE); - goto err; - } - } BN_CTX_start(ctx); + if ((a = BN_CTX_get(ctx)) == NULL) goto err; if ((b = BN_CTX_get(ctx)) == NULL) @@ -288,9 +264,8 @@ ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) ret = 1; err: - if (ctx != NULL) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); + return ret; } @@ -341,18 +316,12 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; int ret = 0; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } if (x != NULL) { if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err; - if (group->meth->field_encode) { + if (group->meth->field_encode != NULL) { if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err; } @@ -360,7 +329,7 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group, if (y != NULL) { if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err; - if (group->meth->field_encode) { + if (group->meth->field_encode != NULL) { if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err; } @@ -371,7 +340,7 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group, if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err; Z_is_one = BN_is_one(&point->Z); - if (group->meth->field_encode) { + if (group->meth->field_encode != NULL) { if (Z_is_one && (group->meth->field_set_to_one != 0)) { if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err; @@ -385,7 +354,6 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group, ret = 1; err: - BN_CTX_free(new_ctx); return ret; } @@ -393,15 +361,9 @@ int ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; int ret = 0; - if (group->meth->field_decode != 0) { - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } + if (group->meth->field_decode != NULL) { if (x != NULL) { if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err; @@ -432,7 +394,6 @@ ec_GFp_simple_get_Jprojective_coordinates(const EC_GROUP *group, ret = 1; err: - BN_CTX_free(new_ctx); return ret; } @@ -453,7 +414,6 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *Z, *Z_1, *Z_2, *Z_3; const BIGNUM *Z_; int ret = 0; @@ -462,12 +422,9 @@ ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT ECerror(EC_R_POINT_AT_INFINITY); return 0; } - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } + BN_CTX_start(ctx); + if ((Z = BN_CTX_get(ctx)) == NULL) goto err; if ((Z_1 = BN_CTX_get(ctx)) == NULL) @@ -552,7 +509,7 @@ ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } @@ -561,9 +518,8 @@ ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const E { int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); - const BIGNUM *p; - BN_CTX *new_ctx = NULL; BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; + const BIGNUM *p; int ret = 0; if (a == b) @@ -577,12 +533,8 @@ ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const E field_sqr = group->meth->field_sqr; p = &group->field; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } BN_CTX_start(ctx); + if ((n0 = BN_CTX_get(ctx)) == NULL) goto end; if ((n1 = BN_CTX_get(ctx)) == NULL) @@ -738,9 +690,8 @@ ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const E ret = 1; end: - if (ctx) /* otherwise we already called BN_CTX_end */ - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); + return ret; } @@ -750,7 +701,6 @@ ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); const BIGNUM *p; - BN_CTX *new_ctx = NULL; BIGNUM *n0, *n1, *n2, *n3; int ret = 0; @@ -763,12 +713,8 @@ ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX field_sqr = group->meth->field_sqr; p = &group->field; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } BN_CTX_start(ctx); + if ((n0 = BN_CTX_get(ctx)) == NULL) goto err; if ((n1 = BN_CTX_get(ctx)) == NULL) @@ -881,7 +827,7 @@ ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } @@ -907,7 +853,6 @@ ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX * int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); const BIGNUM *p; - BN_CTX *new_ctx = NULL; BIGNUM *rh, *tmp, *Z4, *Z6; int ret = -1; @@ -918,12 +863,8 @@ ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX * field_sqr = group->meth->field_sqr; p = &group->field; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } BN_CTX_start(ctx); + if ((rh = BN_CTX_get(ctx)) == NULL) goto err; if ((tmp = BN_CTX_get(ctx)) == NULL) @@ -999,7 +940,7 @@ ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX * err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } @@ -1013,29 +954,24 @@ ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, B int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); - BN_CTX *new_ctx = NULL; BIGNUM *tmp1, *tmp2, *Za23, *Zb23; const BIGNUM *tmp1_, *tmp2_; int ret = -1; - if (EC_POINT_is_at_infinity(group, a) > 0) { + if (EC_POINT_is_at_infinity(group, a) > 0) return EC_POINT_is_at_infinity(group, b) > 0 ? 0 : 1; - } + if (EC_POINT_is_at_infinity(group, b) > 0) return 1; - if (a->Z_is_one && b->Z_is_one) { + if (a->Z_is_one && b->Z_is_one) return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; - } + field_mul = group->meth->field_mul; field_sqr = group->meth->field_sqr; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } BN_CTX_start(ctx); + if ((tmp1 = BN_CTX_get(ctx)) == NULL) goto end; if ((tmp2 = BN_CTX_get(ctx)) == NULL) @@ -1100,26 +1036,21 @@ ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, B end: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *x, *y; int ret = 0; if (point->Z_is_one || EC_POINT_is_at_infinity(group, point) > 0) return 1; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } BN_CTX_start(ctx); + if ((x = BN_CTX_get(ctx)) == NULL) goto err; if ((y = BN_CTX_get(ctx)) == NULL) @@ -1137,14 +1068,13 @@ ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + return ret; } int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; BIGNUM *tmp0, *tmp1; size_t pow2 = 0; BIGNUM **heap = NULL; @@ -1154,12 +1084,8 @@ ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *po if (num == 0) return 1; - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } BN_CTX_start(ctx); + if ((tmp0 = BN_CTX_get(ctx)) == NULL) goto err; if ((tmp1 = BN_CTX_get(ctx)) == NULL) @@ -1301,7 +1227,7 @@ ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *po err: BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + if (heap != NULL) { /* * heap[pow2/2] .. heap[pow2-1] have not been allocated @@ -1431,12 +1357,8 @@ ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, BIGNUM *k = NULL; BIGNUM *lambda = NULL; BIGNUM *cardinality = NULL; - BN_CTX *new_ctx = NULL; int ret = 0; - if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); if ((s = EC_POINT_new(group)) == NULL) @@ -1605,9 +1527,7 @@ ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, err: EC_POINT_free(s); - if (ctx != NULL) - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); + BN_CTX_end(ctx); return ret; } -- 2.20.1