aboutsummaryrefslogtreecommitdiff
path: root/src/lib/ctime
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2020-01-16 19:23:20 -0500
committerNick Mathewson <nickm@torproject.org>2020-01-21 10:31:36 -0500
commit4269ab97c685cb3bef9607cbada8af5b6b84640c (patch)
tree91c97a02639354a897350b18a537033c86ed056a /src/lib/ctime
parentb6250236a2427b116c819be3305727fcbefdb424 (diff)
downloadtor-4269ab97c685cb3bef9607cbada8af5b6b84640c.tar.gz
tor-4269ab97c685cb3bef9607cbada8af5b6b84640c.zip
Add a function to maybe memcpy() a value, in constant time.
Diffstat (limited to 'src/lib/ctime')
-rw-r--r--src/lib/ctime/di_ops.c27
-rw-r--r--src/lib/ctime/di_ops.h2
2 files changed, 29 insertions, 0 deletions
diff --git a/src/lib/ctime/di_ops.c b/src/lib/ctime/di_ops.c
index 7448a9973e..0859dd8bee 100644
--- a/src/lib/ctime/di_ops.c
+++ b/src/lib/ctime/di_ops.c
@@ -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;
+ }
+}
diff --git a/src/lib/ctime/di_ops.h b/src/lib/ctime/di_ops.h
index 4ff8f03165..9fe2884ecc 100644
--- a/src/lib/ctime/di_ops.h
+++ b/src/lib/ctime/di_ops.h
@@ -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) */