diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index 09de92f173..0cb3f2a346 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -417,9 +417,11 @@ void mbedtls_ct_memmove_left(void *start, * * \param condition The condition * \param dest Secret. Destination pointer. - * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE). Shouldn't overlap with \p dest. + * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE). + * This may be equal to \p dest, but may not overlap in other ways. * \param src2 Secret (contents only - may branch to test if src2 == NULL). - * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). Shouldn't overlap with \p dest. May be NULL. + * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL. + * This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1. * \param len Number of bytes to copy. */ void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, @@ -450,7 +452,7 @@ void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, * buffer of at least \p len bytes. * \param src Secret. The base of the source buffer. This must point to a * readable buffer of at least \p offset_max + \p len - * bytes. Shouldn't overlap with \p dest. + * bytes. Shouldn't overlap with \p dest * \param offset Secret. The offset in the source buffer from which to copy. * This must be no less than \p offset_min and no greater * than \p offset_max. diff --git a/tests/suites/test_suite_constant_time.function b/tests/suites/test_suite_constant_time.function index ac4dd7ab78..2fafa948d6 100644 --- a/tests/suites/test_suite_constant_time.function +++ b/tests/suites/test_suite_constant_time.function @@ -224,6 +224,7 @@ void mbedtls_ct_memcpy_if(int eq, int size, int offset) ASSERT_ALLOC(result, size + offset); ASSERT_ALLOC(expected, size + offset); + /* Apply offset to result only */ for (int i = 0; i < size + offset; i++) { src[i] = 1; result[i] = 0xff; @@ -243,6 +244,8 @@ void mbedtls_ct_memcpy_if(int eq, int size, int offset) ASSERT_COMPARE(expected, size, result + offset, size); + + /* Apply offset to src only */ for (int i = 0; i < size + offset; i++) { src[i] = 1; result[i] = 0xff; @@ -261,6 +264,8 @@ void mbedtls_ct_memcpy_if(int eq, int size, int offset) ASSERT_COMPARE(expected, size, result, size); + + /* Apply offset to src and src2 */ for (int i = 0; i < size + offset; i++) { src[i] = 1; src2[i] = 2; @@ -281,6 +286,25 @@ void mbedtls_ct_memcpy_if(int eq, int size, int offset) TEST_CF_PUBLIC(result, size + offset); ASSERT_COMPARE(expected, size, result, size); + + + /* result == src == dest */ + for (int i = 0; i < size + offset; i++) { + src[i] = 2; + expected[i] = 2; + } + + TEST_CF_SECRET(&secret_eq, sizeof(secret_eq)); + TEST_CF_SECRET(src, size + offset); + TEST_CF_SECRET(result, size + offset); + + mbedtls_ct_memcpy_if(mbedtls_ct_bool(secret_eq), src + offset, src + offset, src + offset, size); + + TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq)); + TEST_CF_PUBLIC(src, size + offset); + TEST_CF_PUBLIC(result, size + offset); + + ASSERT_COMPARE(expected, size, src + offset, size); exit: mbedtls_free(src); mbedtls_free(src2);