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;