mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Add a function to maybe memcpy() a value, in constant time.
This commit is contained in:
parent
b6250236a2
commit
4269ab97c6
@ -279,3 +279,30 @@ select_array_member_cumulative_timei(const uint64_t *entries, int n_entries,
|
||||
|
||||
return i_chosen;
|
||||
}
|
||||
|
||||
/**
|
||||
* If <b>s</b> is true, then copy <b>n</b> bytes from <b>src</d> to
|
||||
* <b>dest</b>. Otherwise leave <b>dest</b> alone.
|
||||
*
|
||||
* This function behaves the same as
|
||||
*
|
||||
* if (s)
|
||||
* memcpy(dest, src, n);
|
||||
*
|
||||
* except that it tries to run in the same amount of time whether <b>s</b> is
|
||||
* true or not.
|
||||
**/
|
||||
void
|
||||
memcpy_if_true_timei(bool s, void *dest, const void *src, size_t n)
|
||||
{
|
||||
// If s is true, mask will be ~0. If s is false, mask will be 0.
|
||||
const char mask = (char) -(signed char)s;
|
||||
|
||||
char *destp = dest;
|
||||
const char *srcp = src;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
*destp = (*destp & ~mask) | (*srcp & mask);
|
||||
++destp;
|
||||
++srcp;
|
||||
}
|
||||
}
|
||||
|
@ -73,4 +73,6 @@ int select_array_member_cumulative_timei(const uint64_t *entries,
|
||||
int n_entries,
|
||||
uint64_t total, uint64_t rand_val);
|
||||
|
||||
void memcpy_if_true_timei(bool s, void *dest, const void *src, size_t n);
|
||||
|
||||
#endif /* !defined(TOR_DI_OPS_H) */
|
||||
|
@ -4571,6 +4571,35 @@ test_util_di_ops(void *arg)
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_util_memcpy_iftrue_timei(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
char buf1[25];
|
||||
char buf2[25];
|
||||
char buf3[25];
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
crypto_rand(buf1, sizeof(buf1));
|
||||
crypto_rand(buf2, sizeof(buf2));
|
||||
memcpy(buf3, buf1, sizeof(buf1));
|
||||
|
||||
/* We just copied buf1 into buf3. Now we're going to copy buf2 into buf2,
|
||||
iff our coin flip comes up heads. */
|
||||
bool coinflip = crypto_rand_int(2) == 0;
|
||||
|
||||
memcpy_if_true_timei(coinflip, buf3, buf2, sizeof(buf3));
|
||||
|
||||
if (coinflip) {
|
||||
tt_mem_op(buf3, OP_EQ, buf2, sizeof(buf2));
|
||||
} else {
|
||||
tt_mem_op(buf3, OP_EQ, buf1, sizeof(buf1));
|
||||
}
|
||||
}
|
||||
done:
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_util_di_map(void *arg)
|
||||
{
|
||||
@ -6386,6 +6415,7 @@ struct testcase_t util_tests[] = {
|
||||
UTIL_LEGACY(path_is_relative),
|
||||
UTIL_LEGACY(strtok),
|
||||
UTIL_LEGACY(di_ops),
|
||||
UTIL_TEST(memcpy_iftrue_timei, 0),
|
||||
UTIL_TEST(di_map, 0),
|
||||
UTIL_TEST(round_to_next_multiple_of, 0),
|
||||
UTIL_TEST(laplace, 0),
|
||||
|
Loading…
Reference in New Issue
Block a user