aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-02-04 04:38:28 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2019-02-04 04:42:04 +0100
commitb783d49467a54606471d1a55ac79a0c350ba2219 (patch)
treeeb38ff4a9823232fb7f412e6f8ba5f4a8eaad767
parentnoise: store clamped key instead of raw key (diff)
downloadWireGuard-jd/base-time.tar.xz
WireGuard-jd/base-time.zip
noise: compute timestamps from a given base timejd/base-time
-rw-r--r--src/noise.c27
-rw-r--r--src/noise.h1
2 files changed, 18 insertions, 10 deletions
diff --git a/src/noise.c b/src/noise.c
index 4405125..ae83796 100644
--- a/src/noise.c
+++ b/src/noise.c
@@ -447,23 +447,30 @@ static void message_ephemeral(u8 ephemeral_dst[NOISE_PUBLIC_KEY_LEN],
NOISE_PUBLIC_KEY_LEN, chaining_key);
}
-static void tai64n_now(u8 output[NOISE_TIMESTAMP_LEN])
+static void time_or_monotonic(u8 output[NOISE_TIMESTAMP_LEN],
+ struct noise_handshake *handshake)
{
- struct timespec64 now;
-
- ktime_get_real_ts64(&now);
-
/* In order to prevent some sort of infoleak from precise timers, we
* round down the nanoseconds part to the closest rounded-down power of
* two to the maximum initiations per second allowed anyway by the
* implementation.
*/
- now.tv_nsec = ALIGN_DOWN(now.tv_nsec,
- rounddown_pow_of_two(NSEC_PER_SEC / INITIATIONS_PER_SECOND));
+ ktime_t now = ns_to_ktime(ALIGN_DOWN(ktime_get_real_ns(),
+ rounddown_pow_of_two(NSEC_PER_SEC / INITIATIONS_PER_SECOND)));
+ struct timespec64 stamp;
+
+ if (unlikely(!handshake->base_time)) {
+ handshake->base_time = now;
+ } else {
+ handshake->base_time = ktime_add_ns(handshake->base_time, 1);
+ if (unlikely(ktime_after(handshake->base_time, now)))
+ handshake->base_time = now;
+ }
+ stamp = ktime_to_timespec64(handshake->base_time);
/* https://cr.yp.to/libtai/tai64.html */
- *(__be64 *)output = cpu_to_be64(0x400000000000000aULL + now.tv_sec);
- *(__be32 *)(output + sizeof(__be64)) = cpu_to_be32(now.tv_nsec);
+ *(__be64 *)output = cpu_to_be64(0x400000000000000aULL + stamp.tv_sec);
+ *(__be32 *)(output + sizeof(__be64)) = cpu_to_be32(stamp.tv_nsec);
}
bool
@@ -516,7 +523,7 @@ wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
handshake->chaining_key);
/* {t} */
- tai64n_now(timestamp);
+ time_or_monotonic(timestamp, handshake);
message_encrypt(dst->encrypted_timestamp, timestamp,
NOISE_TIMESTAMP_LEN, key, handshake->hash);
diff --git a/src/noise.h b/src/noise.h
index 8e5cc0a..4b0ccc8 100644
--- a/src/noise.h
+++ b/src/noise.h
@@ -83,6 +83,7 @@ struct noise_handshake {
u8 hash[NOISE_HASH_LEN];
u8 chaining_key[NOISE_HASH_LEN];
+ ktime_t base_time;
u8 latest_timestamp[NOISE_TIMESTAMP_LEN];
__le32 remote_index;