From e0842aa7512438b9e749f4137b15ee810052ecaf Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 13 Aug 2024 08:40:31 +0100 Subject: [PATCH] Add tests for optionally safe codepaths The new test hooks allow to check whether there was an unsafe call of an optionally safe function in the codepath. For the sake of simplicity the MBEDTLS_MPI_IS_* macros are reused for signalling safe/unsafe codepaths here too. Signed-off-by: Janos Follath --- library/bignum_core.c | 18 ++++++++++++++++++ library/bignum_core.h | 10 ++++++++++ tests/suites/test_suite_bignum_core.function | 12 ++++++++++++ 3 files changed, 40 insertions(+) diff --git a/library/bignum_core.c b/library/bignum_core.c index 260a1f2661..f46df0c8c7 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -765,6 +765,9 @@ static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E_limb_index = E_bits / biL; *E_bit_index = E_bits % biL; } +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC; +#endif } else { /* * Here we need to be constant time with respect to E and can't do anything better than @@ -772,6 +775,12 @@ static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint */ *E_limb_index = E_limbs; *E_bit_index = 0; +#if defined(MBEDTLS_TEST_HOOKS) + // Only mark the codepath safe if there wasn't an unsafe codepath before + if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) { + mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET; + } +#endif } } @@ -788,11 +797,20 @@ static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselec { if (window_public == MBEDTLS_MPI_IS_PUBLIC) { memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL); +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC; +#endif } else { /* Select Wtable[window] without leaking window through * memory access patterns. */ mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, AN_limbs, welem, window); +#if defined(MBEDTLS_TEST_HOOKS) + // Only mark the codepath safe if there wasn't an unsafe codepath before + if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) { + mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET; + } +#endif } } diff --git a/library/bignum_core.h b/library/bignum_core.h index 6c214a530b..50c53e6c39 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -817,4 +817,14 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, mbedtls_mpi_uint mm, mbedtls_mpi_uint *T); +#if defined(MBEDTLS_TEST_HOOKS) +int mbedtls_mpi_optionally_safe_codepath; + +static inline void mbedtls_mpi_optionally_safe_codepath_reset() +{ + // Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET + mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1; +} +#endif + #endif /* MBEDTLS_BIGNUM_CORE_H */ diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index db84d6238f..373bda4e8c 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -1229,13 +1229,25 @@ void mpi_core_exp_mod(char *input_N, char *input_A, TEST_CALLOC(T, working_limbs); +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath_reset(); +#endif mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T); +#if defined(MBEDTLS_TEST_HOOKS) + TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); +#endif TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); /* Check when output aliased to input */ +#if defined(MBEDTLS_TEST_HOOKS) + mbedtls_mpi_optionally_safe_codepath_reset(); +#endif mbedtls_mpi_core_exp_mod(A, A, N, N_limbs, E, E_limbs, R2, T); +#if defined(MBEDTLS_TEST_HOOKS) + TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET); +#endif TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint)));