Merge branch 'development' into development-restricted
diff --git a/library/bignum_core.c b/library/bignum_core.c
index 1a3e0b9..39ab6e9 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -449,9 +449,10 @@
mbedtls_mpi_uint c = 0;
for (size_t i = 0; i < limbs; i++) {
- mbedtls_mpi_uint z = (A[i] < c);
+ mbedtls_mpi_uint z = mbedtls_ct_mpi_uint_if(mbedtls_ct_uint_lt(A[i], c),
+ 1, 0);
mbedtls_mpi_uint t = A[i] - c;
- c = (t < B[i]) + z;
+ c = mbedtls_ct_mpi_uint_if(mbedtls_ct_uint_lt(t, B[i]), 1, 0) + z;
X[i] = t - B[i];
}
@@ -489,7 +490,7 @@
while (excess_len--) {
*d += c;
- c = (*d < c);
+ c = mbedtls_ct_mpi_uint_if(mbedtls_ct_uint_lt(*d, c), 1, 0);
d++;
}
diff --git a/library/bignum_core.h b/library/bignum_core.h
index 92c8d47..51ecca5 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -376,6 +376,9 @@
* \p X may be aliased to \p A or \p B, or even both, but may not overlap
* either otherwise.
*
+ * This function operates in constant time with respect to the values
+ * of \p A and \p B.
+ *
* \param[out] X The result of the subtraction.
* \param[in] A Little-endian presentation of left operand.
* \param[in] B Little-endian presentation of right operand.
@@ -397,6 +400,9 @@
*
* This function operates modulo `2^(biL*X_limbs)`.
*
+ * This function operates in constant time with respect to the values
+ * of \p X and \p A and \p b.
+ *
* \param[in,out] X The pointer to the (little-endian) array
* representing the bignum to accumulate onto.
* \param X_limbs The number of limbs of \p X. This must be
@@ -456,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
@@ -611,6 +621,9 @@
* \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs ==
* \p AN_limbs.
*
+ * This function operates in constant time with respect
+ * to the values of \p A, \p N and \p E.
+ *
* \param[out] X The destination MPI, as a little endian array of length
* \p AN_limbs.
* \param[in] A The base MPI, as a little endian array of length \p AN_limbs.
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index de74f97..3417b0d 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -2087,6 +2087,7 @@
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
+ scripts/config.py unset MBEDTLS_HAVE_ASM
CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
make
@@ -2105,6 +2106,7 @@
scripts/config.py full
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
+ scripts/config.py unset MBEDTLS_HAVE_ASM
CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
make
diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function
index db84d62..6c0bd1e 100644
--- a/tests/suites/test_suite_bignum_core.function
+++ b/tests/suites/test_suite_bignum_core.function
@@ -660,31 +660,48 @@
memcpy(b, B.p, B.n * sizeof(mbedtls_mpi_uint));
memcpy(x, X.p, X.n * sizeof(mbedtls_mpi_uint));
+ TEST_CF_SECRET(a, bytes);
+ TEST_CF_SECRET(b, bytes);
+
/* 1a) r = a - b => we should get the correct carry */
TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, a, b, limbs));
+ TEST_CF_PUBLIC(r, bytes);
+
/* 1b) r = a - b => we should get the correct result */
TEST_MEMORY_COMPARE(r, bytes, x, bytes);
/* 2 and 3 test "r may be aliased to a or b" */
/* 2a) r = a; r -= b => we should get the correct carry (use r to avoid clobbering a) */
memcpy(r, a, bytes);
+
+ TEST_CF_SECRET(r, bytes);
+
TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, r, b, limbs));
+ TEST_CF_PUBLIC(r, bytes);
+
/* 2b) r -= b => we should get the correct result */
TEST_MEMORY_COMPARE(r, bytes, x, bytes);
/* 3a) r = b; r = a - r => we should get the correct carry (use r to avoid clobbering b) */
memcpy(r, b, bytes);
+
+ TEST_CF_SECRET(r, bytes);
+
TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, a, r, limbs));
+ TEST_CF_PUBLIC(r, bytes);
+
/* 3b) r = a - b => we should get the correct result */
TEST_MEMORY_COMPARE(r, bytes, x, bytes);
/* 4 tests "r may be aliased to [...] both" */
if (A.n == B.n && memcmp(A.p, B.p, bytes) == 0) {
memcpy(r, b, bytes);
+ TEST_CF_SECRET(r, bytes);
TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, r, r, limbs));
+ TEST_CF_PUBLIC(r, bytes);
TEST_MEMORY_COMPARE(r, bytes, x, bytes);
}
@@ -770,16 +787,32 @@
memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint));
memcpy(x, X->p, X->n * sizeof(mbedtls_mpi_uint));
+ TEST_CF_SECRET(a, bytes);
+ TEST_CF_SECRET(B.p, B.n * sizeof(mbedtls_mpi_uint));
+ TEST_CF_SECRET(S.p, sizeof(mbedtls_mpi_uint));
+
/* 1a) A += B * s => we should get the correct carry */
TEST_EQUAL(mbedtls_mpi_core_mla(a, limbs, B.p, B.n, *S.p), *cy->p);
+ TEST_CF_PUBLIC(a, bytes);
+ TEST_CF_PUBLIC(B.p, B.n * sizeof(mbedtls_mpi_uint));
+ TEST_CF_PUBLIC(S.p, sizeof(mbedtls_mpi_uint));
+
/* 1b) A += B * s => we should get the correct result */
TEST_MEMORY_COMPARE(a, bytes, x, bytes);
if (A.n == B.n && memcmp(A.p, B.p, bytes) == 0) {
/* Check when A and B are aliased */
memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint));
+
+ TEST_CF_SECRET(a, bytes);
+ TEST_CF_SECRET(S.p, sizeof(mbedtls_mpi_uint));
+
TEST_EQUAL(mbedtls_mpi_core_mla(a, limbs, a, limbs, *S.p), *cy->p);
+
+ TEST_CF_PUBLIC(a, bytes);
+ TEST_CF_PUBLIC(S.p, sizeof(mbedtls_mpi_uint));
+
TEST_MEMORY_COMPARE(a, bytes, x, bytes);
}
@@ -883,12 +916,20 @@
TEST_EQUAL(working_limbs, limbs_AN * 2 + 1);
TEST_EQUAL(0, mbedtls_mpi_grow(&T, working_limbs));
+ TEST_CF_SECRET(N.p, N.n * sizeof(mbedtls_mpi_uint));
+
/* 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 */
+ 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));
+
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);
@@ -896,7 +937,13 @@
memcpy(R.p, A.p, bytes);
+ 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));
+
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 */
@@ -905,18 +952,33 @@
memcpy(R.p, N.p, bytes);
+ 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));
+
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 */
+ 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));
+
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 */
@@ -924,7 +986,13 @@
/* The output may be aliased to B - last test, so we don't save B */
+ 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));
+
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);
}
@@ -1229,14 +1297,24 @@
TEST_CALLOC(T, working_limbs);
+ TEST_CF_SECRET(A, A_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_SECRET(N, N_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_SECRET(E, E_limbs * sizeof(mbedtls_mpi_uint));
+
mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T);
+ TEST_CF_PUBLIC(Y, N_limbs * sizeof(mbedtls_mpi_uint));
+
TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint)));
- /* Check when output aliased to input */
+ TEST_CF_SECRET(A, A_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_SECRET(N, N_limbs * sizeof(mbedtls_mpi_uint));
+ TEST_CF_SECRET(E, E_limbs * sizeof(mbedtls_mpi_uint));
+ /* Check when output aliased to input */
mbedtls_mpi_core_exp_mod(A, A, N, N_limbs, E, E_limbs, R2, T);
+ TEST_CF_PUBLIC(A, A_limbs * sizeof(mbedtls_mpi_uint));
TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint)));
exit: