Commit 48116c2d0f for openssl.org

commit 48116c2d0fbb1db875e2bc703c08089bf3c5c5c3
Author: Agustin Gianni <agustingianni@gmail.com>
Date:   Fri Jan 8 16:04:05 2021 +0100

    Fix incorrect use of BN_CTX API

    In some edge cases BN_CTX_end was being called without first calling
    BN_CTX_start. This creates a situation where the state of the big
    number allocator is corrupted and may lead to crashes.

    Fixes #13812

    Reviewed-by: Matt Caswell <matt@openssl.org>
    Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13813)

diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c
index a344d7df02..810f3c7b3d 100644
--- a/crypto/bn/bn_prime.c
+++ b/crypto/bn/bn_prime.c
@@ -145,8 +145,10 @@ int BN_generate_prime_ex2(BIGNUM *ret, int bits, int safe,
     }

     mods = OPENSSL_zalloc(sizeof(*mods) * NUMPRIMES);
-    if (mods == NULL)
-        goto err;
+    if (mods == NULL) {
+        ERR_raise(ERR_LIB_BN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }

     BN_CTX_start(ctx);
     t = BN_CTX_get(ctx);
diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c
index e323a7f7ab..e0b21ab575 100644
--- a/crypto/bn/bn_sqrt.c
+++ b/crypto/bn/bn_sqrt.c
@@ -22,6 +22,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
     int r;
     BIGNUM *A, *b, *q, *t, *x, *y;
     int e, i, j;
+    int used_ctx = 0;

     if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
         if (BN_abs_is_word(p, 2)) {
@@ -57,6 +58,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
     }

     BN_CTX_start(ctx);
+    used_ctx = 1;
     A = BN_CTX_get(ctx);
     b = BN_CTX_get(ctx);
     q = BN_CTX_get(ctx);
@@ -353,7 +355,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
             BN_clear_free(ret);
         ret = NULL;
     }
-    BN_CTX_end(ctx);
+    if (used_ctx)
+        BN_CTX_end(ctx);
     bn_check_top(ret);
     return ret;
 }
diff --git a/crypto/bn/bn_x931p.c b/crypto/bn/bn_x931p.c
index 1e4d4991b2..bca7c9788e 100644
--- a/crypto/bn/bn_x931p.c
+++ b/crypto/bn/bn_x931p.c
@@ -174,7 +174,7 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
      * exceeded.
      */
     if (!BN_priv_rand_ex(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY, ctx))
-        goto err;
+        return 0;

     BN_CTX_start(ctx);
     t = BN_CTX_get(ctx);
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c
index 87b9eab604..98bcab2321 100644
--- a/crypto/ec/ec_mult.c
+++ b/crypto/ec/ec_mult.c
@@ -835,6 +835,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
     EC_POINT **points = NULL;
     EC_PRE_COMP *pre_comp;
     int ret = 0;
+    int used_ctx = 0;
 #ifndef FIPS_MODULE
     BN_CTX *new_ctx = NULL;
 #endif
@@ -858,6 +859,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
         goto err;

     BN_CTX_start(ctx);
+    used_ctx = 1;

     order = EC_GROUP_get0_order(group);
     if (order == NULL)
@@ -967,7 +969,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
     ret = 1;

  err:
-    BN_CTX_end(ctx);
+    if (used_ctx)
+        BN_CTX_end(ctx);
 #ifndef FIPS_MODULE
     BN_CTX_free(new_ctx);
 #endif