Handle BN_CTX at the EC API boundary.
authorjsing <jsing@openbsd.org>
Tue, 11 Apr 2023 18:58:20 +0000 (18:58 +0000)
committerjsing <jsing@openbsd.org>
Tue, 11 Apr 2023 18:58:20 +0000 (18:58 +0000)
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
lib/libcrypto/ec/ec2_oct.c
lib/libcrypto/ec/ec2_smpl.c
lib/libcrypto/ec/ec_check.c
lib/libcrypto/ec/ec_lib.c
lib/libcrypto/ec/ec_mult.c
lib/libcrypto/ec/ec_oct.c
lib/libcrypto/ec/ecp_mont.c
lib/libcrypto/ec/ecp_nist.c
lib/libcrypto/ec/ecp_oct.c
lib/libcrypto/ec/ecp_smpl.c

index d32b744..d7cbd93 100644 (file)
@@ -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;
 }
 
index d3fbc12..6cb7259 100644 (file)
@@ -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
index 1ad339c..850159c 100644 (file)
@@ -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;
 }
 
index 5c6165e..4e065c7 100644 (file)
@@ -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.
  *
 #include <openssl/err.h>
 
 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;
 }
index 38ddd7a..bc472b7 100644 (file)
@@ -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
index c792725..b70e60a 100644 (file)
@@ -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;
index ef17ec5..b1c9e6a 100644 (file)
@@ -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.
  */
 
 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;
 }
index 915cf15..b113855 100644 (file)
@@ -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;
 }
 
index c736526..9478b4d 100644 (file)
@@ -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 = {
index f2f1929..8cdf544 100644 (file)
@@ -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 <fibikova@exp-math.uni-essen.de>
  * 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;
 }
index 9033065..1162d89 100644 (file)
@@ -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 <fibikova@exp-math.uni-essen.de>
  * 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;
 }