Improve error handling if decompression of an ec point fails, and cleanup
[openssl.git] / crypto / bn / bn_gf2m.c
index 1cdad7473b464aafe3ffef5f63b7caa1ec73bea7..8a945f043f20c1e45e64fac364a90356b1da12d8 100644 (file)
@@ -228,7 +228,7 @@ static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const
        BN_ULONG tab[16], top3b = a >> 61;
        register BN_ULONG a1, a2, a4, a8;
 
        BN_ULONG tab[16], top3b = a >> 61;
        register BN_ULONG a1, a2, a4, a8;
 
-       a1 = a & (0x1FFFFFFFFFFFFFFF); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1;
+       a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1;
 
        tab[ 0] = 0;     tab[ 1] = a1;       tab[ 2] = a2;       tab[ 3] = a1^a2;
        tab[ 4] = a4;    tab[ 5] = a1^a4;    tab[ 6] = a2^a4;    tab[ 7] = a1^a2^a4;
 
        tab[ 0] = 0;     tab[ 1] = a1;       tab[ 2] = a2;       tab[ 3] = a1^a2;
        tab[ 4] = a4;    tab[ 5] = a1^a4;    tab[ 6] = a2^a4;    tab[ 7] = a1^a2^a4;
@@ -288,6 +288,9 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
        int i;
        const BIGNUM *at, *bt;
 
        int i;
        const BIGNUM *at, *bt;
 
+       bn_check_top(a);
+       bn_check_top(b);
+
        if (a->top < b->top) { at = b; bt = a; }
        else { at = a; bt = b; }
 
        if (a->top < b->top) { at = b; bt = a; }
        else { at = a; bt = b; }
 
@@ -322,10 +325,15 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[])
        int j, k;
        int n, dN, d0, d1;
        BN_ULONG zz, *z;
        int j, k;
        int n, dN, d0, d1;
        BN_ULONG zz, *z;
-       
+
+       bn_check_top(a);
+
        if (!p[0])
        if (!p[0])
+               {
                /* reduction mod 1 => return 0 */
                /* reduction mod 1 => return 0 */
-               return BN_zero(r);
+               BN_zero(r);
+               return 1;
+               }
 
        /* Since the algorithm does reduction in the r value, if a != r, copy
         * the contents of a into r so we can do reduction in r. 
 
        /* Since the algorithm does reduction in the r value, if a != r, copy
         * the contents of a into r so we can do reduction in r. 
@@ -397,7 +405,6 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[])
                }
 
        bn_correct_top(r);
                }
 
        bn_correct_top(r);
-       
        return 1;
        }
 
        return 1;
        }
 
@@ -409,8 +416,11 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[])
  */
 int    BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
        {
  */
 int    BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
        {
+       int ret = 0;
        const int max = BN_num_bits(p);
        const int max = BN_num_bits(p);
-       unsigned int *arr=NULL, ret = 0;
+       unsigned int *arr=NULL;
+       bn_check_top(a);
+       bn_check_top(p);
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
@@ -420,7 +430,7 @@ int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
                }
        ret = BN_GF2m_mod_arr(r, a, arr);
        bn_check_top(r);
                }
        ret = BN_GF2m_mod_arr(r, a, arr);
        bn_check_top(r);
-  err:
+err:
        if (arr) OPENSSL_free(arr);
        return ret;
        }
        if (arr) OPENSSL_free(arr);
        return ret;
        }
@@ -434,12 +444,14 @@ int       BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
        int zlen, i, j, k, ret = 0;
        BIGNUM *s;
        BN_ULONG x1, x0, y1, y0, zz[4];
        int zlen, i, j, k, ret = 0;
        BIGNUM *s;
        BN_ULONG x1, x0, y1, y0, zz[4];
-       
+
+       bn_check_top(a);
+       bn_check_top(b);
+
        if (a == b)
                {
                return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
                }
        if (a == b)
                {
                return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
                }
-       
 
        BN_CTX_start(ctx);
        if ((s = BN_CTX_get(ctx)) == NULL) goto err;
 
        BN_CTX_start(ctx);
        if ((s = BN_CTX_get(ctx)) == NULL) goto err;
@@ -468,10 +480,9 @@ int        BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
                ret = 1;
        bn_check_top(r);
 
                ret = 1;
        bn_check_top(r);
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        BN_CTX_end(ctx);
        return ret;
-       
        }
 
 /* Compute the product of two polynomials a and b, reduce modulo p, and store
        }
 
 /* Compute the product of two polynomials a and b, reduce modulo p, and store
@@ -483,8 +494,12 @@ int        BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
  */
 int    BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
        {
  */
 int    BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
        {
+       int ret = 0;
        const int max = BN_num_bits(p);
        const int max = BN_num_bits(p);
-       unsigned int *arr=NULL, ret = 0;
+       unsigned int *arr=NULL;
+       bn_check_top(a);
+       bn_check_top(b);
+       bn_check_top(p);
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
@@ -494,7 +509,7 @@ int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p
                }
        ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
        bn_check_top(r);
                }
        ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
        bn_check_top(r);
-  err:
+err:
        if (arr) OPENSSL_free(arr);
        return ret;
        }
        if (arr) OPENSSL_free(arr);
        return ret;
        }
@@ -505,7 +520,8 @@ int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_C
        {
        int i, ret = 0;
        BIGNUM *s;
        {
        int i, ret = 0;
        BIGNUM *s;
-       
+
+       bn_check_top(a);
        BN_CTX_start(ctx);
        if ((s = BN_CTX_get(ctx)) == NULL) return 0;
        if (!bn_wexpand(s, 2 * a->top)) goto err;
        BN_CTX_start(ctx);
        if ((s = BN_CTX_get(ctx)) == NULL) return 0;
        if (!bn_wexpand(s, 2 * a->top)) goto err;
@@ -521,7 +537,7 @@ int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_C
        if (!BN_GF2m_mod_arr(r, s, p)) goto err;
        bn_check_top(r);
        ret = 1;
        if (!BN_GF2m_mod_arr(r, s, p)) goto err;
        bn_check_top(r);
        ret = 1;
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -534,8 +550,12 @@ int        BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_C
  */
 int    BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        {
  */
 int    BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        {
+       int ret = 0;
        const int max = BN_num_bits(p);
        const int max = BN_num_bits(p);
-       unsigned int *arr=NULL, ret = 0;
+       unsigned int *arr=NULL;
+
+       bn_check_top(a);
+       bn_check_top(p);
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
@@ -545,7 +565,7 @@ int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                }
        ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
        bn_check_top(r);
                }
        ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
        bn_check_top(r);
-  err:
+err:
        if (arr) OPENSSL_free(arr);
        return ret;
        }
        if (arr) OPENSSL_free(arr);
        return ret;
        }
@@ -561,6 +581,9 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        BIGNUM *b, *c, *u, *v, *tmp;
        int ret = 0;
 
        BIGNUM *b, *c, *u, *v, *tmp;
        int ret = 0;
 
+       bn_check_top(a);
+       bn_check_top(p);
+
        BN_CTX_start(ctx);
        
        b = BN_CTX_get(ctx);
        BN_CTX_start(ctx);
        
        b = BN_CTX_get(ctx);
@@ -570,7 +593,6 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        if (v == NULL) goto err;
 
        if (!BN_one(b)) goto err;
        if (v == NULL) goto err;
 
        if (!BN_one(b)) goto err;
-       if (!BN_zero(c)) goto err;
        if (!BN_GF2m_mod(u, a, p)) goto err;
        if (!BN_copy(v, p)) goto err;
 
        if (!BN_GF2m_mod(u, a, p)) goto err;
        if (!BN_copy(v, p)) goto err;
 
@@ -605,7 +627,7 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        bn_check_top(r);
        ret = 1;
 
        bn_check_top(r);
        ret = 1;
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -621,6 +643,7 @@ int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_
        BIGNUM *field;
        int ret = 0;
 
        BIGNUM *field;
        int ret = 0;
 
+       bn_check_top(xx);
        BN_CTX_start(ctx);
        if ((field = BN_CTX_get(ctx)) == NULL) goto err;
        if (!BN_GF2m_arr2poly(p, field)) goto err;
        BN_CTX_start(ctx);
        if ((field = BN_CTX_get(ctx)) == NULL) goto err;
        if (!BN_GF2m_arr2poly(p, field)) goto err;
@@ -628,7 +651,7 @@ int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_
        ret = BN_GF2m_mod_inv(r, xx, field, ctx);
        bn_check_top(r);
 
        ret = BN_GF2m_mod_inv(r, xx, field, ctx);
        bn_check_top(r);
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -642,7 +665,11 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
        {
        BIGNUM *xinv = NULL;
        int ret = 0;
        {
        BIGNUM *xinv = NULL;
        int ret = 0;
-       
+
+       bn_check_top(y);
+       bn_check_top(x);
+       bn_check_top(p);
+
        BN_CTX_start(ctx);
        xinv = BN_CTX_get(ctx);
        if (xinv == NULL) goto err;
        BN_CTX_start(ctx);
        xinv = BN_CTX_get(ctx);
        if (xinv == NULL) goto err;
@@ -652,7 +679,7 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
        bn_check_top(r);
        ret = 1;
 
        bn_check_top(r);
        ret = 1;
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -668,6 +695,10 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
        BIGNUM *a, *b, *u, *v;
        int ret = 0;
 
        BIGNUM *a, *b, *u, *v;
        int ret = 0;
 
+       bn_check_top(y);
+       bn_check_top(x);
+       bn_check_top(p);
+
        BN_CTX_start(ctx);
        
        a = BN_CTX_get(ctx);
        BN_CTX_start(ctx);
        
        a = BN_CTX_get(ctx);
@@ -680,7 +711,6 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
        if (!BN_GF2m_mod(u, y, p)) goto err;
        if (!BN_GF2m_mod(a, x, p)) goto err;
        if (!BN_copy(b, p)) goto err;
        if (!BN_GF2m_mod(u, y, p)) goto err;
        if (!BN_GF2m_mod(a, x, p)) goto err;
        if (!BN_copy(b, p)) goto err;
-       if (!BN_zero(v)) goto err;
        
        while (!BN_is_odd(a))
                {
        
        while (!BN_is_odd(a))
                {
@@ -721,7 +751,7 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
        bn_check_top(r);
        ret = 1;
 
        bn_check_top(r);
        ret = 1;
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -739,6 +769,9 @@ int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const uns
        BIGNUM *field;
        int ret = 0;
 
        BIGNUM *field;
        int ret = 0;
 
+       bn_check_top(yy);
+       bn_check_top(xx);
+
        BN_CTX_start(ctx);
        if ((field = BN_CTX_get(ctx)) == NULL) goto err;
        if (!BN_GF2m_arr2poly(p, field)) goto err;
        BN_CTX_start(ctx);
        if ((field = BN_CTX_get(ctx)) == NULL) goto err;
        if (!BN_GF2m_arr2poly(p, field)) goto err;
@@ -746,7 +779,7 @@ int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const uns
        ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
        bn_check_top(r);
 
        ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
        bn_check_top(r);
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -760,13 +793,15 @@ int       BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
        {
        int ret = 0, i, n;
        BIGNUM *u;
        {
        int ret = 0, i, n;
        BIGNUM *u;
-       
+
+       bn_check_top(a);
+       bn_check_top(b);
+
        if (BN_is_zero(b))
                return(BN_one(r));
 
        if (BN_abs_is_word(b, 1))
                return (BN_copy(r, a) != NULL);
        if (BN_is_zero(b))
                return(BN_one(r));
 
        if (BN_abs_is_word(b, 1))
                return (BN_copy(r, a) != NULL);
-       
 
        BN_CTX_start(ctx);
        if ((u = BN_CTX_get(ctx)) == NULL) goto err;
 
        BN_CTX_start(ctx);
        if ((u = BN_CTX_get(ctx)) == NULL) goto err;
@@ -784,10 +819,8 @@ int        BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
                }
        if (!BN_copy(r, u)) goto err;
        bn_check_top(r);
                }
        if (!BN_copy(r, u)) goto err;
        bn_check_top(r);
-
        ret = 1;
        ret = 1;
-
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -801,8 +834,12 @@ int        BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsig
  */
 int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
        {
  */
 int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
        {
+       int ret = 0;
        const int max = BN_num_bits(p);
        const int max = BN_num_bits(p);
-       unsigned int *arr=NULL, ret = 0;
+       unsigned int *arr=NULL;
+       bn_check_top(a);
+       bn_check_top(b);
+       bn_check_top(p);
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
@@ -812,7 +849,7 @@ int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p
                }
        ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
        bn_check_top(r);
                }
        ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
        bn_check_top(r);
-  err:
+err:
        if (arr) OPENSSL_free(arr);
        return ret;
        }
        if (arr) OPENSSL_free(arr);
        return ret;
        }
@@ -826,19 +863,23 @@ int       BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_
        int ret = 0;
        BIGNUM *u;
 
        int ret = 0;
        BIGNUM *u;
 
+       bn_check_top(a);
+
        if (!p[0])
        if (!p[0])
+               {
                /* reduction mod 1 => return 0 */
                /* reduction mod 1 => return 0 */
-               return BN_zero(r);
-       
+               BN_zero(r);
+               return 1;
+               }
+
        BN_CTX_start(ctx);
        if ((u = BN_CTX_get(ctx)) == NULL) goto err;
        
        BN_CTX_start(ctx);
        if ((u = BN_CTX_get(ctx)) == NULL) goto err;
        
-       if (!BN_zero(u)) goto err;
        if (!BN_set_bit(u, p[0] - 1)) goto err;
        ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
        bn_check_top(r);
 
        if (!BN_set_bit(u, p[0] - 1)) goto err;
        ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
        bn_check_top(r);
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -852,8 +893,11 @@ int        BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_
  */
 int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        {
  */
 int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        {
+       int ret = 0;
        const int max = BN_num_bits(p);
        const int max = BN_num_bits(p);
-       unsigned int *arr=NULL, ret = 0;
+       unsigned int *arr=NULL;
+       bn_check_top(a);
+       bn_check_top(p);
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
        if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
@@ -863,7 +907,7 @@ int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                }
        ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
        bn_check_top(r);
                }
        ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
        bn_check_top(r);
-  err:
+err:
        if (arr) OPENSSL_free(arr);
        return ret;
        }
        if (arr) OPENSSL_free(arr);
        return ret;
        }
@@ -877,9 +921,14 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p
        unsigned int j;
        BIGNUM *a, *z, *rho, *w, *w2, *tmp;
 
        unsigned int j;
        BIGNUM *a, *z, *rho, *w, *w2, *tmp;
 
+       bn_check_top(a_);
+
        if (!p[0])
        if (!p[0])
+               {
                /* reduction mod 1 => return 0 */
                /* reduction mod 1 => return 0 */
-               return BN_zero(r);
+               BN_zero(r);
+               return 1;
+               }
 
        BN_CTX_start(ctx);
        a = BN_CTX_get(ctx);
 
        BN_CTX_start(ctx);
        a = BN_CTX_get(ctx);
@@ -891,7 +940,8 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p
        
        if (BN_is_zero(a))
                {
        
        if (BN_is_zero(a))
                {
-               ret = BN_zero(r);
+               BN_zero(r);
+               ret = 1;
                goto err;
                }
 
                goto err;
                }
 
@@ -917,7 +967,7 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p
                        {
                        if (!BN_rand(rho, p[0], 0, 0)) goto err;
                        if (!BN_GF2m_mod_arr(rho, rho, p)) goto err;
                        {
                        if (!BN_rand(rho, p[0], 0, 0)) goto err;
                        if (!BN_GF2m_mod_arr(rho, rho, p)) goto err;
-                       if (!BN_zero(z)) goto err;
+                       BN_zero(z);
                        if (!BN_copy(w, rho)) goto err;
                        for (j = 1; j <= p[0] - 1; j++)
                                {
                        if (!BN_copy(w, rho)) goto err;
                        for (j = 1; j <= p[0] - 1; j++)
                                {
@@ -938,14 +988,18 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p
        
        if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) goto err;
        if (!BN_GF2m_add(w, z, w)) goto err;
        
        if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) goto err;
        if (!BN_GF2m_add(w, z, w)) goto err;
-       if (BN_GF2m_cmp(w, a)) goto err;
+       if (BN_GF2m_cmp(w, a))
+               {
+               BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
+               goto err;
+               }
 
        if (!BN_copy(r, z)) goto err;
        bn_check_top(r);
 
        ret = 1;
 
 
        if (!BN_copy(r, z)) goto err;
        bn_check_top(r);
 
        ret = 1;
 
-  err:
+err:
        BN_CTX_end(ctx);
        return ret;
        }
        BN_CTX_end(ctx);
        return ret;
        }
@@ -958,9 +1012,13 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p
  */
 int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        {
  */
 int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        {
+       int ret = 0;
        const int max = BN_num_bits(p);
        const int max = BN_num_bits(p);
-       unsigned int *arr=NULL, ret = 0;
-       if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
+       unsigned int *arr=NULL;
+       bn_check_top(a);
+       bn_check_top(p);
+       if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) *
+                                               max)) == NULL) goto err;
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
                {
        ret = BN_GF2m_poly2arr(p, arr, max);
        if (!ret || ret > max)
                {
@@ -969,7 +1027,7 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *
                }
        ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
        bn_check_top(r);
                }
        ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
        bn_check_top(r);
-  err:
+err:
        if (arr) OPENSSL_free(arr);
        return ret;
        }
        if (arr) OPENSSL_free(arr);
        return ret;
        }
@@ -1018,6 +1076,7 @@ int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a)
        {
        int i;
 
        {
        int i;
 
+       bn_check_top(a);
        BN_zero(a);
        for (i = 0; p[i] != 0; i++)
                {
        BN_zero(a);
        for (i = 0; p[i] != 0; i++)
                {
@@ -1025,7 +1084,7 @@ int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a)
                }
        BN_set_bit(a, 0);
        bn_check_top(a);
                }
        BN_set_bit(a, 0);
        bn_check_top(a);
-       
+
        return 1;
        }
 
        return 1;
        }