xref: /dragonfly/sys/net/wg/wg_cookie.c (revision dfbadd37)
1 /*-
2  * SPDX-License-Identifier: ISC
3  *
4  * Copyright (C) 2015-2021 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
5  * Copyright (C) 2019-2021 Matt Dunwoodie <ncon@noconroy.net>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "opt_inet6.h"
21 
22 #include <sys/param.h>
23 #include <sys/systm.h>
24 #include <sys/callout.h>
25 #include <sys/kernel.h>
26 #include <sys/lock.h>
27 #include <sys/malloc.h>
28 #include <sys/objcache.h>
29 #include <sys/queue.h>
30 #include <sys/socket.h>
31 #include <sys/time.h>
32 #include <netinet/in.h>
33 
34 #include <crypto/chachapoly.h>
35 #include <crypto/blake2/blake2s.h>
36 #include <crypto/siphash/siphash.h>
37 
38 #include "wg_cookie.h"
39 
40 #define COOKIE_MAC1_KEY_LABEL	"mac1----"
41 #define COOKIE_COOKIE_KEY_LABEL	"cookie--"
42 #define COOKIE_SECRET_MAX_AGE	120
43 #define COOKIE_SECRET_LATENCY	5
44 
45 /* Constants for initiation rate limiting */
46 #define RATELIMIT_SIZE		(1 << 13)
47 #define RATELIMIT_MASK		(RATELIMIT_SIZE - 1)
48 #define RATELIMIT_SIZE_MAX	(RATELIMIT_SIZE * 8)
49 #define NSEC_PER_SEC		1000000000LL
50 #define INITIATIONS_PER_SECOND	20
51 #define INITIATIONS_BURSTABLE	5
52 #define INITIATION_COST		(NSEC_PER_SEC / INITIATIONS_PER_SECOND)
53 #define TOKEN_MAX		(INITIATION_COST * INITIATIONS_BURSTABLE)
54 #define ELEMENT_TIMEOUT		1 /* second */
55 #define IPV4_MASK_SIZE		4 /* Use all 4 bytes of IPv4 address */
56 #define IPV6_MASK_SIZE		8 /* Use top 8 bytes (/64) of IPv6 address */
57 
58 struct ratelimit_key {
59 	uint8_t ip[IPV6_MASK_SIZE];
60 };
61 
62 struct ratelimit_entry {
63 	LIST_ENTRY(ratelimit_entry)	r_entry;
64 	struct ratelimit_key		r_key;
65 	struct timespec			r_last_time;	/* nanouptime */
66 	uint64_t			r_tokens;
67 };
68 
69 struct ratelimit {
70 	uint8_t				rl_secret[SIPHASH_KEY_LENGTH];
71 	struct lock			rl_mtx;
72 	struct callout			rl_gc;
73 	LIST_HEAD(, ratelimit_entry)	rl_table[RATELIMIT_SIZE];
74 	size_t				rl_table_num;
75 	bool				rl_initialized;
76 };
77 
78 
79 static void	macs_mac1(struct cookie_macs *, const void *, size_t,
80 			  const uint8_t[COOKIE_KEY_SIZE]);
81 static void	macs_mac2(struct cookie_macs *, const void *, size_t,
82 			  const uint8_t[COOKIE_COOKIE_SIZE]);
83 static void	make_cookie(struct cookie_checker *,
84 			    uint8_t[COOKIE_COOKIE_SIZE],
85 			    const struct sockaddr *);
86 static void	precompute_key(uint8_t[COOKIE_KEY_SIZE],
87 			       const uint8_t[COOKIE_INPUT_SIZE],
88 			       const uint8_t *, size_t);
89 static void	ratelimit_init(struct ratelimit *);
90 static void	ratelimit_deinit(struct ratelimit *);
91 static void	ratelimit_gc_callout(void *);
92 static void	ratelimit_gc_schedule(struct ratelimit *);
93 static void	ratelimit_gc(struct ratelimit *, bool);
94 static int	ratelimit_allow(struct ratelimit *, const struct sockaddr *);
95 
96 
97 static struct ratelimit ratelimit_v4;
98 #ifdef INET6
99 static struct ratelimit ratelimit_v6;
100 #endif
101 
102 static struct objcache *ratelimit_zone;
103 static MALLOC_DEFINE(M_WG_RATELIMIT, "WG ratelimit", "wireguard ratelimit");
104 
105 
106 static inline uint64_t
107 siphash13(const uint8_t key[SIPHASH_KEY_LENGTH], const void *src, size_t len)
108 {
109 	SIPHASH_CTX ctx;
110 	return SipHashX(&ctx, 1, 3, key, src, len);
111 }
112 
113 static inline bool
114 timer_expired(const struct timespec *birthdate, time_t sec, long nsec)
115 {
116 	struct timespec uptime;
117 	struct timespec expire = { .tv_sec = sec, .tv_nsec = nsec };
118 
119 	if (birthdate->tv_sec == 0 && birthdate->tv_nsec == 0)
120 		return (true);
121 
122 	getnanouptime(&uptime);
123 	timespecadd(birthdate, &expire, &expire);
124 	return timespeccmp(&uptime, &expire, >);
125 }
126 
127 /*----------------------------------------------------------------------------*/
128 /* Public Functions */
129 
130 int
131 cookie_init(void)
132 {
133 	ratelimit_zone = objcache_create_simple(
134 	    M_WG_RATELIMIT, sizeof(struct ratelimit_entry));
135 	if (ratelimit_zone == NULL)
136 		return (ENOMEM);
137 
138 	ratelimit_init(&ratelimit_v4);
139 #ifdef INET6
140 	ratelimit_init(&ratelimit_v6);
141 #endif
142 
143 	return (0);
144 }
145 
146 void
147 cookie_deinit(void)
148 {
149 	ratelimit_deinit(&ratelimit_v4);
150 #ifdef INET6
151 	ratelimit_deinit(&ratelimit_v6);
152 #endif
153 	if (ratelimit_zone != NULL)
154 		objcache_destroy(ratelimit_zone);
155 }
156 
157 void
158 cookie_checker_init(struct cookie_checker *cc)
159 {
160 	bzero(cc, sizeof(*cc));
161 	lockinit(&cc->cc_key_lock, "cookie_checker_key", 0, 0);
162 	lockinit(&cc->cc_secret_mtx, "cookie_checker_secret", 0, 0);
163 }
164 
165 void
166 cookie_checker_free(struct cookie_checker *cc)
167 {
168 	lockuninit(&cc->cc_key_lock);
169 	lockuninit(&cc->cc_secret_mtx);
170 	explicit_bzero(cc, sizeof(*cc));
171 }
172 
173 void
174 cookie_checker_update(struct cookie_checker *cc,
175 		      const uint8_t key[COOKIE_INPUT_SIZE])
176 {
177 	lockmgr(&cc->cc_key_lock, LK_EXCLUSIVE);
178 	if (key != NULL) {
179 		precompute_key(cc->cc_mac1_key, key, COOKIE_MAC1_KEY_LABEL,
180 			       sizeof(COOKIE_MAC1_KEY_LABEL) - 1);
181 		precompute_key(cc->cc_cookie_key, key, COOKIE_COOKIE_KEY_LABEL,
182 			       sizeof(COOKIE_COOKIE_KEY_LABEL) - 1);
183 	} else {
184 		bzero(cc->cc_mac1_key, sizeof(cc->cc_mac1_key));
185 		bzero(cc->cc_cookie_key, sizeof(cc->cc_cookie_key));
186 	}
187 	lockmgr(&cc->cc_key_lock, LK_RELEASE);
188 }
189 
190 void
191 cookie_checker_create_payload(struct cookie_checker *cc,
192 			      const struct cookie_macs *macs,
193 			      uint8_t nonce[COOKIE_NONCE_SIZE],
194 			      uint8_t ecookie[COOKIE_ENCRYPTED_SIZE],
195 			      const struct sockaddr *sa)
196 {
197 	uint8_t cookie[COOKIE_COOKIE_SIZE];
198 
199 	make_cookie(cc, cookie, sa);
200 	karc4random_buf(nonce, COOKIE_NONCE_SIZE);
201 
202 	lockmgr(&cc->cc_key_lock, LK_SHARED);
203 	xchacha20poly1305_encrypt(ecookie, cookie, COOKIE_COOKIE_SIZE,
204 				  macs->mac1, COOKIE_MAC_SIZE, nonce,
205 				  cc->cc_cookie_key);
206 	lockmgr(&cc->cc_key_lock, LK_RELEASE);
207 
208 	explicit_bzero(cookie, sizeof(cookie));
209 }
210 
211 int
212 cookie_checker_validate_macs(struct cookie_checker *cc,
213 			     const struct cookie_macs *macs,
214 			     const void *buf, size_t len, bool check_cookie,
215 			     const struct sockaddr *sa)
216 {
217 	struct cookie_macs our_macs;
218 	uint8_t cookie[COOKIE_COOKIE_SIZE];
219 
220 	/* Validate incoming MACs */
221 	lockmgr(&cc->cc_key_lock, LK_SHARED);
222 	macs_mac1(&our_macs, buf, len, cc->cc_mac1_key);
223 	lockmgr(&cc->cc_key_lock, LK_RELEASE);
224 
225 	/* If mac1 is invald, we want to drop the packet */
226 	if (timingsafe_bcmp(our_macs.mac1, macs->mac1, COOKIE_MAC_SIZE) != 0)
227 		return (EINVAL);
228 
229 	if (check_cookie) {
230 		make_cookie(cc, cookie, sa);
231 		macs_mac2(&our_macs, buf, len, cookie);
232 
233 		/* If mac2 is invalid, we want to send a cookie response. */
234 		if (timingsafe_bcmp(our_macs.mac2, macs->mac2, COOKIE_MAC_SIZE)
235 		    != 0)
236 			return (EAGAIN);
237 
238 		/*
239 		 * If the mac2 is valid, we may want to rate limit the peer.
240 		 * ratelimit_allow() will return either 0 or ECONNREFUSED,
241 		 * implying there is no ratelimiting, or we should ratelimit
242 		 * (refuse), respectively.
243 		 */
244 		if (sa->sa_family == AF_INET)
245 			return ratelimit_allow(&ratelimit_v4, sa);
246 #ifdef INET6
247 		else if (sa->sa_family == AF_INET6)
248 			return ratelimit_allow(&ratelimit_v6, sa);
249 #endif
250 		else
251 			return (EAFNOSUPPORT);
252 	}
253 
254 	return (0);
255 }
256 
257 void
258 cookie_maker_init(struct cookie_maker *cm, const uint8_t key[COOKIE_INPUT_SIZE])
259 {
260 	bzero(cm, sizeof(*cm));
261 	precompute_key(cm->cm_mac1_key, key, COOKIE_MAC1_KEY_LABEL,
262 		       sizeof(COOKIE_MAC1_KEY_LABEL) - 1);
263 	precompute_key(cm->cm_cookie_key, key, COOKIE_COOKIE_KEY_LABEL,
264 		       sizeof(COOKIE_COOKIE_KEY_LABEL) - 1);
265 	lockinit(&cm->cm_lock, "cookie_maker", 0, 0);
266 }
267 
268 void
269 cookie_maker_free(struct cookie_maker *cm)
270 {
271 	lockuninit(&cm->cm_lock);
272 	explicit_bzero(cm, sizeof(*cm));
273 }
274 
275 int
276 cookie_maker_consume_payload(struct cookie_maker *cm,
277 			     const uint8_t nonce[COOKIE_NONCE_SIZE],
278 			     const uint8_t ecookie[COOKIE_ENCRYPTED_SIZE])
279 {
280 	uint8_t cookie[COOKIE_COOKIE_SIZE];
281 	int ret = 0;
282 
283 	lockmgr(&cm->cm_lock, LK_SHARED);
284 
285 	if (!cm->cm_mac1_sent) {
286 		ret = ETIMEDOUT;
287 		goto out;
288 	}
289 
290 	if (!xchacha20poly1305_decrypt(cookie, ecookie, COOKIE_ENCRYPTED_SIZE,
291 				       cm->cm_mac1_last, COOKIE_MAC_SIZE,
292 				       nonce, cm->cm_cookie_key)) {
293 		ret = EINVAL;
294 		goto out;
295 	}
296 
297 	lockmgr(&cm->cm_lock, LK_RELEASE);
298 	lockmgr(&cm->cm_lock, LK_EXCLUSIVE);
299 
300 	memcpy(cm->cm_cookie, cookie, COOKIE_COOKIE_SIZE);
301 	getnanouptime(&cm->cm_cookie_birthdate);
302 	cm->cm_cookie_valid = true;
303 	cm->cm_mac1_sent = false;
304 
305 out:
306 	lockmgr(&cm->cm_lock, LK_RELEASE);
307 	return (ret);
308 }
309 
310 void
311 cookie_maker_mac(struct cookie_maker *cm, struct cookie_macs *macs,
312 		 const void *buf, size_t len)
313 {
314 	lockmgr(&cm->cm_lock, LK_EXCLUSIVE);
315 
316 	macs_mac1(macs, buf, len, cm->cm_mac1_key);
317 	memcpy(cm->cm_mac1_last, macs->mac1, COOKIE_MAC_SIZE);
318 	cm->cm_mac1_sent = true;
319 
320 	if (cm->cm_cookie_valid &&
321 	    !timer_expired(&cm->cm_cookie_birthdate,
322 			   COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY, 0)) {
323 		macs_mac2(macs, buf, len, cm->cm_cookie);
324 	} else {
325 		bzero(macs->mac2, COOKIE_MAC_SIZE);
326 		cm->cm_cookie_valid = false;
327 	}
328 
329 	lockmgr(&cm->cm_lock, LK_RELEASE);
330 }
331 
332 /*----------------------------------------------------------------------------*/
333 /* Private functions */
334 
335 static void
336 precompute_key(uint8_t key[COOKIE_KEY_SIZE],
337 	       const uint8_t input[COOKIE_INPUT_SIZE],
338 	       const uint8_t *label, size_t label_len)
339 {
340 	struct blake2s_state blake;
341 
342 	blake2s_init(&blake, COOKIE_KEY_SIZE);
343 	blake2s_update(&blake, label, label_len);
344 	blake2s_update(&blake, input, COOKIE_INPUT_SIZE);
345 	blake2s_final(&blake, key);
346 }
347 
348 static void
349 macs_mac1(struct cookie_macs *macs, const void *buf, size_t len,
350 	  const uint8_t key[COOKIE_KEY_SIZE])
351 {
352 	struct blake2s_state state;
353 
354 	blake2s_init_key(&state, COOKIE_MAC_SIZE, key, COOKIE_KEY_SIZE);
355 	blake2s_update(&state, buf, len);
356 	blake2s_final(&state, macs->mac1);
357 }
358 
359 static void
360 macs_mac2(struct cookie_macs *macs, const void *buf, size_t len,
361 	  const uint8_t key[COOKIE_COOKIE_SIZE])
362 {
363 	struct blake2s_state state;
364 
365 	blake2s_init_key(&state, COOKIE_MAC_SIZE, key, COOKIE_COOKIE_SIZE);
366 	blake2s_update(&state, buf, len);
367 	blake2s_update(&state, macs->mac1, COOKIE_MAC_SIZE);
368 	blake2s_final(&state, macs->mac2);
369 }
370 
371 static void
372 make_cookie(struct cookie_checker *cc, uint8_t cookie[COOKIE_COOKIE_SIZE],
373 	    const struct sockaddr *sa)
374 {
375 	struct blake2s_state state;
376 
377 	lockmgr(&cc->cc_secret_mtx, LK_EXCLUSIVE);
378 	if (timer_expired(&cc->cc_secret_birthdate,
379 			  COOKIE_SECRET_MAX_AGE, 0)) {
380 		karc4random_buf(cc->cc_secret, COOKIE_SECRET_SIZE);
381 		getnanouptime(&cc->cc_secret_birthdate);
382 	}
383 	blake2s_init_key(&state, COOKIE_COOKIE_SIZE, cc->cc_secret,
384 			 COOKIE_SECRET_SIZE);
385 	lockmgr(&cc->cc_secret_mtx, LK_RELEASE);
386 
387 	if (sa->sa_family == AF_INET) {
388 		const struct sockaddr_in *sin = (const void *)sa;
389 		blake2s_update(&state, (const uint8_t *)&sin->sin_addr,
390 			       sizeof(sin->sin_addr));
391 		blake2s_update(&state, (const uint8_t *)&sin->sin_port,
392 			       sizeof(sin->sin_port));
393 		blake2s_final(&state, cookie);
394 #ifdef INET6
395 	} else if (sa->sa_family == AF_INET6) {
396 		const struct sockaddr_in6 *sin6 = (const void *)sa;
397 		blake2s_update(&state, (const uint8_t *)&sin6->sin6_addr,
398 			       sizeof(sin6->sin6_addr));
399 		blake2s_update(&state, (const uint8_t *)&sin6->sin6_port,
400 			       sizeof(sin6->sin6_port));
401 		blake2s_final(&state, cookie);
402 #endif
403 	} else {
404 		karc4random_buf(cookie, COOKIE_COOKIE_SIZE);
405 	}
406 }
407 
408 
409 static void
410 ratelimit_init(struct ratelimit *rl)
411 {
412 	size_t i;
413 
414 	bzero(rl, sizeof(*rl));
415 	lockinit(&rl->rl_mtx, "ratelimit_lock", 0, 0);
416 	callout_init_lk(&rl->rl_gc, &rl->rl_mtx);
417 	karc4random_buf(rl->rl_secret, sizeof(rl->rl_secret));
418 	for (i = 0; i < RATELIMIT_SIZE; i++)
419 		LIST_INIT(&rl->rl_table[i]);
420 	rl->rl_table_num = 0;
421 
422 	rl->rl_initialized = true;
423 }
424 
425 static void
426 ratelimit_deinit(struct ratelimit *rl)
427 {
428 	if (!rl->rl_initialized)
429 		return;
430 
431 	lockmgr(&rl->rl_mtx, LK_EXCLUSIVE);
432 	callout_stop(&rl->rl_gc);
433 	ratelimit_gc(rl, true);
434 	lockmgr(&rl->rl_mtx, LK_RELEASE);
435 	lockuninit(&rl->rl_mtx);
436 
437 	rl->rl_initialized = false;
438 }
439 
440 static void
441 ratelimit_gc_callout(void *_rl)
442 {
443 	/* callout will lock for us */
444 	ratelimit_gc(_rl, false);
445 }
446 
447 static void
448 ratelimit_gc_schedule(struct ratelimit *rl)
449 {
450 	/*
451 	 * Trigger another GC if needed.  There is no point calling GC if
452 	 * there are no entries in the table.  We also want to ensure that
453 	 * GC occurs on a regular interval, so don't override a currently
454 	 * pending GC.
455 	 *
456 	 * In the case of a forced ratelimit_gc(), there will be no entries
457 	 * left so we will not schedule another GC.
458 	 */
459 	if (rl->rl_table_num > 0 && !callout_pending(&rl->rl_gc))
460 		callout_reset(&rl->rl_gc, ELEMENT_TIMEOUT * hz,
461 			      ratelimit_gc_callout, rl);
462 }
463 
464 static void
465 ratelimit_gc(struct ratelimit *rl, bool force)
466 {
467 	struct ratelimit_entry *r, *tr;
468 	struct timespec expiry;
469 	size_t i;
470 
471 	KKASSERT(lockstatus(&rl->rl_mtx, curthread) == LK_EXCLUSIVE);
472 
473 	if (rl->rl_table_num == 0)
474 		return;
475 
476 	getnanouptime(&expiry);
477 	expiry.tv_sec -= ELEMENT_TIMEOUT;
478 
479 	for (i = 0; i < RATELIMIT_SIZE; i++) {
480 		LIST_FOREACH_MUTABLE(r, &rl->rl_table[i], r_entry, tr) {
481 			if (force ||
482 			    timespeccmp(&r->r_last_time, &expiry, <)) {
483 				rl->rl_table_num--;
484 				LIST_REMOVE(r, r_entry);
485 				objcache_put(ratelimit_zone, r);
486 			}
487 		}
488 	}
489 
490 	ratelimit_gc_schedule(rl);
491 }
492 
493 static int
494 ratelimit_allow(struct ratelimit *rl, const struct sockaddr *sa)
495 {
496 	struct timespec diff;
497 	struct ratelimit_entry *r;
498 	struct ratelimit_key key = { 0 };
499 	uint64_t bucket, tokens;
500 	size_t len;
501 	int ret = ECONNREFUSED;
502 
503 	if (sa->sa_family == AF_INET) {
504 		len = IPV4_MASK_SIZE;
505 		memcpy(key.ip, &((const struct sockaddr_in *)sa)->sin_addr,
506 		       len);
507 	}
508 #ifdef INET6
509 	else if (sa->sa_family == AF_INET6) {
510 		len = IPV6_MASK_SIZE;
511 		memcpy(key.ip, &((const struct sockaddr_in6 *)sa)->sin6_addr,
512 		       len);
513 	}
514 #endif
515 	else {
516 		return (ret);
517 	}
518 
519 	bucket = siphash13(rl->rl_secret, &key, len) & RATELIMIT_MASK;
520 	lockmgr(&rl->rl_mtx, LK_EXCLUSIVE);
521 
522 	LIST_FOREACH(r, &rl->rl_table[bucket], r_entry) {
523 		if (memcmp(&r->r_key, &key, len) != 0)
524 			continue;
525 
526 		/*
527 		 * Found an entry for the endpoint.  We apply standard token
528 		 * bucket, by calculating the time lapsed since last_time,
529 		 * adding that, ensuring that we cap the tokens at TOKEN_MAX.
530 		 * If the endpoint has no tokens left (i.e., tokens <
531 		 * INITIATION_COST) then we block the request.  Otherwise, we
532 		 * subtract the INITITIATION_COST and return OK.
533 		 */
534 		diff = r->r_last_time;
535 		getnanouptime(&r->r_last_time);
536 		timespecsub(&r->r_last_time, &diff, &diff);
537 
538 		tokens = r->r_tokens;
539 		tokens += diff.tv_sec * NSEC_PER_SEC + diff.tv_nsec;
540 		if (tokens > TOKEN_MAX)
541 			tokens = TOKEN_MAX;
542 
543 		if (tokens >= INITIATION_COST) {
544 			r->r_tokens = tokens - INITIATION_COST;
545 			goto ok;
546 		} else {
547 			r->r_tokens = tokens;
548 			goto error;
549 		}
550 	}
551 
552 	/*
553 	 * Didn't have an entry for the endpoint, so let's add one if we
554 	 * have space.
555 	 */
556 	if (rl->rl_table_num >= RATELIMIT_SIZE_MAX)
557 		goto error;
558 
559 	if ((r = objcache_get(ratelimit_zone, M_NOWAIT)) == NULL)
560 		goto error;
561 	bzero(r, sizeof(*r)); /* objcache_get() doesn't ensure M_ZERO. */
562 
563 	rl->rl_table_num++;
564 
565 	/* Insert the new entry and initialize it. */
566 	LIST_INSERT_HEAD(&rl->rl_table[bucket], r, r_entry);
567 	r->r_key = key;
568 	r->r_tokens = TOKEN_MAX - INITIATION_COST;
569 	getnanouptime(&r->r_last_time);
570 
571 	/* We've added a new entry; let's trigger GC. */
572 	ratelimit_gc_schedule(rl);
573 
574 ok:
575 	ret = 0;
576 error:
577 	lockmgr(&rl->rl_mtx, LK_RELEASE);
578 	return (ret);
579 }
580 
581 
582 #ifdef WG_SELFTESTS
583 #include "selftest/cookie.c"
584 #endif /* WG_SELFTESTS */
585