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