Handle BN_mod_word failures.

As of 67cb49d045f04973ddba0f92fe8a8ad483c7da89 and the corresponding upstream
change, BN_mod_word may fail, like BN_div_word. Handle this properly and
document in bn.h. Thanks to Brian Smith for pointing this out.

Change-Id: I6d4f32dc37bcabf70847c9a8b417d55d31b3a380
Reviewed-on: https://boringssl-review.googlesource.com/8491
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/bn/bn_test.cc b/crypto/bn/bn_test.cc
index d909ee2..25207e7 100644
--- a/crypto/bn/bn_test.cc
+++ b/crypto/bn/bn_test.cc
@@ -852,7 +852,7 @@
     BN_ULONG s = b->d[0];
     BN_ULONG rmod = BN_mod_word(b.get(), s);
     BN_ULONG r = BN_div_word(b.get(), s);
-    if (r == (BN_ULONG)-1) {
+    if (r == (BN_ULONG)-1 || rmod == (BN_ULONG)-1) {
       return false;
     }
 
diff --git a/crypto/bn/prime.c b/crypto/bn/prime.c
index d07e609..98a46a9 100644
--- a/crypto/bn/prime.c
+++ b/crypto/bn/prime.c
@@ -496,7 +496,11 @@
 
   if (do_trial_division) {
     for (i = 1; i < NUMPRIMES; i++) {
-      if (BN_mod_word(a, primes[i]) == 0) {
+      BN_ULONG mod = BN_mod_word(a, primes[i]);
+      if (mod == (BN_ULONG)-1) {
+        goto err;
+      }
+      if (mod == 0) {
         return 0;
       }
     }
@@ -653,7 +657,11 @@
 
   /* we now have a random number 'rnd' to test. */
   for (i = 1; i < NUMPRIMES; i++) {
-    mods[i] = (uint16_t)BN_mod_word(rnd, (BN_ULONG)primes[i]);
+    BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+    if (mod == (BN_ULONG)-1) {
+      return 0;
+    }
+    mods[i] = (uint16_t)mod;
   }
   /* If bits is so small that it fits into a single word then we
    * additionally don't want to exceed that many bits. */
@@ -753,7 +761,11 @@
 loop:
   for (i = 1; i < NUMPRIMES; i++) {
     /* check that rnd is a prime */
-    if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
+    BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+    if (mod == (BN_ULONG)-1) {
+      goto err;
+    }
+    if (mod <= 1) {
       if (!BN_add(rnd, rnd, add)) {
         goto err;
       }
@@ -825,8 +837,12 @@
     /* check that p and q are prime */
     /* check that for p and q
      * gcd(p-1,primes) == 1 (except for 2) */
-    if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) ||
-        (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) {
+    BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]);
+    BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]);
+    if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1) {
+      goto err;
+    }
+    if (pmod == 0 || qmod == 0) {
       if (!BN_add(p, p, padd)) {
         goto err;
       }
diff --git a/crypto/dh/check.c b/crypto/dh/check.c
index fbe58a5..ed1508f 100644
--- a/crypto/dh/check.c
+++ b/crypto/dh/check.c
@@ -173,11 +173,17 @@
     }
   } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
     l = BN_mod_word(dh->p, 24);
+    if (l == (BN_ULONG)-1) {
+      goto err;
+    }
     if (l != 11) {
       *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
     }
   } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
     l = BN_mod_word(dh->p, 10);
+    if (l == (BN_ULONG)-1) {
+      goto err;
+    }
     if (l != 3 && l != 7) {
       *ret |= DH_CHECK_NOT_SUITABLE_GENERATOR;
     }
diff --git a/include/openssl/bn.h b/include/openssl/bn.h
index e9be0f5..9ee2237 100644
--- a/include/openssl/bn.h
+++ b/include/openssl/bn.h
@@ -502,7 +502,7 @@
 
 /* Modulo arithmetic. */
 
-/* BN_mod_word returns |a| mod |w|. */
+/* BN_mod_word returns |a| mod |w| or (BN_ULONG)-1 on error. */
 OPENSSL_EXPORT BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
 
 /* BN_mod is a helper macro that calls |BN_div| and discards the quotient. */