Ensure we test all parameters for BN_FLG_CONSTTIME
[openssl.git] / crypto / bn / bn_div.c
index cbf27d3e943eb4bc973eee8c5ff7ce471179f0db..6801eccdd1ce2cf6d4511155c37e11df8f82cc06 100644 (file)
@@ -1,59 +1,10 @@
-/* crypto/bn/bn_div.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
  *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
  */
 
 #include <openssl/bn.h>
@@ -83,7 +34,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
         }
         if (dv != NULL)
             BN_zero(dv);
-        return (1);
+        return 1;
     }
 
     BN_CTX_start(ctx);
@@ -154,7 +105,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
         ({  asm volatile (                      \
                 "divl   %4"                     \
                 : "=a"(q), "=d"(rem)            \
-                : "a"(n1), "d"(n0), "g"(d0)     \
+                : "a"(n1), "d"(n0), "r"(d0)     \
                 : "cc");                        \
             q;                                  \
         })
@@ -169,7 +120,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
         ({  asm volatile (                      \
                 "divq   %4"                     \
                 : "=a"(q), "=d"(rem)            \
-                : "a"(n1), "d"(n0), "g"(d0)     \
+                : "a"(n1), "d"(n0), "r"(d0)     \
                 : "cc");                        \
             q;                                  \
         })
@@ -179,7 +130,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
 # endif                         /* OPENSSL_NO_ASM */
 
 /*-
- * BN_div computes  dv := num / divisor,  rounding towards
+ * BN_div computes  dv := num / divisor, rounding towards
  * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
  * Thus:
  *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
@@ -236,18 +187,15 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
         }
         if (dv != NULL)
             BN_zero(dv);
-        return (1);
+        return 1;
     }
 
     BN_CTX_start(ctx);
+    res = (dv == NULL) ? BN_CTX_get(ctx) : dv;
     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 || tmp == NULL || snum == NULL)
+    if (sdiv == NULL)
         goto err;
 
     /* First we normalise the numbers */
@@ -303,9 +251,9 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
     wnump = &(snum->d[num_n - 1]);
 
     /* Setup to 'res' */
-    res->neg = (num->neg ^ divisor->neg);
     if (!bn_wexpand(res, (loop + 1)))
         goto err;
+    res->neg = (num->neg ^ divisor->neg);
     res->top = loop - no_branch;
     resp = &(res->d[loop - 1]);
 
@@ -327,6 +275,9 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
             res->top--;
     }
 
+    /* Increase the resp pointer so that we never create an invalid pointer. */
+    resp++;
+
     /*
      * if res->top == 0 then clear the neg value otherwise decrease the resp
      * pointer
@@ -336,7 +287,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
     else
         resp--;
 
-    for (i = 0; i < loop - 1; i++, wnump--, resp--) {
+    for (i = 0; i < loop - 1; i++, wnump--) {
         BN_ULONG q, l0;
         /*
          * the first part of the loop uses the top two words of snum and sdiv
@@ -361,10 +312,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
             q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0);
 #   else
             q = bn_div_words(n0, n1, d0);
-#    ifdef BN_DEBUG_LEVITTE
-            fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
-X) -> 0x%08X\n", n0, n1, d0, q);
-#    endif
 #   endif
 
 #   ifndef REMAINDER_IS_ALREADY_CALCULATED
@@ -389,10 +336,6 @@ X) -> 0x%08X\n", n0, n1, d0, q);
             BN_ULONG t2l, t2h;
 
             q = bn_div_words(n0, n1, d0);
-#   ifdef BN_DEBUG_LEVITTE
-            fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
-X) -> 0x%08X\n", n0, n1, d0, q);
-#   endif
 #   ifndef REMAINDER_IS_ALREADY_CALCULATED
             rem = (n1 - q * d0) & BN_MASK2;
 #   endif
@@ -450,6 +393,7 @@ X) -> 0x%08X\n", n0, n1, d0, q);
                 (*wnump)++;
         }
         /* store part of the result */
+        resp--;
         *resp = q;
     }
     bn_correct_top(snum);
@@ -467,7 +411,7 @@ X) -> 0x%08X\n", n0, n1, d0, q);
     if (no_branch)
         bn_correct_top(res);
     BN_CTX_end(ctx);
-    return (1);
+    return 1;
  err:
     bn_check_top(rm);
     BN_CTX_end(ctx);