+ bn_correct_top(snum);
+ if (rm != NULL)
+ {
+ /* Keep a copy of the neg flag in num because if rm==num
+ * BN_rshift() will overwrite it.
+ */
+ int neg = num->neg;
+ BN_rshift(rm,snum,norm_shift);
+ if (!BN_is_zero(rm))
+ rm->neg = neg;
+ bn_check_top(rm);
+ }
+ BN_CTX_end(ctx);
+ return(1);
+err:
+ bn_check_top(rm);
+ BN_CTX_end(ctx);
+ return(0);
+ }
+
+
+/* BN_div_no_branch is a special version of BN_div. It does not contain
+ * branches that may leak sensitive information.
+ */
+static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
+ const BIGNUM *divisor, BN_CTX *ctx)
+ {
+ int norm_shift,i,loop;
+ BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+ BN_ULONG *resp,*wnump;
+ BN_ULONG d0,d1;
+ int num_n,div_n;
+
+ bn_check_top(dv);
+ bn_check_top(rm);
+ bn_check_top(num);
+ bn_check_top(divisor);
+
+ if (BN_is_zero(divisor))
+ {
+ BNerr(BN_F_BN_DIV_NO_BRANCH,BN_R_DIV_BY_ZERO);
+ return(0);
+ }
+
+ BN_CTX_start(ctx);
+ tmp=BN_CTX_get(ctx);
+ snum=BN_CTX_get(ctx);
+ sdiv=BN_CTX_get(ctx);
+ if (dv == NULL)
+ res=BN_CTX_get(ctx);
+ else res=dv;
+ if (sdiv == NULL || res == NULL) goto err;
+
+ /* First we normalise the numbers */
+ norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+ if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
+ sdiv->neg=0;
+ norm_shift+=BN_BITS2;
+ if (!(BN_lshift(snum,num,norm_shift))) goto err;
+ snum->neg=0;
+
+ /* Since we don't know whether snum is larger than sdiv,
+ * we pad snum with enough zeroes without changing its
+ * value.
+ */
+ if (snum->top <= sdiv->top+1)
+ {
+ if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
+ for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
+ snum->top = sdiv->top + 2;
+ }
+ else
+ {
+ if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
+ snum->d[snum->top] = 0;
+ snum->top ++;
+ }
+
+ div_n=sdiv->top;
+ num_n=snum->top;
+ loop=num_n-div_n;
+ /* Lets setup a 'window' into snum
+ * This is the part that corresponds to the current
+ * 'area' being divided */
+ wnum.neg = 0;
+ wnum.d = &(snum->d[loop]);
+ wnum.top = div_n;
+ /* only needed when BN_ucmp messes up the values between top and max */
+ wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
+
+ /* Get the top 2 words of sdiv */
+ /* div_n=sdiv->top; */
+ d0=sdiv->d[div_n-1];
+ d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+ /* pointer to the 'top' of snum */
+ wnump= &(snum->d[num_n-1]);
+
+ /* Setup to 'res' */
+ res->neg= (num->neg^divisor->neg);
+ if (!bn_wexpand(res,(loop+1))) goto err;
+ res->top=loop-1;
+ resp= &(res->d[loop-1]);
+
+ /* space for temp */
+ if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+ /* if res->top == 0 then clear the neg value otherwise decrease
+ * the resp pointer */
+ if (res->top == 0)
+ res->neg = 0;
+ else
+ resp--;
+
+ for (i=0; i<loop-1; i++, wnump--, resp--)
+ {
+ BN_ULONG q,l0;
+ /* the first part of the loop uses the top two words of
+ * snum and sdiv to calculate a BN_ULONG q such that
+ * | wnum - sdiv * q | < sdiv */
+#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+ BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
+ q=bn_div_3_words(wnump,d1,d0);
+#else
+ BN_ULONG n0,n1,rem=0;
+
+ n0=wnump[0];
+ n1=wnump[-1];
+ if (n0 == d0)
+ q=BN_MASK2;
+ else /* n0 < d0 */
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t2;