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