if_wg.c revision 1.86 1 /* $NetBSD: if_wg.c,v 1.86 2024/07/25 00:24:02 christos Exp $ */
2
3 /*
4 * Copyright (C) Ryota Ozaki <ozaki.ryota (at) gmail.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*
33 * This network interface aims to implement the WireGuard protocol.
34 * The implementation is based on the paper of WireGuard as of
35 * 2018-06-30 [1]. The paper is referred in the source code with label
36 * [W]. Also the specification of the Noise protocol framework as of
37 * 2018-07-11 [2] is referred with label [N].
38 *
39 * [1] https://www.wireguard.com/papers/wireguard.pdf
40 * [2] http://noiseprotocol.org/noise.pdf
41 */
42
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.86 2024/07/25 00:24:02 christos Exp $");
45
46 #ifdef _KERNEL_OPT
47 #include "opt_altq_enabled.h"
48 #include "opt_inet.h"
49 #endif
50
51 #include <sys/param.h>
52 #include <sys/types.h>
53
54 #include <sys/atomic.h>
55 #include <sys/callout.h>
56 #include <sys/cprng.h>
57 #include <sys/cpu.h>
58 #include <sys/device.h>
59 #include <sys/domain.h>
60 #include <sys/errno.h>
61 #include <sys/intr.h>
62 #include <sys/ioctl.h>
63 #include <sys/kernel.h>
64 #include <sys/kmem.h>
65 #include <sys/mbuf.h>
66 #include <sys/module.h>
67 #include <sys/mutex.h>
68 #include <sys/once.h>
69 #include <sys/percpu.h>
70 #include <sys/pserialize.h>
71 #include <sys/psref.h>
72 #include <sys/queue.h>
73 #include <sys/rwlock.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
76 #include <sys/sockio.h>
77 #include <sys/sysctl.h>
78 #include <sys/syslog.h>
79 #include <sys/systm.h>
80 #include <sys/thmap.h>
81 #include <sys/threadpool.h>
82 #include <sys/time.h>
83 #include <sys/timespec.h>
84 #include <sys/workqueue.h>
85
86 #include <lib/libkern/libkern.h>
87
88 #include <net/bpf.h>
89 #include <net/if.h>
90 #include <net/if_types.h>
91 #include <net/if_wg.h>
92 #include <net/pktqueue.h>
93 #include <net/route.h>
94
95 #include <netinet/in.h>
96 #include <netinet/in_pcb.h>
97 #include <netinet/in_var.h>
98 #include <netinet/ip.h>
99 #include <netinet/ip_var.h>
100 #include <netinet/udp.h>
101 #include <netinet/udp_var.h>
102
103 #ifdef INET6
104 #include <netinet/ip6.h>
105 #include <netinet6/in6_pcb.h>
106 #include <netinet6/in6_var.h>
107 #include <netinet6/ip6_var.h>
108 #include <netinet6/udp6_var.h>
109 #endif /* INET6 */
110
111 #include <prop/proplib.h>
112
113 #include <crypto/blake2/blake2s.h>
114 #include <crypto/sodium/crypto_aead_chacha20poly1305.h>
115 #include <crypto/sodium/crypto_aead_xchacha20poly1305.h>
116 #include <crypto/sodium/crypto_scalarmult.h>
117
118 #include "ioconf.h"
119
120 #ifdef WG_RUMPKERNEL
121 #include "wg_user.h"
122 #endif
123
124 /*
125 * Data structures
126 * - struct wg_softc is an instance of wg interfaces
127 * - It has a list of peers (struct wg_peer)
128 * - It has a threadpool job that sends/receives handshake messages and
129 * runs event handlers
130 * - It has its own two routing tables: one is for IPv4 and the other IPv6
131 * - struct wg_peer is a representative of a peer
132 * - It has a struct work to handle handshakes and timer tasks
133 * - It has a pair of session instances (struct wg_session)
134 * - It has a pair of endpoint instances (struct wg_sockaddr)
135 * - Normally one endpoint is used and the second one is used only on
136 * a peer migration (a change of peer's IP address)
137 * - It has a list of IP addresses and sub networks called allowedips
138 * (struct wg_allowedip)
139 * - A packets sent over a session is allowed if its destination matches
140 * any IP addresses or sub networks of the list
141 * - struct wg_session represents a session of a secure tunnel with a peer
142 * - Two instances of sessions belong to a peer; a stable session and a
143 * unstable session
144 * - A handshake process of a session always starts with a unstable instance
145 * - Once a session is established, its instance becomes stable and the
146 * other becomes unstable instead
147 * - Data messages are always sent via a stable session
148 *
149 * Locking notes:
150 * - Each wg has a mutex(9) wg_lock, and a rwlock(9) wg_rwlock
151 * - Changes to the peer list are serialized by wg_lock
152 * - The peer list may be read with pserialize(9) and psref(9)
153 * - The rwlock (wg_rwlock) protects the routing tables (wg_rtable_ipv[46])
154 * => XXX replace by pserialize when routing table is psz-safe
155 * - Each peer (struct wg_peer, wgp) has a mutex wgp_lock, which can be taken
156 * only in thread context and serializes:
157 * - the stable and unstable session pointers
158 * - all unstable session state
159 * - Packet processing may be done in softint context:
160 * - The stable session can be read under pserialize(9) or psref(9)
161 * - The stable session is always ESTABLISHED
162 * - On a session swap, we must wait for all readers to release a
163 * reference to a stable session before changing wgs_state and
164 * session states
165 * - Lock order: wg_lock -> wgp_lock
166 */
167
168
169 #define WGLOG(level, fmt, args...) \
170 log(level, "%s: " fmt, __func__, ##args)
171
172 #define WG_DEBUG
173
174 /* Debug options */
175 #ifdef WG_DEBUG
176 /* Output debug logs */
177 #ifndef WG_DEBUG_LOG
178 #define WG_DEBUG_LOG
179 #endif
180 /* Output trace logs */
181 #ifndef WG_DEBUG_TRACE
182 #define WG_DEBUG_TRACE
183 #endif
184 /* Output hash values, etc. */
185 #ifndef WG_DEBUG_DUMP
186 #define WG_DEBUG_DUMP
187 #endif
188 /* debug packets */
189 #ifndef WG_DEBUG_PACKET
190 #define WG_DEBUG_PACKET
191 #endif
192 /* Make some internal parameters configurable for testing and debugging */
193 #ifndef WG_DEBUG_PARAMS
194 #define WG_DEBUG_PARAMS
195 #endif
196 #endif /* WG_DEBUG */
197
198 #ifndef WG_DEBUG
199 # if defined(WG_DEBUG_LOG) || defined(WG_DEBUG_TRACE) || \
200 defined(WG_DEBUG_DUMP) || defined(WG_DEBUG_PARAMS)
201 # define WG_DEBUG
202 # endif
203 #endif
204
205 #ifdef WG_DEBUG
206 int wg_debug;
207 #define WG_DEBUG_FLAGS_LOG 1
208 #define WG_DEBUG_FLAGS_TRACE 2
209 #define WG_DEBUG_FLAGS_DUMP 4
210 #define WG_DEBUG_FLAGS_PACKET 8
211 #endif
212
213
214 #ifdef WG_DEBUG_TRACE
215 #define WG_TRACE(msg) do { \
216 if (wg_debug & WG_DEBUG_FLAGS_TRACE) \
217 log(LOG_DEBUG, "%s:%d: %s\n", __func__, __LINE__, (msg)); \
218 } while (0)
219 #else
220 #define WG_TRACE(msg) __nothing
221 #endif
222
223 #ifdef WG_DEBUG_LOG
224 #define WG_DLOG(fmt, args...) do { \
225 if (wg_debug & WG_DEBUG_FLAGS_LOG) \
226 log(LOG_DEBUG, "%s: " fmt, __func__, ##args); \
227 } while (0)
228 #else
229 #define WG_DLOG(fmt, args...) __nothing
230 #endif
231
232 #define WG_LOG_RATECHECK(wgprc, level, fmt, args...) do { \
233 if (ppsratecheck(&(wgprc)->wgprc_lasttime, \
234 &(wgprc)->wgprc_curpps, 1)) { \
235 log(level, fmt, ##args); \
236 } \
237 } while (0)
238
239 #ifdef WG_DEBUG_PARAMS
240 static bool wg_force_underload = false;
241 #endif
242
243 #ifdef WG_DEBUG_DUMP
244
245 static char *
246 gethexdump(const void *vp, size_t n)
247 {
248 char *buf;
249 const uint8_t *p = vp;
250 size_t i;
251
252 if (n > (SIZE_MAX - 1) / 3)
253 return NULL;
254 buf = kmem_alloc(3 * n + 1, KM_NOSLEEP);
255 if (buf == NULL)
256 return NULL;
257 for (i = 0; i < n; i++)
258 snprintf(buf + 3 * i, 3 + 1, " %02hhx", p[i]);
259 return buf;
260 }
261
262 static void
263 puthexdump(char *buf, const void *p, size_t n)
264 {
265
266 if (buf == NULL)
267 return;
268 kmem_free(buf, 3*n + 1);
269 }
270
271 #ifdef WG_RUMPKERNEL
272 static void
273 wg_dump_buf(const char *func, const char *buf, const size_t size)
274 {
275 if ((wg_debug & WG_DEBUG_FLAGS_DUMP) == 0)
276 return;
277
278 char *hex = gethexdump(buf, size);
279
280 log(LOG_DEBUG, "%s: %s\n", func, hex ? hex : "(enomem)");
281 puthexdump(hex, buf, size);
282 }
283 #endif
284
285 static void
286 wg_dump_hash(const uint8_t *func, const uint8_t *name, const uint8_t *hash,
287 const size_t size)
288 {
289 if ((wg_debug & WG_DEBUG_FLAGS_DUMP) == 0)
290 return;
291
292 char *hex = gethexdump(hash, size);
293
294 log(LOG_DEBUG, "%s: %s: %s\n", func, name, hex ? hex : "(enomem)");
295 puthexdump(hex, hash, size);
296 }
297
298 #define WG_DUMP_HASH(name, hash) \
299 wg_dump_hash(__func__, name, hash, WG_HASH_LEN)
300 #define WG_DUMP_HASH48(name, hash) \
301 wg_dump_hash(__func__, name, hash, 48)
302 #define WG_DUMP_BUF(buf, size) \
303 wg_dump_buf(__func__, buf, size)
304 #else
305 #define WG_DUMP_HASH(name, hash) __nothing
306 #define WG_DUMP_HASH48(name, hash) __nothing
307 #define WG_DUMP_BUF(buf, size) __nothing
308 #endif /* WG_DEBUG_DUMP */
309
310 /* chosen somewhat arbitrarily -- fits in signed 16 bits NUL-terminated */
311 #define WG_MAX_PROPLEN 32766
312
313 #define WG_MTU 1420
314 #define WG_ALLOWEDIPS 16
315
316 #define CURVE25519_KEY_LEN 32
317 #define TAI64N_LEN sizeof(uint32_t) * 3
318 #define POLY1305_AUTHTAG_LEN 16
319 #define HMAC_BLOCK_LEN 64
320
321 /* [N] 4.1: "DHLEN must be 32 or greater." WireGuard chooses 32. */
322 /* [N] 4.3: Hash functions */
323 #define NOISE_DHLEN 32
324 /* [N] 4.3: "Must be 32 or 64." WireGuard chooses 32. */
325 #define NOISE_HASHLEN 32
326 #define NOISE_BLOCKLEN 64
327 #define NOISE_HKDF_OUTPUT_LEN NOISE_HASHLEN
328 /* [N] 5.1: "k" */
329 #define NOISE_CIPHER_KEY_LEN 32
330 /*
331 * [N] 9.2: "psk"
332 * "... psk is a 32-byte secret value provided by the application."
333 */
334 #define NOISE_PRESHARED_KEY_LEN 32
335
336 #define WG_STATIC_KEY_LEN CURVE25519_KEY_LEN
337 #define WG_TIMESTAMP_LEN TAI64N_LEN
338
339 #define WG_PRESHARED_KEY_LEN NOISE_PRESHARED_KEY_LEN
340
341 #define WG_COOKIE_LEN 16
342 #define WG_MAC_LEN 16
343 #define WG_RANDVAL_LEN 24
344
345 #define WG_EPHEMERAL_KEY_LEN CURVE25519_KEY_LEN
346 /* [N] 5.2: "ck: A chaining key of HASHLEN bytes" */
347 #define WG_CHAINING_KEY_LEN NOISE_HASHLEN
348 /* [N] 5.2: "h: A hash output of HASHLEN bytes" */
349 #define WG_HASH_LEN NOISE_HASHLEN
350 #define WG_CIPHER_KEY_LEN NOISE_CIPHER_KEY_LEN
351 #define WG_DH_OUTPUT_LEN NOISE_DHLEN
352 #define WG_KDF_OUTPUT_LEN NOISE_HKDF_OUTPUT_LEN
353 #define WG_AUTHTAG_LEN POLY1305_AUTHTAG_LEN
354 #define WG_DATA_KEY_LEN 32
355 #define WG_SALT_LEN 24
356
357 /*
358 * The protocol messages
359 */
360 struct wg_msg {
361 uint32_t wgm_type;
362 } __packed;
363
364 /* [W] 5.4.2 First Message: Initiator to Responder */
365 struct wg_msg_init {
366 uint32_t wgmi_type;
367 uint32_t wgmi_sender;
368 uint8_t wgmi_ephemeral[WG_EPHEMERAL_KEY_LEN];
369 uint8_t wgmi_static[WG_STATIC_KEY_LEN + WG_AUTHTAG_LEN];
370 uint8_t wgmi_timestamp[WG_TIMESTAMP_LEN + WG_AUTHTAG_LEN];
371 uint8_t wgmi_mac1[WG_MAC_LEN];
372 uint8_t wgmi_mac2[WG_MAC_LEN];
373 } __packed;
374
375 /* [W] 5.4.3 Second Message: Responder to Initiator */
376 struct wg_msg_resp {
377 uint32_t wgmr_type;
378 uint32_t wgmr_sender;
379 uint32_t wgmr_receiver;
380 uint8_t wgmr_ephemeral[WG_EPHEMERAL_KEY_LEN];
381 uint8_t wgmr_empty[0 + WG_AUTHTAG_LEN];
382 uint8_t wgmr_mac1[WG_MAC_LEN];
383 uint8_t wgmr_mac2[WG_MAC_LEN];
384 } __packed;
385
386 /* [W] 5.4.6 Subsequent Messages: Transport Data Messages */
387 struct wg_msg_data {
388 uint32_t wgmd_type;
389 uint32_t wgmd_receiver;
390 uint64_t wgmd_counter;
391 uint32_t wgmd_packet[0];
392 } __packed;
393
394 /* [W] 5.4.7 Under Load: Cookie Reply Message */
395 struct wg_msg_cookie {
396 uint32_t wgmc_type;
397 uint32_t wgmc_receiver;
398 uint8_t wgmc_salt[WG_SALT_LEN];
399 uint8_t wgmc_cookie[WG_COOKIE_LEN + WG_AUTHTAG_LEN];
400 } __packed;
401
402 #define WG_MSG_TYPE_INIT 1
403 #define WG_MSG_TYPE_RESP 2
404 #define WG_MSG_TYPE_COOKIE 3
405 #define WG_MSG_TYPE_DATA 4
406 #define WG_MSG_TYPE_MAX WG_MSG_TYPE_DATA
407
408 /* Sliding windows */
409
410 #define SLIWIN_BITS 2048u
411 #define SLIWIN_TYPE uint32_t
412 #define SLIWIN_BPW NBBY*sizeof(SLIWIN_TYPE)
413 #define SLIWIN_WORDS howmany(SLIWIN_BITS, SLIWIN_BPW)
414 #define SLIWIN_NPKT (SLIWIN_BITS - NBBY*sizeof(SLIWIN_TYPE))
415
416 struct sliwin {
417 SLIWIN_TYPE B[SLIWIN_WORDS];
418 uint64_t T;
419 };
420
421 static void
422 sliwin_reset(struct sliwin *W)
423 {
424
425 memset(W, 0, sizeof(*W));
426 }
427
428 static int
429 sliwin_check_fast(const volatile struct sliwin *W, uint64_t S)
430 {
431
432 /*
433 * If it's more than one window older than the highest sequence
434 * number we've seen, reject.
435 */
436 #ifdef __HAVE_ATOMIC64_LOADSTORE
437 if (S + SLIWIN_NPKT < atomic_load_relaxed(&W->T))
438 return EAUTH;
439 #endif
440
441 /*
442 * Otherwise, we need to take the lock to decide, so don't
443 * reject just yet. Caller must serialize a call to
444 * sliwin_update in this case.
445 */
446 return 0;
447 }
448
449 static int
450 sliwin_update(struct sliwin *W, uint64_t S)
451 {
452 unsigned word, bit;
453
454 /*
455 * If it's more than one window older than the highest sequence
456 * number we've seen, reject.
457 */
458 if (S + SLIWIN_NPKT < W->T)
459 return EAUTH;
460
461 /*
462 * If it's higher than the highest sequence number we've seen,
463 * advance the window.
464 */
465 if (S > W->T) {
466 uint64_t i = W->T / SLIWIN_BPW;
467 uint64_t j = S / SLIWIN_BPW;
468 unsigned k;
469
470 for (k = 0; k < MIN(j - i, SLIWIN_WORDS); k++)
471 W->B[(i + k + 1) % SLIWIN_WORDS] = 0;
472 #ifdef __HAVE_ATOMIC64_LOADSTORE
473 atomic_store_relaxed(&W->T, S);
474 #else
475 W->T = S;
476 #endif
477 }
478
479 /* Test and set the bit -- if already set, reject. */
480 word = (S / SLIWIN_BPW) % SLIWIN_WORDS;
481 bit = S % SLIWIN_BPW;
482 if (W->B[word] & (1UL << bit))
483 return EAUTH;
484 W->B[word] |= 1U << bit;
485
486 /* Accept! */
487 return 0;
488 }
489
490 struct wg_session {
491 struct wg_peer *wgs_peer;
492 struct psref_target
493 wgs_psref;
494
495 int wgs_state;
496 #define WGS_STATE_UNKNOWN 0
497 #define WGS_STATE_INIT_ACTIVE 1
498 #define WGS_STATE_INIT_PASSIVE 2
499 #define WGS_STATE_ESTABLISHED 3
500 #define WGS_STATE_DESTROYING 4
501
502 time_t wgs_time_established;
503 time_t wgs_time_last_data_sent;
504 bool wgs_is_initiator;
505
506 uint32_t wgs_local_index;
507 uint32_t wgs_remote_index;
508 #ifdef __HAVE_ATOMIC64_LOADSTORE
509 volatile uint64_t
510 wgs_send_counter;
511 #else
512 kmutex_t wgs_send_counter_lock;
513 uint64_t wgs_send_counter;
514 #endif
515
516 struct {
517 kmutex_t lock;
518 struct sliwin window;
519 } *wgs_recvwin;
520
521 uint8_t wgs_handshake_hash[WG_HASH_LEN];
522 uint8_t wgs_chaining_key[WG_CHAINING_KEY_LEN];
523 uint8_t wgs_ephemeral_key_pub[WG_EPHEMERAL_KEY_LEN];
524 uint8_t wgs_ephemeral_key_priv[WG_EPHEMERAL_KEY_LEN];
525 uint8_t wgs_ephemeral_key_peer[WG_EPHEMERAL_KEY_LEN];
526 uint8_t wgs_tkey_send[WG_DATA_KEY_LEN];
527 uint8_t wgs_tkey_recv[WG_DATA_KEY_LEN];
528 };
529
530 struct wg_sockaddr {
531 union {
532 struct sockaddr_storage _ss;
533 struct sockaddr _sa;
534 struct sockaddr_in _sin;
535 struct sockaddr_in6 _sin6;
536 };
537 struct psref_target wgsa_psref;
538 };
539
540 #define wgsatoss(wgsa) (&(wgsa)->_ss)
541 #define wgsatosa(wgsa) (&(wgsa)->_sa)
542 #define wgsatosin(wgsa) (&(wgsa)->_sin)
543 #define wgsatosin6(wgsa) (&(wgsa)->_sin6)
544
545 #define wgsa_family(wgsa) (wgsatosa(wgsa)->sa_family)
546
547 struct wg_peer;
548 struct wg_allowedip {
549 struct radix_node wga_nodes[2];
550 struct wg_sockaddr _wga_sa_addr;
551 struct wg_sockaddr _wga_sa_mask;
552 #define wga_sa_addr _wga_sa_addr._sa
553 #define wga_sa_mask _wga_sa_mask._sa
554
555 int wga_family;
556 uint8_t wga_cidr;
557 union {
558 struct in_addr _ip4;
559 struct in6_addr _ip6;
560 } wga_addr;
561 #define wga_addr4 wga_addr._ip4
562 #define wga_addr6 wga_addr._ip6
563
564 struct wg_peer *wga_peer;
565 };
566
567 typedef uint8_t wg_timestamp_t[WG_TIMESTAMP_LEN];
568
569 struct wg_ppsratecheck {
570 struct timeval wgprc_lasttime;
571 int wgprc_curpps;
572 };
573
574 struct wg_softc;
575 struct wg_peer {
576 struct wg_softc *wgp_sc;
577 char wgp_name[WG_PEER_NAME_MAXLEN + 1];
578 struct pslist_entry wgp_peerlist_entry;
579 pserialize_t wgp_psz;
580 struct psref_target wgp_psref;
581 kmutex_t *wgp_lock;
582 kmutex_t *wgp_intr_lock;
583
584 uint8_t wgp_pubkey[WG_STATIC_KEY_LEN];
585 struct wg_sockaddr *wgp_endpoint;
586 struct wg_sockaddr *wgp_endpoint0;
587 volatile unsigned wgp_endpoint_changing;
588 bool wgp_endpoint_available;
589
590 /* The preshared key (optional) */
591 uint8_t wgp_psk[WG_PRESHARED_KEY_LEN];
592
593 struct wg_session *wgp_session_stable;
594 struct wg_session *wgp_session_unstable;
595
596 /* first outgoing packet awaiting session initiation */
597 struct mbuf *wgp_pending;
598
599 /* timestamp in big-endian */
600 wg_timestamp_t wgp_timestamp_latest_init;
601
602 struct timespec wgp_last_handshake_time;
603
604 callout_t wgp_rekey_timer;
605 callout_t wgp_handshake_timeout_timer;
606 callout_t wgp_session_dtor_timer;
607
608 time_t wgp_handshake_start_time;
609
610 int wgp_n_allowedips;
611 struct wg_allowedip wgp_allowedips[WG_ALLOWEDIPS];
612
613 time_t wgp_latest_cookie_time;
614 uint8_t wgp_latest_cookie[WG_COOKIE_LEN];
615 uint8_t wgp_last_sent_mac1[WG_MAC_LEN];
616 bool wgp_last_sent_mac1_valid;
617 uint8_t wgp_last_sent_cookie[WG_COOKIE_LEN];
618 bool wgp_last_sent_cookie_valid;
619
620 time_t wgp_last_msg_received_time[WG_MSG_TYPE_MAX];
621
622 time_t wgp_last_genrandval_time;
623 uint32_t wgp_randval;
624
625 struct wg_ppsratecheck wgp_ppsratecheck;
626
627 struct work wgp_work;
628 unsigned int wgp_tasks;
629 #define WGP_TASK_SEND_INIT_MESSAGE __BIT(0)
630 #define WGP_TASK_RETRY_HANDSHAKE __BIT(1)
631 #define WGP_TASK_ESTABLISH_SESSION __BIT(2)
632 #define WGP_TASK_ENDPOINT_CHANGED __BIT(3)
633 #define WGP_TASK_SEND_KEEPALIVE_MESSAGE __BIT(4)
634 #define WGP_TASK_DESTROY_PREV_SESSION __BIT(5)
635 };
636
637 struct wg_ops;
638
639 struct wg_softc {
640 struct ifnet wg_if;
641 LIST_ENTRY(wg_softc) wg_list;
642 kmutex_t *wg_lock;
643 kmutex_t *wg_intr_lock;
644 krwlock_t *wg_rwlock;
645
646 uint8_t wg_privkey[WG_STATIC_KEY_LEN];
647 uint8_t wg_pubkey[WG_STATIC_KEY_LEN];
648
649 int wg_npeers;
650 struct pslist_head wg_peers;
651 struct thmap *wg_peers_bypubkey;
652 struct thmap *wg_peers_byname;
653 struct thmap *wg_sessions_byindex;
654 uint16_t wg_listen_port;
655
656 struct threadpool *wg_threadpool;
657
658 struct threadpool_job wg_job;
659 int wg_upcalls;
660 #define WG_UPCALL_INET __BIT(0)
661 #define WG_UPCALL_INET6 __BIT(1)
662
663 #ifdef INET
664 struct socket *wg_so4;
665 struct radix_node_head *wg_rtable_ipv4;
666 #endif
667 #ifdef INET6
668 struct socket *wg_so6;
669 struct radix_node_head *wg_rtable_ipv6;
670 #endif
671
672 struct wg_ppsratecheck wg_ppsratecheck;
673
674 struct wg_ops *wg_ops;
675
676 #ifdef WG_RUMPKERNEL
677 struct wg_user *wg_user;
678 #endif
679 };
680
681 /* [W] 6.1 Preliminaries */
682 #define WG_REKEY_AFTER_MESSAGES (1ULL << 60)
683 #define WG_REJECT_AFTER_MESSAGES (UINT64_MAX - (1 << 13))
684 #define WG_REKEY_AFTER_TIME 120
685 #define WG_REJECT_AFTER_TIME 180
686 #define WG_REKEY_ATTEMPT_TIME 90
687 #define WG_REKEY_TIMEOUT 5
688 #define WG_KEEPALIVE_TIMEOUT 10
689
690 #define WG_COOKIE_TIME 120
691 #define WG_RANDVAL_TIME (2 * 60)
692
693 static uint64_t wg_rekey_after_messages = WG_REKEY_AFTER_MESSAGES;
694 static uint64_t wg_reject_after_messages = WG_REJECT_AFTER_MESSAGES;
695 static unsigned wg_rekey_after_time = WG_REKEY_AFTER_TIME;
696 static unsigned wg_reject_after_time = WG_REJECT_AFTER_TIME;
697 static unsigned wg_rekey_attempt_time = WG_REKEY_ATTEMPT_TIME;
698 static unsigned wg_rekey_timeout = WG_REKEY_TIMEOUT;
699 static unsigned wg_keepalive_timeout = WG_KEEPALIVE_TIMEOUT;
700
701 static struct mbuf *
702 wg_get_mbuf(size_t, size_t);
703
704 static int wg_send_data_msg(struct wg_peer *, struct wg_session *,
705 struct mbuf *);
706 static int wg_send_cookie_msg(struct wg_softc *, struct wg_peer *,
707 const uint32_t, const uint8_t [WG_MAC_LEN],
708 const struct sockaddr *);
709 static int wg_send_handshake_msg_resp(struct wg_softc *, struct wg_peer *,
710 struct wg_session *, const struct wg_msg_init *);
711 static void wg_send_keepalive_msg(struct wg_peer *, struct wg_session *);
712
713 static struct wg_peer *
714 wg_pick_peer_by_sa(struct wg_softc *, const struct sockaddr *,
715 struct psref *);
716 static struct wg_peer *
717 wg_lookup_peer_by_pubkey(struct wg_softc *,
718 const uint8_t [WG_STATIC_KEY_LEN], struct psref *);
719
720 static struct wg_session *
721 wg_lookup_session_by_index(struct wg_softc *,
722 const uint32_t, struct psref *);
723
724 static void wg_update_endpoint_if_necessary(struct wg_peer *,
725 const struct sockaddr *);
726
727 static void wg_schedule_rekey_timer(struct wg_peer *);
728 static void wg_schedule_session_dtor_timer(struct wg_peer *);
729
730 static bool wg_is_underload(struct wg_softc *, struct wg_peer *, int);
731 static void wg_calculate_keys(struct wg_session *, const bool);
732
733 static void wg_clear_states(struct wg_session *);
734
735 static void wg_get_peer(struct wg_peer *, struct psref *);
736 static void wg_put_peer(struct wg_peer *, struct psref *);
737
738 static int wg_send_so(struct wg_peer *, struct mbuf *);
739 static int wg_send_udp(struct wg_peer *, struct mbuf *);
740 static int wg_output(struct ifnet *, struct mbuf *,
741 const struct sockaddr *, const struct rtentry *);
742 static void wg_input(struct ifnet *, struct mbuf *, const int);
743 static int wg_ioctl(struct ifnet *, u_long, void *);
744 static int wg_bind_port(struct wg_softc *, const uint16_t);
745 static int wg_init(struct ifnet *);
746 #ifdef ALTQ
747 static void wg_start(struct ifnet *);
748 #endif
749 static void wg_stop(struct ifnet *, int);
750
751 static void wg_peer_work(struct work *, void *);
752 static void wg_job(struct threadpool_job *);
753 static void wgintr(void *);
754 static void wg_purge_pending_packets(struct wg_peer *);
755
756 static int wg_clone_create(struct if_clone *, int);
757 static int wg_clone_destroy(struct ifnet *);
758
759 struct wg_ops {
760 int (*send_hs_msg)(struct wg_peer *, struct mbuf *);
761 int (*send_data_msg)(struct wg_peer *, struct mbuf *);
762 void (*input)(struct ifnet *, struct mbuf *, const int);
763 int (*bind_port)(struct wg_softc *, const uint16_t);
764 };
765
766 struct wg_ops wg_ops_rumpkernel = {
767 .send_hs_msg = wg_send_so,
768 .send_data_msg = wg_send_udp,
769 .input = wg_input,
770 .bind_port = wg_bind_port,
771 };
772
773 #ifdef WG_RUMPKERNEL
774 static bool wg_user_mode(struct wg_softc *);
775 static int wg_ioctl_linkstr(struct wg_softc *, struct ifdrv *);
776
777 static int wg_send_user(struct wg_peer *, struct mbuf *);
778 static void wg_input_user(struct ifnet *, struct mbuf *, const int);
779 static int wg_bind_port_user(struct wg_softc *, const uint16_t);
780
781 struct wg_ops wg_ops_rumpuser = {
782 .send_hs_msg = wg_send_user,
783 .send_data_msg = wg_send_user,
784 .input = wg_input_user,
785 .bind_port = wg_bind_port_user,
786 };
787 #endif
788
789 #define WG_PEER_READER_FOREACH(wgp, wg) \
790 PSLIST_READER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \
791 wgp_peerlist_entry)
792 #define WG_PEER_WRITER_FOREACH(wgp, wg) \
793 PSLIST_WRITER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \
794 wgp_peerlist_entry)
795 #define WG_PEER_WRITER_INSERT_HEAD(wgp, wg) \
796 PSLIST_WRITER_INSERT_HEAD(&(wg)->wg_peers, (wgp), wgp_peerlist_entry)
797 #define WG_PEER_WRITER_REMOVE(wgp) \
798 PSLIST_WRITER_REMOVE((wgp), wgp_peerlist_entry)
799
800 struct wg_route {
801 struct radix_node wgr_nodes[2];
802 struct wg_peer *wgr_peer;
803 };
804
805 static struct radix_node_head *
806 wg_rnh(struct wg_softc *wg, const int family)
807 {
808
809 switch (family) {
810 case AF_INET:
811 return wg->wg_rtable_ipv4;
812 #ifdef INET6
813 case AF_INET6:
814 return wg->wg_rtable_ipv6;
815 #endif
816 default:
817 return NULL;
818 }
819 }
820
821
822 /*
823 * Global variables
824 */
825 static volatile unsigned wg_count __cacheline_aligned;
826
827 struct psref_class *wg_psref_class __read_mostly;
828
829 static struct if_clone wg_cloner =
830 IF_CLONE_INITIALIZER("wg", wg_clone_create, wg_clone_destroy);
831
832 static struct pktqueue *wg_pktq __read_mostly;
833 static struct workqueue *wg_wq __read_mostly;
834
835 void wgattach(int);
836 /* ARGSUSED */
837 void
838 wgattach(int count)
839 {
840 /*
841 * Nothing to do here, initialization is handled by the
842 * module initialization code in wginit() below).
843 */
844 }
845
846 static void
847 wginit(void)
848 {
849
850 wg_psref_class = psref_class_create("wg", IPL_SOFTNET);
851
852 if_clone_attach(&wg_cloner);
853 }
854
855 /*
856 * XXX Kludge: This should just happen in wginit, but workqueue_create
857 * cannot be run until after CPUs have been detected, and wginit runs
858 * before configure.
859 */
860 static int
861 wginitqueues(void)
862 {
863 int error __diagused;
864
865 wg_pktq = pktq_create(IFQ_MAXLEN, wgintr, NULL);
866 KASSERT(wg_pktq != NULL);
867
868 error = workqueue_create(&wg_wq, "wgpeer", wg_peer_work, NULL,
869 PRI_NONE, IPL_SOFTNET, WQ_MPSAFE|WQ_PERCPU);
870 KASSERT(error == 0);
871
872 return 0;
873 }
874
875 static void
876 wg_guarantee_initialized(void)
877 {
878 static ONCE_DECL(init);
879 int error __diagused;
880
881 error = RUN_ONCE(&init, wginitqueues);
882 KASSERT(error == 0);
883 }
884
885 static int
886 wg_count_inc(void)
887 {
888 unsigned o, n;
889
890 do {
891 o = atomic_load_relaxed(&wg_count);
892 if (o == UINT_MAX)
893 return ENFILE;
894 n = o + 1;
895 } while (atomic_cas_uint(&wg_count, o, n) != o);
896
897 return 0;
898 }
899
900 static void
901 wg_count_dec(void)
902 {
903 unsigned c __diagused;
904
905 c = atomic_dec_uint_nv(&wg_count);
906 KASSERT(c != UINT_MAX);
907 }
908
909 static int
910 wgdetach(void)
911 {
912
913 /* Prevent new interface creation. */
914 if_clone_detach(&wg_cloner);
915
916 /* Check whether there are any existing interfaces. */
917 if (atomic_load_relaxed(&wg_count)) {
918 /* Back out -- reattach the cloner. */
919 if_clone_attach(&wg_cloner);
920 return EBUSY;
921 }
922
923 /* No interfaces left. Nuke it. */
924 workqueue_destroy(wg_wq);
925 pktq_destroy(wg_pktq);
926 psref_class_destroy(wg_psref_class);
927
928 return 0;
929 }
930
931 static void
932 wg_init_key_and_hash(uint8_t ckey[WG_CHAINING_KEY_LEN],
933 uint8_t hash[WG_HASH_LEN])
934 {
935 /* [W] 5.4: CONSTRUCTION */
936 const char *signature = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
937 /* [W] 5.4: IDENTIFIER */
938 const char *id = "WireGuard v1 zx2c4 Jason (at) zx2c4.com";
939 struct blake2s state;
940
941 blake2s(ckey, WG_CHAINING_KEY_LEN, NULL, 0,
942 signature, strlen(signature));
943
944 CTASSERT(WG_HASH_LEN == WG_CHAINING_KEY_LEN);
945 memcpy(hash, ckey, WG_CHAINING_KEY_LEN);
946
947 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
948 blake2s_update(&state, ckey, WG_CHAINING_KEY_LEN);
949 blake2s_update(&state, id, strlen(id));
950 blake2s_final(&state, hash);
951
952 WG_DUMP_HASH("ckey", ckey);
953 WG_DUMP_HASH("hash", hash);
954 }
955
956 static void
957 wg_algo_hash(uint8_t hash[WG_HASH_LEN], const uint8_t input[],
958 const size_t inputsize)
959 {
960 struct blake2s state;
961
962 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
963 blake2s_update(&state, hash, WG_HASH_LEN);
964 blake2s_update(&state, input, inputsize);
965 blake2s_final(&state, hash);
966 }
967
968 static void
969 wg_algo_mac(uint8_t out[], const size_t outsize,
970 const uint8_t key[], const size_t keylen,
971 const uint8_t input1[], const size_t input1len,
972 const uint8_t input2[], const size_t input2len)
973 {
974 struct blake2s state;
975
976 blake2s_init(&state, outsize, key, keylen);
977
978 blake2s_update(&state, input1, input1len);
979 if (input2 != NULL)
980 blake2s_update(&state, input2, input2len);
981 blake2s_final(&state, out);
982 }
983
984 static void
985 wg_algo_mac_mac1(uint8_t out[], const size_t outsize,
986 const uint8_t input1[], const size_t input1len,
987 const uint8_t input2[], const size_t input2len)
988 {
989 struct blake2s state;
990 /* [W] 5.4: LABEL-MAC1 */
991 const char *label = "mac1----";
992 uint8_t key[WG_HASH_LEN];
993
994 blake2s_init(&state, sizeof(key), NULL, 0);
995 blake2s_update(&state, label, strlen(label));
996 blake2s_update(&state, input1, input1len);
997 blake2s_final(&state, key);
998
999 blake2s_init(&state, outsize, key, sizeof(key));
1000 if (input2 != NULL)
1001 blake2s_update(&state, input2, input2len);
1002 blake2s_final(&state, out);
1003 }
1004
1005 static void
1006 wg_algo_mac_cookie(uint8_t out[], const size_t outsize,
1007 const uint8_t input1[], const size_t input1len)
1008 {
1009 struct blake2s state;
1010 /* [W] 5.4: LABEL-COOKIE */
1011 const char *label = "cookie--";
1012
1013 blake2s_init(&state, outsize, NULL, 0);
1014 blake2s_update(&state, label, strlen(label));
1015 blake2s_update(&state, input1, input1len);
1016 blake2s_final(&state, out);
1017 }
1018
1019 static void
1020 wg_algo_generate_keypair(uint8_t pubkey[WG_EPHEMERAL_KEY_LEN],
1021 uint8_t privkey[WG_EPHEMERAL_KEY_LEN])
1022 {
1023
1024 CTASSERT(WG_EPHEMERAL_KEY_LEN == crypto_scalarmult_curve25519_BYTES);
1025
1026 cprng_strong(kern_cprng, privkey, WG_EPHEMERAL_KEY_LEN, 0);
1027 crypto_scalarmult_base(pubkey, privkey);
1028 }
1029
1030 static void
1031 wg_algo_dh(uint8_t out[WG_DH_OUTPUT_LEN],
1032 const uint8_t privkey[WG_STATIC_KEY_LEN],
1033 const uint8_t pubkey[WG_STATIC_KEY_LEN])
1034 {
1035
1036 CTASSERT(WG_STATIC_KEY_LEN == crypto_scalarmult_curve25519_BYTES);
1037
1038 int ret __diagused = crypto_scalarmult(out, privkey, pubkey);
1039 KASSERT(ret == 0);
1040 }
1041
1042 static void
1043 wg_algo_hmac(uint8_t out[], const size_t outlen,
1044 const uint8_t key[], const size_t keylen,
1045 const uint8_t in[], const size_t inlen)
1046 {
1047 #define IPAD 0x36
1048 #define OPAD 0x5c
1049 uint8_t hmackey[HMAC_BLOCK_LEN] = {0};
1050 uint8_t ipad[HMAC_BLOCK_LEN];
1051 uint8_t opad[HMAC_BLOCK_LEN];
1052 size_t i;
1053 struct blake2s state;
1054
1055 KASSERT(outlen == WG_HASH_LEN);
1056 KASSERT(keylen <= HMAC_BLOCK_LEN);
1057
1058 memcpy(hmackey, key, keylen);
1059
1060 for (i = 0; i < sizeof(hmackey); i++) {
1061 ipad[i] = hmackey[i] ^ IPAD;
1062 opad[i] = hmackey[i] ^ OPAD;
1063 }
1064
1065 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
1066 blake2s_update(&state, ipad, sizeof(ipad));
1067 blake2s_update(&state, in, inlen);
1068 blake2s_final(&state, out);
1069
1070 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
1071 blake2s_update(&state, opad, sizeof(opad));
1072 blake2s_update(&state, out, WG_HASH_LEN);
1073 blake2s_final(&state, out);
1074 #undef IPAD
1075 #undef OPAD
1076 }
1077
1078 static void
1079 wg_algo_kdf(uint8_t out1[WG_KDF_OUTPUT_LEN], uint8_t out2[WG_KDF_OUTPUT_LEN],
1080 uint8_t out3[WG_KDF_OUTPUT_LEN], const uint8_t ckey[WG_CHAINING_KEY_LEN],
1081 const uint8_t input[], const size_t inputlen)
1082 {
1083 uint8_t tmp1[WG_KDF_OUTPUT_LEN], tmp2[WG_KDF_OUTPUT_LEN + 1];
1084 uint8_t one[1];
1085
1086 /*
1087 * [N] 4.3: "an input_key_material byte sequence with length
1088 * either zero bytes, 32 bytes, or DHLEN bytes."
1089 */
1090 KASSERT(inputlen == 0 || inputlen == 32 || inputlen == NOISE_DHLEN);
1091
1092 WG_DUMP_HASH("ckey", ckey);
1093 if (input != NULL)
1094 WG_DUMP_HASH("input", input);
1095 wg_algo_hmac(tmp1, sizeof(tmp1), ckey, WG_CHAINING_KEY_LEN,
1096 input, inputlen);
1097 WG_DUMP_HASH("tmp1", tmp1);
1098 one[0] = 1;
1099 wg_algo_hmac(out1, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
1100 one, sizeof(one));
1101 WG_DUMP_HASH("out1", out1);
1102 if (out2 == NULL)
1103 return;
1104 memcpy(tmp2, out1, WG_KDF_OUTPUT_LEN);
1105 tmp2[WG_KDF_OUTPUT_LEN] = 2;
1106 wg_algo_hmac(out2, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
1107 tmp2, sizeof(tmp2));
1108 WG_DUMP_HASH("out2", out2);
1109 if (out3 == NULL)
1110 return;
1111 memcpy(tmp2, out2, WG_KDF_OUTPUT_LEN);
1112 tmp2[WG_KDF_OUTPUT_LEN] = 3;
1113 wg_algo_hmac(out3, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
1114 tmp2, sizeof(tmp2));
1115 WG_DUMP_HASH("out3", out3);
1116 }
1117
1118 static void __noinline
1119 wg_algo_dh_kdf(uint8_t ckey[WG_CHAINING_KEY_LEN],
1120 uint8_t cipher_key[WG_CIPHER_KEY_LEN],
1121 const uint8_t local_key[WG_STATIC_KEY_LEN],
1122 const uint8_t remote_key[WG_STATIC_KEY_LEN])
1123 {
1124 uint8_t dhout[WG_DH_OUTPUT_LEN];
1125
1126 wg_algo_dh(dhout, local_key, remote_key);
1127 wg_algo_kdf(ckey, cipher_key, NULL, ckey, dhout, sizeof(dhout));
1128
1129 WG_DUMP_HASH("dhout", dhout);
1130 WG_DUMP_HASH("ckey", ckey);
1131 if (cipher_key != NULL)
1132 WG_DUMP_HASH("cipher_key", cipher_key);
1133 }
1134
1135 static void
1136 wg_algo_aead_enc(uint8_t out[], size_t expected_outsize, const uint8_t key[],
1137 const uint64_t counter, const uint8_t plain[], const size_t plainsize,
1138 const uint8_t auth[], size_t authlen)
1139 {
1140 uint8_t nonce[(32 + 64) / 8] = {0};
1141 long long unsigned int outsize;
1142 int error __diagused;
1143
1144 le64enc(&nonce[4], counter);
1145
1146 error = crypto_aead_chacha20poly1305_ietf_encrypt(out, &outsize, plain,
1147 plainsize, auth, authlen, NULL, nonce, key);
1148 KASSERT(error == 0);
1149 KASSERT(outsize == expected_outsize);
1150 }
1151
1152 static int
1153 wg_algo_aead_dec(uint8_t out[], size_t expected_outsize, const uint8_t key[],
1154 const uint64_t counter, const uint8_t encrypted[],
1155 const size_t encryptedsize, const uint8_t auth[], size_t authlen)
1156 {
1157 uint8_t nonce[(32 + 64) / 8] = {0};
1158 long long unsigned int outsize;
1159 int error;
1160
1161 le64enc(&nonce[4], counter);
1162
1163 error = crypto_aead_chacha20poly1305_ietf_decrypt(out, &outsize, NULL,
1164 encrypted, encryptedsize, auth, authlen, nonce, key);
1165 if (error == 0)
1166 KASSERT(outsize == expected_outsize);
1167 return error;
1168 }
1169
1170 static void
1171 wg_algo_xaead_enc(uint8_t out[], const size_t expected_outsize,
1172 const uint8_t key[], const uint8_t plain[], const size_t plainsize,
1173 const uint8_t auth[], size_t authlen,
1174 const uint8_t nonce[WG_SALT_LEN])
1175 {
1176 long long unsigned int outsize;
1177 int error __diagused;
1178
1179 CTASSERT(WG_SALT_LEN == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
1180 error = crypto_aead_xchacha20poly1305_ietf_encrypt(out, &outsize,
1181 plain, plainsize, auth, authlen, NULL, nonce, key);
1182 KASSERT(error == 0);
1183 KASSERT(outsize == expected_outsize);
1184 }
1185
1186 static int
1187 wg_algo_xaead_dec(uint8_t out[], const size_t expected_outsize,
1188 const uint8_t key[], const uint8_t encrypted[], const size_t encryptedsize,
1189 const uint8_t auth[], size_t authlen,
1190 const uint8_t nonce[WG_SALT_LEN])
1191 {
1192 long long unsigned int outsize;
1193 int error;
1194
1195 error = crypto_aead_xchacha20poly1305_ietf_decrypt(out, &outsize, NULL,
1196 encrypted, encryptedsize, auth, authlen, nonce, key);
1197 if (error == 0)
1198 KASSERT(outsize == expected_outsize);
1199 return error;
1200 }
1201
1202 static void
1203 wg_algo_tai64n(wg_timestamp_t timestamp)
1204 {
1205 struct timespec ts;
1206
1207 /* FIXME strict TAI64N (https://cr.yp.to/libtai/tai64.html) */
1208 getnanotime(&ts);
1209 /* TAI64 label in external TAI64 format */
1210 be32enc(timestamp, 0x40000000U + (uint32_t)(ts.tv_sec >> 32));
1211 /* second beginning from 1970 TAI */
1212 be32enc(timestamp + 4, (uint32_t)(ts.tv_sec & 0xffffffffU));
1213 /* nanosecond in big-endian format */
1214 be32enc(timestamp + 8, (uint32_t)ts.tv_nsec);
1215 }
1216
1217 /*
1218 * wg_get_stable_session(wgp, psref)
1219 *
1220 * Get a passive reference to the current stable session, or
1221 * return NULL if there is no current stable session.
1222 *
1223 * The pointer is always there but the session is not necessarily
1224 * ESTABLISHED; if it is not ESTABLISHED, return NULL. However,
1225 * the session may transition from ESTABLISHED to DESTROYING while
1226 * holding the passive reference.
1227 */
1228 static struct wg_session *
1229 wg_get_stable_session(struct wg_peer *wgp, struct psref *psref)
1230 {
1231 int s;
1232 struct wg_session *wgs;
1233
1234 s = pserialize_read_enter();
1235 wgs = atomic_load_consume(&wgp->wgp_session_stable);
1236 if (__predict_false(wgs->wgs_state != WGS_STATE_ESTABLISHED))
1237 wgs = NULL;
1238 else
1239 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class);
1240 pserialize_read_exit(s);
1241
1242 return wgs;
1243 }
1244
1245 static void
1246 wg_put_session(struct wg_session *wgs, struct psref *psref)
1247 {
1248
1249 psref_release(psref, &wgs->wgs_psref, wg_psref_class);
1250 }
1251
1252 static void
1253 wg_destroy_session(struct wg_softc *wg, struct wg_session *wgs)
1254 {
1255 struct wg_peer *wgp = wgs->wgs_peer;
1256 struct wg_session *wgs0 __diagused;
1257 void *garbage;
1258
1259 KASSERT(mutex_owned(wgp->wgp_lock));
1260 KASSERT(wgs->wgs_state != WGS_STATE_UNKNOWN);
1261
1262 /* Remove the session from the table. */
1263 wgs0 = thmap_del(wg->wg_sessions_byindex,
1264 &wgs->wgs_local_index, sizeof(wgs->wgs_local_index));
1265 KASSERT(wgs0 == wgs);
1266 garbage = thmap_stage_gc(wg->wg_sessions_byindex);
1267
1268 /* Wait for passive references to drain. */
1269 pserialize_perform(wgp->wgp_psz);
1270 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
1271
1272 /* Free memory, zero state, and transition to UNKNOWN. */
1273 thmap_gc(wg->wg_sessions_byindex, garbage);
1274 wg_clear_states(wgs);
1275 wgs->wgs_state = WGS_STATE_UNKNOWN;
1276 }
1277
1278 /*
1279 * wg_get_session_index(wg, wgs)
1280 *
1281 * Choose a session index for wgs->wgs_local_index, and store it
1282 * in wg's table of sessions by index.
1283 *
1284 * wgs must be the unstable session of its peer, and must be
1285 * transitioning out of the UNKNOWN state.
1286 */
1287 static void
1288 wg_get_session_index(struct wg_softc *wg, struct wg_session *wgs)
1289 {
1290 struct wg_peer *wgp __diagused = wgs->wgs_peer;
1291 struct wg_session *wgs0;
1292 uint32_t index;
1293
1294 KASSERT(mutex_owned(wgp->wgp_lock));
1295 KASSERT(wgs == wgp->wgp_session_unstable);
1296 KASSERT(wgs->wgs_state == WGS_STATE_UNKNOWN);
1297
1298 do {
1299 /* Pick a uniform random index. */
1300 index = cprng_strong32();
1301
1302 /* Try to take it. */
1303 wgs->wgs_local_index = index;
1304 wgs0 = thmap_put(wg->wg_sessions_byindex,
1305 &wgs->wgs_local_index, sizeof wgs->wgs_local_index, wgs);
1306
1307 /* If someone else beat us, start over. */
1308 } while (__predict_false(wgs0 != wgs));
1309 }
1310
1311 /*
1312 * wg_put_session_index(wg, wgs)
1313 *
1314 * Remove wgs from the table of sessions by index, wait for any
1315 * passive references to drain, and transition the session to the
1316 * UNKNOWN state.
1317 *
1318 * wgs must be the unstable session of its peer, and must not be
1319 * UNKNOWN or ESTABLISHED.
1320 */
1321 static void
1322 wg_put_session_index(struct wg_softc *wg, struct wg_session *wgs)
1323 {
1324 struct wg_peer *wgp __diagused = wgs->wgs_peer;
1325
1326 KASSERT(mutex_owned(wgp->wgp_lock));
1327 KASSERT(wgs == wgp->wgp_session_unstable);
1328 KASSERT(wgs->wgs_state != WGS_STATE_UNKNOWN);
1329 KASSERT(wgs->wgs_state != WGS_STATE_ESTABLISHED);
1330
1331 wg_destroy_session(wg, wgs);
1332 psref_target_init(&wgs->wgs_psref, wg_psref_class);
1333 }
1334
1335 /*
1336 * Handshake patterns
1337 *
1338 * [W] 5: "These messages use the "IK" pattern from Noise"
1339 * [N] 7.5. Interactive handshake patterns (fundamental)
1340 * "The first character refers to the initiators static key:"
1341 * "I = Static key for initiator Immediately transmitted to responder,
1342 * despite reduced or absent identity hiding"
1343 * "The second character refers to the responders static key:"
1344 * "K = Static key for responder Known to initiator"
1345 * "IK:
1346 * <- s
1347 * ...
1348 * -> e, es, s, ss
1349 * <- e, ee, se"
1350 * [N] 9.4. Pattern modifiers
1351 * "IKpsk2:
1352 * <- s
1353 * ...
1354 * -> e, es, s, ss
1355 * <- e, ee, se, psk"
1356 */
1357 static void
1358 wg_fill_msg_init(struct wg_softc *wg, struct wg_peer *wgp,
1359 struct wg_session *wgs, struct wg_msg_init *wgmi)
1360 {
1361 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.2: Ci */
1362 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.2: Hi */
1363 uint8_t cipher_key[WG_CIPHER_KEY_LEN];
1364 uint8_t pubkey[WG_EPHEMERAL_KEY_LEN];
1365 uint8_t privkey[WG_EPHEMERAL_KEY_LEN];
1366
1367 KASSERT(mutex_owned(wgp->wgp_lock));
1368 KASSERT(wgs == wgp->wgp_session_unstable);
1369 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE);
1370
1371 wgmi->wgmi_type = htole32(WG_MSG_TYPE_INIT);
1372 wgmi->wgmi_sender = wgs->wgs_local_index;
1373
1374 /* [W] 5.4.2: First Message: Initiator to Responder */
1375
1376 /* Ci := HASH(CONSTRUCTION) */
1377 /* Hi := HASH(Ci || IDENTIFIER) */
1378 wg_init_key_and_hash(ckey, hash);
1379 /* Hi := HASH(Hi || Sr^pub) */
1380 wg_algo_hash(hash, wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey));
1381
1382 WG_DUMP_HASH("hash", hash);
1383
1384 /* [N] 2.2: "e" */
1385 /* Ei^priv, Ei^pub := DH-GENERATE() */
1386 wg_algo_generate_keypair(pubkey, privkey);
1387 /* Ci := KDF1(Ci, Ei^pub) */
1388 wg_algo_kdf(ckey, NULL, NULL, ckey, pubkey, sizeof(pubkey));
1389 /* msg.ephemeral := Ei^pub */
1390 memcpy(wgmi->wgmi_ephemeral, pubkey, sizeof(wgmi->wgmi_ephemeral));
1391 /* Hi := HASH(Hi || msg.ephemeral) */
1392 wg_algo_hash(hash, pubkey, sizeof(pubkey));
1393
1394 WG_DUMP_HASH("ckey", ckey);
1395 WG_DUMP_HASH("hash", hash);
1396
1397 /* [N] 2.2: "es" */
1398 /* Ci, k := KDF2(Ci, DH(Ei^priv, Sr^pub)) */
1399 wg_algo_dh_kdf(ckey, cipher_key, privkey, wgp->wgp_pubkey);
1400
1401 /* [N] 2.2: "s" */
1402 /* msg.static := AEAD(k, 0, Si^pub, Hi) */
1403 wg_algo_aead_enc(wgmi->wgmi_static, sizeof(wgmi->wgmi_static),
1404 cipher_key, 0, wg->wg_pubkey, sizeof(wg->wg_pubkey),
1405 hash, sizeof(hash));
1406 /* Hi := HASH(Hi || msg.static) */
1407 wg_algo_hash(hash, wgmi->wgmi_static, sizeof(wgmi->wgmi_static));
1408
1409 WG_DUMP_HASH48("wgmi_static", wgmi->wgmi_static);
1410
1411 /* [N] 2.2: "ss" */
1412 /* Ci, k := KDF2(Ci, DH(Si^priv, Sr^pub)) */
1413 wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey);
1414
1415 /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */
1416 wg_timestamp_t timestamp;
1417 wg_algo_tai64n(timestamp);
1418 wg_algo_aead_enc(wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp),
1419 cipher_key, 0, timestamp, sizeof(timestamp), hash, sizeof(hash));
1420 /* Hi := HASH(Hi || msg.timestamp) */
1421 wg_algo_hash(hash, wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp));
1422
1423 /* [W] 5.4.4 Cookie MACs */
1424 wg_algo_mac_mac1(wgmi->wgmi_mac1, sizeof(wgmi->wgmi_mac1),
1425 wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey),
1426 (const uint8_t *)wgmi, offsetof(struct wg_msg_init, wgmi_mac1));
1427 /* Need mac1 to decrypt a cookie from a cookie message */
1428 memcpy(wgp->wgp_last_sent_mac1, wgmi->wgmi_mac1,
1429 sizeof(wgp->wgp_last_sent_mac1));
1430 wgp->wgp_last_sent_mac1_valid = true;
1431
1432 if (wgp->wgp_latest_cookie_time == 0 ||
1433 (time_uptime - wgp->wgp_latest_cookie_time) >= WG_COOKIE_TIME)
1434 memset(wgmi->wgmi_mac2, 0, sizeof(wgmi->wgmi_mac2));
1435 else {
1436 wg_algo_mac(wgmi->wgmi_mac2, sizeof(wgmi->wgmi_mac2),
1437 wgp->wgp_latest_cookie, WG_COOKIE_LEN,
1438 (const uint8_t *)wgmi,
1439 offsetof(struct wg_msg_init, wgmi_mac2),
1440 NULL, 0);
1441 }
1442
1443 memcpy(wgs->wgs_ephemeral_key_pub, pubkey, sizeof(pubkey));
1444 memcpy(wgs->wgs_ephemeral_key_priv, privkey, sizeof(privkey));
1445 memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash));
1446 memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey));
1447 WG_DLOG("%s: sender=%x\n", __func__, wgs->wgs_local_index);
1448 }
1449
1450 static void __noinline
1451 wg_handle_msg_init(struct wg_softc *wg, const struct wg_msg_init *wgmi,
1452 const struct sockaddr *src)
1453 {
1454 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.2: Ci */
1455 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.2: Hi */
1456 uint8_t cipher_key[WG_CIPHER_KEY_LEN];
1457 uint8_t peer_pubkey[WG_STATIC_KEY_LEN];
1458 struct wg_peer *wgp;
1459 struct wg_session *wgs;
1460 int error, ret;
1461 struct psref psref_peer;
1462 uint8_t mac1[WG_MAC_LEN];
1463
1464 WG_TRACE("init msg received");
1465
1466 wg_algo_mac_mac1(mac1, sizeof(mac1),
1467 wg->wg_pubkey, sizeof(wg->wg_pubkey),
1468 (const uint8_t *)wgmi, offsetof(struct wg_msg_init, wgmi_mac1));
1469
1470 /*
1471 * [W] 5.3: Denial of Service Mitigation & Cookies
1472 * "the responder, ..., must always reject messages with an invalid
1473 * msg.mac1"
1474 */
1475 if (!consttime_memequal(mac1, wgmi->wgmi_mac1, sizeof(mac1))) {
1476 WG_DLOG("mac1 is invalid\n");
1477 return;
1478 }
1479
1480 /*
1481 * [W] 5.4.2: First Message: Initiator to Responder
1482 * "When the responder receives this message, it does the same
1483 * operations so that its final state variables are identical,
1484 * replacing the operands of the DH function to produce equivalent
1485 * values."
1486 * Note that the following comments of operations are just copies of
1487 * the initiator's ones.
1488 */
1489
1490 /* Ci := HASH(CONSTRUCTION) */
1491 /* Hi := HASH(Ci || IDENTIFIER) */
1492 wg_init_key_and_hash(ckey, hash);
1493 /* Hi := HASH(Hi || Sr^pub) */
1494 wg_algo_hash(hash, wg->wg_pubkey, sizeof(wg->wg_pubkey));
1495
1496 /* [N] 2.2: "e" */
1497 /* Ci := KDF1(Ci, Ei^pub) */
1498 wg_algo_kdf(ckey, NULL, NULL, ckey, wgmi->wgmi_ephemeral,
1499 sizeof(wgmi->wgmi_ephemeral));
1500 /* Hi := HASH(Hi || msg.ephemeral) */
1501 wg_algo_hash(hash, wgmi->wgmi_ephemeral, sizeof(wgmi->wgmi_ephemeral));
1502
1503 WG_DUMP_HASH("ckey", ckey);
1504
1505 /* [N] 2.2: "es" */
1506 /* Ci, k := KDF2(Ci, DH(Ei^priv, Sr^pub)) */
1507 wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgmi->wgmi_ephemeral);
1508
1509 WG_DUMP_HASH48("wgmi_static", wgmi->wgmi_static);
1510
1511 /* [N] 2.2: "s" */
1512 /* msg.static := AEAD(k, 0, Si^pub, Hi) */
1513 error = wg_algo_aead_dec(peer_pubkey, WG_STATIC_KEY_LEN, cipher_key, 0,
1514 wgmi->wgmi_static, sizeof(wgmi->wgmi_static), hash, sizeof(hash));
1515 if (error != 0) {
1516 WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG,
1517 "%s: wg_algo_aead_dec for secret key failed\n",
1518 if_name(&wg->wg_if));
1519 return;
1520 }
1521 /* Hi := HASH(Hi || msg.static) */
1522 wg_algo_hash(hash, wgmi->wgmi_static, sizeof(wgmi->wgmi_static));
1523
1524 wgp = wg_lookup_peer_by_pubkey(wg, peer_pubkey, &psref_peer);
1525 if (wgp == NULL) {
1526 WG_DLOG("peer not found\n");
1527 return;
1528 }
1529
1530 /*
1531 * Lock the peer to serialize access to cookie state.
1532 *
1533 * XXX Can we safely avoid holding the lock across DH? Take it
1534 * just to verify mac2 and then unlock/DH/lock?
1535 */
1536 mutex_enter(wgp->wgp_lock);
1537
1538 if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_INIT))) {
1539 WG_TRACE("under load");
1540 /*
1541 * [W] 5.3: Denial of Service Mitigation & Cookies
1542 * "the responder, ..., and when under load may reject messages
1543 * with an invalid msg.mac2. If the responder receives a
1544 * message with a valid msg.mac1 yet with an invalid msg.mac2,
1545 * and is under load, it may respond with a cookie reply
1546 * message"
1547 */
1548 uint8_t zero[WG_MAC_LEN] = {0};
1549 if (consttime_memequal(wgmi->wgmi_mac2, zero, sizeof(zero))) {
1550 WG_TRACE("sending a cookie message: no cookie included");
1551 (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender,
1552 wgmi->wgmi_mac1, src);
1553 goto out;
1554 }
1555 if (!wgp->wgp_last_sent_cookie_valid) {
1556 WG_TRACE("sending a cookie message: no cookie sent ever");
1557 (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender,
1558 wgmi->wgmi_mac1, src);
1559 goto out;
1560 }
1561 uint8_t mac2[WG_MAC_LEN];
1562 wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie,
1563 WG_COOKIE_LEN, (const uint8_t *)wgmi,
1564 offsetof(struct wg_msg_init, wgmi_mac2), NULL, 0);
1565 if (!consttime_memequal(mac2, wgmi->wgmi_mac2, sizeof(mac2))) {
1566 WG_DLOG("mac2 is invalid\n");
1567 goto out;
1568 }
1569 WG_TRACE("under load, but continue to sending");
1570 }
1571
1572 /* [N] 2.2: "ss" */
1573 /* Ci, k := KDF2(Ci, DH(Si^priv, Sr^pub)) */
1574 wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey);
1575
1576 /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */
1577 wg_timestamp_t timestamp;
1578 error = wg_algo_aead_dec(timestamp, sizeof(timestamp), cipher_key, 0,
1579 wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp),
1580 hash, sizeof(hash));
1581 if (error != 0) {
1582 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
1583 "%s: peer %s: wg_algo_aead_dec for timestamp failed\n",
1584 if_name(&wg->wg_if), wgp->wgp_name);
1585 goto out;
1586 }
1587 /* Hi := HASH(Hi || msg.timestamp) */
1588 wg_algo_hash(hash, wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp));
1589
1590 /*
1591 * [W] 5.1 "The responder keeps track of the greatest timestamp
1592 * received per peer and discards packets containing
1593 * timestamps less than or equal to it."
1594 */
1595 ret = memcmp(timestamp, wgp->wgp_timestamp_latest_init,
1596 sizeof(timestamp));
1597 if (ret <= 0) {
1598 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
1599 "%s: peer %s: invalid init msg: timestamp is old\n",
1600 if_name(&wg->wg_if), wgp->wgp_name);
1601 goto out;
1602 }
1603 memcpy(wgp->wgp_timestamp_latest_init, timestamp, sizeof(timestamp));
1604
1605 /*
1606 * Message is good -- we're committing to handle it now, unless
1607 * we were already initiating a session.
1608 */
1609 wgs = wgp->wgp_session_unstable;
1610 switch (wgs->wgs_state) {
1611 case WGS_STATE_UNKNOWN: /* new session initiated by peer */
1612 wg_get_session_index(wg, wgs);
1613 break;
1614 case WGS_STATE_INIT_ACTIVE: /* we're already initiating, drop */
1615 WG_TRACE("Session already initializing, ignoring the message");
1616 goto out;
1617 case WGS_STATE_INIT_PASSIVE: /* peer is retrying, start over */
1618 WG_TRACE("Session already initializing, destroying old states");
1619 wg_clear_states(wgs);
1620 /* keep session index */
1621 break;
1622 case WGS_STATE_ESTABLISHED: /* can't happen */
1623 panic("unstable session can't be established");
1624 break;
1625 case WGS_STATE_DESTROYING: /* rekey initiated by peer */
1626 WG_TRACE("Session destroying, but force to clear");
1627 callout_stop(&wgp->wgp_session_dtor_timer);
1628 wg_clear_states(wgs);
1629 /* keep session index */
1630 break;
1631 default:
1632 panic("invalid session state: %d", wgs->wgs_state);
1633 }
1634 wgs->wgs_state = WGS_STATE_INIT_PASSIVE;
1635
1636 memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash));
1637 memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey));
1638 memcpy(wgs->wgs_ephemeral_key_peer, wgmi->wgmi_ephemeral,
1639 sizeof(wgmi->wgmi_ephemeral));
1640
1641 wg_update_endpoint_if_necessary(wgp, src);
1642
1643 (void)wg_send_handshake_msg_resp(wg, wgp, wgs, wgmi);
1644
1645 wg_calculate_keys(wgs, false);
1646 wg_clear_states(wgs);
1647
1648 out:
1649 mutex_exit(wgp->wgp_lock);
1650 wg_put_peer(wgp, &psref_peer);
1651 }
1652
1653 static struct socket *
1654 wg_get_so_by_af(struct wg_softc *wg, const int af)
1655 {
1656
1657 switch (af) {
1658 #ifdef INET
1659 case AF_INET:
1660 return wg->wg_so4;
1661 #endif
1662 #ifdef INET6
1663 case AF_INET6:
1664 return wg->wg_so6;
1665 #endif
1666 default:
1667 panic("wg: no such af: %d", af);
1668 }
1669 }
1670
1671 static struct socket *
1672 wg_get_so_by_peer(struct wg_peer *wgp, struct wg_sockaddr *wgsa)
1673 {
1674
1675 return wg_get_so_by_af(wgp->wgp_sc, wgsa_family(wgsa));
1676 }
1677
1678 static struct wg_sockaddr *
1679 wg_get_endpoint_sa(struct wg_peer *wgp, struct psref *psref)
1680 {
1681 struct wg_sockaddr *wgsa;
1682 int s;
1683
1684 s = pserialize_read_enter();
1685 wgsa = atomic_load_consume(&wgp->wgp_endpoint);
1686 psref_acquire(psref, &wgsa->wgsa_psref, wg_psref_class);
1687 pserialize_read_exit(s);
1688
1689 return wgsa;
1690 }
1691
1692 static void
1693 wg_put_sa(struct wg_peer *wgp, struct wg_sockaddr *wgsa, struct psref *psref)
1694 {
1695
1696 psref_release(psref, &wgsa->wgsa_psref, wg_psref_class);
1697 }
1698
1699 static int
1700 wg_send_so(struct wg_peer *wgp, struct mbuf *m)
1701 {
1702 int error;
1703 struct socket *so;
1704 struct psref psref;
1705 struct wg_sockaddr *wgsa;
1706
1707 wgsa = wg_get_endpoint_sa(wgp, &psref);
1708 so = wg_get_so_by_peer(wgp, wgsa);
1709 error = sosend(so, wgsatosa(wgsa), NULL, m, NULL, 0, curlwp);
1710 wg_put_sa(wgp, wgsa, &psref);
1711
1712 return error;
1713 }
1714
1715 static int
1716 wg_send_handshake_msg_init(struct wg_softc *wg, struct wg_peer *wgp)
1717 {
1718 int error;
1719 struct mbuf *m;
1720 struct wg_msg_init *wgmi;
1721 struct wg_session *wgs;
1722
1723 KASSERT(mutex_owned(wgp->wgp_lock));
1724
1725 wgs = wgp->wgp_session_unstable;
1726 /* XXX pull dispatch out into wg_task_send_init_message */
1727 switch (wgs->wgs_state) {
1728 case WGS_STATE_UNKNOWN: /* new session initiated by us */
1729 wg_get_session_index(wg, wgs);
1730 break;
1731 case WGS_STATE_INIT_ACTIVE: /* we're already initiating, stop */
1732 WG_TRACE("Session already initializing, skip starting new one");
1733 return EBUSY;
1734 case WGS_STATE_INIT_PASSIVE: /* peer was trying -- XXX what now? */
1735 WG_TRACE("Session already initializing, destroying old states");
1736 wg_clear_states(wgs);
1737 /* keep session index */
1738 break;
1739 case WGS_STATE_ESTABLISHED: /* can't happen */
1740 panic("unstable session can't be established");
1741 break;
1742 case WGS_STATE_DESTROYING: /* rekey initiated by us too early */
1743 WG_TRACE("Session destroying");
1744 /* XXX should wait? */
1745 return EBUSY;
1746 }
1747 wgs->wgs_state = WGS_STATE_INIT_ACTIVE;
1748
1749 m = m_gethdr(M_WAIT, MT_DATA);
1750 if (sizeof(*wgmi) > MHLEN) {
1751 m_clget(m, M_WAIT);
1752 CTASSERT(sizeof(*wgmi) <= MCLBYTES);
1753 }
1754 m->m_pkthdr.len = m->m_len = sizeof(*wgmi);
1755 wgmi = mtod(m, struct wg_msg_init *);
1756 wg_fill_msg_init(wg, wgp, wgs, wgmi);
1757
1758 error = wg->wg_ops->send_hs_msg(wgp, m);
1759 if (error == 0) {
1760 WG_TRACE("init msg sent");
1761
1762 if (wgp->wgp_handshake_start_time == 0)
1763 wgp->wgp_handshake_start_time = time_uptime;
1764 callout_schedule(&wgp->wgp_handshake_timeout_timer,
1765 MIN(wg_rekey_timeout, (unsigned)(INT_MAX / hz)) * hz);
1766 } else {
1767 wg_put_session_index(wg, wgs);
1768 /* Initiation failed; toss packet waiting for it if any. */
1769 m = atomic_swap_ptr(&wgp->wgp_pending, NULL);
1770 m_freem(m);
1771 }
1772
1773 return error;
1774 }
1775
1776 static void
1777 wg_fill_msg_resp(struct wg_softc *wg, struct wg_peer *wgp,
1778 struct wg_session *wgs, struct wg_msg_resp *wgmr,
1779 const struct wg_msg_init *wgmi)
1780 {
1781 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */
1782 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Hr */
1783 uint8_t cipher_key[WG_KDF_OUTPUT_LEN];
1784 uint8_t pubkey[WG_EPHEMERAL_KEY_LEN];
1785 uint8_t privkey[WG_EPHEMERAL_KEY_LEN];
1786
1787 KASSERT(mutex_owned(wgp->wgp_lock));
1788 KASSERT(wgs == wgp->wgp_session_unstable);
1789 KASSERT(wgs->wgs_state == WGS_STATE_INIT_PASSIVE);
1790
1791 memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash));
1792 memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey));
1793
1794 wgmr->wgmr_type = htole32(WG_MSG_TYPE_RESP);
1795 wgmr->wgmr_sender = wgs->wgs_local_index;
1796 wgmr->wgmr_receiver = wgmi->wgmi_sender;
1797
1798 /* [W] 5.4.3 Second Message: Responder to Initiator */
1799
1800 /* [N] 2.2: "e" */
1801 /* Er^priv, Er^pub := DH-GENERATE() */
1802 wg_algo_generate_keypair(pubkey, privkey);
1803 /* Cr := KDF1(Cr, Er^pub) */
1804 wg_algo_kdf(ckey, NULL, NULL, ckey, pubkey, sizeof(pubkey));
1805 /* msg.ephemeral := Er^pub */
1806 memcpy(wgmr->wgmr_ephemeral, pubkey, sizeof(wgmr->wgmr_ephemeral));
1807 /* Hr := HASH(Hr || msg.ephemeral) */
1808 wg_algo_hash(hash, pubkey, sizeof(pubkey));
1809
1810 WG_DUMP_HASH("ckey", ckey);
1811 WG_DUMP_HASH("hash", hash);
1812
1813 /* [N] 2.2: "ee" */
1814 /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */
1815 wg_algo_dh_kdf(ckey, NULL, privkey, wgs->wgs_ephemeral_key_peer);
1816
1817 /* [N] 2.2: "se" */
1818 /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */
1819 wg_algo_dh_kdf(ckey, NULL, privkey, wgp->wgp_pubkey);
1820
1821 /* [N] 9.2: "psk" */
1822 {
1823 uint8_t kdfout[WG_KDF_OUTPUT_LEN];
1824 /* Cr, r, k := KDF3(Cr, Q) */
1825 wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk,
1826 sizeof(wgp->wgp_psk));
1827 /* Hr := HASH(Hr || r) */
1828 wg_algo_hash(hash, kdfout, sizeof(kdfout));
1829 }
1830
1831 /* msg.empty := AEAD(k, 0, e, Hr) */
1832 wg_algo_aead_enc(wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty),
1833 cipher_key, 0, NULL, 0, hash, sizeof(hash));
1834 /* Hr := HASH(Hr || msg.empty) */
1835 wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty));
1836
1837 WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty);
1838
1839 /* [W] 5.4.4: Cookie MACs */
1840 /* msg.mac1 := MAC(HASH(LABEL-MAC1 || Sm'^pub), msg_a) */
1841 wg_algo_mac_mac1(wgmr->wgmr_mac1, sizeof(wgmi->wgmi_mac1),
1842 wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey),
1843 (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1));
1844 /* Need mac1 to decrypt a cookie from a cookie message */
1845 memcpy(wgp->wgp_last_sent_mac1, wgmr->wgmr_mac1,
1846 sizeof(wgp->wgp_last_sent_mac1));
1847 wgp->wgp_last_sent_mac1_valid = true;
1848
1849 if (wgp->wgp_latest_cookie_time == 0 ||
1850 (time_uptime - wgp->wgp_latest_cookie_time) >= WG_COOKIE_TIME)
1851 /* msg.mac2 := 0^16 */
1852 memset(wgmr->wgmr_mac2, 0, sizeof(wgmr->wgmr_mac2));
1853 else {
1854 /* msg.mac2 := MAC(Lm, msg_b) */
1855 wg_algo_mac(wgmr->wgmr_mac2, sizeof(wgmi->wgmi_mac2),
1856 wgp->wgp_latest_cookie, WG_COOKIE_LEN,
1857 (const uint8_t *)wgmr,
1858 offsetof(struct wg_msg_resp, wgmr_mac2),
1859 NULL, 0);
1860 }
1861
1862 memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash));
1863 memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey));
1864 memcpy(wgs->wgs_ephemeral_key_pub, pubkey, sizeof(pubkey));
1865 memcpy(wgs->wgs_ephemeral_key_priv, privkey, sizeof(privkey));
1866 wgs->wgs_remote_index = wgmi->wgmi_sender;
1867 WG_DLOG("sender=%x\n", wgs->wgs_local_index);
1868 WG_DLOG("receiver=%x\n", wgs->wgs_remote_index);
1869 }
1870
1871 static void
1872 wg_swap_sessions(struct wg_peer *wgp)
1873 {
1874 struct wg_session *wgs, *wgs_prev;
1875
1876 KASSERT(mutex_owned(wgp->wgp_lock));
1877
1878 wgs = wgp->wgp_session_unstable;
1879 KASSERT(wgs->wgs_state == WGS_STATE_ESTABLISHED);
1880
1881 wgs_prev = wgp->wgp_session_stable;
1882 KASSERT(wgs_prev->wgs_state == WGS_STATE_ESTABLISHED ||
1883 wgs_prev->wgs_state == WGS_STATE_UNKNOWN);
1884 atomic_store_release(&wgp->wgp_session_stable, wgs);
1885 wgp->wgp_session_unstable = wgs_prev;
1886 }
1887
1888 static void __noinline
1889 wg_handle_msg_resp(struct wg_softc *wg, const struct wg_msg_resp *wgmr,
1890 const struct sockaddr *src)
1891 {
1892 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */
1893 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Kr */
1894 uint8_t cipher_key[WG_KDF_OUTPUT_LEN];
1895 struct wg_peer *wgp;
1896 struct wg_session *wgs;
1897 struct psref psref;
1898 int error;
1899 uint8_t mac1[WG_MAC_LEN];
1900 struct wg_session *wgs_prev;
1901 struct mbuf *m;
1902
1903 wg_algo_mac_mac1(mac1, sizeof(mac1),
1904 wg->wg_pubkey, sizeof(wg->wg_pubkey),
1905 (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1));
1906
1907 /*
1908 * [W] 5.3: Denial of Service Mitigation & Cookies
1909 * "the responder, ..., must always reject messages with an invalid
1910 * msg.mac1"
1911 */
1912 if (!consttime_memequal(mac1, wgmr->wgmr_mac1, sizeof(mac1))) {
1913 WG_DLOG("mac1 is invalid\n");
1914 return;
1915 }
1916
1917 WG_TRACE("resp msg received");
1918 wgs = wg_lookup_session_by_index(wg, wgmr->wgmr_receiver, &psref);
1919 if (wgs == NULL) {
1920 WG_TRACE("No session found");
1921 return;
1922 }
1923
1924 wgp = wgs->wgs_peer;
1925
1926 mutex_enter(wgp->wgp_lock);
1927
1928 /* If we weren't waiting for a handshake response, drop it. */
1929 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE) {
1930 WG_TRACE("peer sent spurious handshake response, ignoring");
1931 goto out;
1932 }
1933
1934 if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_RESP))) {
1935 WG_TRACE("under load");
1936 /*
1937 * [W] 5.3: Denial of Service Mitigation & Cookies
1938 * "the responder, ..., and when under load may reject messages
1939 * with an invalid msg.mac2. If the responder receives a
1940 * message with a valid msg.mac1 yet with an invalid msg.mac2,
1941 * and is under load, it may respond with a cookie reply
1942 * message"
1943 */
1944 uint8_t zero[WG_MAC_LEN] = {0};
1945 if (consttime_memequal(wgmr->wgmr_mac2, zero, sizeof(zero))) {
1946 WG_TRACE("sending a cookie message: no cookie included");
1947 (void)wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender,
1948 wgmr->wgmr_mac1, src);
1949 goto out;
1950 }
1951 if (!wgp->wgp_last_sent_cookie_valid) {
1952 WG_TRACE("sending a cookie message: no cookie sent ever");
1953 (void)wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender,
1954 wgmr->wgmr_mac1, src);
1955 goto out;
1956 }
1957 uint8_t mac2[WG_MAC_LEN];
1958 wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie,
1959 WG_COOKIE_LEN, (const uint8_t *)wgmr,
1960 offsetof(struct wg_msg_resp, wgmr_mac2), NULL, 0);
1961 if (!consttime_memequal(mac2, wgmr->wgmr_mac2, sizeof(mac2))) {
1962 WG_DLOG("mac2 is invalid\n");
1963 goto out;
1964 }
1965 WG_TRACE("under load, but continue to sending");
1966 }
1967
1968 memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash));
1969 memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey));
1970
1971 /*
1972 * [W] 5.4.3 Second Message: Responder to Initiator
1973 * "When the initiator receives this message, it does the same
1974 * operations so that its final state variables are identical,
1975 * replacing the operands of the DH function to produce equivalent
1976 * values."
1977 * Note that the following comments of operations are just copies of
1978 * the initiator's ones.
1979 */
1980
1981 /* [N] 2.2: "e" */
1982 /* Cr := KDF1(Cr, Er^pub) */
1983 wg_algo_kdf(ckey, NULL, NULL, ckey, wgmr->wgmr_ephemeral,
1984 sizeof(wgmr->wgmr_ephemeral));
1985 /* Hr := HASH(Hr || msg.ephemeral) */
1986 wg_algo_hash(hash, wgmr->wgmr_ephemeral, sizeof(wgmr->wgmr_ephemeral));
1987
1988 WG_DUMP_HASH("ckey", ckey);
1989 WG_DUMP_HASH("hash", hash);
1990
1991 /* [N] 2.2: "ee" */
1992 /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */
1993 wg_algo_dh_kdf(ckey, NULL, wgs->wgs_ephemeral_key_priv,
1994 wgmr->wgmr_ephemeral);
1995
1996 /* [N] 2.2: "se" */
1997 /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */
1998 wg_algo_dh_kdf(ckey, NULL, wg->wg_privkey, wgmr->wgmr_ephemeral);
1999
2000 /* [N] 9.2: "psk" */
2001 {
2002 uint8_t kdfout[WG_KDF_OUTPUT_LEN];
2003 /* Cr, r, k := KDF3(Cr, Q) */
2004 wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk,
2005 sizeof(wgp->wgp_psk));
2006 /* Hr := HASH(Hr || r) */
2007 wg_algo_hash(hash, kdfout, sizeof(kdfout));
2008 }
2009
2010 {
2011 uint8_t out[sizeof(wgmr->wgmr_empty)]; /* for safety */
2012 /* msg.empty := AEAD(k, 0, e, Hr) */
2013 error = wg_algo_aead_dec(out, 0, cipher_key, 0, wgmr->wgmr_empty,
2014 sizeof(wgmr->wgmr_empty), hash, sizeof(hash));
2015 WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty);
2016 if (error != 0) {
2017 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2018 "%s: peer %s: wg_algo_aead_dec for empty message failed\n",
2019 if_name(&wg->wg_if), wgp->wgp_name);
2020 goto out;
2021 }
2022 /* Hr := HASH(Hr || msg.empty) */
2023 wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty));
2024 }
2025
2026 memcpy(wgs->wgs_handshake_hash, hash, sizeof(wgs->wgs_handshake_hash));
2027 memcpy(wgs->wgs_chaining_key, ckey, sizeof(wgs->wgs_chaining_key));
2028 wgs->wgs_remote_index = wgmr->wgmr_sender;
2029 WG_DLOG("receiver=%x\n", wgs->wgs_remote_index);
2030
2031 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE);
2032 wgs->wgs_state = WGS_STATE_ESTABLISHED;
2033 wgs->wgs_time_established = time_uptime;
2034 wgs->wgs_time_last_data_sent = 0;
2035 wgs->wgs_is_initiator = true;
2036 wg_calculate_keys(wgs, true);
2037 wg_clear_states(wgs);
2038 WG_TRACE("WGS_STATE_ESTABLISHED");
2039
2040 callout_stop(&wgp->wgp_handshake_timeout_timer);
2041
2042 wg_swap_sessions(wgp);
2043 KASSERT(wgs == wgp->wgp_session_stable);
2044 wgs_prev = wgp->wgp_session_unstable;
2045 getnanotime(&wgp->wgp_last_handshake_time);
2046 wgp->wgp_handshake_start_time = 0;
2047 wgp->wgp_last_sent_mac1_valid = false;
2048 wgp->wgp_last_sent_cookie_valid = false;
2049
2050 wg_schedule_rekey_timer(wgp);
2051
2052 wg_update_endpoint_if_necessary(wgp, src);
2053
2054 /*
2055 * If we had a data packet queued up, send it; otherwise send a
2056 * keepalive message -- either way we have to send something
2057 * immediately or else the responder will never answer.
2058 */
2059 if ((m = atomic_swap_ptr(&wgp->wgp_pending, NULL)) != NULL) {
2060 kpreempt_disable();
2061 const uint32_t h = curcpu()->ci_index; // pktq_rps_hash(m)
2062 M_SETCTX(m, wgp);
2063 if (__predict_false(!pktq_enqueue(wg_pktq, m, h))) {
2064 WGLOG(LOG_ERR, "%s: pktq full, dropping\n",
2065 if_name(&wg->wg_if));
2066 m_freem(m);
2067 }
2068 kpreempt_enable();
2069 } else {
2070 wg_send_keepalive_msg(wgp, wgs);
2071 }
2072
2073 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) {
2074 /* Wait for wg_get_stable_session to drain. */
2075 pserialize_perform(wgp->wgp_psz);
2076
2077 /* Transition ESTABLISHED->DESTROYING. */
2078 wgs_prev->wgs_state = WGS_STATE_DESTROYING;
2079
2080 /* We can't destroy the old session immediately */
2081 wg_schedule_session_dtor_timer(wgp);
2082 } else {
2083 KASSERTMSG(wgs_prev->wgs_state == WGS_STATE_UNKNOWN,
2084 "state=%d", wgs_prev->wgs_state);
2085 }
2086
2087 out:
2088 mutex_exit(wgp->wgp_lock);
2089 wg_put_session(wgs, &psref);
2090 }
2091
2092 static int
2093 wg_send_handshake_msg_resp(struct wg_softc *wg, struct wg_peer *wgp,
2094 struct wg_session *wgs, const struct wg_msg_init *wgmi)
2095 {
2096 int error;
2097 struct mbuf *m;
2098 struct wg_msg_resp *wgmr;
2099
2100 KASSERT(mutex_owned(wgp->wgp_lock));
2101 KASSERT(wgs == wgp->wgp_session_unstable);
2102 KASSERT(wgs->wgs_state == WGS_STATE_INIT_PASSIVE);
2103
2104 m = m_gethdr(M_WAIT, MT_DATA);
2105 if (sizeof(*wgmr) > MHLEN) {
2106 m_clget(m, M_WAIT);
2107 CTASSERT(sizeof(*wgmr) <= MCLBYTES);
2108 }
2109 m->m_pkthdr.len = m->m_len = sizeof(*wgmr);
2110 wgmr = mtod(m, struct wg_msg_resp *);
2111 wg_fill_msg_resp(wg, wgp, wgs, wgmr, wgmi);
2112
2113 error = wg->wg_ops->send_hs_msg(wgp, m);
2114 if (error == 0)
2115 WG_TRACE("resp msg sent");
2116 return error;
2117 }
2118
2119 static struct wg_peer *
2120 wg_lookup_peer_by_pubkey(struct wg_softc *wg,
2121 const uint8_t pubkey[WG_STATIC_KEY_LEN], struct psref *psref)
2122 {
2123 struct wg_peer *wgp;
2124
2125 int s = pserialize_read_enter();
2126 wgp = thmap_get(wg->wg_peers_bypubkey, pubkey, WG_STATIC_KEY_LEN);
2127 if (wgp != NULL)
2128 wg_get_peer(wgp, psref);
2129 pserialize_read_exit(s);
2130
2131 return wgp;
2132 }
2133
2134 static void
2135 wg_fill_msg_cookie(struct wg_softc *wg, struct wg_peer *wgp,
2136 struct wg_msg_cookie *wgmc, const uint32_t sender,
2137 const uint8_t mac1[WG_MAC_LEN], const struct sockaddr *src)
2138 {
2139 uint8_t cookie[WG_COOKIE_LEN];
2140 uint8_t key[WG_HASH_LEN];
2141 uint8_t addr[sizeof(struct in6_addr)];
2142 size_t addrlen;
2143 uint16_t uh_sport; /* be */
2144
2145 KASSERT(mutex_owned(wgp->wgp_lock));
2146
2147 wgmc->wgmc_type = htole32(WG_MSG_TYPE_COOKIE);
2148 wgmc->wgmc_receiver = sender;
2149 cprng_fast(wgmc->wgmc_salt, sizeof(wgmc->wgmc_salt));
2150
2151 /*
2152 * [W] 5.4.7: Under Load: Cookie Reply Message
2153 * "The secret variable, Rm, changes every two minutes to a
2154 * random value"
2155 */
2156 if ((time_uptime - wgp->wgp_last_genrandval_time) > WG_RANDVAL_TIME) {
2157 wgp->wgp_randval = cprng_strong32();
2158 wgp->wgp_last_genrandval_time = time_uptime;
2159 }
2160
2161 switch (src->sa_family) {
2162 case AF_INET: {
2163 const struct sockaddr_in *sin = satocsin(src);
2164 addrlen = sizeof(sin->sin_addr);
2165 memcpy(addr, &sin->sin_addr, addrlen);
2166 uh_sport = sin->sin_port;
2167 break;
2168 }
2169 #ifdef INET6
2170 case AF_INET6: {
2171 const struct sockaddr_in6 *sin6 = satocsin6(src);
2172 addrlen = sizeof(sin6->sin6_addr);
2173 memcpy(addr, &sin6->sin6_addr, addrlen);
2174 uh_sport = sin6->sin6_port;
2175 break;
2176 }
2177 #endif
2178 default:
2179 panic("invalid af=%d", src->sa_family);
2180 }
2181
2182 wg_algo_mac(cookie, sizeof(cookie),
2183 (const uint8_t *)&wgp->wgp_randval, sizeof(wgp->wgp_randval),
2184 addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport));
2185 wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey,
2186 sizeof(wg->wg_pubkey));
2187 wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key,
2188 cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt);
2189
2190 /* Need to store to calculate mac2 */
2191 memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie));
2192 wgp->wgp_last_sent_cookie_valid = true;
2193 }
2194
2195 static int
2196 wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp,
2197 const uint32_t sender, const uint8_t mac1[WG_MAC_LEN],
2198 const struct sockaddr *src)
2199 {
2200 int error;
2201 struct mbuf *m;
2202 struct wg_msg_cookie *wgmc;
2203
2204 KASSERT(mutex_owned(wgp->wgp_lock));
2205
2206 m = m_gethdr(M_WAIT, MT_DATA);
2207 if (sizeof(*wgmc) > MHLEN) {
2208 m_clget(m, M_WAIT);
2209 CTASSERT(sizeof(*wgmc) <= MCLBYTES);
2210 }
2211 m->m_pkthdr.len = m->m_len = sizeof(*wgmc);
2212 wgmc = mtod(m, struct wg_msg_cookie *);
2213 wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src);
2214
2215 error = wg->wg_ops->send_hs_msg(wgp, m);
2216 if (error == 0)
2217 WG_TRACE("cookie msg sent");
2218 return error;
2219 }
2220
2221 static bool
2222 wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype)
2223 {
2224 #ifdef WG_DEBUG_PARAMS
2225 if (wg_force_underload)
2226 return true;
2227 #endif
2228
2229 /*
2230 * XXX we don't have a means of a load estimation. The purpose of
2231 * the mechanism is a DoS mitigation, so we consider frequent handshake
2232 * messages as (a kind of) load; if a message of the same type comes
2233 * to a peer within 1 second, we consider we are under load.
2234 */
2235 time_t last = wgp->wgp_last_msg_received_time[msgtype];
2236 wgp->wgp_last_msg_received_time[msgtype] = time_uptime;
2237 return (time_uptime - last) == 0;
2238 }
2239
2240 static void
2241 wg_calculate_keys(struct wg_session *wgs, const bool initiator)
2242 {
2243
2244 KASSERT(mutex_owned(wgs->wgs_peer->wgp_lock));
2245
2246 /*
2247 * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e)
2248 */
2249 if (initiator) {
2250 wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL,
2251 wgs->wgs_chaining_key, NULL, 0);
2252 } else {
2253 wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL,
2254 wgs->wgs_chaining_key, NULL, 0);
2255 }
2256 WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send);
2257 WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv);
2258 }
2259
2260 static uint64_t
2261 wg_session_get_send_counter(struct wg_session *wgs)
2262 {
2263 #ifdef __HAVE_ATOMIC64_LOADSTORE
2264 return atomic_load_relaxed(&wgs->wgs_send_counter);
2265 #else
2266 uint64_t send_counter;
2267
2268 mutex_enter(&wgs->wgs_send_counter_lock);
2269 send_counter = wgs->wgs_send_counter;
2270 mutex_exit(&wgs->wgs_send_counter_lock);
2271
2272 return send_counter;
2273 #endif
2274 }
2275
2276 static uint64_t
2277 wg_session_inc_send_counter(struct wg_session *wgs)
2278 {
2279 #ifdef __HAVE_ATOMIC64_LOADSTORE
2280 return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1;
2281 #else
2282 uint64_t send_counter;
2283
2284 mutex_enter(&wgs->wgs_send_counter_lock);
2285 send_counter = wgs->wgs_send_counter++;
2286 mutex_exit(&wgs->wgs_send_counter_lock);
2287
2288 return send_counter;
2289 #endif
2290 }
2291
2292 static void
2293 wg_clear_states(struct wg_session *wgs)
2294 {
2295
2296 KASSERT(mutex_owned(wgs->wgs_peer->wgp_lock));
2297
2298 wgs->wgs_send_counter = 0;
2299 sliwin_reset(&wgs->wgs_recvwin->window);
2300
2301 #define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v))
2302 wgs_clear(handshake_hash);
2303 wgs_clear(chaining_key);
2304 wgs_clear(ephemeral_key_pub);
2305 wgs_clear(ephemeral_key_priv);
2306 wgs_clear(ephemeral_key_peer);
2307 #undef wgs_clear
2308 }
2309
2310 static struct wg_session *
2311 wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index,
2312 struct psref *psref)
2313 {
2314 struct wg_session *wgs;
2315
2316 int s = pserialize_read_enter();
2317 wgs = thmap_get(wg->wg_sessions_byindex, &index, sizeof index);
2318 if (wgs != NULL) {
2319 KASSERT(atomic_load_relaxed(&wgs->wgs_state) !=
2320 WGS_STATE_UNKNOWN);
2321 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class);
2322 }
2323 pserialize_read_exit(s);
2324
2325 return wgs;
2326 }
2327
2328 static void
2329 wg_schedule_rekey_timer(struct wg_peer *wgp)
2330 {
2331 int timeout = MIN(wg_rekey_after_time, (unsigned)(INT_MAX / hz));
2332
2333 callout_schedule(&wgp->wgp_rekey_timer, timeout * hz);
2334 }
2335
2336 static void
2337 wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs)
2338 {
2339 struct mbuf *m;
2340
2341 /*
2342 * [W] 6.5 Passive Keepalive
2343 * "A keepalive message is simply a transport data message with
2344 * a zero-length encapsulated encrypted inner-packet."
2345 */
2346 WG_TRACE("");
2347 m = m_gethdr(M_WAIT, MT_DATA);
2348 wg_send_data_msg(wgp, wgs, m);
2349 }
2350
2351 static bool
2352 wg_need_to_send_init_message(struct wg_session *wgs)
2353 {
2354 /*
2355 * [W] 6.2 Transport Message Limits
2356 * "if a peer is the initiator of a current secure session,
2357 * WireGuard will send a handshake initiation message to begin
2358 * a new secure session ... if after receiving a transport data
2359 * message, the current secure session is (REJECT-AFTER-TIME
2360 * KEEPALIVE-TIMEOUT REKEY-TIMEOUT) seconds old and it has
2361 * not yet acted upon this event."
2362 */
2363 return wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0 &&
2364 (time_uptime - wgs->wgs_time_established) >=
2365 (wg_reject_after_time - wg_keepalive_timeout - wg_rekey_timeout);
2366 }
2367
2368 static void
2369 wg_schedule_peer_task(struct wg_peer *wgp, unsigned int task)
2370 {
2371
2372 mutex_enter(wgp->wgp_intr_lock);
2373 WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task);
2374 if (wgp->wgp_tasks == 0)
2375 /*
2376 * XXX If the current CPU is already loaded -- e.g., if
2377 * there's already a bunch of handshakes queued up --
2378 * consider tossing this over to another CPU to
2379 * distribute the load.
2380 */
2381 workqueue_enqueue(wg_wq, &wgp->wgp_work, NULL);
2382 wgp->wgp_tasks |= task;
2383 mutex_exit(wgp->wgp_intr_lock);
2384 }
2385
2386 static void
2387 wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new)
2388 {
2389 struct wg_sockaddr *wgsa_prev;
2390
2391 WG_TRACE("Changing endpoint");
2392
2393 memcpy(wgp->wgp_endpoint0, new, new->sa_len);
2394 wgsa_prev = wgp->wgp_endpoint;
2395 atomic_store_release(&wgp->wgp_endpoint, wgp->wgp_endpoint0);
2396 wgp->wgp_endpoint0 = wgsa_prev;
2397 atomic_store_release(&wgp->wgp_endpoint_available, true);
2398
2399 wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED);
2400 }
2401
2402 static bool
2403 wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af)
2404 {
2405 uint16_t packet_len;
2406 const struct ip *ip;
2407
2408 if (__predict_false(decrypted_len < sizeof(*ip))) {
2409 WG_DLOG("decrypted_len=%zu < %zu\n", decrypted_len,
2410 sizeof(*ip));
2411 return false;
2412 }
2413
2414 ip = (const struct ip *)packet;
2415 if (ip->ip_v == 4)
2416 *af = AF_INET;
2417 else if (ip->ip_v == 6)
2418 *af = AF_INET6;
2419 else {
2420 WG_DLOG("ip_v=%d\n", ip->ip_v);
2421 return false;
2422 }
2423
2424 WG_DLOG("af=%d\n", *af);
2425
2426 switch (*af) {
2427 #ifdef INET
2428 case AF_INET:
2429 packet_len = ntohs(ip->ip_len);
2430 break;
2431 #endif
2432 #ifdef INET6
2433 case AF_INET6: {
2434 const struct ip6_hdr *ip6;
2435
2436 if (__predict_false(decrypted_len < sizeof(*ip6))) {
2437 WG_DLOG("decrypted_len=%zu < %zu\n", decrypted_len,
2438 sizeof(*ip6));
2439 return false;
2440 }
2441
2442 ip6 = (const struct ip6_hdr *)packet;
2443 packet_len = sizeof(*ip6) + ntohs(ip6->ip6_plen);
2444 break;
2445 }
2446 #endif
2447 default:
2448 return false;
2449 }
2450
2451 if (packet_len > decrypted_len) {
2452 WG_DLOG("packet_len %u > decrypted_len %zu\n", packet_len,
2453 decrypted_len);
2454 return false;
2455 }
2456
2457 return true;
2458 }
2459
2460 static bool
2461 wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected,
2462 int af, char *packet)
2463 {
2464 struct sockaddr_storage ss;
2465 struct sockaddr *sa;
2466 struct psref psref;
2467 struct wg_peer *wgp;
2468 bool ok;
2469
2470 /*
2471 * II CRYPTOKEY ROUTING
2472 * "it will only accept it if its source IP resolves in the
2473 * table to the public key used in the secure session for
2474 * decrypting it."
2475 */
2476
2477 if (af == AF_INET) {
2478 const struct ip *ip = (const struct ip *)packet;
2479 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
2480 sockaddr_in_init(sin, &ip->ip_src, 0);
2481 sa = sintosa(sin);
2482 #ifdef INET6
2483 } else {
2484 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet;
2485 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
2486 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0);
2487 sa = sin6tosa(sin6);
2488 #endif
2489 }
2490
2491 wgp = wg_pick_peer_by_sa(wg, sa, &psref);
2492 ok = (wgp == wgp_expected);
2493 if (wgp != NULL)
2494 wg_put_peer(wgp, &psref);
2495
2496 return ok;
2497 }
2498
2499 static void
2500 wg_session_dtor_timer(void *arg)
2501 {
2502 struct wg_peer *wgp = arg;
2503
2504 WG_TRACE("enter");
2505
2506 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION);
2507 }
2508
2509 static void
2510 wg_schedule_session_dtor_timer(struct wg_peer *wgp)
2511 {
2512
2513 /* 1 second grace period */
2514 callout_schedule(&wgp->wgp_session_dtor_timer, hz);
2515 }
2516
2517 static bool
2518 sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2)
2519 {
2520 if (sa1->sa_family != sa2->sa_family)
2521 return false;
2522
2523 switch (sa1->sa_family) {
2524 #ifdef INET
2525 case AF_INET:
2526 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port;
2527 #endif
2528 #ifdef INET6
2529 case AF_INET6:
2530 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port;
2531 #endif
2532 default:
2533 return false;
2534 }
2535 }
2536
2537 static void
2538 wg_update_endpoint_if_necessary(struct wg_peer *wgp,
2539 const struct sockaddr *src)
2540 {
2541 struct wg_sockaddr *wgsa;
2542 struct psref psref;
2543
2544 wgsa = wg_get_endpoint_sa(wgp, &psref);
2545
2546 #ifdef WG_DEBUG_LOG
2547 char oldaddr[128], newaddr[128];
2548 sockaddr_format(wgsatosa(wgsa), oldaddr, sizeof(oldaddr));
2549 sockaddr_format(src, newaddr, sizeof(newaddr));
2550 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr);
2551 #endif
2552
2553 /*
2554 * III: "Since the packet has authenticated correctly, the source IP of
2555 * the outer UDP/IP packet is used to update the endpoint for peer..."
2556 */
2557 if (__predict_false(sockaddr_cmp(src, wgsatosa(wgsa)) != 0 ||
2558 !sockaddr_port_match(src, wgsatosa(wgsa)))) {
2559 /* XXX We can't change the endpoint twice in a short period */
2560 if (atomic_swap_uint(&wgp->wgp_endpoint_changing, 1) == 0) {
2561 wg_change_endpoint(wgp, src);
2562 }
2563 }
2564
2565 wg_put_sa(wgp, wgsa, &psref);
2566 }
2567
2568 static void __noinline
2569 wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m,
2570 const struct sockaddr *src)
2571 {
2572 struct wg_msg_data *wgmd;
2573 char *encrypted_buf = NULL, *decrypted_buf;
2574 size_t encrypted_len, decrypted_len;
2575 struct wg_session *wgs;
2576 struct wg_peer *wgp;
2577 int state;
2578 size_t mlen;
2579 struct psref psref;
2580 int error, af;
2581 bool success, free_encrypted_buf = false, ok;
2582 struct mbuf *n;
2583
2584 KASSERT(m->m_len >= sizeof(struct wg_msg_data));
2585 wgmd = mtod(m, struct wg_msg_data *);
2586
2587 KASSERT(wgmd->wgmd_type == htole32(WG_MSG_TYPE_DATA));
2588 WG_TRACE("data");
2589
2590 /* Find the putative session, or drop. */
2591 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref);
2592 if (wgs == NULL) {
2593 WG_TRACE("No session found");
2594 m_freem(m);
2595 return;
2596 }
2597
2598 /*
2599 * We are only ready to handle data when in INIT_PASSIVE,
2600 * ESTABLISHED, or DESTROYING. All transitions out of that
2601 * state dissociate the session index and drain psrefs.
2602 */
2603 state = atomic_load_relaxed(&wgs->wgs_state);
2604 switch (state) {
2605 case WGS_STATE_UNKNOWN:
2606 panic("wg session %p in unknown state has session index %u",
2607 wgs, wgmd->wgmd_receiver);
2608 case WGS_STATE_INIT_ACTIVE:
2609 WG_TRACE("not yet ready for data");
2610 goto out;
2611 case WGS_STATE_INIT_PASSIVE:
2612 case WGS_STATE_ESTABLISHED:
2613 case WGS_STATE_DESTROYING:
2614 break;
2615 }
2616
2617 /*
2618 * Get the peer, for rate-limited logs (XXX MPSAFE, dtrace) and
2619 * to update the endpoint if authentication succeeds.
2620 */
2621 wgp = wgs->wgs_peer;
2622
2623 /*
2624 * Reject outrageously wrong sequence numbers before doing any
2625 * crypto work or taking any locks.
2626 */
2627 error = sliwin_check_fast(&wgs->wgs_recvwin->window,
2628 le64toh(wgmd->wgmd_counter));
2629 if (error) {
2630 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2631 "%s: peer %s: out-of-window packet: %"PRIu64"\n",
2632 if_name(&wg->wg_if), wgp->wgp_name,
2633 le64toh(wgmd->wgmd_counter));
2634 goto out;
2635 }
2636
2637 /* Ensure the payload and authenticator are contiguous. */
2638 mlen = m_length(m);
2639 encrypted_len = mlen - sizeof(*wgmd);
2640 if (encrypted_len < WG_AUTHTAG_LEN) {
2641 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len);
2642 goto out;
2643 }
2644 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len);
2645 if (success) {
2646 encrypted_buf = mtod(m, char *) + sizeof(*wgmd);
2647 } else {
2648 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP);
2649 if (encrypted_buf == NULL) {
2650 WG_DLOG("failed to allocate encrypted_buf\n");
2651 goto out;
2652 }
2653 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf);
2654 free_encrypted_buf = true;
2655 }
2656 /* m_ensure_contig may change m regardless of its result */
2657 KASSERT(m->m_len >= sizeof(*wgmd));
2658 wgmd = mtod(m, struct wg_msg_data *);
2659
2660 /*
2661 * Get a buffer for the plaintext. Add WG_AUTHTAG_LEN to avoid
2662 * a zero-length buffer (XXX). Drop if plaintext is longer
2663 * than MCLBYTES (XXX).
2664 */
2665 decrypted_len = encrypted_len - WG_AUTHTAG_LEN;
2666 if (decrypted_len > MCLBYTES) {
2667 /* FIXME handle larger data than MCLBYTES */
2668 WG_DLOG("couldn't handle larger data than MCLBYTES\n");
2669 goto out;
2670 }
2671 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN);
2672 if (n == NULL) {
2673 WG_DLOG("wg_get_mbuf failed\n");
2674 goto out;
2675 }
2676 decrypted_buf = mtod(n, char *);
2677
2678 /* Decrypt and verify the packet. */
2679 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len);
2680 error = wg_algo_aead_dec(decrypted_buf,
2681 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */,
2682 wgs->wgs_tkey_recv, le64toh(wgmd->wgmd_counter), encrypted_buf,
2683 encrypted_len, NULL, 0);
2684 if (error != 0) {
2685 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2686 "%s: peer %s: failed to wg_algo_aead_dec\n",
2687 if_name(&wg->wg_if), wgp->wgp_name);
2688 m_freem(n);
2689 goto out;
2690 }
2691 WG_DLOG("outsize=%u\n", (u_int)decrypted_len);
2692
2693 /* Packet is genuine. Reject it if a replay or just too old. */
2694 mutex_enter(&wgs->wgs_recvwin->lock);
2695 error = sliwin_update(&wgs->wgs_recvwin->window,
2696 le64toh(wgmd->wgmd_counter));
2697 mutex_exit(&wgs->wgs_recvwin->lock);
2698 if (error) {
2699 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2700 "%s: peer %s: replay or out-of-window packet: %"PRIu64"\n",
2701 if_name(&wg->wg_if), wgp->wgp_name,
2702 le64toh(wgmd->wgmd_counter));
2703 m_freem(n);
2704 goto out;
2705 }
2706
2707 #ifdef WG_DEBUG_PACKET
2708 if (wg_debug & WG_DEBUG_FLAGS_PACKET) {
2709 hexdump(aprint_debug, "wgmd", wgmd, sizeof(*wgmd));
2710 hexdump(aprint_debug, "decrypted_buf", decrypted_buf,
2711 decrypted_len);
2712 }
2713 #endif
2714 /* We're done with m now; free it and chuck the pointers. */
2715 m_freem(m);
2716 m = NULL;
2717 wgmd = NULL;
2718
2719 /*
2720 * Validate the encapsulated packet header and get the address
2721 * family, or drop.
2722 */
2723 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af);
2724 if (!ok) {
2725 m_freem(n);
2726 goto out;
2727 }
2728
2729 /*
2730 * The packet is genuine. Update the peer's endpoint if the
2731 * source address changed.
2732 *
2733 * XXX How to prevent DoS by replaying genuine packets from the
2734 * wrong source address?
2735 */
2736 wg_update_endpoint_if_necessary(wgp, src);
2737
2738 /* Submit it into our network stack if routable. */
2739 ok = wg_validate_route(wg, wgp, af, decrypted_buf);
2740 if (ok) {
2741 wg->wg_ops->input(&wg->wg_if, n, af);
2742 } else {
2743 char addrstr[INET6_ADDRSTRLEN];
2744 memset(addrstr, 0, sizeof(addrstr));
2745 if (af == AF_INET) {
2746 const struct ip *ip = (const struct ip *)decrypted_buf;
2747 IN_PRINT(addrstr, &ip->ip_src);
2748 #ifdef INET6
2749 } else if (af == AF_INET6) {
2750 const struct ip6_hdr *ip6 =
2751 (const struct ip6_hdr *)decrypted_buf;
2752 IN6_PRINT(addrstr, &ip6->ip6_src);
2753 #endif
2754 }
2755 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2756 "%s: peer %s: invalid source address (%s)\n",
2757 if_name(&wg->wg_if), wgp->wgp_name, addrstr);
2758 m_freem(n);
2759 /*
2760 * The inner address is invalid however the session is valid
2761 * so continue the session processing below.
2762 */
2763 }
2764 n = NULL;
2765
2766 /* Update the state machine if necessary. */
2767 if (__predict_false(state == WGS_STATE_INIT_PASSIVE)) {
2768 /*
2769 * We were waiting for the initiator to send their
2770 * first data transport message, and that has happened.
2771 * Schedule a task to establish this session.
2772 */
2773 wg_schedule_peer_task(wgp, WGP_TASK_ESTABLISH_SESSION);
2774 } else {
2775 if (__predict_false(wg_need_to_send_init_message(wgs))) {
2776 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2777 }
2778 /*
2779 * [W] 6.5 Passive Keepalive
2780 * "If a peer has received a validly-authenticated transport
2781 * data message (section 5.4.6), but does not have any packets
2782 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends
2783 * a keepalive message."
2784 */
2785 WG_DLOG("time_uptime=%ju wgs_time_last_data_sent=%ju\n",
2786 (uintmax_t)time_uptime,
2787 (uintmax_t)wgs->wgs_time_last_data_sent);
2788 if ((time_uptime - wgs->wgs_time_last_data_sent) >=
2789 wg_keepalive_timeout) {
2790 WG_TRACE("Schedule sending keepalive message");
2791 /*
2792 * We can't send a keepalive message here to avoid
2793 * a deadlock; we already hold the solock of a socket
2794 * that is used to send the message.
2795 */
2796 wg_schedule_peer_task(wgp,
2797 WGP_TASK_SEND_KEEPALIVE_MESSAGE);
2798 }
2799 }
2800 out:
2801 wg_put_session(wgs, &psref);
2802 m_freem(m);
2803 if (free_encrypted_buf)
2804 kmem_intr_free(encrypted_buf, encrypted_len);
2805 }
2806
2807 static void __noinline
2808 wg_handle_msg_cookie(struct wg_softc *wg, const struct wg_msg_cookie *wgmc)
2809 {
2810 struct wg_session *wgs;
2811 struct wg_peer *wgp;
2812 struct psref psref;
2813 int error;
2814 uint8_t key[WG_HASH_LEN];
2815 uint8_t cookie[WG_COOKIE_LEN];
2816
2817 WG_TRACE("cookie msg received");
2818
2819 /* Find the putative session. */
2820 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref);
2821 if (wgs == NULL) {
2822 WG_TRACE("No session found");
2823 return;
2824 }
2825
2826 /* Lock the peer so we can update the cookie state. */
2827 wgp = wgs->wgs_peer;
2828 mutex_enter(wgp->wgp_lock);
2829
2830 if (!wgp->wgp_last_sent_mac1_valid) {
2831 WG_TRACE("No valid mac1 sent (or expired)");
2832 goto out;
2833 }
2834
2835 /* Decrypt the cookie and store it for later handshake retry. */
2836 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey,
2837 sizeof(wgp->wgp_pubkey));
2838 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key,
2839 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie),
2840 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1),
2841 wgmc->wgmc_salt);
2842 if (error != 0) {
2843 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2844 "%s: peer %s: wg_algo_aead_dec for cookie failed: "
2845 "error=%d\n", if_name(&wg->wg_if), wgp->wgp_name, error);
2846 goto out;
2847 }
2848 /*
2849 * [W] 6.6: Interaction with Cookie Reply System
2850 * "it should simply store the decrypted cookie value from the cookie
2851 * reply message, and wait for the expiration of the REKEY-TIMEOUT
2852 * timer for retrying a handshake initiation message."
2853 */
2854 wgp->wgp_latest_cookie_time = time_uptime;
2855 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie));
2856 out:
2857 mutex_exit(wgp->wgp_lock);
2858 wg_put_session(wgs, &psref);
2859 }
2860
2861 static struct mbuf *
2862 wg_validate_msg_header(struct wg_softc *wg, struct mbuf *m)
2863 {
2864 struct wg_msg wgm;
2865 size_t mbuflen;
2866 size_t msglen;
2867
2868 /*
2869 * Get the mbuf chain length. It is already guaranteed, by
2870 * wg_overudp_cb, to be large enough for a struct wg_msg.
2871 */
2872 mbuflen = m_length(m);
2873 KASSERT(mbuflen >= sizeof(struct wg_msg));
2874
2875 /*
2876 * Copy the message header (32-bit message type) out -- we'll
2877 * worry about contiguity and alignment later.
2878 */
2879 m_copydata(m, 0, sizeof(wgm), &wgm);
2880 switch (le32toh(wgm.wgm_type)) {
2881 case WG_MSG_TYPE_INIT:
2882 msglen = sizeof(struct wg_msg_init);
2883 break;
2884 case WG_MSG_TYPE_RESP:
2885 msglen = sizeof(struct wg_msg_resp);
2886 break;
2887 case WG_MSG_TYPE_COOKIE:
2888 msglen = sizeof(struct wg_msg_cookie);
2889 break;
2890 case WG_MSG_TYPE_DATA:
2891 msglen = sizeof(struct wg_msg_data);
2892 break;
2893 default:
2894 WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG,
2895 "%s: Unexpected msg type: %u\n", if_name(&wg->wg_if),
2896 le32toh(wgm.wgm_type));
2897 goto error;
2898 }
2899
2900 /* Verify the mbuf chain is long enough for this type of message. */
2901 if (__predict_false(mbuflen < msglen)) {
2902 WG_DLOG("Invalid msg size: mbuflen=%lu type=%u\n", mbuflen,
2903 le32toh(wgm.wgm_type));
2904 goto error;
2905 }
2906
2907 /* Make the message header contiguous if necessary. */
2908 if (__predict_false(m->m_len < msglen)) {
2909 m = m_pullup(m, msglen);
2910 if (m == NULL)
2911 return NULL;
2912 }
2913
2914 return m;
2915
2916 error:
2917 m_freem(m);
2918 return NULL;
2919 }
2920
2921 static void
2922 wg_handle_packet(struct wg_softc *wg, struct mbuf *m,
2923 const struct sockaddr *src)
2924 {
2925 struct wg_msg *wgm;
2926
2927 KASSERT(curlwp->l_pflag & LP_BOUND);
2928
2929 m = wg_validate_msg_header(wg, m);
2930 if (__predict_false(m == NULL))
2931 return;
2932
2933 KASSERT(m->m_len >= sizeof(struct wg_msg));
2934 wgm = mtod(m, struct wg_msg *);
2935 switch (le32toh(wgm->wgm_type)) {
2936 case WG_MSG_TYPE_INIT:
2937 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src);
2938 break;
2939 case WG_MSG_TYPE_RESP:
2940 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src);
2941 break;
2942 case WG_MSG_TYPE_COOKIE:
2943 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm);
2944 break;
2945 case WG_MSG_TYPE_DATA:
2946 wg_handle_msg_data(wg, m, src);
2947 /* wg_handle_msg_data frees m for us */
2948 return;
2949 default:
2950 panic("invalid message type: %d", le32toh(wgm->wgm_type));
2951 }
2952
2953 m_freem(m);
2954 }
2955
2956 static void
2957 wg_receive_packets(struct wg_softc *wg, const int af)
2958 {
2959
2960 for (;;) {
2961 int error, flags;
2962 struct socket *so;
2963 struct mbuf *m = NULL;
2964 struct uio dummy_uio;
2965 struct mbuf *paddr = NULL;
2966 struct sockaddr *src;
2967
2968 so = wg_get_so_by_af(wg, af);
2969 flags = MSG_DONTWAIT;
2970 dummy_uio.uio_resid = 1000000000;
2971
2972 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL,
2973 &flags);
2974 if (error || m == NULL) {
2975 //if (error == EWOULDBLOCK)
2976 return;
2977 }
2978
2979 KASSERT(paddr != NULL);
2980 KASSERT(paddr->m_len >= sizeof(struct sockaddr));
2981 src = mtod(paddr, struct sockaddr *);
2982
2983 wg_handle_packet(wg, m, src);
2984 }
2985 }
2986
2987 static void
2988 wg_get_peer(struct wg_peer *wgp, struct psref *psref)
2989 {
2990
2991 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class);
2992 }
2993
2994 static void
2995 wg_put_peer(struct wg_peer *wgp, struct psref *psref)
2996 {
2997
2998 psref_release(psref, &wgp->wgp_psref, wg_psref_class);
2999 }
3000
3001 static void
3002 wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp)
3003 {
3004 struct wg_session *wgs;
3005
3006 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE");
3007
3008 KASSERT(mutex_owned(wgp->wgp_lock));
3009
3010 if (!atomic_load_acquire(&wgp->wgp_endpoint_available)) {
3011 WGLOG(LOG_DEBUG, "%s: No endpoint available\n",
3012 if_name(&wg->wg_if));
3013 /* XXX should do something? */
3014 return;
3015 }
3016
3017 wgs = wgp->wgp_session_stable;
3018 if (wgs->wgs_state == WGS_STATE_UNKNOWN) {
3019 /* XXX What if the unstable session is already INIT_ACTIVE? */
3020 wg_send_handshake_msg_init(wg, wgp);
3021 } else {
3022 /* rekey */
3023 wgs = wgp->wgp_session_unstable;
3024 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE)
3025 wg_send_handshake_msg_init(wg, wgp);
3026 }
3027 }
3028
3029 static void
3030 wg_task_retry_handshake(struct wg_softc *wg, struct wg_peer *wgp)
3031 {
3032 struct wg_session *wgs;
3033
3034 WG_TRACE("WGP_TASK_RETRY_HANDSHAKE");
3035
3036 KASSERT(mutex_owned(wgp->wgp_lock));
3037 KASSERT(wgp->wgp_handshake_start_time != 0);
3038
3039 wgs = wgp->wgp_session_unstable;
3040 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE)
3041 return;
3042
3043 /*
3044 * XXX no real need to assign a new index here, but we do need
3045 * to transition to UNKNOWN temporarily
3046 */
3047 wg_put_session_index(wg, wgs);
3048
3049 /* [W] 6.4 Handshake Initiation Retransmission */
3050 if ((time_uptime - wgp->wgp_handshake_start_time) >
3051 wg_rekey_attempt_time) {
3052 /* Give up handshaking */
3053 wgp->wgp_handshake_start_time = 0;
3054 WG_TRACE("give up");
3055
3056 /*
3057 * If a new data packet comes, handshaking will be retried
3058 * and a new session would be established at that time,
3059 * however we don't want to send pending packets then.
3060 */
3061 wg_purge_pending_packets(wgp);
3062 return;
3063 }
3064
3065 wg_task_send_init_message(wg, wgp);
3066 }
3067
3068 static void
3069 wg_task_establish_session(struct wg_softc *wg, struct wg_peer *wgp)
3070 {
3071 struct wg_session *wgs, *wgs_prev;
3072 struct mbuf *m;
3073
3074 KASSERT(mutex_owned(wgp->wgp_lock));
3075
3076 wgs = wgp->wgp_session_unstable;
3077 if (wgs->wgs_state != WGS_STATE_INIT_PASSIVE)
3078 /* XXX Can this happen? */
3079 return;
3080
3081 wgs->wgs_state = WGS_STATE_ESTABLISHED;
3082 wgs->wgs_time_established = time_uptime;
3083 wgs->wgs_time_last_data_sent = 0;
3084 wgs->wgs_is_initiator = false;
3085 WG_TRACE("WGS_STATE_ESTABLISHED");
3086
3087 wg_swap_sessions(wgp);
3088 KASSERT(wgs == wgp->wgp_session_stable);
3089 wgs_prev = wgp->wgp_session_unstable;
3090 getnanotime(&wgp->wgp_last_handshake_time);
3091 wgp->wgp_handshake_start_time = 0;
3092 wgp->wgp_last_sent_mac1_valid = false;
3093 wgp->wgp_last_sent_cookie_valid = false;
3094
3095 /* If we had a data packet queued up, send it. */
3096 if ((m = atomic_swap_ptr(&wgp->wgp_pending, NULL)) != NULL) {
3097 kpreempt_disable();
3098 const uint32_t h = curcpu()->ci_index; // pktq_rps_hash(m)
3099 M_SETCTX(m, wgp);
3100 if (__predict_false(!pktq_enqueue(wg_pktq, m, h))) {
3101 WGLOG(LOG_ERR, "%s: pktq full, dropping\n",
3102 if_name(&wg->wg_if));
3103 m_freem(m);
3104 }
3105 kpreempt_enable();
3106 }
3107
3108 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) {
3109 /* Wait for wg_get_stable_session to drain. */
3110 pserialize_perform(wgp->wgp_psz);
3111
3112 /* Transition ESTABLISHED->DESTROYING. */
3113 wgs_prev->wgs_state = WGS_STATE_DESTROYING;
3114
3115 /* We can't destroy the old session immediately */
3116 wg_schedule_session_dtor_timer(wgp);
3117 } else {
3118 KASSERTMSG(wgs_prev->wgs_state == WGS_STATE_UNKNOWN,
3119 "state=%d", wgs_prev->wgs_state);
3120 wg_clear_states(wgs_prev);
3121 wgs_prev->wgs_state = WGS_STATE_UNKNOWN;
3122 }
3123 }
3124
3125 static void
3126 wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp)
3127 {
3128
3129 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED");
3130
3131 KASSERT(mutex_owned(wgp->wgp_lock));
3132
3133 if (atomic_load_relaxed(&wgp->wgp_endpoint_changing)) {
3134 pserialize_perform(wgp->wgp_psz);
3135 mutex_exit(wgp->wgp_lock);
3136 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref,
3137 wg_psref_class);
3138 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref,
3139 wg_psref_class);
3140 mutex_enter(wgp->wgp_lock);
3141 atomic_store_release(&wgp->wgp_endpoint_changing, 0);
3142 }
3143 }
3144
3145 static void
3146 wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp)
3147 {
3148 struct wg_session *wgs;
3149
3150 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE");
3151
3152 KASSERT(mutex_owned(wgp->wgp_lock));
3153
3154 wgs = wgp->wgp_session_stable;
3155 if (wgs->wgs_state != WGS_STATE_ESTABLISHED)
3156 return;
3157
3158 wg_send_keepalive_msg(wgp, wgs);
3159 }
3160
3161 static void
3162 wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp)
3163 {
3164 struct wg_session *wgs;
3165
3166 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION");
3167
3168 KASSERT(mutex_owned(wgp->wgp_lock));
3169
3170 wgs = wgp->wgp_session_unstable;
3171 if (wgs->wgs_state == WGS_STATE_DESTROYING) {
3172 wg_put_session_index(wg, wgs);
3173 }
3174 }
3175
3176 static void
3177 wg_peer_work(struct work *wk, void *cookie)
3178 {
3179 struct wg_peer *wgp = container_of(wk, struct wg_peer, wgp_work);
3180 struct wg_softc *wg = wgp->wgp_sc;
3181 unsigned int tasks;
3182
3183 mutex_enter(wgp->wgp_intr_lock);
3184 while ((tasks = wgp->wgp_tasks) != 0) {
3185 wgp->wgp_tasks = 0;
3186 mutex_exit(wgp->wgp_intr_lock);
3187
3188 mutex_enter(wgp->wgp_lock);
3189 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE))
3190 wg_task_send_init_message(wg, wgp);
3191 if (ISSET(tasks, WGP_TASK_RETRY_HANDSHAKE))
3192 wg_task_retry_handshake(wg, wgp);
3193 if (ISSET(tasks, WGP_TASK_ESTABLISH_SESSION))
3194 wg_task_establish_session(wg, wgp);
3195 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED))
3196 wg_task_endpoint_changed(wg, wgp);
3197 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE))
3198 wg_task_send_keepalive_message(wg, wgp);
3199 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION))
3200 wg_task_destroy_prev_session(wg, wgp);
3201 mutex_exit(wgp->wgp_lock);
3202
3203 mutex_enter(wgp->wgp_intr_lock);
3204 }
3205 mutex_exit(wgp->wgp_intr_lock);
3206 }
3207
3208 static void
3209 wg_job(struct threadpool_job *job)
3210 {
3211 struct wg_softc *wg = container_of(job, struct wg_softc, wg_job);
3212 int bound, upcalls;
3213
3214 mutex_enter(wg->wg_intr_lock);
3215 while ((upcalls = wg->wg_upcalls) != 0) {
3216 wg->wg_upcalls = 0;
3217 mutex_exit(wg->wg_intr_lock);
3218 bound = curlwp_bind();
3219 if (ISSET(upcalls, WG_UPCALL_INET))
3220 wg_receive_packets(wg, AF_INET);
3221 if (ISSET(upcalls, WG_UPCALL_INET6))
3222 wg_receive_packets(wg, AF_INET6);
3223 curlwp_bindx(bound);
3224 mutex_enter(wg->wg_intr_lock);
3225 }
3226 threadpool_job_done(job);
3227 mutex_exit(wg->wg_intr_lock);
3228 }
3229
3230 static int
3231 wg_bind_port(struct wg_softc *wg, const uint16_t port)
3232 {
3233 int error;
3234 uint16_t old_port = wg->wg_listen_port;
3235
3236 if (port != 0 && old_port == port)
3237 return 0;
3238
3239 struct sockaddr_in _sin, *sin = &_sin;
3240 sin->sin_len = sizeof(*sin);
3241 sin->sin_family = AF_INET;
3242 sin->sin_addr.s_addr = INADDR_ANY;
3243 sin->sin_port = htons(port);
3244
3245 error = sobind(wg->wg_so4, sintosa(sin), curlwp);
3246 if (error != 0)
3247 return error;
3248
3249 #ifdef INET6
3250 struct sockaddr_in6 _sin6, *sin6 = &_sin6;
3251 sin6->sin6_len = sizeof(*sin6);
3252 sin6->sin6_family = AF_INET6;
3253 sin6->sin6_addr = in6addr_any;
3254 sin6->sin6_port = htons(port);
3255
3256 error = sobind(wg->wg_so6, sin6tosa(sin6), curlwp);
3257 if (error != 0)
3258 return error;
3259 #endif
3260
3261 wg->wg_listen_port = port;
3262
3263 return 0;
3264 }
3265
3266 static void
3267 wg_so_upcall(struct socket *so, void *cookie, int events, int waitflag)
3268 {
3269 struct wg_softc *wg = cookie;
3270 int reason;
3271
3272 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ?
3273 WG_UPCALL_INET :
3274 WG_UPCALL_INET6;
3275
3276 mutex_enter(wg->wg_intr_lock);
3277 wg->wg_upcalls |= reason;
3278 threadpool_schedule_job(wg->wg_threadpool, &wg->wg_job);
3279 mutex_exit(wg->wg_intr_lock);
3280 }
3281
3282 static int
3283 wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so,
3284 struct sockaddr *src, void *arg)
3285 {
3286 struct wg_softc *wg = arg;
3287 struct wg_msg wgm;
3288 struct mbuf *m = *mp;
3289
3290 WG_TRACE("enter");
3291
3292 /* Verify the mbuf chain is long enough to have a wg msg header. */
3293 KASSERT(offset <= m_length(m));
3294 if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) {
3295 /* drop on the floor */
3296 m_freem(m);
3297 return -1;
3298 }
3299
3300 /*
3301 * Copy the message header (32-bit message type) out -- we'll
3302 * worry about contiguity and alignment later.
3303 */
3304 m_copydata(m, offset, sizeof(struct wg_msg), &wgm);
3305 WG_DLOG("type=%d\n", le32toh(wgm.wgm_type));
3306
3307 /*
3308 * Handle DATA packets promptly as they arrive. Other packets
3309 * may require expensive public-key crypto and are not as
3310 * sensitive to latency, so defer them to the worker thread.
3311 */
3312 switch (le32toh(wgm.wgm_type)) {
3313 case WG_MSG_TYPE_DATA:
3314 /* handle immediately */
3315 m_adj(m, offset);
3316 if (__predict_false(m->m_len < sizeof(struct wg_msg_data))) {
3317 m = m_pullup(m, sizeof(struct wg_msg_data));
3318 if (m == NULL)
3319 return -1;
3320 }
3321 wg_handle_msg_data(wg, m, src);
3322 *mp = NULL;
3323 return 1;
3324 case WG_MSG_TYPE_INIT:
3325 case WG_MSG_TYPE_RESP:
3326 case WG_MSG_TYPE_COOKIE:
3327 /* pass through to so_receive in wg_receive_packets */
3328 return 0;
3329 default:
3330 /* drop on the floor */
3331 m_freem(m);
3332 return -1;
3333 }
3334 }
3335
3336 static int
3337 wg_socreate(struct wg_softc *wg, int af, struct socket **sop)
3338 {
3339 int error;
3340 struct socket *so;
3341
3342 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL);
3343 if (error != 0)
3344 return error;
3345
3346 solock(so);
3347 so->so_upcallarg = wg;
3348 so->so_upcall = wg_so_upcall;
3349 so->so_rcv.sb_flags |= SB_UPCALL;
3350 inpcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg);
3351 sounlock(so);
3352
3353 *sop = so;
3354
3355 return 0;
3356 }
3357
3358 static bool
3359 wg_session_hit_limits(struct wg_session *wgs)
3360 {
3361
3362 /*
3363 * [W] 6.2: Transport Message Limits
3364 * "After REJECT-AFTER-MESSAGES transport data messages or after the
3365 * current secure session is REJECT-AFTER-TIME seconds old, whichever
3366 * comes first, WireGuard will refuse to send any more transport data
3367 * messages using the current secure session, ..."
3368 */
3369 KASSERT(wgs->wgs_time_established != 0);
3370 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) {
3371 WG_DLOG("The session hits REJECT_AFTER_TIME\n");
3372 return true;
3373 } else if (wg_session_get_send_counter(wgs) >
3374 wg_reject_after_messages) {
3375 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n");
3376 return true;
3377 }
3378
3379 return false;
3380 }
3381
3382 static void
3383 wgintr(void *cookie)
3384 {
3385 struct wg_peer *wgp;
3386 struct wg_session *wgs;
3387 struct mbuf *m;
3388 struct psref psref;
3389
3390 while ((m = pktq_dequeue(wg_pktq)) != NULL) {
3391 wgp = M_GETCTX(m, struct wg_peer *);
3392 if ((wgs = wg_get_stable_session(wgp, &psref)) == NULL) {
3393 WG_TRACE("no stable session");
3394 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3395 goto next0;
3396 }
3397 if (__predict_false(wg_session_hit_limits(wgs))) {
3398 WG_TRACE("stable session hit limits");
3399 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3400 goto next1;
3401 }
3402 wg_send_data_msg(wgp, wgs, m);
3403 m = NULL; /* consumed */
3404 next1: wg_put_session(wgs, &psref);
3405 next0: m_freem(m);
3406 /* XXX Yield to avoid userland starvation? */
3407 }
3408 }
3409
3410 static void
3411 wg_rekey_timer(void *arg)
3412 {
3413 struct wg_peer *wgp = arg;
3414
3415 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3416 }
3417
3418 static void
3419 wg_purge_pending_packets(struct wg_peer *wgp)
3420 {
3421 struct mbuf *m;
3422
3423 m = atomic_swap_ptr(&wgp->wgp_pending, NULL);
3424 m_freem(m);
3425 pktq_barrier(wg_pktq);
3426 }
3427
3428 static void
3429 wg_handshake_timeout_timer(void *arg)
3430 {
3431 struct wg_peer *wgp = arg;
3432
3433 WG_TRACE("enter");
3434
3435 wg_schedule_peer_task(wgp, WGP_TASK_RETRY_HANDSHAKE);
3436 }
3437
3438 static struct wg_peer *
3439 wg_alloc_peer(struct wg_softc *wg)
3440 {
3441 struct wg_peer *wgp;
3442
3443 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP);
3444
3445 wgp->wgp_sc = wg;
3446 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE);
3447 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp);
3448 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE);
3449 callout_setfunc(&wgp->wgp_handshake_timeout_timer,
3450 wg_handshake_timeout_timer, wgp);
3451 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE);
3452 callout_setfunc(&wgp->wgp_session_dtor_timer,
3453 wg_session_dtor_timer, wgp);
3454 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry);
3455 wgp->wgp_endpoint_changing = false;
3456 wgp->wgp_endpoint_available = false;
3457 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3458 wgp->wgp_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
3459 wgp->wgp_psz = pserialize_create();
3460 psref_target_init(&wgp->wgp_psref, wg_psref_class);
3461
3462 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP);
3463 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP);
3464 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3465 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3466
3467 struct wg_session *wgs;
3468 wgp->wgp_session_stable =
3469 kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP);
3470 wgp->wgp_session_unstable =
3471 kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP);
3472 wgs = wgp->wgp_session_stable;
3473 wgs->wgs_peer = wgp;
3474 wgs->wgs_state = WGS_STATE_UNKNOWN;
3475 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3476 #ifndef __HAVE_ATOMIC64_LOADSTORE
3477 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3478 #endif
3479 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3480 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_SOFTNET);
3481
3482 wgs = wgp->wgp_session_unstable;
3483 wgs->wgs_peer = wgp;
3484 wgs->wgs_state = WGS_STATE_UNKNOWN;
3485 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3486 #ifndef __HAVE_ATOMIC64_LOADSTORE
3487 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3488 #endif
3489 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3490 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_SOFTNET);
3491
3492 return wgp;
3493 }
3494
3495 static void
3496 wg_destroy_peer(struct wg_peer *wgp)
3497 {
3498 struct wg_session *wgs;
3499 struct wg_softc *wg = wgp->wgp_sc;
3500
3501 /* Prevent new packets from this peer on any source address. */
3502 rw_enter(wg->wg_rwlock, RW_WRITER);
3503 for (int i = 0; i < wgp->wgp_n_allowedips; i++) {
3504 struct wg_allowedip *wga = &wgp->wgp_allowedips[i];
3505 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family);
3506 struct radix_node *rn;
3507
3508 KASSERT(rnh != NULL);
3509 rn = rnh->rnh_deladdr(&wga->wga_sa_addr,
3510 &wga->wga_sa_mask, rnh);
3511 if (rn == NULL) {
3512 char addrstr[128];
3513 sockaddr_format(&wga->wga_sa_addr, addrstr,
3514 sizeof(addrstr));
3515 WGLOG(LOG_WARNING, "%s: Couldn't delete %s",
3516 if_name(&wg->wg_if), addrstr);
3517 }
3518 }
3519 rw_exit(wg->wg_rwlock);
3520
3521 /* Purge pending packets. */
3522 wg_purge_pending_packets(wgp);
3523
3524 /* Halt all packet processing and timeouts. */
3525 callout_halt(&wgp->wgp_rekey_timer, NULL);
3526 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL);
3527 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
3528
3529 /* Wait for any queued work to complete. */
3530 workqueue_wait(wg_wq, &wgp->wgp_work);
3531
3532 wgs = wgp->wgp_session_unstable;
3533 if (wgs->wgs_state != WGS_STATE_UNKNOWN) {
3534 mutex_enter(wgp->wgp_lock);
3535 wg_destroy_session(wg, wgs);
3536 mutex_exit(wgp->wgp_lock);
3537 }
3538 mutex_destroy(&wgs->wgs_recvwin->lock);
3539 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3540 #ifndef __HAVE_ATOMIC64_LOADSTORE
3541 mutex_destroy(&wgs->wgs_send_counter_lock);
3542 #endif
3543 kmem_free(wgs, sizeof(*wgs));
3544
3545 wgs = wgp->wgp_session_stable;
3546 if (wgs->wgs_state != WGS_STATE_UNKNOWN) {
3547 mutex_enter(wgp->wgp_lock);
3548 wg_destroy_session(wg, wgs);
3549 mutex_exit(wgp->wgp_lock);
3550 }
3551 mutex_destroy(&wgs->wgs_recvwin->lock);
3552 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3553 #ifndef __HAVE_ATOMIC64_LOADSTORE
3554 mutex_destroy(&wgs->wgs_send_counter_lock);
3555 #endif
3556 kmem_free(wgs, sizeof(*wgs));
3557
3558 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3559 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3560 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint));
3561 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0));
3562
3563 pserialize_destroy(wgp->wgp_psz);
3564 mutex_obj_free(wgp->wgp_intr_lock);
3565 mutex_obj_free(wgp->wgp_lock);
3566
3567 kmem_free(wgp, sizeof(*wgp));
3568 }
3569
3570 static void
3571 wg_destroy_all_peers(struct wg_softc *wg)
3572 {
3573 struct wg_peer *wgp, *wgp0 __diagused;
3574 void *garbage_byname, *garbage_bypubkey;
3575
3576 restart:
3577 garbage_byname = garbage_bypubkey = NULL;
3578 mutex_enter(wg->wg_lock);
3579 WG_PEER_WRITER_FOREACH(wgp, wg) {
3580 if (wgp->wgp_name[0]) {
3581 wgp0 = thmap_del(wg->wg_peers_byname, wgp->wgp_name,
3582 strlen(wgp->wgp_name));
3583 KASSERT(wgp0 == wgp);
3584 garbage_byname = thmap_stage_gc(wg->wg_peers_byname);
3585 }
3586 wgp0 = thmap_del(wg->wg_peers_bypubkey, wgp->wgp_pubkey,
3587 sizeof(wgp->wgp_pubkey));
3588 KASSERT(wgp0 == wgp);
3589 garbage_bypubkey = thmap_stage_gc(wg->wg_peers_bypubkey);
3590 WG_PEER_WRITER_REMOVE(wgp);
3591 wg->wg_npeers--;
3592 mutex_enter(wgp->wgp_lock);
3593 pserialize_perform(wgp->wgp_psz);
3594 mutex_exit(wgp->wgp_lock);
3595 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3596 break;
3597 }
3598 mutex_exit(wg->wg_lock);
3599
3600 if (wgp == NULL)
3601 return;
3602
3603 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3604
3605 wg_destroy_peer(wgp);
3606 thmap_gc(wg->wg_peers_byname, garbage_byname);
3607 thmap_gc(wg->wg_peers_bypubkey, garbage_bypubkey);
3608
3609 goto restart;
3610 }
3611
3612 static int
3613 wg_destroy_peer_name(struct wg_softc *wg, const char *name)
3614 {
3615 struct wg_peer *wgp, *wgp0 __diagused;
3616 void *garbage_byname, *garbage_bypubkey;
3617
3618 mutex_enter(wg->wg_lock);
3619 wgp = thmap_del(wg->wg_peers_byname, name, strlen(name));
3620 if (wgp != NULL) {
3621 wgp0 = thmap_del(wg->wg_peers_bypubkey, wgp->wgp_pubkey,
3622 sizeof(wgp->wgp_pubkey));
3623 KASSERT(wgp0 == wgp);
3624 garbage_byname = thmap_stage_gc(wg->wg_peers_byname);
3625 garbage_bypubkey = thmap_stage_gc(wg->wg_peers_bypubkey);
3626 WG_PEER_WRITER_REMOVE(wgp);
3627 wg->wg_npeers--;
3628 if (wg->wg_npeers == 0)
3629 if_link_state_change(&wg->wg_if, LINK_STATE_DOWN);
3630 mutex_enter(wgp->wgp_lock);
3631 pserialize_perform(wgp->wgp_psz);
3632 mutex_exit(wgp->wgp_lock);
3633 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3634 }
3635 mutex_exit(wg->wg_lock);
3636
3637 if (wgp == NULL)
3638 return ENOENT;
3639
3640 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3641
3642 wg_destroy_peer(wgp);
3643 thmap_gc(wg->wg_peers_byname, garbage_byname);
3644 thmap_gc(wg->wg_peers_bypubkey, garbage_bypubkey);
3645
3646 return 0;
3647 }
3648
3649 static int
3650 wg_if_attach(struct wg_softc *wg)
3651 {
3652
3653 wg->wg_if.if_addrlen = 0;
3654 wg->wg_if.if_mtu = WG_MTU;
3655 wg->wg_if.if_flags = IFF_MULTICAST;
3656 wg->wg_if.if_extflags = IFEF_MPSAFE;
3657 wg->wg_if.if_ioctl = wg_ioctl;
3658 wg->wg_if.if_output = wg_output;
3659 wg->wg_if.if_init = wg_init;
3660 #ifdef ALTQ
3661 wg->wg_if.if_start = wg_start;
3662 #endif
3663 wg->wg_if.if_stop = wg_stop;
3664 wg->wg_if.if_type = IFT_OTHER;
3665 wg->wg_if.if_dlt = DLT_NULL;
3666 wg->wg_if.if_softc = wg;
3667 #ifdef ALTQ
3668 IFQ_SET_READY(&wg->wg_if.if_snd);
3669 #endif
3670 if_initialize(&wg->wg_if);
3671
3672 wg->wg_if.if_link_state = LINK_STATE_DOWN;
3673 if_alloc_sadl(&wg->wg_if);
3674 if_register(&wg->wg_if);
3675
3676 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t));
3677
3678 return 0;
3679 }
3680
3681 static void
3682 wg_if_detach(struct wg_softc *wg)
3683 {
3684 struct ifnet *ifp = &wg->wg_if;
3685
3686 bpf_detach(ifp);
3687 if_detach(ifp);
3688 }
3689
3690 static int
3691 wg_clone_create(struct if_clone *ifc, int unit)
3692 {
3693 struct wg_softc *wg;
3694 int error;
3695
3696 wg_guarantee_initialized();
3697
3698 error = wg_count_inc();
3699 if (error)
3700 return error;
3701
3702 wg = kmem_zalloc(sizeof(*wg), KM_SLEEP);
3703
3704 if_initname(&wg->wg_if, ifc->ifc_name, unit);
3705
3706 PSLIST_INIT(&wg->wg_peers);
3707 wg->wg_peers_bypubkey = thmap_create(0, NULL, THMAP_NOCOPY);
3708 wg->wg_peers_byname = thmap_create(0, NULL, THMAP_NOCOPY);
3709 wg->wg_sessions_byindex = thmap_create(0, NULL, THMAP_NOCOPY);
3710 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3711 wg->wg_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
3712 wg->wg_rwlock = rw_obj_alloc();
3713 threadpool_job_init(&wg->wg_job, wg_job, wg->wg_intr_lock,
3714 "%s", if_name(&wg->wg_if));
3715 wg->wg_ops = &wg_ops_rumpkernel;
3716
3717 error = threadpool_get(&wg->wg_threadpool, PRI_NONE);
3718 if (error)
3719 goto fail0;
3720
3721 #ifdef INET
3722 error = wg_socreate(wg, AF_INET, &wg->wg_so4);
3723 if (error)
3724 goto fail1;
3725 rn_inithead((void **)&wg->wg_rtable_ipv4,
3726 offsetof(struct sockaddr_in, sin_addr) * NBBY);
3727 #endif
3728 #ifdef INET6
3729 error = wg_socreate(wg, AF_INET6, &wg->wg_so6);
3730 if (error)
3731 goto fail2;
3732 rn_inithead((void **)&wg->wg_rtable_ipv6,
3733 offsetof(struct sockaddr_in6, sin6_addr) * NBBY);
3734 #endif
3735
3736 error = wg_if_attach(wg);
3737 if (error)
3738 goto fail3;
3739
3740 return 0;
3741
3742 fail4: __unused
3743 wg_if_detach(wg);
3744 fail3: wg_destroy_all_peers(wg);
3745 #ifdef INET6
3746 solock(wg->wg_so6);
3747 wg->wg_so6->so_rcv.sb_flags &= ~SB_UPCALL;
3748 sounlock(wg->wg_so6);
3749 #endif
3750 #ifdef INET
3751 solock(wg->wg_so4);
3752 wg->wg_so4->so_rcv.sb_flags &= ~SB_UPCALL;
3753 sounlock(wg->wg_so4);
3754 #endif
3755 mutex_enter(wg->wg_intr_lock);
3756 threadpool_cancel_job(wg->wg_threadpool, &wg->wg_job);
3757 mutex_exit(wg->wg_intr_lock);
3758 #ifdef INET6
3759 if (wg->wg_rtable_ipv6 != NULL)
3760 free(wg->wg_rtable_ipv6, M_RTABLE);
3761 soclose(wg->wg_so6);
3762 fail2:
3763 #endif
3764 #ifdef INET
3765 if (wg->wg_rtable_ipv4 != NULL)
3766 free(wg->wg_rtable_ipv4, M_RTABLE);
3767 soclose(wg->wg_so4);
3768 fail1:
3769 #endif
3770 threadpool_put(wg->wg_threadpool, PRI_NONE);
3771 fail0: threadpool_job_destroy(&wg->wg_job);
3772 rw_obj_free(wg->wg_rwlock);
3773 mutex_obj_free(wg->wg_intr_lock);
3774 mutex_obj_free(wg->wg_lock);
3775 thmap_destroy(wg->wg_sessions_byindex);
3776 thmap_destroy(wg->wg_peers_byname);
3777 thmap_destroy(wg->wg_peers_bypubkey);
3778 PSLIST_DESTROY(&wg->wg_peers);
3779 kmem_free(wg, sizeof(*wg));
3780 wg_count_dec();
3781 return error;
3782 }
3783
3784 static int
3785 wg_clone_destroy(struct ifnet *ifp)
3786 {
3787 struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if);
3788
3789 #ifdef WG_RUMPKERNEL
3790 if (wg_user_mode(wg)) {
3791 rumpuser_wg_destroy(wg->wg_user);
3792 wg->wg_user = NULL;
3793 }
3794 #endif
3795
3796 wg_if_detach(wg);
3797 wg_destroy_all_peers(wg);
3798 #ifdef INET6
3799 solock(wg->wg_so6);
3800 wg->wg_so6->so_rcv.sb_flags &= ~SB_UPCALL;
3801 sounlock(wg->wg_so6);
3802 #endif
3803 #ifdef INET
3804 solock(wg->wg_so4);
3805 wg->wg_so4->so_rcv.sb_flags &= ~SB_UPCALL;
3806 sounlock(wg->wg_so4);
3807 #endif
3808 mutex_enter(wg->wg_intr_lock);
3809 threadpool_cancel_job(wg->wg_threadpool, &wg->wg_job);
3810 mutex_exit(wg->wg_intr_lock);
3811 #ifdef INET6
3812 if (wg->wg_rtable_ipv6 != NULL)
3813 free(wg->wg_rtable_ipv6, M_RTABLE);
3814 soclose(wg->wg_so6);
3815 #endif
3816 #ifdef INET
3817 if (wg->wg_rtable_ipv4 != NULL)
3818 free(wg->wg_rtable_ipv4, M_RTABLE);
3819 soclose(wg->wg_so4);
3820 #endif
3821 threadpool_put(wg->wg_threadpool, PRI_NONE);
3822 threadpool_job_destroy(&wg->wg_job);
3823 rw_obj_free(wg->wg_rwlock);
3824 mutex_obj_free(wg->wg_intr_lock);
3825 mutex_obj_free(wg->wg_lock);
3826 thmap_destroy(wg->wg_sessions_byindex);
3827 thmap_destroy(wg->wg_peers_byname);
3828 thmap_destroy(wg->wg_peers_bypubkey);
3829 PSLIST_DESTROY(&wg->wg_peers);
3830 kmem_free(wg, sizeof(*wg));
3831 wg_count_dec();
3832
3833 return 0;
3834 }
3835
3836 static struct wg_peer *
3837 wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa,
3838 struct psref *psref)
3839 {
3840 struct radix_node_head *rnh;
3841 struct radix_node *rn;
3842 struct wg_peer *wgp = NULL;
3843 struct wg_allowedip *wga;
3844
3845 #ifdef WG_DEBUG_LOG
3846 char addrstr[128];
3847 sockaddr_format(sa, addrstr, sizeof(addrstr));
3848 WG_DLOG("sa=%s\n", addrstr);
3849 #endif
3850
3851 rw_enter(wg->wg_rwlock, RW_READER);
3852
3853 rnh = wg_rnh(wg, sa->sa_family);
3854 if (rnh == NULL)
3855 goto out;
3856
3857 rn = rnh->rnh_matchaddr(sa, rnh);
3858 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
3859 goto out;
3860
3861 WG_TRACE("success");
3862
3863 wga = container_of(rn, struct wg_allowedip, wga_nodes[0]);
3864 wgp = wga->wga_peer;
3865 wg_get_peer(wgp, psref);
3866
3867 out:
3868 rw_exit(wg->wg_rwlock);
3869 return wgp;
3870 }
3871
3872 static void
3873 wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp,
3874 struct wg_session *wgs, struct wg_msg_data *wgmd)
3875 {
3876
3877 memset(wgmd, 0, sizeof(*wgmd));
3878 wgmd->wgmd_type = htole32(WG_MSG_TYPE_DATA);
3879 wgmd->wgmd_receiver = wgs->wgs_remote_index;
3880 /* [W] 5.4.6: msg.counter := Nm^send */
3881 /* [W] 5.4.6: Nm^send := Nm^send + 1 */
3882 wgmd->wgmd_counter = htole64(wg_session_inc_send_counter(wgs));
3883 WG_DLOG("counter=%"PRIu64"\n", le64toh(wgmd->wgmd_counter));
3884 }
3885
3886 static int
3887 wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
3888 const struct rtentry *rt)
3889 {
3890 struct wg_softc *wg = ifp->if_softc;
3891 struct wg_peer *wgp = NULL;
3892 struct wg_session *wgs = NULL;
3893 struct psref wgp_psref, wgs_psref;
3894 int bound;
3895 int error;
3896
3897 bound = curlwp_bind();
3898
3899 /* TODO make the nest limit configurable via sysctl */
3900 error = if_tunnel_check_nesting(ifp, m, 1);
3901 if (error) {
3902 WGLOG(LOG_ERR,
3903 "%s: tunneling loop detected and packet dropped\n",
3904 if_name(&wg->wg_if));
3905 goto out0;
3906 }
3907
3908 #ifdef ALTQ
3909 bool altq = atomic_load_relaxed(&ifp->if_snd.altq_flags)
3910 & ALTQF_ENABLED;
3911 if (altq)
3912 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
3913 #endif
3914
3915 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT);
3916
3917 m->m_flags &= ~(M_BCAST|M_MCAST);
3918
3919 wgp = wg_pick_peer_by_sa(wg, dst, &wgp_psref);
3920 if (wgp == NULL) {
3921 WG_TRACE("peer not found");
3922 error = EHOSTUNREACH;
3923 goto out0;
3924 }
3925
3926 /* Clear checksum-offload flags. */
3927 m->m_pkthdr.csum_flags = 0;
3928 m->m_pkthdr.csum_data = 0;
3929
3930 /* Check whether there's an established session. */
3931 wgs = wg_get_stable_session(wgp, &wgs_psref);
3932 if (wgs == NULL) {
3933 /*
3934 * No established session. If we're the first to try
3935 * sending data, schedule a handshake and queue the
3936 * packet for when the handshake is done; otherwise
3937 * just drop the packet and let the ongoing handshake
3938 * attempt continue. We could queue more data packets
3939 * but it's not clear that's worthwhile.
3940 */
3941 if (atomic_cas_ptr(&wgp->wgp_pending, NULL, m) == NULL) {
3942 m = NULL; /* consume */
3943 WG_TRACE("queued first packet; init handshake");
3944 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3945 } else {
3946 WG_TRACE("first packet already queued, dropping");
3947 }
3948 goto out1;
3949 }
3950
3951 /* There's an established session. Toss it in the queue. */
3952 #ifdef ALTQ
3953 if (altq) {
3954 mutex_enter(ifp->if_snd.ifq_lock);
3955 if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
3956 M_SETCTX(m, wgp);
3957 ALTQ_ENQUEUE(&ifp->if_snd, m, error);
3958 m = NULL; /* consume */
3959 }
3960 mutex_exit(ifp->if_snd.ifq_lock);
3961 if (m == NULL) {
3962 wg_start(ifp);
3963 goto out2;
3964 }
3965 }
3966 #endif
3967 kpreempt_disable();
3968 const uint32_t h = curcpu()->ci_index; // pktq_rps_hash(m)
3969 M_SETCTX(m, wgp);
3970 if (__predict_false(!pktq_enqueue(wg_pktq, m, h))) {
3971 WGLOG(LOG_ERR, "%s: pktq full, dropping\n",
3972 if_name(&wg->wg_if));
3973 error = ENOBUFS;
3974 goto out3;
3975 }
3976 m = NULL; /* consumed */
3977 error = 0;
3978 out3: kpreempt_enable();
3979
3980 #ifdef ALTQ
3981 out2:
3982 #endif
3983 wg_put_session(wgs, &wgs_psref);
3984 out1: wg_put_peer(wgp, &wgp_psref);
3985 out0: m_freem(m);
3986 curlwp_bindx(bound);
3987 return error;
3988 }
3989
3990 static int
3991 wg_send_udp(struct wg_peer *wgp, struct mbuf *m)
3992 {
3993 struct psref psref;
3994 struct wg_sockaddr *wgsa;
3995 int error;
3996 struct socket *so;
3997
3998 wgsa = wg_get_endpoint_sa(wgp, &psref);
3999 so = wg_get_so_by_peer(wgp, wgsa);
4000 solock(so);
4001 if (wgsatosa(wgsa)->sa_family == AF_INET) {
4002 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp);
4003 } else {
4004 #ifdef INET6
4005 error = udp6_output(sotoinpcb(so), m, wgsatosin6(wgsa),
4006 NULL, curlwp);
4007 #else
4008 m_freem(m);
4009 error = EPFNOSUPPORT;
4010 #endif
4011 }
4012 sounlock(so);
4013 wg_put_sa(wgp, wgsa, &psref);
4014
4015 return error;
4016 }
4017
4018 /* Inspired by pppoe_get_mbuf */
4019 static struct mbuf *
4020 wg_get_mbuf(size_t leading_len, size_t len)
4021 {
4022 struct mbuf *m;
4023
4024 KASSERT(leading_len <= MCLBYTES);
4025 KASSERT(len <= MCLBYTES - leading_len);
4026
4027 m = m_gethdr(M_DONTWAIT, MT_DATA);
4028 if (m == NULL)
4029 return NULL;
4030 if (len + leading_len > MHLEN) {
4031 m_clget(m, M_DONTWAIT);
4032 if ((m->m_flags & M_EXT) == 0) {
4033 m_free(m);
4034 return NULL;
4035 }
4036 }
4037 m->m_data += leading_len;
4038 m->m_pkthdr.len = m->m_len = len;
4039
4040 return m;
4041 }
4042
4043 static int
4044 wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs,
4045 struct mbuf *m)
4046 {
4047 struct wg_softc *wg = wgp->wgp_sc;
4048 int error;
4049 size_t inner_len, padded_len, encrypted_len;
4050 char *padded_buf = NULL;
4051 size_t mlen;
4052 struct wg_msg_data *wgmd;
4053 bool free_padded_buf = false;
4054 struct mbuf *n;
4055 size_t leading_len = max_hdr + sizeof(struct udphdr);
4056
4057 mlen = m_length(m);
4058 inner_len = mlen;
4059 padded_len = roundup(mlen, 16);
4060 encrypted_len = padded_len + WG_AUTHTAG_LEN;
4061 WG_DLOG("inner=%lu, padded=%lu, encrypted_len=%lu\n",
4062 inner_len, padded_len, encrypted_len);
4063 if (mlen != 0) {
4064 bool success;
4065 success = m_ensure_contig(&m, padded_len);
4066 if (success) {
4067 padded_buf = mtod(m, char *);
4068 } else {
4069 padded_buf = kmem_intr_alloc(padded_len, KM_NOSLEEP);
4070 if (padded_buf == NULL) {
4071 error = ENOBUFS;
4072 goto end;
4073 }
4074 free_padded_buf = true;
4075 m_copydata(m, 0, mlen, padded_buf);
4076 }
4077 memset(padded_buf + mlen, 0, padded_len - inner_len);
4078 }
4079
4080 n = wg_get_mbuf(leading_len, sizeof(*wgmd) + encrypted_len);
4081 if (n == NULL) {
4082 error = ENOBUFS;
4083 goto end;
4084 }
4085 KASSERT(n->m_len >= sizeof(*wgmd));
4086 wgmd = mtod(n, struct wg_msg_data *);
4087 wg_fill_msg_data(wg, wgp, wgs, wgmd);
4088 #ifdef WG_DEBUG_PACKET
4089 if (wg_debug & WG_DEBUG_FLAGS_PACKET) {
4090 hexdump(aprint_debug, "wgmd", wgmd, sizeof(*wgmd));
4091 hexdump(aprint_debug, "padded_buf", padded_buf,
4092 padded_len);
4093 }
4094 #endif
4095 /* [W] 5.4.6: AEAD(Tm^send, Nm^send, P, e) */
4096 wg_algo_aead_enc((char *)wgmd + sizeof(*wgmd), encrypted_len,
4097 wgs->wgs_tkey_send, le64toh(wgmd->wgmd_counter),
4098 padded_buf, padded_len,
4099 NULL, 0);
4100
4101 error = wg->wg_ops->send_data_msg(wgp, n);
4102 if (error == 0) {
4103 struct ifnet *ifp = &wg->wg_if;
4104 if_statadd(ifp, if_obytes, mlen);
4105 if_statinc(ifp, if_opackets);
4106 if (wgs->wgs_is_initiator &&
4107 wgs->wgs_time_last_data_sent == 0) {
4108 /*
4109 * [W] 6.2 Transport Message Limits
4110 * "if a peer is the initiator of a current secure
4111 * session, WireGuard will send a handshake initiation
4112 * message to begin a new secure session if, after
4113 * transmitting a transport data message, the current
4114 * secure session is REKEY-AFTER-TIME seconds old,"
4115 */
4116 wg_schedule_rekey_timer(wgp);
4117 }
4118 wgs->wgs_time_last_data_sent = time_uptime;
4119 if (wg_session_get_send_counter(wgs) >=
4120 wg_rekey_after_messages) {
4121 /*
4122 * [W] 6.2 Transport Message Limits
4123 * "WireGuard will try to create a new session, by
4124 * sending a handshake initiation message (section
4125 * 5.4.2), after it has sent REKEY-AFTER-MESSAGES
4126 * transport data messages..."
4127 */
4128 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
4129 }
4130 }
4131 end:
4132 m_freem(m);
4133 if (free_padded_buf)
4134 kmem_intr_free(padded_buf, padded_len);
4135 return error;
4136 }
4137
4138 static void
4139 wg_input(struct ifnet *ifp, struct mbuf *m, const int af)
4140 {
4141 pktqueue_t *pktq;
4142 size_t pktlen;
4143
4144 KASSERT(af == AF_INET || af == AF_INET6);
4145
4146 WG_TRACE("");
4147
4148 m_set_rcvif(m, ifp);
4149 pktlen = m->m_pkthdr.len;
4150
4151 bpf_mtap_af(ifp, af, m, BPF_D_IN);
4152
4153 switch (af) {
4154 case AF_INET:
4155 pktq = ip_pktq;
4156 break;
4157 #ifdef INET6
4158 case AF_INET6:
4159 pktq = ip6_pktq;
4160 break;
4161 #endif
4162 default:
4163 panic("invalid af=%d", af);
4164 }
4165
4166 kpreempt_disable();
4167 const u_int h = curcpu()->ci_index;
4168 if (__predict_true(pktq_enqueue(pktq, m, h))) {
4169 if_statadd(ifp, if_ibytes, pktlen);
4170 if_statinc(ifp, if_ipackets);
4171 } else {
4172 m_freem(m);
4173 }
4174 kpreempt_enable();
4175 }
4176
4177 static void
4178 wg_calc_pubkey(uint8_t pubkey[WG_STATIC_KEY_LEN],
4179 const uint8_t privkey[WG_STATIC_KEY_LEN])
4180 {
4181
4182 crypto_scalarmult_base(pubkey, privkey);
4183 }
4184
4185 static int
4186 wg_rtable_add_route(struct wg_softc *wg, struct wg_allowedip *wga)
4187 {
4188 struct radix_node_head *rnh;
4189 struct radix_node *rn;
4190 int error = 0;
4191
4192 rw_enter(wg->wg_rwlock, RW_WRITER);
4193 rnh = wg_rnh(wg, wga->wga_family);
4194 KASSERT(rnh != NULL);
4195 rn = rnh->rnh_addaddr(&wga->wga_sa_addr, &wga->wga_sa_mask, rnh,
4196 wga->wga_nodes);
4197 rw_exit(wg->wg_rwlock);
4198
4199 if (rn == NULL)
4200 error = EEXIST;
4201
4202 return error;
4203 }
4204
4205 static int
4206 wg_handle_prop_peer(struct wg_softc *wg, prop_dictionary_t peer,
4207 struct wg_peer **wgpp)
4208 {
4209 int error = 0;
4210 const void *pubkey;
4211 size_t pubkey_len;
4212 const void *psk;
4213 size_t psk_len;
4214 const char *name = NULL;
4215
4216 if (prop_dictionary_get_string(peer, "name", &name)) {
4217 if (strlen(name) > WG_PEER_NAME_MAXLEN) {
4218 error = EINVAL;
4219 goto out;
4220 }
4221 }
4222
4223 if (!prop_dictionary_get_data(peer, "public_key",
4224 &pubkey, &pubkey_len)) {
4225 error = EINVAL;
4226 goto out;
4227 }
4228 #ifdef WG_DEBUG_DUMP
4229 if (wg_debug & WG_DEBUG_FLAGS_DUMP) {
4230 char *hex = gethexdump(pubkey, pubkey_len);
4231 log(LOG_DEBUG, "pubkey=%p, pubkey_len=%lu\n%s\n",
4232 pubkey, pubkey_len, hex);
4233 puthexdump(hex, pubkey, pubkey_len);
4234 }
4235 #endif
4236
4237 struct wg_peer *wgp = wg_alloc_peer(wg);
4238 memcpy(wgp->wgp_pubkey, pubkey, sizeof(wgp->wgp_pubkey));
4239 if (name != NULL)
4240 strncpy(wgp->wgp_name, name, sizeof(wgp->wgp_name));
4241
4242 if (prop_dictionary_get_data(peer, "preshared_key", &psk, &psk_len)) {
4243 if (psk_len != sizeof(wgp->wgp_psk)) {
4244 error = EINVAL;
4245 goto out;
4246 }
4247 memcpy(wgp->wgp_psk, psk, sizeof(wgp->wgp_psk));
4248 }
4249
4250 const void *addr;
4251 size_t addr_len;
4252 struct wg_sockaddr *wgsa = wgp->wgp_endpoint;
4253
4254 if (!prop_dictionary_get_data(peer, "endpoint", &addr, &addr_len))
4255 goto skip_endpoint;
4256 if (addr_len < sizeof(*wgsatosa(wgsa)) ||
4257 addr_len > sizeof(*wgsatoss(wgsa))) {
4258 error = EINVAL;
4259 goto out;
4260 }
4261 memcpy(wgsatoss(wgsa), addr, addr_len);
4262 switch (wgsa_family(wgsa)) {
4263 case AF_INET:
4264 #ifdef INET6
4265 case AF_INET6:
4266 #endif
4267 break;
4268 default:
4269 error = EPFNOSUPPORT;
4270 goto out;
4271 }
4272 if (addr_len != sockaddr_getsize_by_family(wgsa_family(wgsa))) {
4273 error = EINVAL;
4274 goto out;
4275 }
4276 {
4277 char addrstr[128];
4278 sockaddr_format(wgsatosa(wgsa), addrstr, sizeof(addrstr));
4279 WG_DLOG("addr=%s\n", addrstr);
4280 }
4281 wgp->wgp_endpoint_available = true;
4282
4283 prop_array_t allowedips;
4284 skip_endpoint:
4285 allowedips = prop_dictionary_get(peer, "allowedips");
4286 if (allowedips == NULL)
4287 goto skip;
4288
4289 prop_object_iterator_t _it = prop_array_iterator(allowedips);
4290 prop_dictionary_t prop_allowedip;
4291 int j = 0;
4292 while ((prop_allowedip = prop_object_iterator_next(_it)) != NULL) {
4293 struct wg_allowedip *wga = &wgp->wgp_allowedips[j];
4294
4295 if (!prop_dictionary_get_int(prop_allowedip, "family",
4296 &wga->wga_family))
4297 continue;
4298 if (!prop_dictionary_get_data(prop_allowedip, "ip",
4299 &addr, &addr_len))
4300 continue;
4301 if (!prop_dictionary_get_uint8(prop_allowedip, "cidr",
4302 &wga->wga_cidr))
4303 continue;
4304
4305 switch (wga->wga_family) {
4306 case AF_INET: {
4307 struct sockaddr_in sin;
4308 char addrstr[128];
4309 struct in_addr mask;
4310 struct sockaddr_in sin_mask;
4311
4312 if (addr_len != sizeof(struct in_addr))
4313 return EINVAL;
4314 memcpy(&wga->wga_addr4, addr, addr_len);
4315
4316 sockaddr_in_init(&sin, (const struct in_addr *)addr,
4317 0);
4318 sockaddr_copy(&wga->wga_sa_addr,
4319 sizeof(sin), sintosa(&sin));
4320
4321 sockaddr_format(sintosa(&sin),
4322 addrstr, sizeof(addrstr));
4323 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
4324
4325 in_len2mask(&mask, wga->wga_cidr);
4326 sockaddr_in_init(&sin_mask, &mask, 0);
4327 sockaddr_copy(&wga->wga_sa_mask,
4328 sizeof(sin_mask), sintosa(&sin_mask));
4329
4330 break;
4331 }
4332 #ifdef INET6
4333 case AF_INET6: {
4334 struct sockaddr_in6 sin6;
4335 char addrstr[128];
4336 struct in6_addr mask;
4337 struct sockaddr_in6 sin6_mask;
4338
4339 if (addr_len != sizeof(struct in6_addr))
4340 return EINVAL;
4341 memcpy(&wga->wga_addr6, addr, addr_len);
4342
4343 sockaddr_in6_init(&sin6, (const struct in6_addr *)addr,
4344 0, 0, 0);
4345 sockaddr_copy(&wga->wga_sa_addr,
4346 sizeof(sin6), sin6tosa(&sin6));
4347
4348 sockaddr_format(sin6tosa(&sin6),
4349 addrstr, sizeof(addrstr));
4350 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
4351
4352 in6_prefixlen2mask(&mask, wga->wga_cidr);
4353 sockaddr_in6_init(&sin6_mask, &mask, 0, 0, 0);
4354 sockaddr_copy(&wga->wga_sa_mask,
4355 sizeof(sin6_mask), sin6tosa(&sin6_mask));
4356
4357 break;
4358 }
4359 #endif
4360 default:
4361 error = EINVAL;
4362 goto out;
4363 }
4364 wga->wga_peer = wgp;
4365
4366 error = wg_rtable_add_route(wg, wga);
4367 if (error != 0)
4368 goto out;
4369
4370 j++;
4371 }
4372 wgp->wgp_n_allowedips = j;
4373 skip:
4374 *wgpp = wgp;
4375 out:
4376 return error;
4377 }
4378
4379 static int
4380 wg_alloc_prop_buf(char **_buf, struct ifdrv *ifd)
4381 {
4382 int error;
4383 char *buf;
4384
4385 WG_DLOG("buf=%p, len=%lu\n", ifd->ifd_data, ifd->ifd_len);
4386 if (ifd->ifd_len >= WG_MAX_PROPLEN)
4387 return E2BIG;
4388 buf = kmem_alloc(ifd->ifd_len + 1, KM_SLEEP);
4389 error = copyin(ifd->ifd_data, buf, ifd->ifd_len);
4390 if (error != 0)
4391 return error;
4392 buf[ifd->ifd_len] = '\0';
4393 #ifdef WG_DEBUG_DUMP
4394 if (wg_debug & WG_DEBUG_FLAGS_DUMP) {
4395 log(LOG_DEBUG, "%.*s\n", (int)MIN(INT_MAX, ifd->ifd_len),
4396 (const char *)buf);
4397 }
4398 #endif
4399 *_buf = buf;
4400 return 0;
4401 }
4402
4403 static int
4404 wg_ioctl_set_private_key(struct wg_softc *wg, struct ifdrv *ifd)
4405 {
4406 int error;
4407 prop_dictionary_t prop_dict;
4408 char *buf = NULL;
4409 const void *privkey;
4410 size_t privkey_len;
4411
4412 error = wg_alloc_prop_buf(&buf, ifd);
4413 if (error != 0)
4414 return error;
4415 error = EINVAL;
4416 prop_dict = prop_dictionary_internalize(buf);
4417 if (prop_dict == NULL)
4418 goto out;
4419 if (!prop_dictionary_get_data(prop_dict, "private_key",
4420 &privkey, &privkey_len))
4421 goto out;
4422 #ifdef WG_DEBUG_DUMP
4423 if (wg_debug & WG_DEBUG_FLAGS_DUMP) {
4424 char *hex = gethexdump(privkey, privkey_len);
4425 log(LOG_DEBUG, "privkey=%p, privkey_len=%lu\n%s\n",
4426 privkey, privkey_len, hex);
4427 puthexdump(hex, privkey, privkey_len);
4428 }
4429 #endif
4430 if (privkey_len != WG_STATIC_KEY_LEN)
4431 goto out;
4432 memcpy(wg->wg_privkey, privkey, WG_STATIC_KEY_LEN);
4433 wg_calc_pubkey(wg->wg_pubkey, wg->wg_privkey);
4434 error = 0;
4435
4436 out:
4437 kmem_free(buf, ifd->ifd_len + 1);
4438 return error;
4439 }
4440
4441 static int
4442 wg_ioctl_set_listen_port(struct wg_softc *wg, struct ifdrv *ifd)
4443 {
4444 int error;
4445 prop_dictionary_t prop_dict;
4446 char *buf = NULL;
4447 uint16_t port;
4448
4449 error = wg_alloc_prop_buf(&buf, ifd);
4450 if (error != 0)
4451 return error;
4452 error = EINVAL;
4453 prop_dict = prop_dictionary_internalize(buf);
4454 if (prop_dict == NULL)
4455 goto out;
4456 if (!prop_dictionary_get_uint16(prop_dict, "listen_port", &port))
4457 goto out;
4458
4459 error = wg->wg_ops->bind_port(wg, (uint16_t)port);
4460
4461 out:
4462 kmem_free(buf, ifd->ifd_len + 1);
4463 return error;
4464 }
4465
4466 static int
4467 wg_ioctl_add_peer(struct wg_softc *wg, struct ifdrv *ifd)
4468 {
4469 int error;
4470 prop_dictionary_t prop_dict;
4471 char *buf = NULL;
4472 struct wg_peer *wgp = NULL, *wgp0 __diagused;
4473
4474 error = wg_alloc_prop_buf(&buf, ifd);
4475 if (error != 0)
4476 return error;
4477 error = EINVAL;
4478 prop_dict = prop_dictionary_internalize(buf);
4479 if (prop_dict == NULL)
4480 goto out;
4481
4482 error = wg_handle_prop_peer(wg, prop_dict, &wgp);
4483 if (error != 0)
4484 goto out;
4485
4486 mutex_enter(wg->wg_lock);
4487 if (thmap_get(wg->wg_peers_bypubkey, wgp->wgp_pubkey,
4488 sizeof(wgp->wgp_pubkey)) != NULL ||
4489 (wgp->wgp_name[0] &&
4490 thmap_get(wg->wg_peers_byname, wgp->wgp_name,
4491 strlen(wgp->wgp_name)) != NULL)) {
4492 mutex_exit(wg->wg_lock);
4493 wg_destroy_peer(wgp);
4494 error = EEXIST;
4495 goto out;
4496 }
4497 wgp0 = thmap_put(wg->wg_peers_bypubkey, wgp->wgp_pubkey,
4498 sizeof(wgp->wgp_pubkey), wgp);
4499 KASSERT(wgp0 == wgp);
4500 if (wgp->wgp_name[0]) {
4501 wgp0 = thmap_put(wg->wg_peers_byname, wgp->wgp_name,
4502 strlen(wgp->wgp_name), wgp);
4503 KASSERT(wgp0 == wgp);
4504 }
4505 WG_PEER_WRITER_INSERT_HEAD(wgp, wg);
4506 wg->wg_npeers++;
4507 mutex_exit(wg->wg_lock);
4508
4509 if_link_state_change(&wg->wg_if, LINK_STATE_UP);
4510
4511 out:
4512 kmem_free(buf, ifd->ifd_len + 1);
4513 return error;
4514 }
4515
4516 static int
4517 wg_ioctl_delete_peer(struct wg_softc *wg, struct ifdrv *ifd)
4518 {
4519 int error;
4520 prop_dictionary_t prop_dict;
4521 char *buf = NULL;
4522 const char *name;
4523
4524 error = wg_alloc_prop_buf(&buf, ifd);
4525 if (error != 0)
4526 return error;
4527 error = EINVAL;
4528 prop_dict = prop_dictionary_internalize(buf);
4529 if (prop_dict == NULL)
4530 goto out;
4531
4532 if (!prop_dictionary_get_string(prop_dict, "name", &name))
4533 goto out;
4534 if (strlen(name) > WG_PEER_NAME_MAXLEN)
4535 goto out;
4536
4537 error = wg_destroy_peer_name(wg, name);
4538 out:
4539 kmem_free(buf, ifd->ifd_len + 1);
4540 return error;
4541 }
4542
4543 static bool
4544 wg_is_authorized(struct wg_softc *wg, u_long cmd)
4545 {
4546 int au = cmd == SIOCGDRVSPEC ?
4547 KAUTH_REQ_NETWORK_INTERFACE_WG_GETPRIV :
4548 KAUTH_REQ_NETWORK_INTERFACE_WG_SETPRIV;
4549 return kauth_authorize_network(kauth_cred_get(),
4550 KAUTH_NETWORK_INTERFACE_WG, au, &wg->wg_if,
4551 (void *)cmd, NULL) == 0;
4552 }
4553
4554 static int
4555 wg_ioctl_get(struct wg_softc *wg, struct ifdrv *ifd)
4556 {
4557 int error = ENOMEM;
4558 prop_dictionary_t prop_dict;
4559 prop_array_t peers = NULL;
4560 char *buf;
4561 struct wg_peer *wgp;
4562 int s, i;
4563
4564 prop_dict = prop_dictionary_create();
4565 if (prop_dict == NULL)
4566 goto error;
4567
4568 if (wg_is_authorized(wg, SIOCGDRVSPEC)) {
4569 if (!prop_dictionary_set_data(prop_dict, "private_key",
4570 wg->wg_privkey, WG_STATIC_KEY_LEN))
4571 goto error;
4572 }
4573
4574 if (wg->wg_listen_port != 0) {
4575 if (!prop_dictionary_set_uint16(prop_dict, "listen_port",
4576 wg->wg_listen_port))
4577 goto error;
4578 }
4579
4580 if (wg->wg_npeers == 0)
4581 goto skip_peers;
4582
4583 peers = prop_array_create();
4584 if (peers == NULL)
4585 goto error;
4586
4587 s = pserialize_read_enter();
4588 i = 0;
4589 WG_PEER_READER_FOREACH(wgp, wg) {
4590 struct wg_sockaddr *wgsa;
4591 struct psref wgp_psref, wgsa_psref;
4592 prop_dictionary_t prop_peer;
4593
4594 wg_get_peer(wgp, &wgp_psref);
4595 pserialize_read_exit(s);
4596
4597 prop_peer = prop_dictionary_create();
4598 if (prop_peer == NULL)
4599 goto next;
4600
4601 if (strlen(wgp->wgp_name) > 0) {
4602 if (!prop_dictionary_set_string(prop_peer, "name",
4603 wgp->wgp_name))
4604 goto next;
4605 }
4606
4607 if (!prop_dictionary_set_data(prop_peer, "public_key",
4608 wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey)))
4609 goto next;
4610
4611 uint8_t psk_zero[WG_PRESHARED_KEY_LEN] = {0};
4612 if (!consttime_memequal(wgp->wgp_psk, psk_zero,
4613 sizeof(wgp->wgp_psk))) {
4614 if (wg_is_authorized(wg, SIOCGDRVSPEC)) {
4615 if (!prop_dictionary_set_data(prop_peer,
4616 "preshared_key",
4617 wgp->wgp_psk, sizeof(wgp->wgp_psk)))
4618 goto next;
4619 }
4620 }
4621
4622 wgsa = wg_get_endpoint_sa(wgp, &wgsa_psref);
4623 CTASSERT(AF_UNSPEC == 0);
4624 if (wgsa_family(wgsa) != 0 /*AF_UNSPEC*/ &&
4625 !prop_dictionary_set_data(prop_peer, "endpoint",
4626 wgsatoss(wgsa),
4627 sockaddr_getsize_by_family(wgsa_family(wgsa)))) {
4628 wg_put_sa(wgp, wgsa, &wgsa_psref);
4629 goto next;
4630 }
4631 wg_put_sa(wgp, wgsa, &wgsa_psref);
4632
4633 const struct timespec *t = &wgp->wgp_last_handshake_time;
4634
4635 if (!prop_dictionary_set_uint64(prop_peer,
4636 "last_handshake_time_sec", (uint64_t)t->tv_sec))
4637 goto next;
4638 if (!prop_dictionary_set_uint32(prop_peer,
4639 "last_handshake_time_nsec", (uint32_t)t->tv_nsec))
4640 goto next;
4641
4642 if (wgp->wgp_n_allowedips == 0)
4643 goto skip_allowedips;
4644
4645 prop_array_t allowedips = prop_array_create();
4646 if (allowedips == NULL)
4647 goto next;
4648 for (int j = 0; j < wgp->wgp_n_allowedips; j++) {
4649 struct wg_allowedip *wga = &wgp->wgp_allowedips[j];
4650 prop_dictionary_t prop_allowedip;
4651
4652 prop_allowedip = prop_dictionary_create();
4653 if (prop_allowedip == NULL)
4654 break;
4655
4656 if (!prop_dictionary_set_int(prop_allowedip, "family",
4657 wga->wga_family))
4658 goto _next;
4659 if (!prop_dictionary_set_uint8(prop_allowedip, "cidr",
4660 wga->wga_cidr))
4661 goto _next;
4662
4663 switch (wga->wga_family) {
4664 case AF_INET:
4665 if (!prop_dictionary_set_data(prop_allowedip,
4666 "ip", &wga->wga_addr4,
4667 sizeof(wga->wga_addr4)))
4668 goto _next;
4669 break;
4670 #ifdef INET6
4671 case AF_INET6:
4672 if (!prop_dictionary_set_data(prop_allowedip,
4673 "ip", &wga->wga_addr6,
4674 sizeof(wga->wga_addr6)))
4675 goto _next;
4676 break;
4677 #endif
4678 default:
4679 break;
4680 }
4681 prop_array_set(allowedips, j, prop_allowedip);
4682 _next:
4683 prop_object_release(prop_allowedip);
4684 }
4685 prop_dictionary_set(prop_peer, "allowedips", allowedips);
4686 prop_object_release(allowedips);
4687
4688 skip_allowedips:
4689
4690 prop_array_set(peers, i, prop_peer);
4691 next:
4692 if (prop_peer)
4693 prop_object_release(prop_peer);
4694 i++;
4695
4696 s = pserialize_read_enter();
4697 wg_put_peer(wgp, &wgp_psref);
4698 }
4699 pserialize_read_exit(s);
4700
4701 prop_dictionary_set(prop_dict, "peers", peers);
4702 prop_object_release(peers);
4703 peers = NULL;
4704
4705 skip_peers:
4706 buf = prop_dictionary_externalize(prop_dict);
4707 if (buf == NULL)
4708 goto error;
4709 if (ifd->ifd_len < (strlen(buf) + 1)) {
4710 error = EINVAL;
4711 goto error;
4712 }
4713 error = copyout(buf, ifd->ifd_data, strlen(buf) + 1);
4714
4715 free(buf, 0);
4716 error:
4717 if (peers != NULL)
4718 prop_object_release(peers);
4719 if (prop_dict != NULL)
4720 prop_object_release(prop_dict);
4721
4722 return error;
4723 }
4724
4725 static int
4726 wg_ioctl(struct ifnet *ifp, u_long cmd, void *data)
4727 {
4728 struct wg_softc *wg = ifp->if_softc;
4729 struct ifreq *ifr = data;
4730 struct ifaddr *ifa = data;
4731 struct ifdrv *ifd = data;
4732 int error = 0;
4733
4734 switch (cmd) {
4735 case SIOCINITIFADDR:
4736 if (ifa->ifa_addr->sa_family != AF_LINK &&
4737 (ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
4738 (IFF_UP | IFF_RUNNING)) {
4739 ifp->if_flags |= IFF_UP;
4740 error = if_init(ifp);
4741 }
4742 return error;
4743 case SIOCADDMULTI:
4744 case SIOCDELMULTI:
4745 switch (ifr->ifr_addr.sa_family) {
4746 case AF_INET: /* IP supports Multicast */
4747 break;
4748 #ifdef INET6
4749 case AF_INET6: /* IP6 supports Multicast */
4750 break;
4751 #endif
4752 default: /* Other protocols doesn't support Multicast */
4753 error = EAFNOSUPPORT;
4754 break;
4755 }
4756 return error;
4757 case SIOCSDRVSPEC:
4758 if (!wg_is_authorized(wg, cmd)) {
4759 return EPERM;
4760 }
4761 switch (ifd->ifd_cmd) {
4762 case WG_IOCTL_SET_PRIVATE_KEY:
4763 error = wg_ioctl_set_private_key(wg, ifd);
4764 break;
4765 case WG_IOCTL_SET_LISTEN_PORT:
4766 error = wg_ioctl_set_listen_port(wg, ifd);
4767 break;
4768 case WG_IOCTL_ADD_PEER:
4769 error = wg_ioctl_add_peer(wg, ifd);
4770 break;
4771 case WG_IOCTL_DELETE_PEER:
4772 error = wg_ioctl_delete_peer(wg, ifd);
4773 break;
4774 default:
4775 error = EINVAL;
4776 break;
4777 }
4778 return error;
4779 case SIOCGDRVSPEC:
4780 return wg_ioctl_get(wg, ifd);
4781 case SIOCSIFFLAGS:
4782 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
4783 break;
4784 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
4785 case IFF_RUNNING:
4786 /*
4787 * If interface is marked down and it is running,
4788 * then stop and disable it.
4789 */
4790 if_stop(ifp, 1);
4791 break;
4792 case IFF_UP:
4793 /*
4794 * If interface is marked up and it is stopped, then
4795 * start it.
4796 */
4797 error = if_init(ifp);
4798 break;
4799 default:
4800 break;
4801 }
4802 return error;
4803 #ifdef WG_RUMPKERNEL
4804 case SIOCSLINKSTR:
4805 error = wg_ioctl_linkstr(wg, ifd);
4806 if (error == 0)
4807 wg->wg_ops = &wg_ops_rumpuser;
4808 return error;
4809 #endif
4810 default:
4811 break;
4812 }
4813
4814 error = ifioctl_common(ifp, cmd, data);
4815
4816 #ifdef WG_RUMPKERNEL
4817 if (!wg_user_mode(wg))
4818 return error;
4819
4820 /* Do the same to the corresponding tun device on the host */
4821 /*
4822 * XXX Actually the command has not been handled yet. It
4823 * will be handled via pr_ioctl form doifioctl later.
4824 */
4825 switch (cmd) {
4826 case SIOCAIFADDR:
4827 case SIOCDIFADDR: {
4828 struct in_aliasreq _ifra = *(const struct in_aliasreq *)data;
4829 struct in_aliasreq *ifra = &_ifra;
4830 KASSERT(error == ENOTTY);
4831 strncpy(ifra->ifra_name, rumpuser_wg_get_tunname(wg->wg_user),
4832 IFNAMSIZ);
4833 error = rumpuser_wg_ioctl(wg->wg_user, cmd, ifra, AF_INET);
4834 if (error == 0)
4835 error = ENOTTY;
4836 break;
4837 }
4838 #ifdef INET6
4839 case SIOCAIFADDR_IN6:
4840 case SIOCDIFADDR_IN6: {
4841 struct in6_aliasreq _ifra = *(const struct in6_aliasreq *)data;
4842 struct in6_aliasreq *ifra = &_ifra;
4843 KASSERT(error == ENOTTY);
4844 strncpy(ifra->ifra_name, rumpuser_wg_get_tunname(wg->wg_user),
4845 IFNAMSIZ);
4846 error = rumpuser_wg_ioctl(wg->wg_user, cmd, ifra, AF_INET6);
4847 if (error == 0)
4848 error = ENOTTY;
4849 break;
4850 }
4851 #endif
4852 }
4853 #endif /* WG_RUMPKERNEL */
4854
4855 return error;
4856 }
4857
4858 static int
4859 wg_init(struct ifnet *ifp)
4860 {
4861
4862 ifp->if_flags |= IFF_RUNNING;
4863
4864 /* TODO flush pending packets. */
4865 return 0;
4866 }
4867
4868 #ifdef ALTQ
4869 static void
4870 wg_start(struct ifnet *ifp)
4871 {
4872 struct mbuf *m;
4873
4874 for (;;) {
4875 IFQ_DEQUEUE(&ifp->if_snd, m);
4876 if (m == NULL)
4877 break;
4878
4879 kpreempt_disable();
4880 const uint32_t h = curcpu()->ci_index; // pktq_rps_hash(m)
4881 if (__predict_false(!pktq_enqueue(wg_pktq, m, h))) {
4882 WGLOG(LOG_ERR, "%s: pktq full, dropping\n",
4883 if_name(ifp));
4884 m_freem(m);
4885 }
4886 kpreempt_enable();
4887 }
4888 }
4889 #endif
4890
4891 static void
4892 wg_stop(struct ifnet *ifp, int disable)
4893 {
4894
4895 KASSERT((ifp->if_flags & IFF_RUNNING) != 0);
4896 ifp->if_flags &= ~IFF_RUNNING;
4897
4898 /* Need to do something? */
4899 }
4900
4901 #ifdef WG_DEBUG_PARAMS
4902 SYSCTL_SETUP(sysctl_net_wg_setup, "sysctl net.wg setup")
4903 {
4904 const struct sysctlnode *node = NULL;
4905
4906 sysctl_createv(clog, 0, NULL, &node,
4907 CTLFLAG_PERMANENT,
4908 CTLTYPE_NODE, "wg",
4909 SYSCTL_DESCR("wg(4)"),
4910 NULL, 0, NULL, 0,
4911 CTL_NET, CTL_CREATE, CTL_EOL);
4912 sysctl_createv(clog, 0, &node, NULL,
4913 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4914 CTLTYPE_QUAD, "rekey_after_messages",
4915 SYSCTL_DESCR("session liftime by messages"),
4916 NULL, 0, &wg_rekey_after_messages, 0, CTL_CREATE, CTL_EOL);
4917 sysctl_createv(clog, 0, &node, NULL,
4918 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4919 CTLTYPE_INT, "rekey_after_time",
4920 SYSCTL_DESCR("session liftime"),
4921 NULL, 0, &wg_rekey_after_time, 0, CTL_CREATE, CTL_EOL);
4922 sysctl_createv(clog, 0, &node, NULL,
4923 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4924 CTLTYPE_INT, "rekey_timeout",
4925 SYSCTL_DESCR("session handshake retry time"),
4926 NULL, 0, &wg_rekey_timeout, 0, CTL_CREATE, CTL_EOL);
4927 sysctl_createv(clog, 0, &node, NULL,
4928 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4929 CTLTYPE_INT, "rekey_attempt_time",
4930 SYSCTL_DESCR("session handshake timeout"),
4931 NULL, 0, &wg_rekey_attempt_time, 0, CTL_CREATE, CTL_EOL);
4932 sysctl_createv(clog, 0, &node, NULL,
4933 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4934 CTLTYPE_INT, "keepalive_timeout",
4935 SYSCTL_DESCR("keepalive timeout"),
4936 NULL, 0, &wg_keepalive_timeout, 0, CTL_CREATE, CTL_EOL);
4937 sysctl_createv(clog, 0, &node, NULL,
4938 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4939 CTLTYPE_BOOL, "force_underload",
4940 SYSCTL_DESCR("force to detemine under load"),
4941 NULL, 0, &wg_force_underload, 0, CTL_CREATE, CTL_EOL);
4942 sysctl_createv(clog, 0, &node, NULL,
4943 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4944 CTLTYPE_INT, "debug",
4945 SYSCTL_DESCR("set debug flags 1=log 2=trace 4=dump 8=packet"),
4946 NULL, 0, &wg_debug, 0, CTL_CREATE, CTL_EOL);
4947 }
4948 #endif
4949
4950 #ifdef WG_RUMPKERNEL
4951 static bool
4952 wg_user_mode(struct wg_softc *wg)
4953 {
4954
4955 return wg->wg_user != NULL;
4956 }
4957
4958 static int
4959 wg_ioctl_linkstr(struct wg_softc *wg, struct ifdrv *ifd)
4960 {
4961 struct ifnet *ifp = &wg->wg_if;
4962 int error;
4963
4964 if (ifp->if_flags & IFF_UP)
4965 return EBUSY;
4966
4967 if (ifd->ifd_cmd == IFLINKSTR_UNSET) {
4968 /* XXX do nothing */
4969 return 0;
4970 } else if (ifd->ifd_cmd != 0) {
4971 return EINVAL;
4972 } else if (wg->wg_user != NULL) {
4973 return EBUSY;
4974 }
4975
4976 /* Assume \0 included */
4977 if (ifd->ifd_len > IFNAMSIZ) {
4978 return E2BIG;
4979 } else if (ifd->ifd_len < 1) {
4980 return EINVAL;
4981 }
4982
4983 char tun_name[IFNAMSIZ];
4984 error = copyinstr(ifd->ifd_data, tun_name, ifd->ifd_len, NULL);
4985 if (error != 0)
4986 return error;
4987
4988 if (strncmp(tun_name, "tun", 3) != 0)
4989 return EINVAL;
4990
4991 error = rumpuser_wg_create(tun_name, wg, &wg->wg_user);
4992
4993 return error;
4994 }
4995
4996 static int
4997 wg_send_user(struct wg_peer *wgp, struct mbuf *m)
4998 {
4999 int error;
5000 struct psref psref;
5001 struct wg_sockaddr *wgsa;
5002 struct wg_softc *wg = wgp->wgp_sc;
5003 struct iovec iov[1];
5004
5005 wgsa = wg_get_endpoint_sa(wgp, &psref);
5006
5007 iov[0].iov_base = mtod(m, void *);
5008 iov[0].iov_len = m->m_len;
5009
5010 /* Send messages to a peer via an ordinary socket. */
5011 error = rumpuser_wg_send_peer(wg->wg_user, wgsatosa(wgsa), iov, 1);
5012
5013 wg_put_sa(wgp, wgsa, &psref);
5014
5015 m_freem(m);
5016
5017 return error;
5018 }
5019
5020 static void
5021 wg_input_user(struct ifnet *ifp, struct mbuf *m, const int af)
5022 {
5023 struct wg_softc *wg = ifp->if_softc;
5024 struct iovec iov[2];
5025 struct sockaddr_storage ss;
5026
5027 KASSERT(af == AF_INET || af == AF_INET6);
5028
5029 WG_TRACE("");
5030
5031 if (af == AF_INET) {
5032 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
5033 struct ip *ip;
5034
5035 KASSERT(m->m_len >= sizeof(struct ip));
5036 ip = mtod(m, struct ip *);
5037 sockaddr_in_init(sin, &ip->ip_dst, 0);
5038 } else {
5039 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
5040 struct ip6_hdr *ip6;
5041
5042 KASSERT(m->m_len >= sizeof(struct ip6_hdr));
5043 ip6 = mtod(m, struct ip6_hdr *);
5044 sockaddr_in6_init(sin6, &ip6->ip6_dst, 0, 0, 0);
5045 }
5046
5047 iov[0].iov_base = &ss;
5048 iov[0].iov_len = ss.ss_len;
5049 iov[1].iov_base = mtod(m, void *);
5050 iov[1].iov_len = m->m_len;
5051
5052 WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len);
5053
5054 /* Send decrypted packets to users via a tun. */
5055 rumpuser_wg_send_user(wg->wg_user, iov, 2);
5056
5057 m_freem(m);
5058 }
5059
5060 static int
5061 wg_bind_port_user(struct wg_softc *wg, const uint16_t port)
5062 {
5063 int error;
5064 uint16_t old_port = wg->wg_listen_port;
5065
5066 if (port != 0 && old_port == port)
5067 return 0;
5068
5069 error = rumpuser_wg_sock_bind(wg->wg_user, port);
5070 if (error == 0)
5071 wg->wg_listen_port = port;
5072 return error;
5073 }
5074
5075 /*
5076 * Receive user packets.
5077 */
5078 void
5079 rumpkern_wg_recv_user(struct wg_softc *wg, struct iovec *iov, size_t iovlen)
5080 {
5081 struct ifnet *ifp = &wg->wg_if;
5082 struct mbuf *m;
5083 const struct sockaddr *dst;
5084
5085 WG_TRACE("");
5086
5087 dst = iov[0].iov_base;
5088
5089 m = m_gethdr(M_DONTWAIT, MT_DATA);
5090 if (m == NULL)
5091 return;
5092 m->m_len = m->m_pkthdr.len = 0;
5093 m_copyback(m, 0, iov[1].iov_len, iov[1].iov_base);
5094
5095 WG_DLOG("iov_len=%lu\n", iov[1].iov_len);
5096 WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len);
5097
5098 (void)wg_output(ifp, m, dst, NULL);
5099 }
5100
5101 /*
5102 * Receive packets from a peer.
5103 */
5104 void
5105 rumpkern_wg_recv_peer(struct wg_softc *wg, struct iovec *iov, size_t iovlen)
5106 {
5107 struct mbuf *m;
5108 const struct sockaddr *src;
5109 int bound;
5110
5111 WG_TRACE("");
5112
5113 src = iov[0].iov_base;
5114
5115 m = m_gethdr(M_DONTWAIT, MT_DATA);
5116 if (m == NULL)
5117 return;
5118 m->m_len = m->m_pkthdr.len = 0;
5119 m_copyback(m, 0, iov[1].iov_len, iov[1].iov_base);
5120
5121 WG_DLOG("iov_len=%lu\n", iov[1].iov_len);
5122 WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len);
5123
5124 bound = curlwp_bind();
5125 wg_handle_packet(wg, m, src);
5126 curlwp_bindx(bound);
5127 }
5128 #endif /* WG_RUMPKERNEL */
5129
5130 /*
5131 * Module infrastructure
5132 */
5133 #include "if_module.h"
5134
5135 IF_MODULE(MODULE_CLASS_DRIVER, wg, "sodium,blake2s")
5136