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