From 122ae06ca9f1c84f8b3b27a9472fe478e66e50cb Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Wed, 29 May 2024 17:11:28 +0000 Subject: [PATCH 1/2] Add constant time tests to mbedtls_mpi_core_montmul() Signed-off-by: Waleed Elmelegy --- library/bignum_core.h | 4 ++ tests/suites/test_suite_bignum_core.function | 46 +++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/library/bignum_core.h b/library/bignum_core.h index eac91f534..818ca7a20 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -462,6 +462,10 @@ mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N); * \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 0869a1e0a..3eec6a438 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -919,21 +919,36 @@ void mpi_core_montmul(int limbs_AN4, int limbs_B4, 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)); - +#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(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); +#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(R.p, R.n * sizeof(mbedtls_mpi_uint)); + TEST_CF_PUBLIC(N.p, N.n * sizeof(mbedtls_mpi_uint)); +#endif 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)); +#endif mbedtls_mpi_core_montmul(A.p, A.p, B.p, B.n, N.p, N.n, mm, T.p); +#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(A.p, A.n * sizeof(mbedtls_mpi_uint)); +#endif TEST_MEMORY_COMPARE(A.p, bytes, X->p, bytes); memcpy(A.p, R.p, bytes); /* restore A */ @@ -941,27 +956,46 @@ void mpi_core_montmul(int limbs_AN4, int limbs_B4, /* 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(A.p, A.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); +#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(N.p, N.n * sizeof(mbedtls_mpi_uint)); +#endif TEST_MEMORY_COMPARE(N.p, bytes, X->p, bytes); memcpy(N.p, R.p, bytes); - +#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(A.p, A.n * sizeof(mbedtls_mpi_uint)); + TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint)); +#endif 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(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); +#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint)); +#endif 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(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); +#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint)); +#endif TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes); } From 80ab4f38869d374ecd32d3cda57a75d6d15e0d58 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Mon, 24 Jun 2024 13:31:15 +0000 Subject: [PATCH 2/2] change montmul constant time testing to be clearer Signed-off-by: Waleed Elmelegy --- tests/suites/test_suite_bignum_core.function | 29 +++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index 3eec6a438..be947578c 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -919,6 +919,7 @@ void mpi_core_montmul(int limbs_AN4, int limbs_B4, 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 @@ -928,14 +929,13 @@ void mpi_core_montmul(int limbs_AN4, int limbs_B4, 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); -#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(R.p, R.n * sizeof(mbedtls_mpi_uint)); - TEST_CF_PUBLIC(N.p, N.n * sizeof(mbedtls_mpi_uint)); -#endif size_t bytes = N.n * sizeof(mbedtls_mpi_uint); TEST_MEMORY_COMPARE(R.p, bytes, X->p, bytes); @@ -944,11 +944,12 @@ void mpi_core_montmul(int limbs_AN4, int limbs_B4, 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); -#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(A.p, A.n * sizeof(mbedtls_mpi_uint)); -#endif TEST_MEMORY_COMPARE(A.p, bytes, X->p, bytes); memcpy(A.p, R.p, bytes); /* restore A */ @@ -957,32 +958,33 @@ void mpi_core_montmul(int limbs_AN4, int limbs_B4, 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); -#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(N.p, N.n * sizeof(mbedtls_mpi_uint)); -#endif TEST_MEMORY_COMPARE(N.p, bytes, X->p, bytes); memcpy(N.p, R.p, bytes); -#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(A.p, A.n * sizeof(mbedtls_mpi_uint)); TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint)); -#endif + 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); -#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint)); -#endif TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes); memcpy(B.p, A.p, bytes); /* restore B from equal value A */ @@ -990,12 +992,13 @@ void mpi_core_montmul(int limbs_AN4, int limbs_B4, /* 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); -#if !defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) + TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint)); -#endif TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes); }