Fix potential constant time issue

The old code contained an explicit "nibble % 5", which could have
generated a non-constant time division operation. This change
replaces it by an equivalent mul-shift-mul that is manifest
constant time.

It appears that Clang, GCC, and MSVC will all replace constant
divisions with such a construction with optimizations on, so this
is unlikely to have caused a leak in practice. However, Clang and
MSVC will emit division instructions with optimizations off.

Thanks to Filippo Valsorda for reporting this.

Bug: 455829614
Change-Id: I7bffaaf4fc79196b27631de6edd8c97b0ec97a89
Signed-off-by: Lukas Zobernig <zlukas@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/83348
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/mldsa/mldsa.cc.inc b/crypto/fipsmodule/mldsa/mldsa.cc.inc
index abd9c97..0871618 100644
--- a/crypto/fipsmodule/mldsa/mldsa.cc.inc
+++ b/crypto/fipsmodule/mldsa/mldsa.cc.inc
@@ -1167,7 +1167,9 @@
   if (constant_time_declassify_int(nibble < 15)) {
     // Knowing bounds on |nibble| seems to tempt some versions of Clang to emit
     // a branch, if we don't have a barrier in |mod_sub|.
-    *result = mod_sub(2, value_barrier_u32(nibble % 5));
+    // Constant time "nibble % 5".
+    nibble = nibble - 5 * ((205 * nibble) >> 10);
+    *result = mod_sub(2, value_barrier_u32(nibble));
     return true;
   }
   return false;