1/* SPDX-License-Identifier: ISC
2 *
3 * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4 * Copyright (C) 2019-2021 Matt Dunwoodie <ncon@noconroy.net>
5 */
6
7#include "opt_inet.h"
8#include "opt_inet6.h"
9
10#include <sys/param.h>
11#include <sys/systm.h>
12#include <sys/kernel.h>
13#include <sys/lock.h>
14#include <sys/mutex.h>
15#include <sys/rwlock.h>
16#include <sys/socket.h>
17#include <crypto/siphash/siphash.h>
18#include <netinet/in.h>
19#include <vm/uma.h>
20
21#include "wg_cookie.h"
22
23#define COOKIE_MAC1_KEY_LABEL	"mac1----"
24#define COOKIE_COOKIE_KEY_LABEL	"cookie--"
25#define COOKIE_SECRET_MAX_AGE	120
26#define COOKIE_SECRET_LATENCY	5
27
28/* Constants for initiation rate limiting */
29#define RATELIMIT_SIZE		(1 << 13)
30#define RATELIMIT_MASK		(RATELIMIT_SIZE - 1)
31#define RATELIMIT_SIZE_MAX	(RATELIMIT_SIZE * 8)
32#define INITIATIONS_PER_SECOND	20
33#define INITIATIONS_BURSTABLE	5
34#define INITIATION_COST		(SBT_1S / INITIATIONS_PER_SECOND)
35#define TOKEN_MAX		(INITIATION_COST * INITIATIONS_BURSTABLE)
36#define ELEMENT_TIMEOUT		1
37#define IPV4_MASK_SIZE		4 /* Use all 4 bytes of IPv4 address */
38#define IPV6_MASK_SIZE		8 /* Use top 8 bytes (/64) of IPv6 address */
39
40struct ratelimit_key {
41	struct vnet *vnet;
42	uint8_t ip[IPV6_MASK_SIZE];
43};
44
45struct ratelimit_entry {
46	LIST_ENTRY(ratelimit_entry)	r_entry;
47	struct ratelimit_key		r_key;
48	sbintime_t			r_last_time;	/* sbinuptime */
49	uint64_t			r_tokens;
50};
51
52struct ratelimit {
53	uint8_t				rl_secret[SIPHASH_KEY_LENGTH];
54	struct mtx			rl_mtx;
55	struct callout			rl_gc;
56	LIST_HEAD(, ratelimit_entry)	rl_table[RATELIMIT_SIZE];
57	size_t				rl_table_num;
58	bool				rl_initialized;
59};
60
61static void	precompute_key(uint8_t *,
62			const uint8_t[COOKIE_INPUT_SIZE], const char *);
63static void	macs_mac1(struct cookie_macs *, const void *, size_t,
64			const uint8_t[COOKIE_KEY_SIZE]);
65static void	macs_mac2(struct cookie_macs *, const void *, size_t,
66			const uint8_t[COOKIE_COOKIE_SIZE]);
67static int	timer_expired(sbintime_t, uint32_t, uint32_t);
68static void	make_cookie(struct cookie_checker *,
69			uint8_t[COOKIE_COOKIE_SIZE], struct sockaddr *);
70static void	ratelimit_init(struct ratelimit *);
71static void	ratelimit_deinit(struct ratelimit *);
72static void	ratelimit_gc_callout(void *);
73static void	ratelimit_gc_schedule(struct ratelimit *);
74static void	ratelimit_gc(struct ratelimit *, bool);
75static int	ratelimit_allow(struct ratelimit *, struct sockaddr *, struct vnet *);
76static uint64_t siphash13(const uint8_t [SIPHASH_KEY_LENGTH], const void *, size_t);
77
78static struct ratelimit ratelimit_v4;
79#ifdef INET6
80static struct ratelimit ratelimit_v6;
81#endif
82static uma_zone_t ratelimit_zone;
83
84/* Public Functions */
85int
86cookie_init(void)
87{
88	ratelimit_zone = uma_zcreate("wg ratelimit",
89	    sizeof(struct ratelimit_entry), NULL, NULL, NULL, NULL, 0, 0);
90
91	ratelimit_init(&ratelimit_v4);
92#ifdef INET6
93	ratelimit_init(&ratelimit_v6);
94#endif
95	return (0);
96}
97
98void
99cookie_deinit(void)
100{
101	ratelimit_deinit(&ratelimit_v4);
102#ifdef INET6
103	ratelimit_deinit(&ratelimit_v6);
104#endif
105	if (ratelimit_zone != NULL)
106		uma_zdestroy(ratelimit_zone);
107}
108
109void
110cookie_checker_init(struct cookie_checker *cc)
111{
112	bzero(cc, sizeof(*cc));
113
114	rw_init(&cc->cc_key_lock, "cookie_checker_key");
115	mtx_init(&cc->cc_secret_mtx, "cookie_checker_secret", NULL, MTX_DEF);
116}
117
118void
119cookie_checker_free(struct cookie_checker *cc)
120{
121	rw_destroy(&cc->cc_key_lock);
122	mtx_destroy(&cc->cc_secret_mtx);
123	explicit_bzero(cc, sizeof(*cc));
124}
125
126void
127cookie_checker_update(struct cookie_checker *cc,
128    const uint8_t key[COOKIE_INPUT_SIZE])
129{
130	rw_wlock(&cc->cc_key_lock);
131	if (key) {
132		precompute_key(cc->cc_mac1_key, key, COOKIE_MAC1_KEY_LABEL);
133		precompute_key(cc->cc_cookie_key, key, COOKIE_COOKIE_KEY_LABEL);
134	} else {
135		bzero(cc->cc_mac1_key, sizeof(cc->cc_mac1_key));
136		bzero(cc->cc_cookie_key, sizeof(cc->cc_cookie_key));
137	}
138	rw_wunlock(&cc->cc_key_lock);
139}
140
141void
142cookie_checker_create_payload(struct cookie_checker *cc,
143    struct cookie_macs *macs, uint8_t nonce[COOKIE_NONCE_SIZE],
144    uint8_t ecookie[COOKIE_ENCRYPTED_SIZE], struct sockaddr *sa)
145{
146	uint8_t cookie[COOKIE_COOKIE_SIZE];
147
148	make_cookie(cc, cookie, sa);
149	arc4random_buf(nonce, COOKIE_NONCE_SIZE);
150
151	rw_rlock(&cc->cc_key_lock);
152	xchacha20poly1305_encrypt(ecookie, cookie, COOKIE_COOKIE_SIZE,
153	    macs->mac1, COOKIE_MAC_SIZE, nonce, cc->cc_cookie_key);
154	rw_runlock(&cc->cc_key_lock);
155
156	explicit_bzero(cookie, sizeof(cookie));
157}
158
159void
160cookie_maker_init(struct cookie_maker *cm, const uint8_t key[COOKIE_INPUT_SIZE])
161{
162	bzero(cm, sizeof(*cm));
163	precompute_key(cm->cm_mac1_key, key, COOKIE_MAC1_KEY_LABEL);
164	precompute_key(cm->cm_cookie_key, key, COOKIE_COOKIE_KEY_LABEL);
165	rw_init(&cm->cm_lock, "cookie_maker");
166}
167
168void
169cookie_maker_free(struct cookie_maker *cm)
170{
171	rw_destroy(&cm->cm_lock);
172	explicit_bzero(cm, sizeof(*cm));
173}
174
175int
176cookie_maker_consume_payload(struct cookie_maker *cm,
177    uint8_t nonce[COOKIE_NONCE_SIZE], uint8_t ecookie[COOKIE_ENCRYPTED_SIZE])
178{
179	uint8_t cookie[COOKIE_COOKIE_SIZE];
180	int ret;
181
182	rw_rlock(&cm->cm_lock);
183	if (!cm->cm_mac1_sent) {
184		ret = ETIMEDOUT;
185		goto error;
186	}
187
188	if (!xchacha20poly1305_decrypt(cookie, ecookie, COOKIE_ENCRYPTED_SIZE,
189	    cm->cm_mac1_last, COOKIE_MAC_SIZE, nonce, cm->cm_cookie_key)) {
190		ret = EINVAL;
191		goto error;
192	}
193	rw_runlock(&cm->cm_lock);
194
195	rw_wlock(&cm->cm_lock);
196	memcpy(cm->cm_cookie, cookie, COOKIE_COOKIE_SIZE);
197	cm->cm_cookie_birthdate = getsbinuptime();
198	cm->cm_cookie_valid = true;
199	cm->cm_mac1_sent = false;
200	rw_wunlock(&cm->cm_lock);
201
202	return 0;
203error:
204	rw_runlock(&cm->cm_lock);
205	return ret;
206}
207
208void
209cookie_maker_mac(struct cookie_maker *cm, struct cookie_macs *macs, void *buf,
210    size_t len)
211{
212	rw_wlock(&cm->cm_lock);
213	macs_mac1(macs, buf, len, cm->cm_mac1_key);
214	memcpy(cm->cm_mac1_last, macs->mac1, COOKIE_MAC_SIZE);
215	cm->cm_mac1_sent = true;
216
217	if (cm->cm_cookie_valid &&
218	    !timer_expired(cm->cm_cookie_birthdate,
219	    COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY, 0)) {
220		macs_mac2(macs, buf, len, cm->cm_cookie);
221	} else {
222		bzero(macs->mac2, COOKIE_MAC_SIZE);
223		cm->cm_cookie_valid = false;
224	}
225	rw_wunlock(&cm->cm_lock);
226}
227
228int
229cookie_checker_validate_macs(struct cookie_checker *cc, struct cookie_macs *macs,
230    void *buf, size_t len, bool check_cookie, struct sockaddr *sa, struct vnet *vnet)
231{
232	struct cookie_macs our_macs;
233	uint8_t cookie[COOKIE_COOKIE_SIZE];
234
235	/* Validate incoming MACs */
236	rw_rlock(&cc->cc_key_lock);
237	macs_mac1(&our_macs, buf, len, cc->cc_mac1_key);
238	rw_runlock(&cc->cc_key_lock);
239
240	/* If mac1 is invald, we want to drop the packet */
241	if (timingsafe_bcmp(our_macs.mac1, macs->mac1, COOKIE_MAC_SIZE) != 0)
242		return EINVAL;
243
244	if (check_cookie) {
245		make_cookie(cc, cookie, sa);
246		macs_mac2(&our_macs, buf, len, cookie);
247
248		/* If the mac2 is invalid, we want to send a cookie response */
249		if (timingsafe_bcmp(our_macs.mac2, macs->mac2, COOKIE_MAC_SIZE) != 0)
250			return EAGAIN;
251
252		/* If the mac2 is valid, we may want rate limit the peer.
253		 * ratelimit_allow will return either 0 or ECONNREFUSED,
254		 * implying there is no ratelimiting, or we should ratelimit
255		 * (refuse) respectively. */
256		if (sa->sa_family == AF_INET)
257			return ratelimit_allow(&ratelimit_v4, sa, vnet);
258#ifdef INET6
259		else if (sa->sa_family == AF_INET6)
260			return ratelimit_allow(&ratelimit_v6, sa, vnet);
261#endif
262		else
263			return EAFNOSUPPORT;
264	}
265
266	return 0;
267}
268
269/* Private functions */
270static void
271precompute_key(uint8_t *key, const uint8_t input[COOKIE_INPUT_SIZE],
272    const char *label)
273{
274	struct blake2s_state blake;
275	blake2s_init(&blake, COOKIE_KEY_SIZE);
276	blake2s_update(&blake, label, strlen(label));
277	blake2s_update(&blake, input, COOKIE_INPUT_SIZE);
278	blake2s_final(&blake, key);
279}
280
281static void
282macs_mac1(struct cookie_macs *macs, const void *buf, size_t len,
283    const uint8_t key[COOKIE_KEY_SIZE])
284{
285	struct blake2s_state state;
286	blake2s_init_key(&state, COOKIE_MAC_SIZE, key, COOKIE_KEY_SIZE);
287	blake2s_update(&state, buf, len);
288	blake2s_final(&state, macs->mac1);
289}
290
291static void
292macs_mac2(struct cookie_macs *macs, const void *buf, size_t len,
293    const uint8_t key[COOKIE_COOKIE_SIZE])
294{
295	struct blake2s_state state;
296	blake2s_init_key(&state, COOKIE_MAC_SIZE, key, COOKIE_COOKIE_SIZE);
297	blake2s_update(&state, buf, len);
298	blake2s_update(&state, macs->mac1, COOKIE_MAC_SIZE);
299	blake2s_final(&state, macs->mac2);
300}
301
302static __inline int
303timer_expired(sbintime_t timer, uint32_t sec, uint32_t nsec)
304{
305	sbintime_t now = getsbinuptime();
306	return (now > (timer + sec * SBT_1S + nstosbt(nsec))) ? ETIMEDOUT : 0;
307}
308
309static void
310make_cookie(struct cookie_checker *cc, uint8_t cookie[COOKIE_COOKIE_SIZE],
311    struct sockaddr *sa)
312{
313	struct blake2s_state state;
314
315	mtx_lock(&cc->cc_secret_mtx);
316	if (timer_expired(cc->cc_secret_birthdate,
317	    COOKIE_SECRET_MAX_AGE, 0)) {
318		arc4random_buf(cc->cc_secret, COOKIE_SECRET_SIZE);
319		cc->cc_secret_birthdate = getsbinuptime();
320	}
321	blake2s_init_key(&state, COOKIE_COOKIE_SIZE, cc->cc_secret,
322	    COOKIE_SECRET_SIZE);
323	mtx_unlock(&cc->cc_secret_mtx);
324
325	if (sa->sa_family == AF_INET) {
326		blake2s_update(&state, (uint8_t *)&satosin(sa)->sin_addr,
327				sizeof(struct in_addr));
328		blake2s_update(&state, (uint8_t *)&satosin(sa)->sin_port,
329				sizeof(in_port_t));
330		blake2s_final(&state, cookie);
331#ifdef INET6
332	} else if (sa->sa_family == AF_INET6) {
333		blake2s_update(&state, (uint8_t *)&satosin6(sa)->sin6_addr,
334				sizeof(struct in6_addr));
335		blake2s_update(&state, (uint8_t *)&satosin6(sa)->sin6_port,
336				sizeof(in_port_t));
337		blake2s_final(&state, cookie);
338#endif
339	} else {
340		arc4random_buf(cookie, COOKIE_COOKIE_SIZE);
341	}
342}
343
344static void
345ratelimit_init(struct ratelimit *rl)
346{
347	size_t i;
348	mtx_init(&rl->rl_mtx, "ratelimit_lock", NULL, MTX_DEF);
349	callout_init_mtx(&rl->rl_gc, &rl->rl_mtx, 0);
350	arc4random_buf(rl->rl_secret, sizeof(rl->rl_secret));
351	for (i = 0; i < RATELIMIT_SIZE; i++)
352		LIST_INIT(&rl->rl_table[i]);
353	rl->rl_table_num = 0;
354	rl->rl_initialized = true;
355}
356
357static void
358ratelimit_deinit(struct ratelimit *rl)
359{
360	if (!rl->rl_initialized)
361		return;
362	mtx_lock(&rl->rl_mtx);
363	callout_stop(&rl->rl_gc);
364	ratelimit_gc(rl, true);
365	mtx_unlock(&rl->rl_mtx);
366	mtx_destroy(&rl->rl_mtx);
367
368	rl->rl_initialized = false;
369}
370
371static void
372ratelimit_gc_callout(void *_rl)
373{
374	/* callout will lock rl_mtx for us */
375	ratelimit_gc(_rl, false);
376}
377
378static void
379ratelimit_gc_schedule(struct ratelimit *rl)
380{
381	/* Trigger another GC if needed. There is no point calling GC if there
382	 * are no entries in the table. We also want to ensure that GC occurs
383	 * on a regular interval, so don't override a currently pending GC.
384	 *
385	 * In the case of a forced ratelimit_gc, there will be no entries left
386	 * so we will will not schedule another GC. */
387	if (rl->rl_table_num > 0 && !callout_pending(&rl->rl_gc))
388		callout_reset(&rl->rl_gc, ELEMENT_TIMEOUT * hz,
389		    ratelimit_gc_callout, rl);
390}
391
392static void
393ratelimit_gc(struct ratelimit *rl, bool force)
394{
395	size_t i;
396	struct ratelimit_entry *r, *tr;
397	sbintime_t expiry;
398
399	mtx_assert(&rl->rl_mtx, MA_OWNED);
400
401	if (rl->rl_table_num == 0)
402		return;
403
404	expiry = getsbinuptime() - ELEMENT_TIMEOUT * SBT_1S;
405
406	for (i = 0; i < RATELIMIT_SIZE; i++) {
407		LIST_FOREACH_SAFE(r, &rl->rl_table[i], r_entry, tr) {
408			if (r->r_last_time < expiry || force) {
409				rl->rl_table_num--;
410				LIST_REMOVE(r, r_entry);
411				uma_zfree(ratelimit_zone, r);
412			}
413		}
414	}
415
416	ratelimit_gc_schedule(rl);
417}
418
419static int
420ratelimit_allow(struct ratelimit *rl, struct sockaddr *sa, struct vnet *vnet)
421{
422	uint64_t bucket, tokens;
423	sbintime_t diff, now;
424	struct ratelimit_entry *r;
425	int ret = ECONNREFUSED;
426	struct ratelimit_key key = { .vnet = vnet };
427	size_t len = sizeof(key);
428
429	if (sa->sa_family == AF_INET) {
430		memcpy(key.ip, &satosin(sa)->sin_addr, IPV4_MASK_SIZE);
431		len -= IPV6_MASK_SIZE - IPV4_MASK_SIZE;
432	}
433#ifdef INET6
434	else if (sa->sa_family == AF_INET6)
435		memcpy(key.ip, &satosin6(sa)->sin6_addr, IPV6_MASK_SIZE);
436#endif
437	else
438		return ret;
439
440	bucket = siphash13(rl->rl_secret, &key, len) & RATELIMIT_MASK;
441	mtx_lock(&rl->rl_mtx);
442
443	LIST_FOREACH(r, &rl->rl_table[bucket], r_entry) {
444		if (bcmp(&r->r_key, &key, len) != 0)
445			continue;
446
447		/* If we get to here, we've found an entry for the endpoint.
448		 * We apply standard token bucket, by calculating the time
449		 * lapsed since our last_time, adding that, ensuring that we
450		 * cap the tokens at TOKEN_MAX. If the endpoint has no tokens
451		 * left (that is tokens <= INITIATION_COST) then we block the
452		 * request, otherwise we subtract the INITITIATION_COST and
453		 * return OK. */
454		now = getsbinuptime();
455		diff = now - r->r_last_time;
456		r->r_last_time = now;
457
458		tokens = r->r_tokens + diff;
459
460		if (tokens > TOKEN_MAX)
461			tokens = TOKEN_MAX;
462
463		if (tokens >= INITIATION_COST) {
464			r->r_tokens = tokens - INITIATION_COST;
465			goto ok;
466		} else {
467			r->r_tokens = tokens;
468			goto error;
469		}
470	}
471
472	/* If we get to here, we didn't have an entry for the endpoint, let's
473	 * add one if we have space. */
474	if (rl->rl_table_num >= RATELIMIT_SIZE_MAX)
475		goto error;
476
477	/* Goto error if out of memory */
478	if ((r = uma_zalloc(ratelimit_zone, M_NOWAIT | M_ZERO)) == NULL)
479		goto error;
480
481	rl->rl_table_num++;
482
483	/* Insert entry into the hashtable and ensure it's initialised */
484	LIST_INSERT_HEAD(&rl->rl_table[bucket], r, r_entry);
485	r->r_key = key;
486	r->r_last_time = getsbinuptime();
487	r->r_tokens = TOKEN_MAX - INITIATION_COST;
488
489	/* If we've added a new entry, let's trigger GC. */
490	ratelimit_gc_schedule(rl);
491ok:
492	ret = 0;
493error:
494	mtx_unlock(&rl->rl_mtx);
495	return ret;
496}
497
498static uint64_t siphash13(const uint8_t key[SIPHASH_KEY_LENGTH], const void *src, size_t len)
499{
500	SIPHASH_CTX ctx;
501	return (SipHashX(&ctx, 1, 3, key, src, len));
502}
503
504#ifdef SELFTESTS
505#include "selftest/cookie.c"
506#endif /* SELFTESTS */
507