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