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