aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-04-24 16:12:23 -0400
committerJason A. Donenfeld <Jason@zx2c4.com>2021-04-24 16:38:24 -0400
commitdd04bc5aa4a3607fd2277a5d7953a2a20a411696 (patch)
tree8b40b7cd6d2e16d827ecdac75580313087784f65
parentversion: bump (diff)
downloadwireguard-freebsd-dd04bc5aa4a3607fd2277a5d7953a2a20a411696.tar.xz
wireguard-freebsd-dd04bc5aa4a3607fd2277a5d7953a2a20a411696.zip
wg_noise: compile on 32-bit
The lack of 64bit atomic helpers on 32bit is an annoyance. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--src/wg_noise.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/src/wg_noise.c b/src/wg_noise.c
index 5ef7a58c3146..7acf1b6ab7cb 100644
--- a/src/wg_noise.c
+++ b/src/wg_noise.c
@@ -780,11 +780,14 @@ noise_keypair_remote(struct noise_keypair *kp)
int
noise_keypair_nonce_next(struct noise_keypair *kp, uint64_t *send)
{
+ if (!ck_pr_load_bool(&kp->kp_can_send))
+ return (EINVAL);
+
#ifdef __LP64__
- *send = atomic_fetchadd_64(&kp->kp_nonce_send, 1);
+ *send = ck_pr_faa_64(&kp->kp_nonce_send, 1);
#else
rw_wlock(&kp->kp_nonce_lock);
- *send = ctr->c_send++;
+ *send = kp->kp_nonce_send++;
rw_wunlock(&kp->kp_nonce_lock);
#endif
if (*send < REJECT_AFTER_MESSAGES)
@@ -821,7 +824,11 @@ noise_keypair_nonce_check(struct noise_keypair *kp, uint64_t recv)
for (i = 1; i <= top; i++)
kp->kp_backtrack[
(i + index_ctr) & (COUNTER_NUM - 1)] = 0;
+#ifdef __LP64__
ck_pr_store_64(&kp->kp_nonce_recv, recv);
+#else
+ kp->kp_nonce_recv = recv;
+#endif
}
index_recv %= COUNTER_NUM;
@@ -844,14 +851,27 @@ noise_keep_key_fresh_send(struct noise_remote *r)
struct epoch_tracker et;
struct noise_keypair *current;
int keep_key_fresh;
+ uint64_t nonce;
NET_EPOCH_ENTER(et);
current = ck_pr_load_ptr(&r->r_current);
- keep_key_fresh = current != NULL && ck_pr_load_bool(&current->kp_can_send) && (
- ck_pr_load_64(&current->kp_nonce_send) > REKEY_AFTER_MESSAGES ||
- (current->kp_is_initiator && noise_timer_expired(current->kp_birthdate, REKEY_AFTER_TIME, 0)));
- NET_EPOCH_EXIT(et);
+ keep_key_fresh = current != NULL && ck_pr_load_bool(&current->kp_can_send);
+ if (!keep_key_fresh)
+ goto out;
+#ifdef __LP64__
+ nonce = ck_pr_load_64(&current->kp_nonce_send);
+#else
+ rw_rlock(&current->kp_nonce_lock);
+ nonce = current->kp_nonce_send;
+ rw_runlock(&current->kp_nonce_lock);
+#endif
+ keep_key_fresh = nonce > REKEY_AFTER_MESSAGES;
+ if (keep_key_fresh)
+ goto out;
+ keep_key_fresh = current->kp_is_initiator && noise_timer_expired(current->kp_birthdate, REKEY_AFTER_TIME, 0);
+out:
+ NET_EPOCH_EXIT(et);
return (keep_key_fresh ? ESTALE : 0);
}
@@ -885,7 +905,17 @@ noise_keypair_encrypt(struct noise_keypair *kp, uint32_t *r_idx, uint64_t nonce,
int
noise_keypair_decrypt(struct noise_keypair *kp, uint64_t nonce, struct mbuf *m)
{
- if (ck_pr_load_64(&kp->kp_nonce_recv) >= REJECT_AFTER_MESSAGES ||
+ uint64_t cur_nonce;
+
+#ifdef __LP64__
+ cur_nonce = ck_pr_load_64(&kp->kp_nonce_recv);
+#else
+ rw_rlock(&kp->kp_nonce_lock);
+ cur_nonce = kp->kp_nonce_recv;
+ rw_runlock(&kp->kp_nonce_lock);
+#endif
+
+ if (cur_nonce >= REJECT_AFTER_MESSAGES ||
noise_timer_expired(kp->kp_birthdate, REJECT_AFTER_TIME, 0))
return (EINVAL);