From b0ee26c7d2e2ba5f8d9159d9c269c93565c36841 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Tue, 11 Apr 2023 18:58:20 +0000 Subject: 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@ --- src/lib/libcrypto/ec/ec_oct.c | 70 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 14 deletions(-) (limited to 'src/lib/libcrypto/ec/ec_oct.c') diff --git a/src/lib/libcrypto/ec/ec_oct.c b/src/lib/libcrypto/ec/ec_oct.c index ef17ec59a5..b1c9e6a634 100644 --- a/src/lib/libcrypto/ec/ec_oct.c +++ b/src/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; } -- cgit v1.2.3-55-g6feb