bn_gf2m.c: optimized BN_GF2m_mod_inv delivers sometimes 2x of ECDSA sign.
[oweals/openssl.git] / crypto / bn / bn_div.c
index 8655eb118e6b4775f2097f02c4f2b79b23b2a7f3..2c5a4b13cfb1cdc506290ba1262f5e5a8efec6e9 100644 (file)
@@ -56,6 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
+#define OPENSSL_FIPSAPI
+
 #include <stdio.h>
 #include <openssl/bn.h>
 #include "cryptlib.h"
@@ -102,7 +104,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
        /* The next 2 are needed so we can do a dv->d[0]|=1 later
         * since BN_lshift1 will only work once there is a value :-) */
        BN_zero(dv);
-       bn_wexpand(dv,1);
+       if(bn_wexpand(dv,1) == NULL) goto end;
        dv->top=1;
 
        if (!BN_lshift(D,D,nm-nd)) goto end;
@@ -155,6 +157,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
     * Same story here, but it's 128-bit by 64-bit division. Wow!
     *                                  <appro@fy.chalmers.se>
     */
+#  undef bn_div_words
 #  define bn_div_words(n0,n1,d0)               \
        ({  asm volatile (                      \
                "divq   %4"                     \
@@ -187,6 +190,17 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
        BN_ULONG d0,d1;
        int num_n,div_n;
 
+       /* Invalid zero-padding would have particularly bad consequences
+        * in the case of 'num', so don't just rely on bn_check_top() for this one
+        * (bn_check_top() works only for BN_DEBUG builds) */
+       if (num->top > 0 && num->d[num->top - 1] == 0)
+               {
+               BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED);
+               return 0;
+               }
+
+       bn_check_top(num);
+
        if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
                {
                return BN_div_no_branch(dv, rm, num, divisor, ctx);
@@ -194,7 +208,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
 
        bn_check_top(dv);
        bn_check_top(rm);
-       bn_check_top(num);
+       /* bn_check_top(num); */ /* 'num' has been checked already */
        bn_check_top(divisor);
 
        if (BN_is_zero(divisor))
@@ -218,7 +232,8 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
        if (dv == NULL)
                res=BN_CTX_get(ctx);
        else    res=dv;
-       if (sdiv == NULL || res == NULL) goto err;
+       if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
+               goto err;
 
        /* First we normalise the numbers */
        norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
@@ -325,7 +340,7 @@ X) -> 0x%08X\n",
                                t2 -= d1;
                                }
 #else /* !BN_LLONG */
-                       BN_ULONG t2l,t2h,ql,qh;
+                       BN_ULONG t2l,t2h;
 
                        q=bn_div_words(n0,n1,d0);
 #ifdef BN_DEBUG_LEVITTE
@@ -343,9 +358,12 @@ X) -> 0x%08X\n",
                        t2l = d1 * q;
                        t2h = BN_UMULT_HIGH(d1,q);
 #else
+                       {
+                       BN_ULONG ql, qh;
                        t2l=LBITS(d1); t2h=HBITS(d1);
                        ql =LBITS(q);  qh =HBITS(q);
                        mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+                       }
 #endif
 
                        for (;;)
@@ -419,7 +437,7 @@ static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
 
        bn_check_top(dv);
        bn_check_top(rm);
-       bn_check_top(num);
+       /* bn_check_top(num); */ /* 'num' has been checked in BN_div() */
        bn_check_top(divisor);
 
        if (BN_is_zero(divisor))
@@ -549,7 +567,7 @@ X) -> 0x%08X\n",
                                t2 -= d1;
                                }
 #else /* !BN_LLONG */
-                       BN_ULONG t2l,t2h,ql,qh;
+                       BN_ULONG t2l,t2h;
 
                        q=bn_div_words(n0,n1,d0);
 #ifdef BN_DEBUG_LEVITTE
@@ -567,9 +585,12 @@ X) -> 0x%08X\n",
                        t2l = d1 * q;
                        t2h = BN_UMULT_HIGH(d1,q);
 #else
+                       {
+                       BN_ULONG ql, qh;
                        t2l=LBITS(d1); t2h=HBITS(d1);
                        ql =LBITS(q);  qh =HBITS(q);
                        mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+                       }
 #endif
 
                        for (;;)