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