xref: /freebsd/sys/dev/wg/wg_cookie.c (revision 0549218b43f028bb5bde430d7fcc6ead6843aa61)
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 
40 struct ratelimit_key {
41 	struct vnet *vnet;
42 	uint8_t ip[IPV6_MASK_SIZE];
43 };
44 
45 struct 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 
52 struct 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 
61 static void	precompute_key(uint8_t *,
62 			const uint8_t[COOKIE_INPUT_SIZE], const char *);
63 static void	macs_mac1(struct cookie_macs *, const void *, size_t,
64 			const uint8_t[COOKIE_KEY_SIZE]);
65 static void	macs_mac2(struct cookie_macs *, const void *, size_t,
66 			const uint8_t[COOKIE_COOKIE_SIZE]);
67 static int	timer_expired(sbintime_t, uint32_t, uint32_t);
68 static void	make_cookie(struct cookie_checker *,
69 			uint8_t[COOKIE_COOKIE_SIZE], struct sockaddr *);
70 static void	ratelimit_init(struct ratelimit *);
71 static void	ratelimit_deinit(struct ratelimit *);
72 static void	ratelimit_gc_callout(void *);
73 static void	ratelimit_gc_schedule(struct ratelimit *);
74 static void	ratelimit_gc(struct ratelimit *, bool);
75 static int	ratelimit_allow(struct ratelimit *, struct sockaddr *, struct vnet *);
76 static uint64_t siphash13(const uint8_t [SIPHASH_KEY_LENGTH], const void *, size_t);
77 
78 static struct ratelimit ratelimit_v4;
79 #ifdef INET6
80 static struct ratelimit ratelimit_v6;
81 #endif
82 static uma_zone_t ratelimit_zone;
83 
84 /* Public Functions */
85 int
86 cookie_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 
98 void
99 cookie_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 
109 void
110 cookie_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 
118 void
119 cookie_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 
126 void
127 cookie_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 
141 void
142 cookie_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 
159 void
160 cookie_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 
168 void
169 cookie_maker_free(struct cookie_maker *cm)
170 {
171 	rw_destroy(&cm->cm_lock);
172 	explicit_bzero(cm, sizeof(*cm));
173 }
174 
175 int
176 cookie_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;
203 error:
204 	rw_runlock(&cm->cm_lock);
205 	return ret;
206 }
207 
208 void
209 cookie_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 
228 int
229 cookie_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 */
270 static void
271 precompute_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 
281 static void
282 macs_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 
291 static void
292 macs_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 
302 static __inline int
303 timer_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 
309 static void
310 make_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 
344 static void
345 ratelimit_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 
357 static void
358 ratelimit_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 
371 static void
372 ratelimit_gc_callout(void *_rl)
373 {
374 	/* callout will lock rl_mtx for us */
375 	ratelimit_gc(_rl, false);
376 }
377 
378 static void
379 ratelimit_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 
392 static void
393 ratelimit_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 
419 static int
420 ratelimit_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);
491 ok:
492 	ret = 0;
493 error:
494 	mtx_unlock(&rl->rl_mtx);
495 	return ret;
496 }
497 
498 static 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