Merge pull request #1240 from Mbed-TLS/change-mpi-montmul-to-constant-time

Change mbedtls_mpi_core_montmul () to constant time
diff --git a/library/bignum_core.h b/library/bignum_core.h
index eac91f5..818ca7a 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -462,6 +462,10 @@
  * \p A and \p B may alias each other, if \p AN_limbs == \p B_limbs. They may
  * not alias \p N (since they must be in canonical form, they cannot == \p N).
  *
+ * This function operates in constant time with respect
+ * to the values of \p A, \p B and \p N.
+ *
+ *
  * \param[out]    X         The destination MPI, as a little-endian array of
  *                          length \p AN_limbs.
  *                          On successful completion, X contains the result of
diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function
index 0869a1e..be94757 100644
--- a/tests/suites/test_suite_bignum_core.function
+++ b/tests/suites/test_suite_bignum_core.function
@@ -919,21 +919,37 @@
     size_t working_limbs = mbedtls_mpi_core_montmul_working_limbs(limbs_AN);
     TEST_EQUAL(working_limbs, limbs_AN * 2 + 1);
     TEST_EQUAL(0, mbedtls_mpi_grow(&T, working_limbs));
-
+    /* Temporary because MEMSAN doesn't support assembly implementation see #1243 */
+#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+    TEST_CF_SECRET(N.p, N.n * sizeof(mbedtls_mpi_uint));
+#endif
     /* Calculate the Montgomery constant (this is unit tested separately) */
     mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N.p);
 
     TEST_EQUAL(0, mbedtls_mpi_grow(&R, limbs_AN));     /* ensure it's got the right number of limbs */
 
+#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+    TEST_CF_SECRET(N.p, N.n * sizeof(mbedtls_mpi_uint));
+    TEST_CF_SECRET(A.p, A.n * sizeof(mbedtls_mpi_uint));
+    TEST_CF_SECRET(B.p, B.n * sizeof(mbedtls_mpi_uint));
+#endif
     mbedtls_mpi_core_montmul(R.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
+
+    TEST_CF_PUBLIC(R.p, R.n * sizeof(mbedtls_mpi_uint));
     size_t bytes = N.n * sizeof(mbedtls_mpi_uint);
     TEST_MEMORY_COMPARE(R.p, bytes, X->p, bytes);
 
     /* The output (R, above) may be aliased to A - use R to save the value of A */
 
     memcpy(R.p, A.p, bytes);
-
+#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+    TEST_CF_SECRET(N.p, N.n * sizeof(mbedtls_mpi_uint));
+    TEST_CF_SECRET(A.p, A.n * sizeof(mbedtls_mpi_uint));
+    TEST_CF_SECRET(B.p, B.n * sizeof(mbedtls_mpi_uint));
+#endif
     mbedtls_mpi_core_montmul(A.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
+
+    TEST_CF_PUBLIC(A.p, A.n * sizeof(mbedtls_mpi_uint));
     TEST_MEMORY_COMPARE(A.p, bytes, X->p, bytes);
 
     memcpy(A.p, R.p, bytes);    /* restore A */
@@ -941,27 +957,48 @@
     /* The output may be aliased to N - use R to save the value of N */
 
     memcpy(R.p, N.p, bytes);
-
+#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+    TEST_CF_SECRET(N.p, N.n * sizeof(mbedtls_mpi_uint));
+    TEST_CF_SECRET(A.p, A.n * sizeof(mbedtls_mpi_uint));
+    TEST_CF_SECRET(B.p, B.n * sizeof(mbedtls_mpi_uint));
+#endif
     mbedtls_mpi_core_montmul(N.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
+
+    TEST_CF_PUBLIC(N.p, N.n * sizeof(mbedtls_mpi_uint));
     TEST_MEMORY_COMPARE(N.p, bytes, X->p, bytes);
 
     memcpy(N.p, R.p, bytes);
 
+    TEST_CF_PUBLIC(A.p, A.n * sizeof(mbedtls_mpi_uint));
+    TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint));
+
     if (limbs_AN == limbs_B) {
         /* Test when A aliased to B (requires A == B on input values) */
         if (memcmp(A.p, B.p, bytes) == 0) {
             /* Test with A aliased to B and output, since this is permitted -
              * don't bother with yet another test with only A and B aliased */
-
+#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+            TEST_CF_SECRET(N.p, N.n * sizeof(mbedtls_mpi_uint));
+            TEST_CF_SECRET(A.p, A.n * sizeof(mbedtls_mpi_uint));
+            TEST_CF_SECRET(B.p, B.n * sizeof(mbedtls_mpi_uint));
+#endif
             mbedtls_mpi_core_montmul(B.p, B.p, B.p, B.n, N.p, N.n, mm, T.p);
+
+            TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint));
             TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes);
 
             memcpy(B.p, A.p, bytes);    /* restore B from equal value A */
         }
 
         /* The output may be aliased to B - last test, so we don't save B */
-
+#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
+        TEST_CF_SECRET(N.p, N.n * sizeof(mbedtls_mpi_uint));
+        TEST_CF_SECRET(A.p, A.n * sizeof(mbedtls_mpi_uint));
+        TEST_CF_SECRET(B.p, B.n * sizeof(mbedtls_mpi_uint));
+#endif
         mbedtls_mpi_core_montmul(B.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
+
+        TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint));
         TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes);
     }