Convert openssl code not to assume the deprecated form of BN_zero().

Remove certain redundant BN_zero() initialisations, because BN_CTX_get(),
BN_init(), [etc] already initialise to zero.

Correct error checking in bn_sqr.c, and be less wishy-wash about how/why
the result's 'top' value is set (note also, 'max' is always > 0 at this
point).
diff --git a/CHANGES b/CHANGES
index e675c90..a8866ad 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
 
  Changes between 0.9.7c and 0.9.8  [xx XXX xxxx]
 
+  *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results,
+     and this should never fail. So the return value from the use of
+     BN_set_word() (which can fail due to needless expansion) is now deprecated;
+     if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro.
+     [Geoff Thorpe]
+
   *) BN_CTX_get() should return zero-valued bignums, providing the same
      initialised value as BN_new().
      [Geoff Thorpe, suggested by Ulf Möller]
diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c
index aef77cb..c11e5af 100644
--- a/crypto/bn/bn_exp.c
+++ b/crypto/bn/bn_exp.c
@@ -266,7 +266,8 @@
 	if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err;		/* 1 */
 	if (BN_is_zero(&(val[0])))
 		{
-		ret = BN_zero(r);
+		BN_zero(r);
+		ret = 1;
 		goto err;
 		}
 
@@ -409,7 +410,8 @@
 		aa=a;
 	if (BN_is_zero(aa))
 		{
-		ret = BN_zero(rr);
+		BN_zero(rr);
+		ret = 1;
 		goto err;
 		}
 	if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
@@ -541,7 +543,8 @@
 		}
 	if (a == 0)
 		{
-		ret = BN_zero(rr);
+		BN_zero(rr);
+		ret = 1;
 		return ret;
 		}
 
@@ -666,7 +669,8 @@
 	if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err;		/* 1 */
 	if (BN_is_zero(&(val[0])))
 		{
-		ret = BN_zero(r);
+		BN_zero(r);
+		ret = 1;
 		goto err;
 		}
 
diff --git a/crypto/bn/bn_exp2.c b/crypto/bn/bn_exp2.c
index 979ceef..1223c67 100644
--- a/crypto/bn/bn_exp2.c
+++ b/crypto/bn/bn_exp2.c
@@ -179,7 +179,8 @@
 		a_mod_m = a1;
 	if (BN_is_zero(a_mod_m))
 		{
-		ret = BN_zero(rr);
+		BN_zero(rr);
+		ret = 1;
 		goto err;
 		}
 
@@ -214,7 +215,8 @@
 		a_mod_m = a2;
 	if (BN_is_zero(a_mod_m))
 		{
-		ret = BN_zero(rr);
+		BN_zero(rr);
+		ret = 1;
 		goto err;
 		}
 	if (!BN_to_montgomery(&(val2[0]),a_mod_m,mont,ctx)) goto err;
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index 30520ee..17513b1 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -329,8 +329,11 @@
 	bn_check_top(a);
 
 	if (!p[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. 
@@ -590,7 +593,6 @@
 	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;
 
@@ -709,7 +711,6 @@
 	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))
 		{
@@ -865,13 +866,15 @@
 	bn_check_top(a);
 
 	if (!p[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;
 	
-	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);
@@ -921,8 +924,11 @@
 	bn_check_top(a_);
 
 	if (!p[0])
+		{
 		/* reduction mod 1 => return 0 */
-		return BN_zero(r);
+		BN_zero(r);
+		return 1;
+		}
 
 	BN_CTX_start(ctx);
 	a = BN_CTX_get(ctx);
@@ -934,7 +940,8 @@
 	
 	if (BN_is_zero(a))
 		{
-		ret = BN_zero(r);
+		BN_zero(r);
+		ret = 1;
 		goto err;
 		}
 
@@ -960,7 +967,7 @@
 			{
 			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++)
 				{
diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c
index 22d23cc..14650ab 100644
--- a/crypto/bn/bn_mont.c
+++ b/crypto/bn/bn_mont.c
@@ -284,7 +284,7 @@
 		BN_ULONG buf[2];
 
 		mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
-		if (!(BN_zero(R))) goto err;
+		BN_zero(R);
 		if (!(BN_set_bit(R,BN_BITS2))) goto err;	/* R */
 
 		buf[0]=mod->d[0]; /* tmod = N mod word size */
@@ -314,7 +314,7 @@
 #else /* !MONT_WORD */
 		{ /* bignum version */
 		mont->ri=BN_num_bits(&mont->N);
-		if (!BN_zero(R)) goto err;
+		BN_zero(R);
 		if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
 		                                        /* Ri = R^-1 mod N*/
 		if ((BN_mod_inverse(&Ri,R,&mont->N,ctx)) == NULL)
@@ -328,7 +328,7 @@
 #endif
 
 	/* setup RR for conversions */
-	if (!BN_zero(&(mont->RR))) goto err;
+	BN_zero(&(mont->RR));
 	if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
 	if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
 
diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c
index 5a92f9a..aec1eaf 100644
--- a/crypto/bn/bn_mul.c
+++ b/crypto/bn/bn_mul.c
@@ -964,7 +964,7 @@
 
 	if ((al == 0) || (bl == 0))
 		{
-		if (!BN_zero(r)) goto err;
+		BN_zero(r);
 		return(1);
 		}
 	top=al+bl;
@@ -1094,8 +1094,8 @@
 	if (r != rr) BN_copy(r,rr);
 	ret=1;
 err:
-	BN_CTX_end(ctx);
 	bn_check_top(r);
+	BN_CTX_end(ctx);
 	return(ret);
 	}
 
diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c
index a29503b..bbe2cbe 100644
--- a/crypto/bn/bn_nist.c
+++ b/crypto/bn/bn_nist.c
@@ -319,7 +319,10 @@
 
 	top = BN_ucmp(field, a);
 	if (top == 0)
-		return BN_zero(r);
+		{
+		BN_zero(r);
+		return 1;
+		}
 	else if (top > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
@@ -394,7 +397,10 @@
 
 	tmp_int = BN_ucmp(field, a);
 	if (tmp_int == 0)
-		return BN_zero(r);
+		{
+		BN_zero(r);
+		return 1;
+		}
 	else if (tmp_int > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
@@ -514,7 +520,10 @@
 	
 	tmp_int = BN_ucmp(field, a);
 	if (tmp_int == 0)
-		return BN_zero(r);
+		{
+		BN_zero(r);
+		return 1;
+		}
 	else if (tmp_int > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
@@ -672,7 +681,10 @@
 
 	tmp_int = BN_ucmp(field, a);
 	if (tmp_int == 0)
-		return BN_zero(r);
+		{
+		BN_zero(r);
+		return 1;
+		}
 	else if (tmp_int > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c
index de5a1f0..df45575 100644
--- a/crypto/bn/bn_rand.c
+++ b/crypto/bn/bn_rand.c
@@ -244,9 +244,7 @@
 	/* BN_is_bit_set(range, n - 1) always holds */
 
 	if (n == 1)
-		{
-		if (!BN_zero(r)) return 0;
-		}
+		BN_zero(r);
 	else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3))
 		{
 		/* range = 100..._2,
diff --git a/crypto/bn/bn_recp.c b/crypto/bn/bn_recp.c
index 411dd60..05b845b 100644
--- a/crypto/bn/bn_recp.c
+++ b/crypto/bn/bn_recp.c
@@ -94,7 +94,7 @@
 int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
 	{
 	if (!BN_copy(&(recp->N),d)) return 0;
-	if (!BN_zero(&(recp->Nr))) return 0;
+	BN_zero(&(recp->Nr));
 	recp->num_bits=BN_num_bits(d);
 	recp->shift=0;
 	return(1);
@@ -148,7 +148,7 @@
 
 	if (BN_ucmp(m,&(recp->N)) < 0)
 		{
-		if (!BN_zero(d)) return 0;
+		BN_zero(d);
 		if (!BN_copy(r,m)) return 0;
 		BN_CTX_end(ctx);
 		return(1);
@@ -221,7 +221,6 @@
 
 	BN_init(&t);
 
-	if (!BN_zero(&t)) goto err;
 	if (!BN_set_bit(&t,len)) goto err;
 
 	if (!BN_div(r,NULL,&t,m,ctx)) goto err;
diff --git a/crypto/bn/bn_sqr.c b/crypto/bn/bn_sqr.c
index ab678d1..8831daa 100644
--- a/crypto/bn/bn_sqr.c
+++ b/crypto/bn/bn_sqr.c
@@ -77,15 +77,15 @@
 	if (al <= 0)
 		{
 		r->top=0;
-		return(1);
+		return 1;
 		}
 
 	BN_CTX_start(ctx);
 	rr=(a != r) ? r : BN_CTX_get(ctx);
 	tmp=BN_CTX_get(ctx);
-	if (tmp == NULL) goto err;
+	if (!rr || !tmp) goto err;
 
-	max=(al+al);
+	max = 2 * al; /* Non-zero (from above) */
 	if (bn_wexpand(rr,max+1) == NULL) goto err;
 
 	if (al == 4)
@@ -138,14 +138,19 @@
 #endif
 		}
 
-	rr->top=max;
 	rr->neg=0;
-	if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
+	/* If the most-significant half of the top word of 'a' is zero, then
+	 * the square of 'a' will max-1 words. */
+	if(a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
+		rr->top = max - 1;
+	else
+		rr->top = max;
 	if (rr != r) BN_copy(r,rr);
 	ret = 1;
  err:
+	if(rr) bn_check_top(rr);
+	if(tmp) bn_check_top(tmp);
 	BN_CTX_end(ctx);
-	bn_check_top(r);
 	return(ret);
 	}
 
diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c
index 5190270..924ee27 100644
--- a/crypto/bn/bn_sqrt.c
+++ b/crypto/bn/bn_sqrt.c
@@ -288,7 +288,7 @@
 		if (BN_is_zero(t))
 			{
 			/* special case: a == 0  (mod p) */
-			if (!BN_zero(ret)) goto end;
+			BN_zero(ret);
 			err = 0;
 			goto end;
 			}
@@ -301,7 +301,7 @@
 		if (BN_is_zero(x))
 			{
 			/* special case: a == 0  (mod p) */
-			if (!BN_zero(ret)) goto end;
+			BN_zero(ret);
 			err = 0;
 			goto end;
 			}
diff --git a/crypto/ec/ec2_mult.c b/crypto/ec/ec2_mult.c
index a0ee7c1..a8ead01 100644
--- a/crypto/ec/ec2_mult.c
+++ b/crypto/ec/ec2_mult.c
@@ -155,8 +155,8 @@
 	
 	if (BN_is_zero(z1))
 		{
-		if (!BN_zero(x2)) return 0;
-		if (!BN_zero(z2)) return 0;
+		BN_zero(x2);
+		BN_zero(z2);
 		return 1;
 		}
 	
diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c
index 89e8152..1132c8e 100644
--- a/crypto/ec/ec2_smpl.c
+++ b/crypto/ec/ec2_smpl.c
@@ -335,7 +335,8 @@
 int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
 	{
 	point->Z_is_one = 0;
-	return (BN_zero(&point->Z));
+	BN_zero(&point->Z);
+	return 1;
 	}
 
 
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index b3ef056..ba5b821 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -299,12 +299,12 @@
 	if (order != NULL)
 		{ if (!BN_copy(&group->order, order)) return 0; }	
 	else
-		{ if (!BN_zero(&group->order)) return 0; }	
+		BN_zero(&group->order);
 
 	if (cofactor != NULL)
 		{ if (!BN_copy(&group->cofactor, cofactor)) return 0; }	
 	else
-		{ if (!BN_zero(&group->cofactor)) return 0; }	
+		BN_zero(&group->cofactor);
 
 	return 1;
 	}
diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c
index 1abe831..de90f90 100644
--- a/crypto/ec/ecp_smpl.c
+++ b/crypto/ec/ecp_smpl.c
@@ -385,7 +385,8 @@
 int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
 	{
 	point->Z_is_one = 0;
-	return (BN_zero(&point->Z));
+	BN_zero(&point->Z);
+	return 1;
 	}
 
 
@@ -1093,7 +1094,7 @@
 		else
 			{
 			/* a is the inverse of b */
-			if (!BN_zero(&r->Z)) goto end;
+			BN_zero(&r->Z);
 			r->Z_is_one = 0;
 			ret = 1;
 			goto end;
@@ -1169,7 +1170,7 @@
 	
 	if (EC_POINT_is_at_infinity(group, a))
 		{
-		if (!BN_zero(&r->Z)) return 0;
+		BN_zero(&r->Z);
 		r->Z_is_one = 0;
 		return 1;
 		}