if_wg.c revision 1.3 1 /* $NetBSD: if_wg.c,v 1.3 2020/08/20 21:30:56 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.3 2020/08/20 21:30:56 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_strong(kern_cprng, privkey, WG_EPHEMERAL_KEY_LEN, 0);
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 bool
2051 wg_validate_inner_packet(char *packet, size_t decrypted_len, int *af)
2052 {
2053 uint16_t packet_len;
2054 struct ip *ip;
2055
2056 if (__predict_false(decrypted_len < sizeof(struct ip)))
2057 return false;
2058
2059 ip = (struct ip *)packet;
2060 if (ip->ip_v == 4)
2061 *af = AF_INET;
2062 else if (ip->ip_v == 6)
2063 *af = AF_INET6;
2064 else
2065 return false;
2066
2067 WG_DLOG("af=%d\n", *af);
2068
2069 if (*af == AF_INET) {
2070 packet_len = ntohs(ip->ip_len);
2071 } else {
2072 struct ip6_hdr *ip6;
2073
2074 if (__predict_false(decrypted_len < sizeof(struct ip6_hdr)))
2075 return false;
2076
2077 ip6 = (struct ip6_hdr *)packet;
2078 packet_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
2079 }
2080
2081 WG_DLOG("packet_len=%u\n", packet_len);
2082 if (packet_len > decrypted_len)
2083 return false;
2084
2085 return true;
2086 }
2087
2088 static bool
2089 wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected,
2090 int af, char *packet)
2091 {
2092 struct sockaddr_storage ss;
2093 struct sockaddr *sa;
2094 struct psref psref;
2095 struct wg_peer *wgp;
2096 bool ok;
2097
2098 /*
2099 * II CRYPTOKEY ROUTING
2100 * "it will only accept it if its source IP resolves in the table to the
2101 * public key used in the secure session for decrypting it."
2102 */
2103
2104 if (af == AF_INET) {
2105 struct ip *ip = (struct ip *)packet;
2106 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
2107 sockaddr_in_init(sin, &ip->ip_src, 0);
2108 sa = sintosa(sin);
2109 #ifdef INET6
2110 } else {
2111 struct ip6_hdr *ip6 = (struct ip6_hdr *)packet;
2112 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
2113 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0);
2114 sa = sin6tosa(sin6);
2115 #endif
2116 }
2117
2118 wgp = wg_pick_peer_by_sa(wg, sa, &psref);
2119 ok = (wgp == wgp_expected);
2120 if (wgp != NULL)
2121 wg_put_peer(wgp, &psref);
2122
2123 return ok;
2124 }
2125
2126 static void
2127 wg_session_dtor_timer(void *arg)
2128 {
2129 struct wg_peer *wgp = arg;
2130
2131 WG_TRACE("enter");
2132
2133 mutex_enter(wgp->wgp_lock);
2134 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
2135 mutex_exit(wgp->wgp_lock);
2136 return;
2137 }
2138 mutex_exit(wgp->wgp_lock);
2139
2140 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION);
2141 }
2142
2143 static void
2144 wg_schedule_session_dtor_timer(struct wg_peer *wgp)
2145 {
2146
2147 /* 1 second grace period */
2148 callout_schedule(&wgp->wgp_session_dtor_timer, hz);
2149 }
2150
2151 static void
2152 wg_stop_session_dtor_timer(struct wg_peer *wgp)
2153 {
2154
2155 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
2156 }
2157
2158 static bool
2159 sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2)
2160 {
2161 if (sa1->sa_family != sa2->sa_family)
2162 return false;
2163
2164 switch (sa1->sa_family) {
2165 case AF_INET:
2166 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port;
2167 case AF_INET6:
2168 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port;
2169 default:
2170 return true;
2171 }
2172 }
2173
2174 static void
2175 wg_update_endpoint_if_necessary(struct wg_peer *wgp,
2176 const struct sockaddr *src)
2177 {
2178
2179 #ifdef WG_DEBUG_LOG
2180 char oldaddr[128], newaddr[128];
2181 sockaddr_format(&wgp->wgp_sa, oldaddr, sizeof(oldaddr));
2182 sockaddr_format(src, newaddr, sizeof(newaddr));
2183 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr);
2184 #endif
2185
2186 /*
2187 * III: "Since the packet has authenticated correctly, the source IP of
2188 * the outer UDP/IP packet is used to update the endpoint for peer..."
2189 */
2190 if (__predict_false(sockaddr_cmp(src, &wgp->wgp_sa) != 0 ||
2191 !sockaddr_port_match(src, &wgp->wgp_sa))) {
2192 mutex_enter(wgp->wgp_lock);
2193 /* XXX We can't change the endpoint twice in a short period */
2194 if (!wgp->wgp_endpoint_changing) {
2195 wg_change_endpoint(wgp, src);
2196 }
2197 mutex_exit(wgp->wgp_lock);
2198 }
2199 }
2200
2201 static void
2202 wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m,
2203 const struct sockaddr *src)
2204 {
2205 struct wg_msg_data *wgmd;
2206 char *encrypted_buf = NULL, *decrypted_buf;
2207 size_t encrypted_len, decrypted_len;
2208 struct wg_session *wgs;
2209 struct wg_peer *wgp;
2210 size_t mlen;
2211 struct psref psref;
2212 int error, af;
2213 bool success, free_encrypted_buf = false, ok;
2214 struct mbuf *n;
2215
2216 if (m->m_len < sizeof(struct wg_msg_data)) {
2217 m = m_pullup(m, sizeof(struct wg_msg_data));
2218 if (m == NULL)
2219 return;
2220 }
2221 wgmd = mtod(m, struct wg_msg_data *);
2222
2223 KASSERT(wgmd->wgmd_type == WG_MSG_TYPE_DATA);
2224 WG_TRACE("data");
2225
2226 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref);
2227 if (wgs == NULL) {
2228 WG_TRACE("No session found");
2229 m_freem(m);
2230 return;
2231 }
2232 wgp = wgs->wgs_peer;
2233
2234 mlen = m_length(m);
2235 encrypted_len = mlen - sizeof(*wgmd);
2236
2237 if (encrypted_len < WG_AUTHTAG_LEN) {
2238 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len);
2239 goto out;
2240 }
2241
2242 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len);
2243 if (success) {
2244 encrypted_buf = mtod(m, char *) + sizeof(*wgmd);
2245 } else {
2246 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP);
2247 if (encrypted_buf == NULL) {
2248 WG_DLOG("failed to allocate encrypted_buf\n");
2249 goto out;
2250 }
2251 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf);
2252 free_encrypted_buf = true;
2253 }
2254 /* m_ensure_contig may change m regardless of its result */
2255 wgmd = mtod(m, struct wg_msg_data *);
2256
2257 decrypted_len = encrypted_len - WG_AUTHTAG_LEN;
2258 if (decrypted_len > MCLBYTES) {
2259 /* FIXME handle larger data than MCLBYTES */
2260 WG_DLOG("couldn't handle larger data than MCLBYTES\n");
2261 goto out;
2262 }
2263
2264 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN); /* To avoid zero length */
2265 if (n == NULL) {
2266 WG_DLOG("wg_get_mbuf failed\n");
2267 goto out;
2268 }
2269 decrypted_buf = mtod(n, char *);
2270
2271 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len);
2272 error = wg_algo_aead_dec(decrypted_buf,
2273 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */,
2274 wgs->wgs_tkey_recv, wgmd->wgmd_counter, encrypted_buf,
2275 encrypted_len, NULL, 0);
2276 if (error != 0) {
2277 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2278 "failed to wg_algo_aead_dec\n");
2279 m_freem(n);
2280 goto out;
2281 }
2282 WG_DLOG("outsize=%u\n", (u_int)decrypted_len);
2283
2284 /* TODO deal with reordering with a sliding window */
2285 if (wgs->wgs_recv_counter != 0 &&
2286 wgmd->wgmd_counter <= wgs->wgs_recv_counter) {
2287 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2288 "wgmd_counter is equal to or smaller than wgs_recv_counter:"
2289 " %"PRIu64" <= %"PRIu64"\n", wgmd->wgmd_counter,
2290 wgs->wgs_recv_counter);
2291 m_freem(n);
2292 goto out;
2293 }
2294 wgs->wgs_recv_counter = wgmd->wgmd_counter;
2295
2296 m_freem(m);
2297 m = NULL;
2298 wgmd = NULL;
2299
2300 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af);
2301 if (!ok) {
2302 /* something wrong... */
2303 m_freem(n);
2304 goto out;
2305 }
2306
2307 wg_update_endpoint_if_necessary(wgp, src);
2308
2309 ok = wg_validate_route(wg, wgp, af, decrypted_buf);
2310 if (ok) {
2311 wg->wg_ops->input(&wg->wg_if, n, af);
2312 } else {
2313 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2314 "invalid source address\n");
2315 m_freem(n);
2316 /*
2317 * The inner address is invalid however the session is valid
2318 * so continue the session processing below.
2319 */
2320 }
2321 n = NULL;
2322
2323 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) {
2324 struct wg_session *wgs_prev;
2325
2326 KASSERT(wgs == wgp->wgp_session_unstable);
2327 wgs->wgs_state = WGS_STATE_ESTABLISHED;
2328 wgs->wgs_time_established = time_uptime;
2329 wgs->wgs_time_last_data_sent = 0;
2330 wgs->wgs_is_initiator = false;
2331 WG_TRACE("WGS_STATE_ESTABLISHED");
2332
2333 mutex_enter(wgp->wgp_lock);
2334 wg_swap_sessions(wgp);
2335 wgs_prev = wgp->wgp_session_unstable;
2336 mutex_enter(wgs_prev->wgs_lock);
2337 getnanotime(&wgp->wgp_last_handshake_time);
2338 wgp->wgp_handshake_start_time = 0;
2339 wgp->wgp_last_sent_mac1_valid = false;
2340 wgp->wgp_last_sent_cookie_valid = false;
2341 mutex_exit(wgp->wgp_lock);
2342
2343 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) {
2344 wgs_prev->wgs_state = WGS_STATE_DESTROYING;
2345 /* We can't destroy the old session immediately */
2346 wg_schedule_session_dtor_timer(wgp);
2347 } else {
2348 wg_clear_states(wgs_prev);
2349 wgs_prev->wgs_state = WGS_STATE_UNKNOWN;
2350 }
2351 mutex_exit(wgs_prev->wgs_lock);
2352
2353 /* Anyway run a softint to flush pending packets */
2354 KASSERT(cpu_softintr_p());
2355 softint_schedule(wgp->wgp_si);
2356 } else {
2357 if (__predict_false(wg_need_to_send_init_message(wgs))) {
2358 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2359 }
2360 /*
2361 * [W] 6.5 Passive Keepalive
2362 * "If a peer has received a validly-authenticated transport
2363 * data message (section 5.4.6), but does not have any packets
2364 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends
2365 * a keepalive message."
2366 */
2367 WG_DLOG("time_uptime=%lu wgs_time_last_data_sent=%lu\n",
2368 time_uptime, wgs->wgs_time_last_data_sent);
2369 if ((time_uptime - wgs->wgs_time_last_data_sent) >=
2370 wg_keepalive_timeout) {
2371 WG_TRACE("Schedule sending keepalive message");
2372 /*
2373 * We can't send a keepalive message here to avoid
2374 * a deadlock; we already hold the solock of a socket
2375 * that is used to send the message.
2376 */
2377 wg_schedule_peer_task(wgp, WGP_TASK_SEND_KEEPALIVE_MESSAGE);
2378 }
2379 }
2380 out:
2381 wg_put_session(wgs, &psref);
2382 if (m != NULL)
2383 m_freem(m);
2384 if (free_encrypted_buf)
2385 kmem_intr_free(encrypted_buf, encrypted_len);
2386 }
2387
2388 static void
2389 wg_handle_msg_cookie(struct wg_softc *wg, const struct wg_msg_cookie *wgmc)
2390 {
2391 struct wg_session *wgs;
2392 struct wg_peer *wgp;
2393 struct psref psref;
2394 int error;
2395 uint8_t key[WG_HASH_LEN];
2396 uint8_t cookie[WG_COOKIE_LEN];
2397
2398 WG_TRACE("cookie msg received");
2399 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref);
2400 if (wgs == NULL) {
2401 WG_TRACE("No session found");
2402 return;
2403 }
2404 wgp = wgs->wgs_peer;
2405
2406 if (!wgp->wgp_last_sent_mac1_valid) {
2407 WG_TRACE("No valid mac1 sent (or expired)");
2408 goto out;
2409 }
2410
2411 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey,
2412 sizeof(wgp->wgp_pubkey));
2413 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 0,
2414 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie),
2415 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1),
2416 wgmc->wgmc_salt);
2417 if (error != 0) {
2418 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2419 "wg_algo_aead_dec for cookie failed: error=%d\n", error);
2420 goto out;
2421 }
2422 /*
2423 * [W] 6.6: Interaction with Cookie Reply System
2424 * "it should simply store the decrypted cookie value from the cookie
2425 * reply message, and wait for the expiration of the REKEY-TIMEOUT
2426 * timer for retrying a handshake initiation message."
2427 */
2428 wgp->wgp_latest_cookie_time = time_uptime;
2429 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie));
2430 out:
2431 wg_put_session(wgs, &psref);
2432 }
2433
2434 static bool
2435 wg_validate_msg_length(struct wg_softc *wg, const struct mbuf *m)
2436 {
2437 struct wg_msg *wgm;
2438 size_t mlen;
2439
2440 mlen = m_length(m);
2441 if (__predict_false(mlen < sizeof(struct wg_msg)))
2442 return false;
2443
2444 wgm = mtod(m, struct wg_msg *);
2445 switch (wgm->wgm_type) {
2446 case WG_MSG_TYPE_INIT:
2447 if (__predict_true(mlen >= sizeof(struct wg_msg_init)))
2448 return true;
2449 break;
2450 case WG_MSG_TYPE_RESP:
2451 if (__predict_true(mlen >= sizeof(struct wg_msg_resp)))
2452 return true;
2453 break;
2454 case WG_MSG_TYPE_COOKIE:
2455 if (__predict_true(mlen >= sizeof(struct wg_msg_cookie)))
2456 return true;
2457 break;
2458 case WG_MSG_TYPE_DATA:
2459 if (__predict_true(mlen >= sizeof(struct wg_msg_data)))
2460 return true;
2461 break;
2462 default:
2463 WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG,
2464 "Unexpected msg type: %u\n", wgm->wgm_type);
2465 return false;
2466 }
2467 WG_DLOG("Invalid msg size: mlen=%lu type=%u\n", mlen, wgm->wgm_type);
2468
2469 return false;
2470 }
2471
2472 static void
2473 wg_handle_packet(struct wg_softc *wg, struct mbuf *m, const struct sockaddr *src)
2474 {
2475 struct wg_msg *wgm;
2476 bool valid;
2477
2478 valid = wg_validate_msg_length(wg, m);
2479 if (!valid) {
2480 m_freem(m);
2481 return;
2482 }
2483
2484 wgm = mtod(m, struct wg_msg *);
2485 switch (wgm->wgm_type) {
2486 case WG_MSG_TYPE_INIT:
2487 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src);
2488 break;
2489 case WG_MSG_TYPE_RESP:
2490 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src);
2491 break;
2492 case WG_MSG_TYPE_COOKIE:
2493 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm);
2494 break;
2495 case WG_MSG_TYPE_DATA:
2496 wg_handle_msg_data(wg, m, src);
2497 break;
2498 default:
2499 /* wg_validate_msg_length should already reject this case */
2500 break;
2501 }
2502 }
2503
2504 static void
2505 wg_receive_packets(struct wg_softc *wg, const int af)
2506 {
2507
2508 while (true) {
2509 int error, flags;
2510 struct socket *so;
2511 struct mbuf *m = NULL;
2512 struct uio dummy_uio;
2513 struct mbuf *paddr = NULL;
2514 struct sockaddr *src;
2515
2516 so = wg_get_so_by_af(wg->wg_worker, af);
2517 flags = MSG_DONTWAIT;
2518 dummy_uio.uio_resid = 1000000000;
2519
2520 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL, &flags);
2521 if (error || m == NULL) {
2522 //if (error == EWOULDBLOCK)
2523 return;
2524 }
2525
2526 KASSERT(paddr != NULL);
2527 src = mtod(paddr, struct sockaddr *);
2528
2529 wg_handle_packet(wg, m, src);
2530 }
2531 }
2532
2533 static void
2534 wg_get_peer(struct wg_peer *wgp, struct psref *psref)
2535 {
2536
2537 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class);
2538 }
2539
2540 static void
2541 wg_put_peer(struct wg_peer *wgp, struct psref *psref)
2542 {
2543
2544 psref_release(psref, &wgp->wgp_psref, wg_psref_class);
2545 }
2546
2547 static void
2548 wg_process_peer_tasks(struct wg_softc *wg)
2549 {
2550 struct wg_peer *wgp;
2551 int s;
2552
2553 /* XXX should avoid checking all peers */
2554 s = pserialize_read_enter();
2555 WG_PEER_READER_FOREACH(wgp, wg) {
2556 struct psref psref;
2557 unsigned int tasks;
2558
2559 if (wgp->wgp_tasks == 0)
2560 continue;
2561
2562 wg_get_peer(wgp, &psref);
2563 pserialize_read_exit(s);
2564
2565 restart:
2566 tasks = atomic_swap_uint(&wgp->wgp_tasks, 0);
2567 KASSERT(tasks != 0);
2568
2569 WG_DLOG("tasks=%x\n", tasks);
2570
2571 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE)) {
2572 struct psref _psref;
2573 struct wg_session *wgs;
2574
2575 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE");
2576 if (!wgp->wgp_endpoint_available) {
2577 WGLOG(LOG_DEBUG, "No endpoint available\n");
2578 /* XXX should do something? */
2579 goto skip_init_message;
2580 }
2581 wgs = wg_get_stable_session(wgp, &_psref);
2582 if (wgs->wgs_state == WGS_STATE_UNKNOWN) {
2583 wg_put_session(wgs, &_psref);
2584 wg_send_handshake_msg_init(wg, wgp);
2585 } else {
2586 wg_put_session(wgs, &_psref);
2587 /* rekey */
2588 wgs = wg_get_unstable_session(wgp, &_psref);
2589 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE)
2590 wg_send_handshake_msg_init(wg, wgp);
2591 wg_put_session(wgs, &_psref);
2592 }
2593 }
2594 skip_init_message:
2595 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED)) {
2596 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED");
2597 mutex_enter(wgp->wgp_lock);
2598 if (wgp->wgp_endpoint_changing) {
2599 pserialize_perform(wgp->wgp_psz);
2600 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref,
2601 wg_psref_class);
2602 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref,
2603 wg_psref_class);
2604 wgp->wgp_endpoint_changing = false;
2605 }
2606 mutex_exit(wgp->wgp_lock);
2607 }
2608 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE)) {
2609 struct psref _psref;
2610 struct wg_session *wgs;
2611
2612 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE");
2613 wgs = wg_get_stable_session(wgp, &_psref);
2614 wg_send_keepalive_msg(wgp, wgs);
2615 wg_put_session(wgs, &_psref);
2616 }
2617 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION)) {
2618 struct wg_session *wgs;
2619
2620 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION");
2621 mutex_enter(wgp->wgp_lock);
2622 wgs = wgp->wgp_session_unstable;
2623 mutex_enter(wgs->wgs_lock);
2624 if (wgs->wgs_state == WGS_STATE_DESTROYING) {
2625 pserialize_perform(wgp->wgp_psz);
2626 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
2627 psref_target_init(&wgs->wgs_psref, wg_psref_class);
2628 wg_clear_states(wgs);
2629 wgs->wgs_state = WGS_STATE_UNKNOWN;
2630 }
2631 mutex_exit(wgs->wgs_lock);
2632 mutex_exit(wgp->wgp_lock);
2633 }
2634
2635 /* New tasks may be scheduled during processing tasks */
2636 WG_DLOG("wgp_tasks=%d\n", wgp->wgp_tasks);
2637 if (wgp->wgp_tasks != 0)
2638 goto restart;
2639
2640 s = pserialize_read_enter();
2641 wg_put_peer(wgp, &psref);
2642 }
2643 pserialize_read_exit(s);
2644 }
2645
2646 static void
2647 wg_worker(void *arg)
2648 {
2649 struct wg_softc *wg = arg;
2650 struct wg_worker *wgw = wg->wg_worker;
2651 int bound = curlwp_bind();
2652
2653 KASSERT(wg != NULL);
2654 KASSERT(wgw != NULL);
2655
2656 while (!wgw->wgw_todie) {
2657 int reasons;
2658
2659 mutex_enter(&wgw->wgw_lock);
2660 /* New tasks may come during task handling */
2661 if (wgw->wgw_wakeup_reasons == 0)
2662 cv_wait(&wgw->wgw_cv, &wgw->wgw_lock);
2663 reasons = wgw->wgw_wakeup_reasons;
2664 wgw->wgw_wakeup_reasons = 0;
2665 mutex_exit(&wgw->wgw_lock);
2666
2667 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4))
2668 wg_receive_packets(wg, AF_INET);
2669 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6))
2670 wg_receive_packets(wg, AF_INET6);
2671 if (!ISSET(reasons, WG_WAKEUP_REASON_PEER))
2672 continue;
2673
2674 wg_process_peer_tasks(wg);
2675 }
2676 curlwp_bindx(bound);
2677 kthread_exit(0);
2678 }
2679
2680 static void
2681 wg_wakeup_worker(struct wg_worker *wgw, const int reason)
2682 {
2683
2684 mutex_enter(&wgw->wgw_lock);
2685 wgw->wgw_wakeup_reasons |= reason;
2686 cv_broadcast(&wgw->wgw_cv);
2687 mutex_exit(&wgw->wgw_lock);
2688 }
2689
2690 static int
2691 wg_bind_port(struct wg_softc *wg, const uint16_t port)
2692 {
2693 int error;
2694 struct wg_worker *wgw = wg->wg_worker;
2695 uint16_t old_port = wg->wg_listen_port;
2696
2697 if (port != 0 && old_port == port)
2698 return 0;
2699
2700 struct sockaddr_in _sin, *sin = &_sin;
2701 sin->sin_len = sizeof(*sin);
2702 sin->sin_family = AF_INET;
2703 sin->sin_addr.s_addr = INADDR_ANY;
2704 sin->sin_port = htons(port);
2705
2706 error = sobind(wgw->wgw_so4, sintosa(sin), curlwp);
2707 if (error != 0)
2708 return error;
2709
2710 #ifdef INET6
2711 struct sockaddr_in6 _sin6, *sin6 = &_sin6;
2712 sin6->sin6_len = sizeof(*sin6);
2713 sin6->sin6_family = AF_INET6;
2714 sin6->sin6_addr = in6addr_any;
2715 sin6->sin6_port = htons(port);
2716
2717 error = sobind(wgw->wgw_so6, sin6tosa(sin6), curlwp);
2718 if (error != 0)
2719 return error;
2720 #endif
2721
2722 wg->wg_listen_port = port;
2723
2724 return 0;
2725 }
2726
2727 static void
2728 wg_so_upcall(struct socket *so, void *arg, int events, int waitflag)
2729 {
2730 struct wg_worker *wgw = arg;
2731 int reason;
2732
2733 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ?
2734 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 :
2735 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6;
2736 wg_wakeup_worker(wgw, reason);
2737 }
2738
2739 static int
2740 wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so,
2741 struct sockaddr *src, void *arg)
2742 {
2743 struct wg_softc *wg = arg;
2744 struct wg_msg wgm;
2745 struct mbuf *m = *mp;
2746
2747 WG_TRACE("enter");
2748
2749 m_copydata(m, offset, sizeof(struct wg_msg), &wgm);
2750 WG_DLOG("type=%d\n", wgm.wgm_type);
2751
2752 switch (wgm.wgm_type) {
2753 case WG_MSG_TYPE_DATA:
2754 m_adj(m, offset);
2755 wg_handle_msg_data(wg, m, src);
2756 *mp = NULL;
2757 return 1;
2758 default:
2759 break;
2760 }
2761
2762 return 0;
2763 }
2764
2765 static int
2766 wg_worker_socreate(struct wg_softc *wg, struct wg_worker *wgw, const int af,
2767 struct socket **sop)
2768 {
2769 int error;
2770 struct socket *so;
2771
2772 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL);
2773 if (error != 0)
2774 return error;
2775
2776 solock(so);
2777 so->so_upcallarg = wgw;
2778 so->so_upcall = wg_so_upcall;
2779 so->so_rcv.sb_flags |= SB_UPCALL;
2780 if (af == AF_INET)
2781 in_pcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg);
2782 #if INET6
2783 else
2784 in6_pcb_register_overudp_cb(sotoin6pcb(so), wg_overudp_cb, wg);
2785 #endif
2786 sounlock(so);
2787
2788 *sop = so;
2789
2790 return 0;
2791 }
2792
2793 static int
2794 wg_worker_init(struct wg_softc *wg)
2795 {
2796 int error;
2797 struct wg_worker *wgw;
2798 const char *ifname = wg->wg_if.if_xname;
2799 struct socket *so;
2800
2801 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP);
2802
2803 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_NONE);
2804 cv_init(&wgw->wgw_cv, ifname);
2805 wgw->wgw_todie = false;
2806 wgw->wgw_wakeup_reasons = 0;
2807
2808 error = wg_worker_socreate(wg, wgw, AF_INET, &so);
2809 if (error != 0)
2810 goto error;
2811 wgw->wgw_so4 = so;
2812 #ifdef INET6
2813 error = wg_worker_socreate(wg, wgw, AF_INET6, &so);
2814 if (error != 0)
2815 goto error;
2816 wgw->wgw_so6 = so;
2817 #endif
2818
2819 wg->wg_worker = wgw;
2820
2821 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN,
2822 NULL, wg_worker, wg, &wg->wg_worker_lwp, "%s", ifname);
2823 if (error != 0)
2824 goto error;
2825
2826 return 0;
2827
2828 error:
2829 #ifdef INET6
2830 if (wgw->wgw_so6 != NULL)
2831 soclose(wgw->wgw_so6);
2832 #endif
2833 if (wgw->wgw_so4 != NULL)
2834 soclose(wgw->wgw_so4);
2835 cv_destroy(&wgw->wgw_cv);
2836 mutex_destroy(&wgw->wgw_lock);
2837
2838 return error;
2839 }
2840
2841 static void
2842 wg_worker_destroy(struct wg_softc *wg)
2843 {
2844 struct wg_worker *wgw = wg->wg_worker;
2845
2846 mutex_enter(&wgw->wgw_lock);
2847 wgw->wgw_todie = true;
2848 wgw->wgw_wakeup_reasons = 0;
2849 cv_broadcast(&wgw->wgw_cv);
2850 mutex_exit(&wgw->wgw_lock);
2851
2852 kthread_join(wg->wg_worker_lwp);
2853
2854 #ifdef INET6
2855 soclose(wgw->wgw_so6);
2856 #endif
2857 soclose(wgw->wgw_so4);
2858 cv_destroy(&wgw->wgw_cv);
2859 mutex_destroy(&wgw->wgw_lock);
2860 kmem_free(wg->wg_worker, sizeof(struct wg_worker));
2861 wg->wg_worker = NULL;
2862 }
2863
2864 static bool
2865 wg_session_hit_limits(struct wg_session *wgs)
2866 {
2867
2868 /*
2869 * [W] 6.2: Transport Message Limits
2870 * "After REJECT-AFTER-MESSAGES transport data messages or after the
2871 * current secure session is REJECT-AFTER-TIME seconds old, whichever
2872 * comes first, WireGuard will refuse to send any more transport data
2873 * messages using the current secure session, ..."
2874 */
2875 KASSERT(wgs->wgs_time_established != 0);
2876 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) {
2877 WG_DLOG("The session hits REJECT_AFTER_TIME\n");
2878 return true;
2879 } else if (wgs->wgs_send_counter > wg_reject_after_messages) {
2880 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n");
2881 return true;
2882 }
2883
2884 return false;
2885 }
2886
2887 static void
2888 wg_peer_softint(void *arg)
2889 {
2890 struct wg_peer *wgp = (struct wg_peer *)arg;
2891 struct wg_session *wgs;
2892 struct mbuf *m;
2893 struct psref psref;
2894
2895 wgs = wg_get_stable_session(wgp, &psref);
2896 if (wgs->wgs_state != WGS_STATE_ESTABLISHED) {
2897 /* XXX how to treat? */
2898 WG_TRACE("skipped");
2899 goto out;
2900 }
2901 if (wg_session_hit_limits(wgs)) {
2902 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2903 goto out;
2904 }
2905 WG_TRACE("running");
2906
2907 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
2908 wg_send_data_msg(wgp, wgs, m);
2909 }
2910 out:
2911 wg_put_session(wgs, &psref);
2912 }
2913
2914 static void
2915 wg_rekey_timer(void *arg)
2916 {
2917 struct wg_peer *wgp = arg;
2918
2919 mutex_enter(wgp->wgp_lock);
2920 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) {
2921 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2922 }
2923 mutex_exit(wgp->wgp_lock);
2924 }
2925
2926 static void
2927 wg_purge_pending_packets(struct wg_peer *wgp)
2928 {
2929 struct mbuf *m;
2930
2931 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
2932 m_freem(m);
2933 }
2934 }
2935
2936 static void
2937 wg_handshake_timeout_timer(void *arg)
2938 {
2939 struct wg_peer *wgp = arg;
2940 struct wg_session *wgs;
2941 struct psref psref;
2942
2943 WG_TRACE("enter");
2944
2945 mutex_enter(wgp->wgp_lock);
2946 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
2947 mutex_exit(wgp->wgp_lock);
2948 return;
2949 }
2950 mutex_exit(wgp->wgp_lock);
2951
2952 KASSERT(wgp->wgp_handshake_start_time != 0);
2953 wgs = wg_get_unstable_session(wgp, &psref);
2954 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE);
2955
2956 /* [W] 6.4 Handshake Initiation Retransmission */
2957 if ((time_uptime - wgp->wgp_handshake_start_time) >
2958 wg_rekey_attempt_time) {
2959 /* Give up handshaking */
2960 wgs->wgs_state = WGS_STATE_UNKNOWN;
2961 wg_clear_states(wgs);
2962 wgp->wgp_state = WGP_STATE_GIVEUP;
2963 wgp->wgp_handshake_start_time = 0;
2964 wg_put_session(wgs, &psref);
2965 WG_TRACE("give up");
2966 /*
2967 * If a new data packet comes, handshaking will be retried
2968 * and a new session would be established at that time,
2969 * however we don't want to send pending packets then.
2970 */
2971 wg_purge_pending_packets(wgp);
2972 return;
2973 }
2974
2975 /* No response for an initiation message sent, retry handshaking */
2976 wgs->wgs_state = WGS_STATE_UNKNOWN;
2977 wg_clear_states(wgs);
2978 wg_put_session(wgs, &psref);
2979
2980 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2981 }
2982
2983 static struct wg_peer *
2984 wg_alloc_peer(struct wg_softc *wg)
2985 {
2986 struct wg_peer *wgp;
2987
2988 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP);
2989
2990 wgp->wgp_sc = wg;
2991 wgp->wgp_state = WGP_STATE_INIT;
2992 wgp->wgp_q = pcq_create(1024, KM_SLEEP);
2993 wgp->wgp_si = softint_establish(SOFTINT_NET, wg_peer_softint, wgp);
2994 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE);
2995 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp);
2996 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE);
2997 callout_setfunc(&wgp->wgp_handshake_timeout_timer,
2998 wg_handshake_timeout_timer, wgp);
2999 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE);
3000 callout_setfunc(&wgp->wgp_session_dtor_timer,
3001 wg_session_dtor_timer, wgp);
3002 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry);
3003 wgp->wgp_endpoint_changing = false;
3004 wgp->wgp_endpoint_available = false;
3005 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3006 wgp->wgp_psz = pserialize_create();
3007 psref_target_init(&wgp->wgp_psref, wg_psref_class);
3008
3009 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP);
3010 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP);
3011 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3012 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3013
3014 struct wg_session *wgs;
3015 wgp->wgp_session_stable = kmem_zalloc(sizeof(struct wg_session), KM_SLEEP);
3016 wgp->wgp_session_unstable = kmem_zalloc(sizeof(struct wg_session), KM_SLEEP);
3017 wgs = wgp->wgp_session_stable;
3018 wgs->wgs_peer = wgp;
3019 wgs->wgs_state = WGS_STATE_UNKNOWN;
3020 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3021 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3022 wgs = wgp->wgp_session_unstable;
3023 wgs->wgs_peer = wgp;
3024 wgs->wgs_state = WGS_STATE_UNKNOWN;
3025 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3026 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3027
3028 return wgp;
3029 }
3030
3031 static void
3032 wg_destroy_peer(struct wg_peer *wgp)
3033 {
3034 struct wg_session *wgs;
3035 struct wg_softc *wg = wgp->wgp_sc;
3036
3037 rw_enter(wg->wg_rwlock, RW_WRITER);
3038 for (int i = 0; i < wgp->wgp_n_allowedips; i++) {
3039 struct wg_allowedip *wga = &wgp->wgp_allowedips[i];
3040 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family);
3041 struct radix_node *rn;
3042
3043 KASSERT(rnh != NULL);
3044 rn = rnh->rnh_deladdr(&wga->wga_sa_addr,
3045 &wga->wga_sa_mask, rnh);
3046 if (rn == NULL) {
3047 char addrstr[128];
3048 sockaddr_format(&wga->wga_sa_addr, addrstr,
3049 sizeof(addrstr));
3050 WGLOG(LOG_WARNING, "Couldn't delete %s", addrstr);
3051 }
3052 }
3053 rw_exit(wg->wg_rwlock);
3054
3055 softint_disestablish(wgp->wgp_si);
3056 callout_halt(&wgp->wgp_rekey_timer, NULL);
3057 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL);
3058 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
3059
3060 wgs = wgp->wgp_session_unstable;
3061 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3062 mutex_obj_free(wgs->wgs_lock);
3063 kmem_free(wgs, sizeof(*wgs));
3064 wgs = wgp->wgp_session_stable;
3065 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3066 mutex_obj_free(wgs->wgs_lock);
3067 kmem_free(wgs, sizeof(*wgs));
3068
3069 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3070 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3071 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint));
3072 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0));
3073
3074 pserialize_destroy(wgp->wgp_psz);
3075 pcq_destroy(wgp->wgp_q);
3076 mutex_obj_free(wgp->wgp_lock);
3077
3078 kmem_free(wgp, sizeof(*wgp));
3079 }
3080
3081 static void
3082 wg_destroy_all_peers(struct wg_softc *wg)
3083 {
3084 struct wg_peer *wgp;
3085
3086 restart:
3087 mutex_enter(wg->wg_lock);
3088 WG_PEER_WRITER_FOREACH(wgp, wg) {
3089 WG_PEER_WRITER_REMOVE(wgp);
3090 mutex_enter(wgp->wgp_lock);
3091 wgp->wgp_state = WGP_STATE_DESTROYING;
3092 pserialize_perform(wgp->wgp_psz);
3093 mutex_exit(wgp->wgp_lock);
3094 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3095 break;
3096 }
3097 mutex_exit(wg->wg_lock);
3098
3099 if (wgp == NULL)
3100 return;
3101
3102 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3103
3104 wg_destroy_peer(wgp);
3105
3106 goto restart;
3107 }
3108
3109 static int
3110 wg_destroy_peer_name(struct wg_softc *wg, const char *name)
3111 {
3112 struct wg_peer *wgp;
3113
3114 mutex_enter(wg->wg_lock);
3115 WG_PEER_WRITER_FOREACH(wgp, wg) {
3116 if (strcmp(wgp->wgp_name, name) == 0)
3117 break;
3118 }
3119 if (wgp != NULL) {
3120 WG_PEER_WRITER_REMOVE(wgp);
3121 wg->wg_npeers--;
3122 mutex_enter(wgp->wgp_lock);
3123 wgp->wgp_state = WGP_STATE_DESTROYING;
3124 pserialize_perform(wgp->wgp_psz);
3125 mutex_exit(wgp->wgp_lock);
3126 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3127 }
3128 mutex_exit(wg->wg_lock);
3129
3130 if (wgp == NULL)
3131 return ENOENT;
3132
3133 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3134
3135 wg_destroy_peer(wgp);
3136
3137 return 0;
3138 }
3139
3140 static int
3141 wg_if_attach(struct wg_softc *wg)
3142 {
3143 int error;
3144
3145 wg->wg_if.if_addrlen = 0;
3146 wg->wg_if.if_mtu = WG_MTU;
3147 wg->wg_if.if_flags = IFF_POINTOPOINT;
3148 wg->wg_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE;
3149 wg->wg_if.if_extflags |= IFEF_MPSAFE;
3150 wg->wg_if.if_ioctl = wg_ioctl;
3151 wg->wg_if.if_output = wg_output;
3152 wg->wg_if.if_init = wg_init;
3153 wg->wg_if.if_stop = wg_stop;
3154 wg->wg_if.if_type = IFT_WIREGUARD;
3155 wg->wg_if.if_dlt = DLT_NULL;
3156 wg->wg_if.if_softc = wg;
3157 IFQ_SET_READY(&wg->wg_if.if_snd);
3158
3159 error = if_initialize(&wg->wg_if);
3160 if (error != 0)
3161 return error;
3162
3163 if_alloc_sadl(&wg->wg_if);
3164 if_register(&wg->wg_if);
3165
3166 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t));
3167
3168 return 0;
3169 }
3170
3171 static int
3172 wg_clone_create(struct if_clone *ifc, int unit)
3173 {
3174 struct wg_softc *wg;
3175 int error;
3176
3177 wg = kmem_zalloc(sizeof(struct wg_softc), KM_SLEEP);
3178
3179 if_initname(&wg->wg_if, ifc->ifc_name, unit);
3180
3181 error = wg_worker_init(wg);
3182 if (error != 0) {
3183 kmem_free(wg, sizeof(struct wg_softc));
3184 return error;
3185 }
3186
3187 rn_inithead((void **)&wg->wg_rtable_ipv4,
3188 offsetof(struct sockaddr_in, sin_addr) * NBBY);
3189 #ifdef INET6
3190 rn_inithead((void **)&wg->wg_rtable_ipv6,
3191 offsetof(struct sockaddr_in6, sin6_addr) * NBBY);
3192 #endif
3193
3194 PSLIST_INIT(&wg->wg_peers);
3195 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3196 wg->wg_rwlock = rw_obj_alloc();
3197 wg->wg_ops = &wg_ops_rumpkernel;
3198
3199 error = wg_if_attach(wg);
3200 if (error != 0) {
3201 wg_worker_destroy(wg);
3202 if (wg->wg_rtable_ipv4 != NULL)
3203 free(wg->wg_rtable_ipv4, M_RTABLE);
3204 if (wg->wg_rtable_ipv6 != NULL)
3205 free(wg->wg_rtable_ipv6, M_RTABLE);
3206 PSLIST_DESTROY(&wg->wg_peers);
3207 mutex_obj_free(wg->wg_lock);
3208 kmem_free(wg, sizeof(struct wg_softc));
3209 return error;
3210 }
3211
3212 mutex_enter(&wg_softcs.lock);
3213 LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list);
3214 mutex_exit(&wg_softcs.lock);
3215
3216 return 0;
3217 }
3218
3219 static int
3220 wg_clone_destroy(struct ifnet *ifp)
3221 {
3222 struct wg_softc *wg = (void *) ifp;
3223
3224 mutex_enter(&wg_softcs.lock);
3225 LIST_REMOVE(wg, wg_list);
3226 mutex_exit(&wg_softcs.lock);
3227
3228 #ifdef WG_RUMPKERNEL
3229 if (wg_user_mode(wg)) {
3230 rumpuser_wg_destroy(wg->wg_user);
3231 wg->wg_user = NULL;
3232 }
3233 #endif
3234
3235 bpf_detach(ifp);
3236 if_detach(ifp);
3237 wg_worker_destroy(wg);
3238 wg_destroy_all_peers(wg);
3239 if (wg->wg_rtable_ipv4 != NULL)
3240 free(wg->wg_rtable_ipv4, M_RTABLE);
3241 if (wg->wg_rtable_ipv6 != NULL)
3242 free(wg->wg_rtable_ipv6, M_RTABLE);
3243
3244 PSLIST_DESTROY(&wg->wg_peers);
3245 mutex_obj_free(wg->wg_lock);
3246 rw_obj_free(wg->wg_rwlock);
3247
3248 kmem_free(wg, sizeof(struct wg_softc));
3249
3250 return 0;
3251 }
3252
3253 static struct wg_peer *
3254 wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa,
3255 struct psref *psref)
3256 {
3257 struct radix_node_head *rnh;
3258 struct radix_node *rn;
3259 struct wg_peer *wgp = NULL;
3260 struct wg_allowedip *wga;
3261
3262 #ifdef WG_DEBUG_LOG
3263 char addrstr[128];
3264 sockaddr_format(sa, addrstr, sizeof(addrstr));
3265 WG_DLOG("sa=%s\n", addrstr);
3266 #endif
3267
3268 rw_enter(wg->wg_rwlock, RW_READER);
3269
3270 rnh = wg_rnh(wg, sa->sa_family);
3271 if (rnh == NULL)
3272 goto out;
3273
3274 rn = rnh->rnh_matchaddr(sa, rnh);
3275 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
3276 goto out;
3277
3278 WG_TRACE("success");
3279
3280 wga = (struct wg_allowedip *)rn;
3281 wgp = wga->wga_peer;
3282 wg_get_peer(wgp, psref);
3283
3284 out:
3285 rw_exit(wg->wg_rwlock);
3286 return wgp;
3287 }
3288
3289 static void
3290 wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp,
3291 struct wg_session *wgs, struct wg_msg_data *wgmd)
3292 {
3293
3294 memset(wgmd, 0, sizeof(*wgmd));
3295 wgmd->wgmd_type = WG_MSG_TYPE_DATA;
3296 wgmd->wgmd_receiver = wgs->wgs_receiver_index;
3297 /* [W] 5.4.6: msg.counter := Nm^send */
3298 /* [W] 5.4.6: Nm^send := Nm^send + 1 */
3299 wgmd->wgmd_counter = atomic_inc_64_nv(&wgs->wgs_send_counter) - 1;
3300 WG_DLOG("counter=%"PRIu64"\n", wgmd->wgmd_counter);
3301 }
3302
3303 static int
3304 wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
3305 const struct rtentry *rt)
3306 {
3307 struct wg_softc *wg = ifp->if_softc;
3308 int error = 0;
3309 int bound;
3310 struct psref psref;
3311
3312 /* TODO make the nest limit configurable via sysctl */
3313 error = if_tunnel_check_nesting(ifp, m, 1);
3314 if (error != 0) {
3315 m_freem(m);
3316 WGLOG(LOG_ERR, "tunneling loop detected and packet dropped\n");
3317 return error;
3318 }
3319
3320 bound = curlwp_bind();
3321
3322 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
3323
3324 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT);
3325
3326 m->m_flags &= ~(M_BCAST|M_MCAST);
3327
3328 struct wg_peer *wgp = wg_pick_peer_by_sa(wg, dst, &psref);
3329 if (wgp == NULL) {
3330 WG_TRACE("peer not found");
3331 error = EHOSTUNREACH;
3332 goto error;
3333 }
3334
3335 /* Clear checksum-offload flags. */
3336 m->m_pkthdr.csum_flags = 0;
3337 m->m_pkthdr.csum_data = 0;
3338
3339 if (!pcq_put(wgp->wgp_q, m)) {
3340 error = ENOBUFS;
3341 goto error;
3342 }
3343
3344 struct psref psref_wgs;
3345 struct wg_session *wgs;
3346 wgs = wg_get_stable_session(wgp, &psref_wgs);
3347 if (wgs->wgs_state == WGS_STATE_ESTABLISHED &&
3348 !wg_session_hit_limits(wgs)) {
3349 kpreempt_disable();
3350 softint_schedule(wgp->wgp_si);
3351 kpreempt_enable();
3352 WG_TRACE("softint scheduled");
3353 } else {
3354 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3355 WG_TRACE("softint NOT scheduled");
3356 }
3357 wg_put_session(wgs, &psref_wgs);
3358 wg_put_peer(wgp, &psref);
3359
3360 return 0;
3361
3362 error:
3363 if (wgp != NULL)
3364 wg_put_peer(wgp, &psref);
3365 if (m != NULL)
3366 m_freem(m);
3367 curlwp_bindx(bound);
3368 return error;
3369 }
3370
3371 static int
3372 wg_send_udp(struct wg_peer *wgp, struct mbuf *m)
3373 {
3374 struct psref psref;
3375 struct wg_sockaddr *wgsa;
3376 int error;
3377 struct socket *so = wg_get_so_by_peer(wgp);
3378
3379 solock(so);
3380 wgsa = wg_get_endpoint_sa(wgp, &psref);
3381 if (wgsatosa(wgsa)->sa_family == AF_INET) {
3382 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp);
3383 } else {
3384 #ifdef INET6
3385 error = udp6_output(sotoin6pcb(so), m, wgsatosin6(wgsa),
3386 NULL, curlwp);
3387 #else
3388 error = EPROTONOSUPPORT;
3389 #endif
3390 }
3391 wg_put_sa(wgp, wgsa, &psref);
3392 sounlock(so);
3393
3394 return error;
3395 }
3396
3397 /* Inspired by pppoe_get_mbuf */
3398 static struct mbuf *
3399 wg_get_mbuf(size_t leading_len, size_t len)
3400 {
3401 struct mbuf *m;
3402
3403 m = m_gethdr(M_DONTWAIT, MT_DATA);
3404 if (m == NULL)
3405 return NULL;
3406 if (len + leading_len > MHLEN) {
3407 m_clget(m, M_DONTWAIT);
3408 if ((m->m_flags & M_EXT) == 0) {
3409 m_free(m);
3410 return NULL;
3411 }
3412 }
3413 m->m_data += leading_len;
3414 m->m_pkthdr.len = m->m_len = len;
3415
3416 return m;
3417 }
3418
3419 static int
3420 wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs,
3421 struct mbuf *m)
3422 {
3423 struct wg_softc *wg = wgp->wgp_sc;
3424 int error;
3425 size_t inner_len, padded_len, encrypted_len;
3426 char *padded_buf = NULL;
3427 size_t mlen;
3428 struct wg_msg_data *wgmd;
3429 bool free_padded_buf = false;
3430 struct mbuf *n;
3431 size_t leading_len = max_linkhdr + sizeof(struct ip6_hdr) +
3432 sizeof(struct udphdr);
3433
3434 mlen = m_length(m);
3435 inner_len = mlen;
3436 padded_len = roundup(mlen, 16);
3437 encrypted_len = padded_len + WG_AUTHTAG_LEN;
3438 WG_DLOG("inner=%lu, padded=%lu, encrypted_len=%lu\n",
3439 inner_len, padded_len, encrypted_len);
3440 if (mlen != 0) {
3441 bool success;
3442 success = m_ensure_contig(&m, padded_len);
3443 if (success) {
3444 padded_buf = mtod(m, char *);
3445 } else {
3446 padded_buf = kmem_intr_alloc(padded_len, KM_NOSLEEP);
3447 if (padded_buf == NULL) {
3448 error = ENOBUFS;
3449 goto end;
3450 }
3451 free_padded_buf = true;
3452 m_copydata(m, 0, mlen, padded_buf);
3453 }
3454 memset(padded_buf + mlen, 0, padded_len - inner_len);
3455 }
3456
3457 n = wg_get_mbuf(leading_len, sizeof(*wgmd) + encrypted_len);
3458 if (n == NULL) {
3459 error = ENOBUFS;
3460 goto end;
3461 }
3462 wgmd = mtod(n, struct wg_msg_data *);
3463 wg_fill_msg_data(wg, wgp, wgs, wgmd);
3464 /* [W] 5.4.6: AEAD(Tm^send, Nm^send, P, e) */
3465 wg_algo_aead_enc((char *)wgmd + sizeof(*wgmd), encrypted_len,
3466 wgs->wgs_tkey_send, wgmd->wgmd_counter, padded_buf, padded_len,
3467 NULL, 0);
3468
3469 error = wg->wg_ops->send_data_msg(wgp, n);
3470 if (error == 0) {
3471 struct ifnet *ifp = &wg->wg_if;
3472 ifp->if_obytes += mlen;
3473 ifp->if_opackets++;
3474 if (wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0) {
3475 /*
3476 * [W] 6.2 Transport Message Limits
3477 * "if a peer is the initiator of a current secure
3478 * session, WireGuard will send a handshake initiation
3479 * message to begin a new secure session if, after
3480 * transmitting a transport data message, the current
3481 * secure session is REKEY-AFTER-TIME seconds old,"
3482 */
3483 wg_schedule_rekey_timer(wgp);
3484 }
3485 wgs->wgs_time_last_data_sent = time_uptime;
3486 if (wgs->wgs_send_counter >= wg_rekey_after_messages) {
3487 /*
3488 * [W] 6.2 Transport Message Limits
3489 * "WireGuard will try to create a new session, by
3490 * sending a handshake initiation message (section
3491 * 5.4.2), after it has sent REKEY-AFTER-MESSAGES
3492 * transport data messages..."
3493 */
3494 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3495 }
3496 }
3497 end:
3498 m_freem(m);
3499 if (free_padded_buf)
3500 kmem_intr_free(padded_buf, padded_len);
3501 return error;
3502 }
3503
3504 static void
3505 wg_input(struct ifnet *ifp, struct mbuf *m, const int af)
3506 {
3507 pktqueue_t *pktq;
3508 size_t pktlen;
3509
3510 KASSERT(af == AF_INET || af == AF_INET6);
3511
3512 WG_TRACE("");
3513
3514 m_set_rcvif(m, ifp);
3515 pktlen = m->m_pkthdr.len;
3516
3517 bpf_mtap_af(ifp, af, m, BPF_D_IN);
3518
3519 switch (af) {
3520 case AF_INET:
3521 pktq = ip_pktq;
3522 break;
3523 #ifdef INET6
3524 case AF_INET6:
3525 pktq = ip6_pktq;
3526 break;
3527 #endif
3528 default:
3529 panic("invalid af=%d", af);
3530 }
3531
3532 const u_int h = curcpu()->ci_index;
3533 if (__predict_true(pktq_enqueue(pktq, m, h))) {
3534 ifp->if_ibytes += pktlen;
3535 ifp->if_ipackets++;
3536 } else {
3537 m_freem(m);
3538 }
3539 }
3540
3541 static void
3542 wg_calc_pubkey(uint8_t pubkey[WG_STATIC_KEY_LEN],
3543 const uint8_t privkey[WG_STATIC_KEY_LEN])
3544 {
3545
3546 crypto_scalarmult_base(pubkey, privkey);
3547 }
3548
3549 static int
3550 wg_rtable_add_route(struct wg_softc *wg, struct wg_allowedip *wga)
3551 {
3552 struct radix_node_head *rnh;
3553 struct radix_node *rn;
3554 int error = 0;
3555
3556 rw_enter(wg->wg_rwlock, RW_WRITER);
3557 rnh = wg_rnh(wg, wga->wga_family);
3558 KASSERT(rnh != NULL);
3559 rn = rnh->rnh_addaddr(&wga->wga_sa_addr, &wga->wga_sa_mask, rnh,
3560 wga->wga_nodes);
3561 rw_exit(wg->wg_rwlock);
3562
3563 if (rn == NULL)
3564 error = EEXIST;
3565
3566 return error;
3567 }
3568
3569 static int
3570 wg_handle_prop_peer(struct wg_softc *wg, prop_dictionary_t peer,
3571 struct wg_peer **wgpp)
3572 {
3573 int error = 0;
3574 prop_object_t prop_obj;
3575 char *pubkey;
3576 size_t pubkey_len;
3577 const char *name = NULL;
3578
3579 prop_obj = prop_dictionary_get(peer, "name");
3580 if (prop_obj != NULL) {
3581 name = prop_string_cstring_nocopy(prop_obj);
3582 if (strlen(name) > WG_PEER_NAME_MAXLEN) {
3583 error = EINVAL;
3584 goto out;
3585 }
3586 }
3587
3588 prop_obj = prop_dictionary_get(peer, "public_key");
3589 if (prop_obj == NULL) {
3590 error = EINVAL;
3591 goto out;
3592 }
3593 pubkey = prop_data_data(prop_obj);
3594 pubkey_len = prop_data_size(prop_obj);
3595 #ifdef WG_DEBUG_DUMP
3596 log(LOG_DEBUG, "pubkey=%p, pubkey_len=%lu\n", pubkey, pubkey_len);
3597 for (int _i = 0; _i < pubkey_len; _i++)
3598 log(LOG_DEBUG, "%c", pubkey[_i]);
3599 log(LOG_DEBUG, "\n");
3600 #else
3601 (void)pubkey_len; /* XXX gcc */
3602 #endif
3603
3604 struct wg_peer *wgp = wg_alloc_peer(wg);
3605 memcpy(wgp->wgp_pubkey, pubkey, sizeof(wgp->wgp_pubkey));
3606 if (name != NULL)
3607 strncpy(wgp->wgp_name, name, sizeof(wgp->wgp_name));
3608
3609 prop_obj = prop_dictionary_get(peer, "preshared_key");
3610 if (prop_obj != NULL) {
3611 char *psk = prop_data_data(prop_obj);
3612 size_t psk_len = prop_data_size(prop_obj);
3613
3614 if (psk_len != sizeof(wgp->wgp_psk)) {
3615 error = EINVAL;
3616 goto out;
3617 }
3618 memcpy(wgp->wgp_psk, psk, sizeof(wgp->wgp_psk));
3619 }
3620
3621 struct sockaddr_storage sockaddr;
3622 char *addr;
3623 size_t addr_len;
3624
3625 prop_obj = prop_dictionary_get(peer, "endpoint");
3626 if (prop_obj == NULL)
3627 goto skip_endpoint;
3628
3629 addr = prop_data_data(prop_obj);
3630 addr_len = prop_data_size(prop_obj);
3631 memcpy(&sockaddr, addr, addr_len);
3632 switch (sockaddr.ss_family) {
3633 case AF_INET: {
3634 struct sockaddr_in sin;
3635 sockaddr_copy(sintosa(&sin), sizeof(sin),
3636 (struct sockaddr *)&sockaddr);
3637 sockaddr_copy(sintosa(&wgp->wgp_sin),
3638 sizeof(wgp->wgp_sin), (struct sockaddr *)&sockaddr);
3639 char addrstr[128];
3640 sockaddr_format(sintosa(&sin), addrstr, sizeof(addrstr));
3641 WG_DLOG("addr=%s\n", addrstr);
3642 break;
3643 }
3644 #ifdef INET6
3645 case AF_INET6: {
3646 struct sockaddr_in6 sin6;
3647 char addrstr[128];
3648 sockaddr_copy(sintosa(&sin6), sizeof(sin6),
3649 (struct sockaddr *)&sockaddr);
3650 sockaddr_format(sintosa(&sin6), addrstr, sizeof(addrstr));
3651 WG_DLOG("addr=%s\n", addrstr);
3652 sockaddr_copy(sin6tosa(&wgp->wgp_sin6),
3653 sizeof(wgp->wgp_sin6), (struct sockaddr *)&sockaddr);
3654 break;
3655 }
3656 #endif
3657 default:
3658 break;
3659 }
3660 wgp->wgp_endpoint_available = true;
3661
3662 prop_array_t allowedips;
3663 skip_endpoint:
3664 allowedips = prop_dictionary_get(peer, "allowedips");
3665 if (allowedips == NULL)
3666 goto skip;
3667
3668 prop_object_iterator_t _it = prop_array_iterator(allowedips);
3669 prop_dictionary_t prop_allowedip;
3670 int j = 0;
3671 while ((prop_allowedip = prop_object_iterator_next(_it)) != NULL) {
3672 struct wg_allowedip *wga = &wgp->wgp_allowedips[j];
3673
3674 prop_obj = prop_dictionary_get(prop_allowedip, "family");
3675 if (prop_obj == NULL)
3676 continue;
3677 wga->wga_family = prop_number_unsigned_integer_value(prop_obj);
3678
3679 prop_obj = prop_dictionary_get(prop_allowedip, "ip");
3680 if (prop_obj == NULL)
3681 continue;
3682 addr = prop_data_data(prop_obj);
3683 addr_len = prop_data_size(prop_obj);
3684
3685 prop_obj = prop_dictionary_get(prop_allowedip, "cidr");
3686 if (prop_obj == NULL)
3687 continue;
3688 wga->wga_cidr = prop_number_unsigned_integer_value(prop_obj);
3689
3690 switch (wga->wga_family) {
3691 case AF_INET: {
3692 struct sockaddr_in sin;
3693 char addrstr[128];
3694 struct in_addr mask;
3695 struct sockaddr_in sin_mask;
3696
3697 if (addr_len != sizeof(struct in_addr))
3698 return EINVAL;
3699 memcpy(&wga->wga_addr4, addr, addr_len);
3700
3701 sockaddr_in_init(&sin, (struct in_addr *)addr, 0);
3702 sockaddr_copy(&wga->wga_sa_addr,
3703 sizeof(sin), sintosa(&sin));
3704
3705 sockaddr_format(sintosa(&sin), addrstr, sizeof(addrstr));
3706 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
3707
3708 in_len2mask(&mask, wga->wga_cidr);
3709 sockaddr_in_init(&sin_mask, &mask, 0);
3710 sockaddr_copy(&wga->wga_sa_mask,
3711 sizeof(sin_mask), sintosa(&sin_mask));
3712
3713 break;
3714 }
3715 #ifdef INET6
3716 case AF_INET6: {
3717 struct sockaddr_in6 sin6;
3718 char addrstr[128];
3719 struct in6_addr mask;
3720 struct sockaddr_in6 sin6_mask;
3721
3722 if (addr_len != sizeof(struct in6_addr))
3723 return EINVAL;
3724 memcpy(&wga->wga_addr6, addr, addr_len);
3725
3726 sockaddr_in6_init(&sin6, (struct in6_addr *)addr, 0, 0, 0);
3727 sockaddr_copy(&wga->wga_sa_addr,
3728 sizeof(sin6), sin6tosa(&sin6));
3729
3730 sockaddr_format(sin6tosa(&sin6), addrstr, sizeof(addrstr));
3731 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
3732
3733 in6_prefixlen2mask(&mask, wga->wga_cidr);
3734 sockaddr_in6_init(&sin6_mask, &mask, 0, 0, 0);
3735 sockaddr_copy(&wga->wga_sa_mask,
3736 sizeof(sin6_mask), sin6tosa(&sin6_mask));
3737
3738 break;
3739 }
3740 #endif
3741 default:
3742 error = EINVAL;
3743 goto out;
3744 }
3745 wga->wga_peer = wgp;
3746
3747 error = wg_rtable_add_route(wg, wga);
3748 if (error != 0)
3749 goto out;
3750
3751 j++;
3752 }
3753 wgp->wgp_n_allowedips = j;
3754 skip:
3755 *wgpp = wgp;
3756 out:
3757 return error;
3758 }
3759
3760 static int
3761 wg_alloc_prop_buf(char **_buf, struct ifdrv *ifd)
3762 {
3763 int error;
3764 char *buf;
3765
3766 WG_DLOG("buf=%p, len=%lu\n", ifd->ifd_data, ifd->ifd_len);
3767 buf = kmem_alloc(ifd->ifd_len + 1, KM_SLEEP);
3768 error = copyin(ifd->ifd_data, buf, ifd->ifd_len);
3769 if (error != 0)
3770 return error;
3771 buf[ifd->ifd_len] = '\0';
3772 #ifdef WG_DEBUG_DUMP
3773 for (int i = 0; i < ifd->ifd_len; i++)
3774 log(LOG_DEBUG, "%c", buf[i]);
3775 log(LOG_DEBUG, "\n");
3776 #endif
3777 *_buf = buf;
3778 return 0;
3779 }
3780
3781 static int
3782 wg_ioctl_set_private_key(struct wg_softc *wg, struct ifdrv *ifd)
3783 {
3784 int error;
3785 prop_dictionary_t prop_dict;
3786 prop_object_t prop_obj;
3787 char *buf = NULL;
3788 char *privkey;
3789 size_t privkey_len;
3790
3791 error = wg_alloc_prop_buf(&buf, ifd);
3792 if (error != 0)
3793 return error;
3794 error = EINVAL;
3795 prop_dict = prop_dictionary_internalize(buf);
3796 if (prop_dict == NULL)
3797 goto out;
3798 prop_obj = prop_dictionary_get(prop_dict, "private_key");
3799 if (prop_obj == NULL)
3800 goto out;
3801
3802 privkey = prop_data_data(prop_obj);
3803 privkey_len = prop_data_size(prop_obj);
3804 #ifdef WG_DEBUG_DUMP
3805 log(LOG_DEBUG, "privkey=%p, privkey_len=%lu\n", privkey, privkey_len);
3806 for (int i = 0; i < privkey_len; i++)
3807 log(LOG_DEBUG, "%c", privkey[i]);
3808 log(LOG_DEBUG, "\n");
3809 #endif
3810 if (privkey_len != WG_STATIC_KEY_LEN)
3811 goto out;
3812 memcpy(wg->wg_privkey, privkey, WG_STATIC_KEY_LEN);
3813 wg_calc_pubkey(wg->wg_pubkey, wg->wg_privkey);
3814 error = 0;
3815
3816 out:
3817 kmem_free(buf, ifd->ifd_len + 1);
3818 return error;
3819 }
3820
3821 static int
3822 wg_ioctl_set_listen_port(struct wg_softc *wg, struct ifdrv *ifd)
3823 {
3824 int error;
3825 prop_dictionary_t prop_dict;
3826 prop_object_t prop_obj;
3827 char *buf = NULL;
3828 uint64_t port;
3829
3830 error = wg_alloc_prop_buf(&buf, ifd);
3831 if (error != 0)
3832 return error;
3833 error = EINVAL;
3834 prop_dict = prop_dictionary_internalize(buf);
3835 if (prop_dict == NULL)
3836 goto out;
3837 prop_obj = prop_dictionary_get(prop_dict, "listen_port");
3838 if (prop_obj == NULL)
3839 goto out;
3840
3841 port = prop_number_unsigned_integer_value(prop_obj);
3842 if (port != (uint64_t)(uint16_t)port)
3843 goto out;
3844 error = wg->wg_ops->bind_port(wg, (uint16_t)port);
3845
3846 out:
3847 kmem_free(buf, ifd->ifd_len + 1);
3848 return error;
3849 }
3850
3851 static int
3852 wg_ioctl_add_peer(struct wg_softc *wg, struct ifdrv *ifd)
3853 {
3854 int error;
3855 prop_dictionary_t prop_dict;
3856 char *buf = NULL;
3857 struct wg_peer *wgp = NULL;
3858
3859 error = wg_alloc_prop_buf(&buf, ifd);
3860 if (error != 0)
3861 return error;
3862 error = EINVAL;
3863 prop_dict = prop_dictionary_internalize(buf);
3864 if (prop_dict == NULL)
3865 goto out;
3866
3867 error = wg_handle_prop_peer(wg, prop_dict, &wgp);
3868 if (error != 0)
3869 goto out;
3870
3871 mutex_enter(wg->wg_lock);
3872 WG_PEER_WRITER_INSERT_HEAD(wgp, wg);
3873 wg->wg_npeers++;
3874 mutex_exit(wg->wg_lock);
3875
3876 out:
3877 kmem_free(buf, ifd->ifd_len + 1);
3878 return error;
3879 }
3880
3881 static int
3882 wg_ioctl_delete_peer(struct wg_softc *wg, struct ifdrv *ifd)
3883 {
3884 int error;
3885 prop_dictionary_t prop_dict;
3886 prop_object_t prop_obj;
3887 char *buf = NULL;
3888 const char *name;
3889
3890 error = wg_alloc_prop_buf(&buf, ifd);
3891 if (error != 0)
3892 return error;
3893 error = EINVAL;
3894 prop_dict = prop_dictionary_internalize(buf);
3895 if (prop_dict == NULL)
3896 goto out;
3897
3898 prop_obj = prop_dictionary_get(prop_dict, "name");
3899 if (prop_obj == NULL)
3900 goto out;
3901
3902 name = prop_string_cstring_nocopy(prop_obj);
3903 if (strlen(name) > WG_PEER_NAME_MAXLEN)
3904 goto out;
3905
3906 error = wg_destroy_peer_name(wg, name);
3907 out:
3908 kmem_free(buf, ifd->ifd_len + 1);
3909 return error;
3910 }
3911
3912 static int
3913 wg_ioctl_get(struct wg_softc *wg, struct ifdrv *ifd)
3914 {
3915 int error = ENOMEM;
3916 prop_dictionary_t prop_dict;
3917 prop_array_t peers;
3918 char *buf;
3919 struct wg_peer *wgp;
3920 int s, i;
3921
3922 prop_dict = prop_dictionary_create();
3923 if (prop_dict == NULL)
3924 goto error;
3925
3926 {
3927 prop_data_t privkey;
3928 privkey = prop_data_create_data(wg->wg_privkey, WG_STATIC_KEY_LEN);
3929 prop_dictionary_set(prop_dict, "private_key", privkey);
3930 prop_object_release(privkey);
3931 }
3932
3933 if (wg->wg_listen_port != 0) {
3934 prop_number_t port;
3935 port = prop_number_create_unsigned_integer(wg->wg_listen_port);
3936 if (port == NULL)
3937 goto error;
3938 prop_dictionary_set(prop_dict, "listen_port", port);
3939 prop_object_release(port);
3940 }
3941
3942 if (wg->wg_npeers == 0)
3943 goto skip_peers;
3944
3945 peers = prop_array_create();
3946 s = pserialize_read_enter();
3947 i = 0;
3948 WG_PEER_READER_FOREACH(wgp, wg) {
3949 struct psref psref;
3950 prop_dictionary_t prop_peer;
3951
3952 wg_get_peer(wgp, &psref);
3953 pserialize_read_exit(s);
3954
3955 prop_peer = prop_dictionary_create();
3956
3957 if (strlen(wgp->wgp_name) > 0) {
3958 prop_string_t name;
3959 name = prop_string_create_cstring(wgp->wgp_name);
3960 prop_dictionary_set(prop_peer, "name", name);
3961 prop_object_release(name);
3962 }
3963
3964 {
3965 prop_data_t pubkey;
3966 pubkey = prop_data_create_data(wgp->wgp_pubkey,
3967 sizeof(wgp->wgp_pubkey));
3968 if (pubkey == NULL)
3969 goto next;
3970 prop_dictionary_set(prop_peer, "public_key", pubkey);
3971 prop_object_release(pubkey);
3972 }
3973
3974 uint8_t psk_zero[WG_PRESHARED_KEY_LEN] = {0};
3975 if (memcmp(wgp->wgp_psk, psk_zero, sizeof(wgp->wgp_psk) != 0)) {
3976 prop_data_t psk = prop_data_create_data(wgp->wgp_psk,
3977 sizeof(wgp->wgp_psk));
3978 if (psk == NULL)
3979 goto next;
3980 prop_dictionary_set(prop_peer, "preshared_key", psk);
3981 prop_object_release(psk);
3982 }
3983
3984 switch (wgp->wgp_sa.sa_family) {
3985 case AF_INET: {
3986 prop_data_t addr;
3987 addr = prop_data_create_data(&wgp->wgp_sin,
3988 sizeof(wgp->wgp_sin));
3989 if (addr == NULL)
3990 goto next;
3991 prop_dictionary_set(prop_peer, "endpoint", addr);
3992 prop_object_release(addr);
3993 break;
3994 }
3995 case AF_INET6: {
3996 prop_data_t addr;
3997 addr = prop_data_create_data(&wgp->wgp_sin6,
3998 sizeof(wgp->wgp_sin6));
3999 if (addr == NULL)
4000 goto next;
4001 prop_dictionary_set(prop_peer, "endpoint", addr);
4002 prop_object_release(addr);
4003 break;
4004 }
4005 }
4006
4007 {
4008 prop_number_t sec;
4009 sec = prop_number_create_unsigned_integer(
4010 wgp->wgp_last_handshake_time.tv_sec);
4011 if (sec == NULL)
4012 goto next;
4013 prop_dictionary_set(prop_peer, "last_handshake_time_sec", sec);
4014 prop_object_release(sec);
4015
4016 prop_number_t nsec;
4017 nsec = prop_number_create_unsigned_integer(
4018 wgp->wgp_last_handshake_time.tv_nsec);
4019 if (nsec == NULL)
4020 goto next;
4021 prop_dictionary_set(prop_peer, "last_handshake_time_nsec", nsec);
4022 prop_object_release(nsec);
4023 }
4024
4025 if (wgp->wgp_n_allowedips == 0)
4026 goto skip_allowedips;
4027
4028 prop_array_t allowedips = prop_array_create();
4029 for (int j = 0; j < wgp->wgp_n_allowedips; j++) {
4030 struct wg_allowedip *wga = &wgp->wgp_allowedips[j];
4031 prop_dictionary_t prop_allowedip;
4032 prop_number_t family;
4033 prop_number_t cidr;
4034 prop_data_t prop_addr;
4035
4036 prop_allowedip = prop_dictionary_create();
4037 if (prop_allowedip == NULL)
4038 break;
4039
4040 family = prop_number_create_unsigned_integer(wga->wga_family);
4041 if (family == NULL)
4042 goto _next;
4043 prop_dictionary_set(prop_allowedip, "family", family);
4044 prop_object_release(family);
4045
4046 cidr = prop_number_create_unsigned_integer(wga->wga_cidr);
4047 if (cidr == NULL)
4048 goto _next;
4049 prop_dictionary_set(prop_allowedip, "cidr", cidr);
4050 prop_object_release(cidr);
4051
4052 switch (wga->wga_family) {
4053 case AF_INET:
4054 prop_addr = prop_data_create_data(
4055 &wga->wga_addr4, sizeof(wga->wga_addr4));
4056 if (prop_addr == NULL)
4057 goto _next;
4058 prop_dictionary_set(prop_allowedip, "ip", prop_addr);
4059 prop_object_release(prop_addr);
4060 break;
4061 #ifdef INET6
4062 case AF_INET6:
4063 prop_addr = prop_data_create_data(
4064 &wga->wga_addr6, sizeof(wga->wga_addr6));
4065 if (prop_addr == NULL)
4066 goto _next;
4067 prop_dictionary_set(prop_allowedip, "ip", prop_addr);
4068 prop_object_release(prop_addr);
4069 break;
4070 #endif
4071 default:
4072 break;
4073 }
4074 prop_array_set(allowedips, j, prop_allowedip);
4075 _next:
4076 prop_object_release(prop_allowedip);
4077 }
4078 prop_dictionary_set(prop_peer, "allowedips", allowedips);
4079 prop_object_release(allowedips);
4080
4081 skip_allowedips:
4082
4083 prop_array_set(peers, i, prop_peer);
4084 next:
4085 prop_object_release(prop_peer);
4086 i++;
4087
4088 s = pserialize_read_enter();
4089 wg_put_peer(wgp, &psref);
4090 }
4091 pserialize_read_exit(s);
4092
4093 prop_dictionary_set(prop_dict, "peers", peers);
4094 prop_object_release(peers);
4095 peers = NULL;
4096
4097 skip_peers:
4098 buf = prop_dictionary_externalize(prop_dict);
4099 if (buf == NULL)
4100 goto error;
4101 if (ifd->ifd_len < (strlen(buf) + 1)) {
4102 error = EINVAL;
4103 goto error;
4104 }
4105 error = copyout(buf, ifd->ifd_data, strlen(buf) + 1);
4106
4107 free(buf, 0);
4108 error:
4109 if (peers != NULL)
4110 prop_object_release(peers);
4111 if (prop_dict != NULL)
4112 prop_object_release(prop_dict);
4113
4114 return error;
4115 }
4116
4117 static int
4118 wg_ioctl(struct ifnet *ifp, u_long cmd, void *data)
4119 {
4120 struct wg_softc *wg = ifp->if_softc;
4121 struct ifreq *ifr = data;
4122 struct ifaddr *ifa = data;
4123 struct ifdrv *ifd = data;
4124 int error = 0;
4125
4126 switch (cmd) {
4127 case SIOCINITIFADDR:
4128 if (ifa->ifa_addr->sa_family != AF_LINK &&
4129 (ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
4130 (IFF_UP | IFF_RUNNING)) {
4131 ifp->if_flags |= IFF_UP;
4132 error = ifp->if_init(ifp);
4133 }
4134 break;
4135
4136 case SIOCADDMULTI:
4137 case SIOCDELMULTI:
4138 switch (ifr->ifr_addr.sa_family) {
4139 case AF_INET: /* IP supports Multicast */
4140 break;
4141 #ifdef INET6
4142 case AF_INET6: /* IP6 supports Multicast */
4143 break;
4144 #endif
4145 default: /* Other protocols doesn't support Multicast */
4146 error = EAFNOSUPPORT;
4147 break;
4148 }
4149 break;
4150
4151 case SIOCSDRVSPEC:
4152 switch (ifd->ifd_cmd) {
4153 case WG_IOCTL_SET_PRIVATE_KEY:
4154 error = wg_ioctl_set_private_key(wg, ifd);
4155 break;
4156 case WG_IOCTL_SET_LISTEN_PORT:
4157 error = wg_ioctl_set_listen_port(wg, ifd);
4158 break;
4159 case WG_IOCTL_ADD_PEER:
4160 error = wg_ioctl_add_peer(wg, ifd);
4161 break;
4162 case WG_IOCTL_DELETE_PEER:
4163 error = wg_ioctl_delete_peer(wg, ifd);
4164 break;
4165 default:
4166 error = EINVAL;
4167 break;
4168 }
4169 break;
4170 case SIOCGDRVSPEC:
4171 error = wg_ioctl_get(wg, ifd);
4172 break;
4173
4174 case SIOCSIFFLAGS:
4175 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
4176 break;
4177 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
4178 case IFF_RUNNING:
4179 /*
4180 * If interface is marked down and it is running,
4181 * then stop and disable it.
4182 */
4183 (*ifp->if_stop)(ifp, 1);
4184 break;
4185 case IFF_UP:
4186 /*
4187 * If interface is marked up and it is stopped, then
4188 * start it.
4189 */
4190 error = (*ifp->if_init)(ifp);
4191 break;
4192 default:
4193 break;
4194 }
4195 break;
4196
4197 #ifdef WG_RUMPKERNEL
4198 case SIOCSLINKSTR:
4199 error = wg_ioctl_linkstr(wg, ifd);
4200 if (error == 0)
4201 wg->wg_ops = &wg_ops_rumpuser;
4202 break;
4203 #endif
4204
4205 default:
4206 error = ifioctl_common(ifp, cmd, data);
4207
4208 #ifdef WG_RUMPKERNEL
4209 if (!wg_user_mode(wg))
4210 break;
4211 /* Do the same to the corresponding tun device on the host */
4212 /*
4213 * XXX Actually the command has not been handled yet. It
4214 * will be handled via pr_ioctl form doifioctl later.
4215 */
4216 switch (cmd) {
4217 case SIOCAIFADDR:
4218 case SIOCDIFADDR: {
4219 struct in_aliasreq _ifra = *(struct in_aliasreq *)data;
4220 struct in_aliasreq *ifra = &_ifra;
4221 KASSERT(error == ENOTTY);
4222 strncpy(ifra->ifra_name, rumpuser_wg_get_tunname(wg->wg_user), IFNAMSIZ);
4223 error = rumpuser_wg_ioctl(wg->wg_user, cmd, ifra, AF_INET);
4224 if (error == 0)
4225 error = ENOTTY;
4226 break;
4227 }
4228 #ifdef INET6
4229 case SIOCAIFADDR_IN6:
4230 case SIOCDIFADDR_IN6: {
4231 struct in6_aliasreq _ifra = *(struct in6_aliasreq *)data;
4232 struct in6_aliasreq *ifra = &_ifra;
4233 KASSERT(error == ENOTTY);
4234 strncpy(ifra->ifra_name, rumpuser_wg_get_tunname(wg->wg_user), IFNAMSIZ);
4235 error = rumpuser_wg_ioctl(wg->wg_user, cmd, ifra, AF_INET6);
4236 if (error == 0)
4237 error = ENOTTY;
4238 break;
4239 }
4240 #endif
4241 }
4242 #endif /* WG_RUMPKERNEL */
4243 }
4244
4245 return error;
4246 }
4247
4248 static int
4249 wg_init(struct ifnet *ifp)
4250 {
4251
4252 ifp->if_flags |= IFF_RUNNING;
4253
4254 /* TODO flush pending packets. */
4255 return 0;
4256 }
4257
4258 static void
4259 wg_stop(struct ifnet *ifp, int disable)
4260 {
4261
4262 KASSERT((ifp->if_flags & IFF_RUNNING) != 0);
4263 ifp->if_flags &= ~IFF_RUNNING;
4264
4265 /* Need to do something? */
4266 }
4267
4268 static struct sysctllog *wg_sysctllog;
4269 static void
4270 wg_setup_sysctl(void)
4271 {
4272 #ifdef WG_DEBUG_PARAMS
4273 const struct sysctlnode *node = NULL;
4274
4275 sysctl_createv(&wg_sysctllog, 0, NULL, &node,
4276 CTLFLAG_PERMANENT, CTLTYPE_NODE, "wireguard",
4277 SYSCTL_DESCR("WireGuard"),
4278 NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL);
4279 if (node != NULL) {
4280 sysctl_createv(&wg_sysctllog, 0, NULL, NULL,
4281 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4282 CTLTYPE_LONG, "rekey_after_messages",
4283 SYSCTL_DESCR("session liftime by messages"),
4284 NULL, 0, &wg_rekey_after_messages, 0,
4285 CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
4286 sysctl_createv(&wg_sysctllog, 0, NULL, NULL,
4287 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4288 CTLTYPE_LONG, "rekey_after_time",
4289 SYSCTL_DESCR("session liftime"),
4290 NULL, 0, &wg_rekey_after_time, 0,
4291 CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
4292 sysctl_createv(&wg_sysctllog, 0, NULL, NULL,
4293 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4294 CTLTYPE_LONG, "rekey_timeout",
4295 SYSCTL_DESCR("session handshake retry time"),
4296 NULL, 0, &wg_rekey_timeout, 0,
4297 CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
4298 sysctl_createv(&wg_sysctllog, 0, NULL, NULL,
4299 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4300 CTLTYPE_LONG, "rekey_attempt_time",
4301 SYSCTL_DESCR("session handshake timeout"),
4302 NULL, 0, &wg_rekey_attempt_time, 0,
4303 CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
4304 sysctl_createv(&wg_sysctllog, 0, NULL, NULL,
4305 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4306 CTLTYPE_LONG, "keepalive_timeout",
4307 SYSCTL_DESCR("keepalive timeout"),
4308 NULL, 0, &wg_keepalive_timeout, 0,
4309 CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
4310
4311 sysctl_createv(&wg_sysctllog, 0, NULL, NULL,
4312 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
4313 CTLTYPE_BOOL, "force_underload",
4314 SYSCTL_DESCR("force to detemine under load"),
4315 NULL, 0, &wg_force_underload, 0,
4316 CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
4317 }
4318 #else
4319 (void)wg_sysctllog;
4320 #endif
4321 }
4322
4323 #ifdef WG_RUMPKERNEL
4324 static bool
4325 wg_user_mode(struct wg_softc *wg)
4326 {
4327
4328 return wg->wg_user != NULL;
4329 }
4330
4331 static int
4332 wg_ioctl_linkstr(struct wg_softc *wg, struct ifdrv *ifd)
4333 {
4334 struct ifnet *ifp = &wg->wg_if;
4335 int error;
4336
4337 if (ifp->if_flags & IFF_UP)
4338 return EBUSY;
4339
4340 if (ifd->ifd_cmd == IFLINKSTR_UNSET) {
4341 /* XXX do nothing */
4342 return 0;
4343 } else if (ifd->ifd_cmd != 0) {
4344 return EINVAL;
4345 } else if (wg->wg_user != NULL) {
4346 return EBUSY;
4347 }
4348
4349 /* Assume \0 included */
4350 if (ifd->ifd_len > IFNAMSIZ) {
4351 return E2BIG;
4352 } else if (ifd->ifd_len < 1) {
4353 return EINVAL;
4354 }
4355
4356 char tun_name[IFNAMSIZ];
4357 error = copyinstr(ifd->ifd_data, tun_name, ifd->ifd_len, NULL);
4358 if (error != 0)
4359 return error;
4360
4361 if (strncmp(tun_name, "tun", 3) != 0)
4362 return EINVAL;
4363
4364 error = rumpuser_wg_create(tun_name, wg, &wg->wg_user);
4365
4366 return error;
4367 }
4368
4369 static int
4370 wg_send_user(struct wg_peer *wgp, struct mbuf *m)
4371 {
4372 int error;
4373 struct psref psref;
4374 struct wg_sockaddr *wgsa;
4375 struct wg_softc *wg = wgp->wgp_sc;
4376 struct iovec iov[1];
4377
4378 wgsa = wg_get_endpoint_sa(wgp, &psref);
4379
4380 iov[0].iov_base = mtod(m, void *);
4381 iov[0].iov_len = m->m_len;
4382
4383 /* Send messages to a peer via an ordinary socket. */
4384 error = rumpuser_wg_send_peer(wg->wg_user, wgsatosa(wgsa), iov, 1);
4385
4386 wg_put_sa(wgp, wgsa, &psref);
4387
4388 return error;
4389 }
4390
4391 static void
4392 wg_input_user(struct ifnet *ifp, struct mbuf *m, const int af)
4393 {
4394 struct wg_softc *wg = ifp->if_softc;
4395 struct iovec iov[2];
4396 struct sockaddr_storage ss;
4397
4398 KASSERT(af == AF_INET || af == AF_INET6);
4399
4400 WG_TRACE("");
4401
4402 if (af == AF_INET) {
4403 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
4404 struct ip *ip;
4405 ip = mtod(m, struct ip *);
4406 sockaddr_in_init(sin, &ip->ip_dst, 0);
4407 } else {
4408 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
4409 struct ip6_hdr *ip6;
4410 ip6 = mtod(m, struct ip6_hdr *);
4411 sockaddr_in6_init(sin6, &ip6->ip6_dst, 0, 0, 0);
4412 }
4413
4414 iov[0].iov_base = &ss;
4415 iov[0].iov_len = ss.ss_len;
4416 iov[1].iov_base = mtod(m, void *);
4417 iov[1].iov_len = m->m_len;
4418
4419 WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len);
4420
4421 /* Send decrypted packets to users via a tun. */
4422 rumpuser_wg_send_user(wg->wg_user, iov, 2);
4423 }
4424
4425 static int
4426 wg_bind_port_user(struct wg_softc *wg, const uint16_t port)
4427 {
4428 int error;
4429 uint16_t old_port = wg->wg_listen_port;
4430
4431 if (port != 0 && old_port == port)
4432 return 0;
4433
4434 error = rumpuser_wg_sock_bind(wg->wg_user, port);
4435 if (error == 0)
4436 wg->wg_listen_port = port;
4437 return error;
4438 }
4439
4440 /*
4441 * Receive user packets.
4442 */
4443 void
4444 rumpkern_wg_recv_user(struct wg_softc *wg, struct iovec *iov, size_t iovlen)
4445 {
4446 struct ifnet *ifp = &wg->wg_if;
4447 struct mbuf *m;
4448 const struct sockaddr *dst;
4449
4450 WG_TRACE("");
4451
4452 dst = iov[0].iov_base;
4453
4454 m = m_gethdr(M_NOWAIT, MT_DATA);
4455 if (m == NULL)
4456 return;
4457 m->m_len = m->m_pkthdr.len = 0;
4458 m_copyback(m, 0, iov[1].iov_len, iov[1].iov_base);
4459
4460 WG_DLOG("iov_len=%lu\n", iov[1].iov_len);
4461 WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len);
4462
4463 (void)wg_output(ifp, m, dst, NULL);
4464 }
4465
4466 /*
4467 * Receive packets from a peer.
4468 */
4469 void
4470 rumpkern_wg_recv_peer(struct wg_softc *wg, struct iovec *iov, size_t iovlen)
4471 {
4472 struct mbuf *m;
4473 const struct sockaddr *src;
4474
4475 WG_TRACE("");
4476
4477 src = iov[0].iov_base;
4478
4479 m = m_gethdr(M_NOWAIT, MT_DATA);
4480 if (m == NULL)
4481 return;
4482 m->m_len = m->m_pkthdr.len = 0;
4483 m_copyback(m, 0, iov[1].iov_len, iov[1].iov_base);
4484
4485 WG_DLOG("iov_len=%lu\n", iov[1].iov_len);
4486 WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len);
4487
4488 wg_handle_packet(wg, m, src);
4489 }
4490 #endif /* WG_RUMPKERNEL */
4491
4492 /*
4493 * Module infrastructure
4494 */
4495 #include "if_module.h"
4496
4497 IF_MODULE(MODULE_CLASS_DRIVER, wg, "")
4498