Thu Aug 27 03:05:34 2020 UTC ()
wg: Make sure all paths into wg_handle_msg_data guarantee enough m_len.

Earlier commit moved the m_pullup into wg_validate_msg_header, but
wg_overudp_cb doesn't go through that.


(riastradh)
diff -r1.28 -r1.29 src/sys/net/if_wg.c

cvs diff -r1.28 -r1.29 src/sys/net/if_wg.c (switch to unified diff)

--- src/sys/net/if_wg.c 2020/08/27 02:55:04 1.28
+++ src/sys/net/if_wg.c 2020/08/27 03:05:34 1.29
@@ -1,1043 +1,1043 @@ @@ -1,1043 +1,1043 @@
1/* $NetBSD: if_wg.c,v 1.28 2020/08/27 02:55:04 riastradh Exp $ */ 1/* $NetBSD: if_wg.c,v 1.29 2020/08/27 03:05:34 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com> 4 * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors 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 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 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 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * This network interface aims to implement the WireGuard protocol. 33 * This network interface aims to implement the WireGuard protocol.
34 * The implementation is based on the paper of WireGuard as of 34 * The implementation is based on the paper of WireGuard as of
35 * 2018-06-30 [1]. The paper is referred in the source code with label 35 * 2018-06-30 [1]. The paper is referred in the source code with label
36 * [W]. Also the specification of the Noise protocol framework as of 36 * [W]. Also the specification of the Noise protocol framework as of
37 * 2018-07-11 [2] is referred with label [N]. 37 * 2018-07-11 [2] is referred with label [N].
38 * 38 *
39 * [1] https://www.wireguard.com/papers/wireguard.pdf 39 * [1] https://www.wireguard.com/papers/wireguard.pdf
40 * [2] http://noiseprotocol.org/noise.pdf 40 * [2] http://noiseprotocol.org/noise.pdf
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.28 2020/08/27 02:55:04 riastradh Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.29 2020/08/27 03:05:34 riastradh Exp $");
45 45
46#ifdef _KERNEL_OPT 46#ifdef _KERNEL_OPT
47#include "opt_inet.h" 47#include "opt_inet.h"
48#endif 48#endif
49 49
50#include <sys/param.h> 50#include <sys/param.h>
51#include <sys/systm.h> 51#include <sys/systm.h>
52#include <sys/kernel.h> 52#include <sys/kernel.h>
53#include <sys/mbuf.h> 53#include <sys/mbuf.h>
54#include <sys/socket.h> 54#include <sys/socket.h>
55#include <sys/sockio.h> 55#include <sys/sockio.h>
56#include <sys/errno.h> 56#include <sys/errno.h>
57#include <sys/ioctl.h> 57#include <sys/ioctl.h>
58#include <sys/time.h> 58#include <sys/time.h>
59#include <sys/timespec.h> 59#include <sys/timespec.h>
60#include <sys/socketvar.h> 60#include <sys/socketvar.h>
61#include <sys/syslog.h> 61#include <sys/syslog.h>
62#include <sys/cpu.h> 62#include <sys/cpu.h>
63#include <sys/intr.h> 63#include <sys/intr.h>
64#include <sys/kmem.h> 64#include <sys/kmem.h>
65#include <sys/device.h> 65#include <sys/device.h>
66#include <sys/module.h> 66#include <sys/module.h>
67#include <sys/mutex.h> 67#include <sys/mutex.h>
68#include <sys/rwlock.h> 68#include <sys/rwlock.h>
69#include <sys/pserialize.h> 69#include <sys/pserialize.h>
70#include <sys/psref.h> 70#include <sys/psref.h>
71#include <sys/kthread.h> 71#include <sys/kthread.h>
72#include <sys/cprng.h> 72#include <sys/cprng.h>
73#include <sys/atomic.h> 73#include <sys/atomic.h>
74#include <sys/sysctl.h> 74#include <sys/sysctl.h>
75#include <sys/domain.h> 75#include <sys/domain.h>
76#include <sys/pcq.h> 76#include <sys/pcq.h>
77#include <sys/queue.h> 77#include <sys/queue.h>
78#include <sys/percpu.h> 78#include <sys/percpu.h>
79#include <sys/callout.h> 79#include <sys/callout.h>
80 80
81#include <net/bpf.h> 81#include <net/bpf.h>
82#include <net/if.h> 82#include <net/if.h>
83#include <net/if_types.h> 83#include <net/if_types.h>
84#include <net/route.h> 84#include <net/route.h>
85 85
86#include <netinet/in.h> 86#include <netinet/in.h>
87#include <netinet/ip.h> 87#include <netinet/ip.h>
88#include <netinet/ip_var.h> 88#include <netinet/ip_var.h>
89#include <netinet/udp.h> 89#include <netinet/udp.h>
90#include <netinet/udp_var.h> 90#include <netinet/udp_var.h>
91#include <netinet/in_var.h> 91#include <netinet/in_var.h>
92#include <netinet/in_pcb.h> 92#include <netinet/in_pcb.h>
93 93
94#ifdef INET6 94#ifdef INET6
95#include <netinet6/in6_var.h> 95#include <netinet6/in6_var.h>
96#include <netinet/ip6.h> 96#include <netinet/ip6.h>
97#include <netinet6/ip6_var.h> 97#include <netinet6/ip6_var.h>
98#include <netinet6/in6_pcb.h> 98#include <netinet6/in6_pcb.h>
99#include <netinet6/udp6_var.h> 99#include <netinet6/udp6_var.h>
100#endif /* INET6 */ 100#endif /* INET6 */
101 101
102#include <net/if_wg.h> 102#include <net/if_wg.h>
103 103
104#include <prop/proplib.h> 104#include <prop/proplib.h>
105 105
106#include <crypto/blake2/blake2s.h> 106#include <crypto/blake2/blake2s.h>
107#include <crypto/sodium/crypto_scalarmult.h> 107#include <crypto/sodium/crypto_scalarmult.h>
108#include <crypto/sodium/crypto_aead_chacha20poly1305.h> 108#include <crypto/sodium/crypto_aead_chacha20poly1305.h>
109#include <crypto/sodium/crypto_aead_xchacha20poly1305.h> 109#include <crypto/sodium/crypto_aead_xchacha20poly1305.h>
110 110
111#include "ioconf.h" 111#include "ioconf.h"
112 112
113#ifdef WG_RUMPKERNEL 113#ifdef WG_RUMPKERNEL
114#include "wg_user.h" 114#include "wg_user.h"
115#endif 115#endif
116 116
117/* 117/*
118 * Data structures 118 * Data structures
119 * - struct wg_softc is an instance of wg interfaces 119 * - struct wg_softc is an instance of wg interfaces
120 * - It has a list of peers (struct wg_peer) 120 * - It has a list of peers (struct wg_peer)
121 * - It has a kthread that sends/receives handshake messages and 121 * - It has a kthread that sends/receives handshake messages and
122 * runs event handlers 122 * runs event handlers
123 * - It has its own two routing tables: one is for IPv4 and the other IPv6 123 * - It has its own two routing tables: one is for IPv4 and the other IPv6
124 * - struct wg_peer is a representative of a peer 124 * - struct wg_peer is a representative of a peer
125 * - It has a softint that is used to send packets over an wg interface 125 * - It has a softint that is used to send packets over an wg interface
126 * to a peer 126 * to a peer
127 * - It has a pair of session instances (struct wg_session) 127 * - It has a pair of session instances (struct wg_session)
128 * - It has a pair of endpoint instances (struct wg_sockaddr) 128 * - It has a pair of endpoint instances (struct wg_sockaddr)
129 * - Normally one endpoint is used and the second one is used only on 129 * - Normally one endpoint is used and the second one is used only on
130 * a peer migration (a change of peer's IP address) 130 * a peer migration (a change of peer's IP address)
131 * - It has a list of IP addresses and sub networks called allowedips 131 * - It has a list of IP addresses and sub networks called allowedips
132 * (struct wg_allowedip) 132 * (struct wg_allowedip)
133 * - A packets sent over a session is allowed if its destination matches 133 * - A packets sent over a session is allowed if its destination matches
134 * any IP addresses or sub networks of the list 134 * any IP addresses or sub networks of the list
135 * - struct wg_session represents a session of a secure tunnel with a peer 135 * - struct wg_session represents a session of a secure tunnel with a peer
136 * - Two instances of sessions belong to a peer; a stable session and a 136 * - Two instances of sessions belong to a peer; a stable session and a
137 * unstable session 137 * unstable session
138 * - A handshake process of a session always starts with a unstable instace 138 * - A handshake process of a session always starts with a unstable instace
139 * - Once a session is established, its instance becomes stable and the 139 * - Once a session is established, its instance becomes stable and the
140 * other becomes unstable instead 140 * other becomes unstable instead
141 * - Data messages are always sent via a stable session 141 * - Data messages are always sent via a stable session
142 * 142 *
143 * Locking notes: 143 * Locking notes:
144 * - wg interfaces (struct wg_softc, wg) is listed in wg_softcs.list and 144 * - wg interfaces (struct wg_softc, wg) is listed in wg_softcs.list and
145 * protected by wg_softcs.lock 145 * protected by wg_softcs.lock
146 * - Each wg has a mutex(9) and a rwlock(9) 146 * - Each wg has a mutex(9) and a rwlock(9)
147 * - The mutex (wg_lock) protects its peer list (wg_peers) 147 * - The mutex (wg_lock) protects its peer list (wg_peers)
148 * - A peer on the list is also protected by pserialize(9) or psref(9) 148 * - A peer on the list is also protected by pserialize(9) or psref(9)
149 * - The rwlock (wg_rwlock) protects the routing tables (wg_rtable_ipv[46]) 149 * - The rwlock (wg_rwlock) protects the routing tables (wg_rtable_ipv[46])
150 * - Each peer (struct wg_peer, wgp) has a mutex 150 * - Each peer (struct wg_peer, wgp) has a mutex
151 * - The mutex (wgp_lock) protects wgp_session_unstable and wgp_state 151 * - The mutex (wgp_lock) protects wgp_session_unstable and wgp_state
152 * - Each session (struct wg_session, wgs) has a mutex 152 * - Each session (struct wg_session, wgs) has a mutex
153 * - The mutex (wgs_lock) protects its state (wgs_state) and its handshake 153 * - The mutex (wgs_lock) protects its state (wgs_state) and its handshake
154 * states 154 * states
155 * - wgs_state of a unstable session can be changed while it never be 155 * - wgs_state of a unstable session can be changed while it never be
156 * changed on a stable session, so once get a session instace via 156 * changed on a stable session, so once get a session instace via
157 * wgp_session_stable we can safely access wgs_state without 157 * wgp_session_stable we can safely access wgs_state without
158 * holding wgs_lock 158 * holding wgs_lock
159 * - A session is protected by pserialize or psref like wgp 159 * - A session is protected by pserialize or psref like wgp
160 * - On a session swap, we must wait for all readers to release a 160 * - On a session swap, we must wait for all readers to release a
161 * reference to a stable session before changing wgs_state and 161 * reference to a stable session before changing wgs_state and
162 * session states 162 * session states
163 */ 163 */
164 164
165 165
166#define WGLOG(level, fmt, args...) \ 166#define WGLOG(level, fmt, args...) \
167 log(level, "%s: " fmt, __func__, ##args) 167 log(level, "%s: " fmt, __func__, ##args)
168 168
169/* Debug options */ 169/* Debug options */
170#ifdef WG_DEBUG 170#ifdef WG_DEBUG
171/* Output debug logs */ 171/* Output debug logs */
172#ifndef WG_DEBUG_LOG 172#ifndef WG_DEBUG_LOG
173#define WG_DEBUG_LOG 173#define WG_DEBUG_LOG
174#endif 174#endif
175/* Output trace logs */ 175/* Output trace logs */
176#ifndef WG_DEBUG_TRACE 176#ifndef WG_DEBUG_TRACE
177#define WG_DEBUG_TRACE 177#define WG_DEBUG_TRACE
178#endif 178#endif
179/* Output hash values, etc. */ 179/* Output hash values, etc. */
180#ifndef WG_DEBUG_DUMP 180#ifndef WG_DEBUG_DUMP
181#define WG_DEBUG_DUMP 181#define WG_DEBUG_DUMP
182#endif 182#endif
183/* Make some internal parameters configurable for testing and debugging */ 183/* Make some internal parameters configurable for testing and debugging */
184#ifndef WG_DEBUG_PARAMS 184#ifndef WG_DEBUG_PARAMS
185#define WG_DEBUG_PARAMS 185#define WG_DEBUG_PARAMS
186#endif 186#endif
187#endif 187#endif
188 188
189#ifdef WG_DEBUG_TRACE 189#ifdef WG_DEBUG_TRACE
190#define WG_TRACE(msg) \ 190#define WG_TRACE(msg) \
191 log(LOG_DEBUG, "%s:%d: %s\n", __func__, __LINE__, (msg)) 191 log(LOG_DEBUG, "%s:%d: %s\n", __func__, __LINE__, (msg))
192#else 192#else
193#define WG_TRACE(msg) __nothing 193#define WG_TRACE(msg) __nothing
194#endif 194#endif
195 195
196#ifdef WG_DEBUG_LOG 196#ifdef WG_DEBUG_LOG
197#define WG_DLOG(fmt, args...) log(LOG_DEBUG, "%s: " fmt, __func__, ##args) 197#define WG_DLOG(fmt, args...) log(LOG_DEBUG, "%s: " fmt, __func__, ##args)
198#else 198#else
199#define WG_DLOG(fmt, args...) __nothing 199#define WG_DLOG(fmt, args...) __nothing
200#endif 200#endif
201 201
202#define WG_LOG_RATECHECK(wgprc, level, fmt, args...) do { \ 202#define WG_LOG_RATECHECK(wgprc, level, fmt, args...) do { \
203 if (ppsratecheck(&(wgprc)->wgprc_lasttime, \ 203 if (ppsratecheck(&(wgprc)->wgprc_lasttime, \
204 &(wgprc)->wgprc_curpps, 1)) { \ 204 &(wgprc)->wgprc_curpps, 1)) { \
205 log(level, fmt, ##args); \ 205 log(level, fmt, ##args); \
206 } \ 206 } \
207} while (0) 207} while (0)
208 208
209#ifdef WG_DEBUG_PARAMS 209#ifdef WG_DEBUG_PARAMS
210static bool wg_force_underload = false; 210static bool wg_force_underload = false;
211#endif 211#endif
212 212
213#ifdef WG_DEBUG_DUMP 213#ifdef WG_DEBUG_DUMP
214 214
215#ifdef WG_RUMPKERNEL 215#ifdef WG_RUMPKERNEL
216static void 216static void
217wg_dump_buf(const char *func, const char *buf, const size_t size) 217wg_dump_buf(const char *func, const char *buf, const size_t size)
218{ 218{
219 219
220 log(LOG_DEBUG, "%s: ", func); 220 log(LOG_DEBUG, "%s: ", func);
221 for (int i = 0; i < size; i++) 221 for (int i = 0; i < size; i++)
222 log(LOG_DEBUG, "%02x ", (int)(0xff & buf[i])); 222 log(LOG_DEBUG, "%02x ", (int)(0xff & buf[i]));
223 log(LOG_DEBUG, "\n"); 223 log(LOG_DEBUG, "\n");
224} 224}
225#endif 225#endif
226 226
227static void 227static void
228wg_dump_hash(const uint8_t *func, const uint8_t *name, const uint8_t *hash, 228wg_dump_hash(const uint8_t *func, const uint8_t *name, const uint8_t *hash,
229 const size_t size) 229 const size_t size)
230{ 230{
231 231
232 log(LOG_DEBUG, "%s: %s: ", func, name); 232 log(LOG_DEBUG, "%s: %s: ", func, name);
233 for (int i = 0; i < size; i++) 233 for (int i = 0; i < size; i++)
234 log(LOG_DEBUG, "%02x ", (int)(0xff & hash[i])); 234 log(LOG_DEBUG, "%02x ", (int)(0xff & hash[i]));
235 log(LOG_DEBUG, "\n"); 235 log(LOG_DEBUG, "\n");
236} 236}
237 237
238#define WG_DUMP_HASH(name, hash) \ 238#define WG_DUMP_HASH(name, hash) \
239 wg_dump_hash(__func__, name, hash, WG_HASH_LEN) 239 wg_dump_hash(__func__, name, hash, WG_HASH_LEN)
240#define WG_DUMP_HASH48(name, hash) \ 240#define WG_DUMP_HASH48(name, hash) \
241 wg_dump_hash(__func__, name, hash, 48) 241 wg_dump_hash(__func__, name, hash, 48)
242#define WG_DUMP_BUF(buf, size) \ 242#define WG_DUMP_BUF(buf, size) \
243 wg_dump_buf(__func__, buf, size) 243 wg_dump_buf(__func__, buf, size)
244#else 244#else
245#define WG_DUMP_HASH(name, hash) __nothing 245#define WG_DUMP_HASH(name, hash) __nothing
246#define WG_DUMP_HASH48(name, hash) __nothing 246#define WG_DUMP_HASH48(name, hash) __nothing
247#define WG_DUMP_BUF(buf, size) __nothing 247#define WG_DUMP_BUF(buf, size) __nothing
248#endif /* WG_DEBUG_DUMP */ 248#endif /* WG_DEBUG_DUMP */
249 249
250#define WG_MTU 1420 250#define WG_MTU 1420
251#define WG_ALLOWEDIPS 16 251#define WG_ALLOWEDIPS 16
252 252
253#define CURVE25519_KEY_LEN 32 253#define CURVE25519_KEY_LEN 32
254#define TAI64N_LEN sizeof(uint32_t) * 3 254#define TAI64N_LEN sizeof(uint32_t) * 3
255#define POLY1305_AUTHTAG_LEN 16 255#define POLY1305_AUTHTAG_LEN 16
256#define HMAC_BLOCK_LEN 64 256#define HMAC_BLOCK_LEN 64
257 257
258/* [N] 4.1: "DHLEN must be 32 or greater." WireGuard chooses 32. */ 258/* [N] 4.1: "DHLEN must be 32 or greater." WireGuard chooses 32. */
259/* [N] 4.3: Hash functions */ 259/* [N] 4.3: Hash functions */
260#define NOISE_DHLEN 32 260#define NOISE_DHLEN 32
261/* [N] 4.3: "Must be 32 or 64." WireGuard chooses 32. */ 261/* [N] 4.3: "Must be 32 or 64." WireGuard chooses 32. */
262#define NOISE_HASHLEN 32 262#define NOISE_HASHLEN 32
263#define NOISE_BLOCKLEN 64 263#define NOISE_BLOCKLEN 64
264#define NOISE_HKDF_OUTPUT_LEN NOISE_HASHLEN 264#define NOISE_HKDF_OUTPUT_LEN NOISE_HASHLEN
265/* [N] 5.1: "k" */ 265/* [N] 5.1: "k" */
266#define NOISE_CIPHER_KEY_LEN 32 266#define NOISE_CIPHER_KEY_LEN 32
267/* 267/*
268 * [N] 9.2: "psk" 268 * [N] 9.2: "psk"
269 * "... psk is a 32-byte secret value provided by the application." 269 * "... psk is a 32-byte secret value provided by the application."
270 */ 270 */
271#define NOISE_PRESHARED_KEY_LEN 32 271#define NOISE_PRESHARED_KEY_LEN 32
272 272
273#define WG_STATIC_KEY_LEN CURVE25519_KEY_LEN 273#define WG_STATIC_KEY_LEN CURVE25519_KEY_LEN
274#define WG_TIMESTAMP_LEN TAI64N_LEN 274#define WG_TIMESTAMP_LEN TAI64N_LEN
275 275
276#define WG_PRESHARED_KEY_LEN NOISE_PRESHARED_KEY_LEN 276#define WG_PRESHARED_KEY_LEN NOISE_PRESHARED_KEY_LEN
277 277
278#define WG_COOKIE_LEN 16 278#define WG_COOKIE_LEN 16
279#define WG_MAC_LEN 16 279#define WG_MAC_LEN 16
280#define WG_RANDVAL_LEN 24 280#define WG_RANDVAL_LEN 24
281 281
282#define WG_EPHEMERAL_KEY_LEN CURVE25519_KEY_LEN 282#define WG_EPHEMERAL_KEY_LEN CURVE25519_KEY_LEN
283/* [N] 5.2: "ck: A chaining key of HASHLEN bytes" */ 283/* [N] 5.2: "ck: A chaining key of HASHLEN bytes" */
284#define WG_CHAINING_KEY_LEN NOISE_HASHLEN 284#define WG_CHAINING_KEY_LEN NOISE_HASHLEN
285/* [N] 5.2: "h: A hash output of HASHLEN bytes" */ 285/* [N] 5.2: "h: A hash output of HASHLEN bytes" */
286#define WG_HASH_LEN NOISE_HASHLEN 286#define WG_HASH_LEN NOISE_HASHLEN
287#define WG_CIPHER_KEY_LEN NOISE_CIPHER_KEY_LEN 287#define WG_CIPHER_KEY_LEN NOISE_CIPHER_KEY_LEN
288#define WG_DH_OUTPUT_LEN NOISE_DHLEN 288#define WG_DH_OUTPUT_LEN NOISE_DHLEN
289#define WG_KDF_OUTPUT_LEN NOISE_HKDF_OUTPUT_LEN 289#define WG_KDF_OUTPUT_LEN NOISE_HKDF_OUTPUT_LEN
290#define WG_AUTHTAG_LEN POLY1305_AUTHTAG_LEN 290#define WG_AUTHTAG_LEN POLY1305_AUTHTAG_LEN
291#define WG_DATA_KEY_LEN 32 291#define WG_DATA_KEY_LEN 32
292#define WG_SALT_LEN 24 292#define WG_SALT_LEN 24
293 293
294/* 294/*
295 * The protocol messages 295 * The protocol messages
296 */ 296 */
297struct wg_msg { 297struct wg_msg {
298 uint32_t wgm_type; 298 uint32_t wgm_type;
299} __packed; 299} __packed;
300 300
301/* [W] 5.4.2 First Message: Initiator to Responder */ 301/* [W] 5.4.2 First Message: Initiator to Responder */
302struct wg_msg_init { 302struct wg_msg_init {
303 uint32_t wgmi_type; 303 uint32_t wgmi_type;
304 uint32_t wgmi_sender; 304 uint32_t wgmi_sender;
305 uint8_t wgmi_ephemeral[WG_EPHEMERAL_KEY_LEN]; 305 uint8_t wgmi_ephemeral[WG_EPHEMERAL_KEY_LEN];
306 uint8_t wgmi_static[WG_STATIC_KEY_LEN + WG_AUTHTAG_LEN]; 306 uint8_t wgmi_static[WG_STATIC_KEY_LEN + WG_AUTHTAG_LEN];
307 uint8_t wgmi_timestamp[WG_TIMESTAMP_LEN + WG_AUTHTAG_LEN]; 307 uint8_t wgmi_timestamp[WG_TIMESTAMP_LEN + WG_AUTHTAG_LEN];
308 uint8_t wgmi_mac1[WG_MAC_LEN]; 308 uint8_t wgmi_mac1[WG_MAC_LEN];
309 uint8_t wgmi_mac2[WG_MAC_LEN]; 309 uint8_t wgmi_mac2[WG_MAC_LEN];
310} __packed; 310} __packed;
311 311
312/* [W] 5.4.3 Second Message: Responder to Initiator */ 312/* [W] 5.4.3 Second Message: Responder to Initiator */
313struct wg_msg_resp { 313struct wg_msg_resp {
314 uint32_t wgmr_type; 314 uint32_t wgmr_type;
315 uint32_t wgmr_sender; 315 uint32_t wgmr_sender;
316 uint32_t wgmr_receiver; 316 uint32_t wgmr_receiver;
317 uint8_t wgmr_ephemeral[WG_EPHEMERAL_KEY_LEN]; 317 uint8_t wgmr_ephemeral[WG_EPHEMERAL_KEY_LEN];
318 uint8_t wgmr_empty[0 + WG_AUTHTAG_LEN]; 318 uint8_t wgmr_empty[0 + WG_AUTHTAG_LEN];
319 uint8_t wgmr_mac1[WG_MAC_LEN]; 319 uint8_t wgmr_mac1[WG_MAC_LEN];
320 uint8_t wgmr_mac2[WG_MAC_LEN]; 320 uint8_t wgmr_mac2[WG_MAC_LEN];
321} __packed; 321} __packed;
322 322
323/* [W] 5.4.6 Subsequent Messages: Transport Data Messages */ 323/* [W] 5.4.6 Subsequent Messages: Transport Data Messages */
324struct wg_msg_data { 324struct wg_msg_data {
325 uint32_t wgmd_type; 325 uint32_t wgmd_type;
326 uint32_t wgmd_receiver; 326 uint32_t wgmd_receiver;
327 uint64_t wgmd_counter; 327 uint64_t wgmd_counter;
328 uint32_t wgmd_packet[0]; 328 uint32_t wgmd_packet[0];
329} __packed; 329} __packed;
330 330
331/* [W] 5.4.7 Under Load: Cookie Reply Message */ 331/* [W] 5.4.7 Under Load: Cookie Reply Message */
332struct wg_msg_cookie { 332struct wg_msg_cookie {
333 uint32_t wgmc_type; 333 uint32_t wgmc_type;
334 uint32_t wgmc_receiver; 334 uint32_t wgmc_receiver;
335 uint8_t wgmc_salt[WG_SALT_LEN]; 335 uint8_t wgmc_salt[WG_SALT_LEN];
336 uint8_t wgmc_cookie[WG_COOKIE_LEN + WG_AUTHTAG_LEN]; 336 uint8_t wgmc_cookie[WG_COOKIE_LEN + WG_AUTHTAG_LEN];
337} __packed; 337} __packed;
338 338
339#define WG_MSG_TYPE_INIT 1 339#define WG_MSG_TYPE_INIT 1
340#define WG_MSG_TYPE_RESP 2 340#define WG_MSG_TYPE_RESP 2
341#define WG_MSG_TYPE_COOKIE 3 341#define WG_MSG_TYPE_COOKIE 3
342#define WG_MSG_TYPE_DATA 4 342#define WG_MSG_TYPE_DATA 4
343#define WG_MSG_TYPE_MAX WG_MSG_TYPE_DATA 343#define WG_MSG_TYPE_MAX WG_MSG_TYPE_DATA
344 344
345/* Sliding windows */ 345/* Sliding windows */
346 346
347#define SLIWIN_BITS 2048u 347#define SLIWIN_BITS 2048u
348#define SLIWIN_TYPE uint32_t 348#define SLIWIN_TYPE uint32_t
349#define SLIWIN_BPW NBBY*sizeof(SLIWIN_TYPE) 349#define SLIWIN_BPW NBBY*sizeof(SLIWIN_TYPE)
350#define SLIWIN_WORDS howmany(SLIWIN_BITS, SLIWIN_BPW) 350#define SLIWIN_WORDS howmany(SLIWIN_BITS, SLIWIN_BPW)
351#define SLIWIN_NPKT (SLIWIN_BITS - NBBY*sizeof(SLIWIN_TYPE)) 351#define SLIWIN_NPKT (SLIWIN_BITS - NBBY*sizeof(SLIWIN_TYPE))
352 352
353struct sliwin { 353struct sliwin {
354 SLIWIN_TYPE B[SLIWIN_WORDS]; 354 SLIWIN_TYPE B[SLIWIN_WORDS];
355 uint64_t T; 355 uint64_t T;
356}; 356};
357 357
358static void 358static void
359sliwin_reset(struct sliwin *W) 359sliwin_reset(struct sliwin *W)
360{ 360{
361 361
362 memset(W, 0, sizeof(*W)); 362 memset(W, 0, sizeof(*W));
363} 363}
364 364
365static int 365static int
366sliwin_check_fast(const volatile struct sliwin *W, uint64_t S) 366sliwin_check_fast(const volatile struct sliwin *W, uint64_t S)
367{ 367{
368 368
369 /* 369 /*
370 * If it's more than one window older than the highest sequence 370 * If it's more than one window older than the highest sequence
371 * number we've seen, reject. 371 * number we've seen, reject.
372 */ 372 */
373#ifdef __HAVE_ATOMIC64_LOADSTORE 373#ifdef __HAVE_ATOMIC64_LOADSTORE
374 if (S + SLIWIN_NPKT < atomic_load_relaxed(&W->T)) 374 if (S + SLIWIN_NPKT < atomic_load_relaxed(&W->T))
375 return EAUTH; 375 return EAUTH;
376#endif 376#endif
377 377
378 /* 378 /*
379 * Otherwise, we need to take the lock to decide, so don't 379 * Otherwise, we need to take the lock to decide, so don't
380 * reject just yet. Caller must serialize a call to 380 * reject just yet. Caller must serialize a call to
381 * sliwin_update in this case. 381 * sliwin_update in this case.
382 */ 382 */
383 return 0; 383 return 0;
384} 384}
385 385
386static int 386static int
387sliwin_update(struct sliwin *W, uint64_t S) 387sliwin_update(struct sliwin *W, uint64_t S)
388{ 388{
389 unsigned word, bit; 389 unsigned word, bit;
390 390
391 /* 391 /*
392 * If it's more than one window older than the highest sequence 392 * If it's more than one window older than the highest sequence
393 * number we've seen, reject. 393 * number we've seen, reject.
394 */ 394 */
395 if (S + SLIWIN_NPKT < W->T) 395 if (S + SLIWIN_NPKT < W->T)
396 return EAUTH; 396 return EAUTH;
397 397
398 /* 398 /*
399 * If it's higher than the highest sequence number we've seen, 399 * If it's higher than the highest sequence number we've seen,
400 * advance the window. 400 * advance the window.
401 */ 401 */
402 if (S > W->T) { 402 if (S > W->T) {
403 uint64_t i = W->T / SLIWIN_BPW; 403 uint64_t i = W->T / SLIWIN_BPW;
404 uint64_t j = S / SLIWIN_BPW; 404 uint64_t j = S / SLIWIN_BPW;
405 unsigned k; 405 unsigned k;
406 406
407 for (k = 0; k < MIN(j - i, SLIWIN_WORDS); k++) 407 for (k = 0; k < MIN(j - i, SLIWIN_WORDS); k++)
408 W->B[(i + k + 1) % SLIWIN_WORDS] = 0; 408 W->B[(i + k + 1) % SLIWIN_WORDS] = 0;
409#ifdef __HAVE_ATOMIC64_LOADSTORE 409#ifdef __HAVE_ATOMIC64_LOADSTORE
410 atomic_store_relaxed(&W->T, S); 410 atomic_store_relaxed(&W->T, S);
411#else 411#else
412 W->T = S; 412 W->T = S;
413#endif 413#endif
414 } 414 }
415 415
416 /* Test and set the bit -- if already set, reject. */ 416 /* Test and set the bit -- if already set, reject. */
417 word = (S / SLIWIN_BPW) % SLIWIN_WORDS; 417 word = (S / SLIWIN_BPW) % SLIWIN_WORDS;
418 bit = S % SLIWIN_BPW; 418 bit = S % SLIWIN_BPW;
419 if (W->B[word] & (1UL << bit)) 419 if (W->B[word] & (1UL << bit))
420 return EAUTH; 420 return EAUTH;
421 W->B[word] |= 1UL << bit; 421 W->B[word] |= 1UL << bit;
422 422
423 /* Accept! */ 423 /* Accept! */
424 return 0; 424 return 0;
425} 425}
426 426
427struct wg_worker { 427struct wg_worker {
428 kmutex_t wgw_lock; 428 kmutex_t wgw_lock;
429 kcondvar_t wgw_cv; 429 kcondvar_t wgw_cv;
430 bool wgw_todie; 430 bool wgw_todie;
431 struct socket *wgw_so4; 431 struct socket *wgw_so4;
432 struct socket *wgw_so6; 432 struct socket *wgw_so6;
433 int wgw_wakeup_reasons; 433 int wgw_wakeup_reasons;
434#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 __BIT(0) 434#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 __BIT(0)
435#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6 __BIT(1) 435#define WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6 __BIT(1)
436#define WG_WAKEUP_REASON_PEER __BIT(2) 436#define WG_WAKEUP_REASON_PEER __BIT(2)
437}; 437};
438 438
439struct wg_session { 439struct wg_session {
440 struct wg_peer *wgs_peer; 440 struct wg_peer *wgs_peer;
441 struct psref_target 441 struct psref_target
442 wgs_psref; 442 wgs_psref;
443 kmutex_t *wgs_lock; 443 kmutex_t *wgs_lock;
444 444
445 int wgs_state; 445 int wgs_state;
446#define WGS_STATE_UNKNOWN 0 446#define WGS_STATE_UNKNOWN 0
447#define WGS_STATE_INIT_ACTIVE 1 447#define WGS_STATE_INIT_ACTIVE 1
448#define WGS_STATE_INIT_PASSIVE 2 448#define WGS_STATE_INIT_PASSIVE 2
449#define WGS_STATE_ESTABLISHED 3 449#define WGS_STATE_ESTABLISHED 3
450#define WGS_STATE_DESTROYING 4 450#define WGS_STATE_DESTROYING 4
451 451
452 time_t wgs_time_established; 452 time_t wgs_time_established;
453 time_t wgs_time_last_data_sent; 453 time_t wgs_time_last_data_sent;
454 bool wgs_is_initiator; 454 bool wgs_is_initiator;
455 455
456 uint32_t wgs_sender_index; 456 uint32_t wgs_sender_index;
457 uint32_t wgs_receiver_index; 457 uint32_t wgs_receiver_index;
458#ifdef __HAVE_ATOMIC64_LOADSTORE 458#ifdef __HAVE_ATOMIC64_LOADSTORE
459 volatile uint64_t 459 volatile uint64_t
460 wgs_send_counter; 460 wgs_send_counter;
461#else 461#else
462 kmutex_t wgs_send_counter_lock; 462 kmutex_t wgs_send_counter_lock;
463 uint64_t wgs_send_counter; 463 uint64_t wgs_send_counter;
464#endif 464#endif
465 465
466 struct { 466 struct {
467 kmutex_t lock; 467 kmutex_t lock;
468 struct sliwin window; 468 struct sliwin window;
469 } *wgs_recvwin; 469 } *wgs_recvwin;
470 470
471 uint8_t wgs_handshake_hash[WG_HASH_LEN]; 471 uint8_t wgs_handshake_hash[WG_HASH_LEN];
472 uint8_t wgs_chaining_key[WG_CHAINING_KEY_LEN]; 472 uint8_t wgs_chaining_key[WG_CHAINING_KEY_LEN];
473 uint8_t wgs_ephemeral_key_pub[WG_EPHEMERAL_KEY_LEN]; 473 uint8_t wgs_ephemeral_key_pub[WG_EPHEMERAL_KEY_LEN];
474 uint8_t wgs_ephemeral_key_priv[WG_EPHEMERAL_KEY_LEN]; 474 uint8_t wgs_ephemeral_key_priv[WG_EPHEMERAL_KEY_LEN];
475 uint8_t wgs_ephemeral_key_peer[WG_EPHEMERAL_KEY_LEN]; 475 uint8_t wgs_ephemeral_key_peer[WG_EPHEMERAL_KEY_LEN];
476 uint8_t wgs_tkey_send[WG_DATA_KEY_LEN]; 476 uint8_t wgs_tkey_send[WG_DATA_KEY_LEN];
477 uint8_t wgs_tkey_recv[WG_DATA_KEY_LEN]; 477 uint8_t wgs_tkey_recv[WG_DATA_KEY_LEN];
478}; 478};
479 479
480struct wg_sockaddr { 480struct wg_sockaddr {
481 union { 481 union {
482 struct sockaddr_storage _ss; 482 struct sockaddr_storage _ss;
483 struct sockaddr _sa; 483 struct sockaddr _sa;
484 struct sockaddr_in _sin; 484 struct sockaddr_in _sin;
485 struct sockaddr_in6 _sin6; 485 struct sockaddr_in6 _sin6;
486 }; 486 };
487 struct psref_target wgsa_psref; 487 struct psref_target wgsa_psref;
488}; 488};
489 489
490#define wgsatosa(wgsa) (&(wgsa)->_sa) 490#define wgsatosa(wgsa) (&(wgsa)->_sa)
491#define wgsatosin(wgsa) (&(wgsa)->_sin) 491#define wgsatosin(wgsa) (&(wgsa)->_sin)
492#define wgsatosin6(wgsa) (&(wgsa)->_sin6) 492#define wgsatosin6(wgsa) (&(wgsa)->_sin6)
493 493
494struct wg_peer; 494struct wg_peer;
495struct wg_allowedip { 495struct wg_allowedip {
496 struct radix_node wga_nodes[2]; 496 struct radix_node wga_nodes[2];
497 struct wg_sockaddr _wga_sa_addr; 497 struct wg_sockaddr _wga_sa_addr;
498 struct wg_sockaddr _wga_sa_mask; 498 struct wg_sockaddr _wga_sa_mask;
499#define wga_sa_addr _wga_sa_addr._sa 499#define wga_sa_addr _wga_sa_addr._sa
500#define wga_sa_mask _wga_sa_mask._sa 500#define wga_sa_mask _wga_sa_mask._sa
501 501
502 int wga_family; 502 int wga_family;
503 uint8_t wga_cidr; 503 uint8_t wga_cidr;
504 union { 504 union {
505 struct in_addr _ip4; 505 struct in_addr _ip4;
506 struct in6_addr _ip6; 506 struct in6_addr _ip6;
507 } wga_addr; 507 } wga_addr;
508#define wga_addr4 wga_addr._ip4 508#define wga_addr4 wga_addr._ip4
509#define wga_addr6 wga_addr._ip6 509#define wga_addr6 wga_addr._ip6
510 510
511 struct wg_peer *wga_peer; 511 struct wg_peer *wga_peer;
512}; 512};
513 513
514typedef uint8_t wg_timestamp_t[WG_TIMESTAMP_LEN]; 514typedef uint8_t wg_timestamp_t[WG_TIMESTAMP_LEN];
515 515
516struct wg_ppsratecheck { 516struct wg_ppsratecheck {
517 struct timeval wgprc_lasttime; 517 struct timeval wgprc_lasttime;
518 int wgprc_curpps; 518 int wgprc_curpps;
519}; 519};
520 520
521struct wg_softc; 521struct wg_softc;
522struct wg_peer { 522struct wg_peer {
523 struct wg_softc *wgp_sc; 523 struct wg_softc *wgp_sc;
524 char wgp_name[WG_PEER_NAME_MAXLEN + 1]; 524 char wgp_name[WG_PEER_NAME_MAXLEN + 1];
525 struct pslist_entry wgp_peerlist_entry; 525 struct pslist_entry wgp_peerlist_entry;
526 pserialize_t wgp_psz; 526 pserialize_t wgp_psz;
527 struct psref_target wgp_psref; 527 struct psref_target wgp_psref;
528 kmutex_t *wgp_lock; 528 kmutex_t *wgp_lock;
529 529
530 uint8_t wgp_pubkey[WG_STATIC_KEY_LEN]; 530 uint8_t wgp_pubkey[WG_STATIC_KEY_LEN];
531 struct wg_sockaddr *wgp_endpoint; 531 struct wg_sockaddr *wgp_endpoint;
532#define wgp_ss wgp_endpoint->_ss 532#define wgp_ss wgp_endpoint->_ss
533#define wgp_sa wgp_endpoint->_sa 533#define wgp_sa wgp_endpoint->_sa
534#define wgp_sin wgp_endpoint->_sin 534#define wgp_sin wgp_endpoint->_sin
535#define wgp_sin6 wgp_endpoint->_sin6 535#define wgp_sin6 wgp_endpoint->_sin6
536 struct wg_sockaddr *wgp_endpoint0; 536 struct wg_sockaddr *wgp_endpoint0;
537 bool wgp_endpoint_changing; 537 bool wgp_endpoint_changing;
538 bool wgp_endpoint_available; 538 bool wgp_endpoint_available;
539 539
540 /* The preshared key (optional) */ 540 /* The preshared key (optional) */
541 uint8_t wgp_psk[WG_PRESHARED_KEY_LEN]; 541 uint8_t wgp_psk[WG_PRESHARED_KEY_LEN];
542 542
543 int wgp_state; 543 int wgp_state;
544#define WGP_STATE_INIT 0 544#define WGP_STATE_INIT 0
545#define WGP_STATE_ESTABLISHED 1 545#define WGP_STATE_ESTABLISHED 1
546#define WGP_STATE_GIVEUP 2 546#define WGP_STATE_GIVEUP 2
547#define WGP_STATE_DESTROYING 3 547#define WGP_STATE_DESTROYING 3
548 548
549 void *wgp_si; 549 void *wgp_si;
550 pcq_t *wgp_q; 550 pcq_t *wgp_q;
551 551
552 struct wg_session *wgp_session_stable; 552 struct wg_session *wgp_session_stable;
553 struct wg_session *wgp_session_unstable; 553 struct wg_session *wgp_session_unstable;
554 554
555 /* timestamp in big-endian */ 555 /* timestamp in big-endian */
556 wg_timestamp_t wgp_timestamp_latest_init; 556 wg_timestamp_t wgp_timestamp_latest_init;
557 557
558 struct timespec wgp_last_handshake_time; 558 struct timespec wgp_last_handshake_time;
559 559
560 callout_t wgp_rekey_timer; 560 callout_t wgp_rekey_timer;
561 callout_t wgp_handshake_timeout_timer; 561 callout_t wgp_handshake_timeout_timer;
562 callout_t wgp_session_dtor_timer; 562 callout_t wgp_session_dtor_timer;
563 563
564 time_t wgp_handshake_start_time; 564 time_t wgp_handshake_start_time;
565 565
566 int wgp_n_allowedips; 566 int wgp_n_allowedips;
567 struct wg_allowedip wgp_allowedips[WG_ALLOWEDIPS]; 567 struct wg_allowedip wgp_allowedips[WG_ALLOWEDIPS];
568 568
569 time_t wgp_latest_cookie_time; 569 time_t wgp_latest_cookie_time;
570 uint8_t wgp_latest_cookie[WG_COOKIE_LEN]; 570 uint8_t wgp_latest_cookie[WG_COOKIE_LEN];
571 uint8_t wgp_last_sent_mac1[WG_MAC_LEN]; 571 uint8_t wgp_last_sent_mac1[WG_MAC_LEN];
572 bool wgp_last_sent_mac1_valid; 572 bool wgp_last_sent_mac1_valid;
573 uint8_t wgp_last_sent_cookie[WG_COOKIE_LEN]; 573 uint8_t wgp_last_sent_cookie[WG_COOKIE_LEN];
574 bool wgp_last_sent_cookie_valid; 574 bool wgp_last_sent_cookie_valid;
575 575
576 time_t wgp_last_msg_received_time[WG_MSG_TYPE_MAX]; 576 time_t wgp_last_msg_received_time[WG_MSG_TYPE_MAX];
577 577
578 time_t wgp_last_genrandval_time; 578 time_t wgp_last_genrandval_time;
579 uint32_t wgp_randval; 579 uint32_t wgp_randval;
580 580
581 struct wg_ppsratecheck wgp_ppsratecheck; 581 struct wg_ppsratecheck wgp_ppsratecheck;
582 582
583 volatile unsigned int wgp_tasks; 583 volatile unsigned int wgp_tasks;
584#define WGP_TASK_SEND_INIT_MESSAGE __BIT(0) 584#define WGP_TASK_SEND_INIT_MESSAGE __BIT(0)
585#define WGP_TASK_ENDPOINT_CHANGED __BIT(1) 585#define WGP_TASK_ENDPOINT_CHANGED __BIT(1)
586#define WGP_TASK_SEND_KEEPALIVE_MESSAGE __BIT(2) 586#define WGP_TASK_SEND_KEEPALIVE_MESSAGE __BIT(2)
587#define WGP_TASK_DESTROY_PREV_SESSION __BIT(3) 587#define WGP_TASK_DESTROY_PREV_SESSION __BIT(3)
588}; 588};
589 589
590struct wg_ops; 590struct wg_ops;
591 591
592struct wg_softc { 592struct wg_softc {
593 struct ifnet wg_if; 593 struct ifnet wg_if;
594 LIST_ENTRY(wg_softc) wg_list; 594 LIST_ENTRY(wg_softc) wg_list;
595 kmutex_t *wg_lock; 595 kmutex_t *wg_lock;
596 krwlock_t *wg_rwlock; 596 krwlock_t *wg_rwlock;
597 597
598 uint8_t wg_privkey[WG_STATIC_KEY_LEN]; 598 uint8_t wg_privkey[WG_STATIC_KEY_LEN];
599 uint8_t wg_pubkey[WG_STATIC_KEY_LEN]; 599 uint8_t wg_pubkey[WG_STATIC_KEY_LEN];
600 600
601 int wg_npeers; 601 int wg_npeers;
602 struct pslist_head wg_peers; 602 struct pslist_head wg_peers;
603 uint16_t wg_listen_port; 603 uint16_t wg_listen_port;
604 604
605 struct wg_worker *wg_worker; 605 struct wg_worker *wg_worker;
606 lwp_t *wg_worker_lwp; 606 lwp_t *wg_worker_lwp;
607 607
608 struct radix_node_head *wg_rtable_ipv4; 608 struct radix_node_head *wg_rtable_ipv4;
609 struct radix_node_head *wg_rtable_ipv6; 609 struct radix_node_head *wg_rtable_ipv6;
610 610
611 struct wg_ppsratecheck wg_ppsratecheck; 611 struct wg_ppsratecheck wg_ppsratecheck;
612 612
613 struct wg_ops *wg_ops; 613 struct wg_ops *wg_ops;
614 614
615#ifdef WG_RUMPKERNEL 615#ifdef WG_RUMPKERNEL
616 struct wg_user *wg_user; 616 struct wg_user *wg_user;
617#endif 617#endif
618}; 618};
619 619
620/* [W] 6.1 Preliminaries */ 620/* [W] 6.1 Preliminaries */
621#define WG_REKEY_AFTER_MESSAGES (1ULL << 60) 621#define WG_REKEY_AFTER_MESSAGES (1ULL << 60)
622#define WG_REJECT_AFTER_MESSAGES (UINT64_MAX - (1 << 13)) 622#define WG_REJECT_AFTER_MESSAGES (UINT64_MAX - (1 << 13))
623#define WG_REKEY_AFTER_TIME 120 623#define WG_REKEY_AFTER_TIME 120
624#define WG_REJECT_AFTER_TIME 180 624#define WG_REJECT_AFTER_TIME 180
625#define WG_REKEY_ATTEMPT_TIME 90 625#define WG_REKEY_ATTEMPT_TIME 90
626#define WG_REKEY_TIMEOUT 5 626#define WG_REKEY_TIMEOUT 5
627#define WG_KEEPALIVE_TIMEOUT 10 627#define WG_KEEPALIVE_TIMEOUT 10
628 628
629#define WG_COOKIE_TIME 120 629#define WG_COOKIE_TIME 120
630#define WG_RANDVAL_TIME (2 * 60) 630#define WG_RANDVAL_TIME (2 * 60)
631 631
632static uint64_t wg_rekey_after_messages = WG_REKEY_AFTER_MESSAGES; 632static uint64_t wg_rekey_after_messages = WG_REKEY_AFTER_MESSAGES;
633static uint64_t wg_reject_after_messages = WG_REJECT_AFTER_MESSAGES; 633static uint64_t wg_reject_after_messages = WG_REJECT_AFTER_MESSAGES;
634static unsigned wg_rekey_after_time = WG_REKEY_AFTER_TIME; 634static unsigned wg_rekey_after_time = WG_REKEY_AFTER_TIME;
635static unsigned wg_reject_after_time = WG_REJECT_AFTER_TIME; 635static unsigned wg_reject_after_time = WG_REJECT_AFTER_TIME;
636static unsigned wg_rekey_attempt_time = WG_REKEY_ATTEMPT_TIME; 636static unsigned wg_rekey_attempt_time = WG_REKEY_ATTEMPT_TIME;
637static unsigned wg_rekey_timeout = WG_REKEY_TIMEOUT; 637static unsigned wg_rekey_timeout = WG_REKEY_TIMEOUT;
638static unsigned wg_keepalive_timeout = WG_KEEPALIVE_TIMEOUT; 638static unsigned wg_keepalive_timeout = WG_KEEPALIVE_TIMEOUT;
639 639
640static struct mbuf * 640static struct mbuf *
641 wg_get_mbuf(size_t, size_t); 641 wg_get_mbuf(size_t, size_t);
642 642
643static void wg_wakeup_worker(struct wg_worker *, int); 643static void wg_wakeup_worker(struct wg_worker *, int);
644 644
645static int wg_send_data_msg(struct wg_peer *, struct wg_session *, 645static int wg_send_data_msg(struct wg_peer *, struct wg_session *,
646 struct mbuf *); 646 struct mbuf *);
647static int wg_send_cookie_msg(struct wg_softc *, struct wg_peer *, 647static int wg_send_cookie_msg(struct wg_softc *, struct wg_peer *,
648 const uint32_t, const uint8_t [], const struct sockaddr *); 648 const uint32_t, const uint8_t [], const struct sockaddr *);
649static int wg_send_handshake_msg_resp(struct wg_softc *, 649static int wg_send_handshake_msg_resp(struct wg_softc *,
650 struct wg_peer *, const struct wg_msg_init *); 650 struct wg_peer *, const struct wg_msg_init *);
651static void wg_send_keepalive_msg(struct wg_peer *, struct wg_session *); 651static void wg_send_keepalive_msg(struct wg_peer *, struct wg_session *);
652 652
653static struct wg_peer * 653static struct wg_peer *
654 wg_pick_peer_by_sa(struct wg_softc *, const struct sockaddr *, 654 wg_pick_peer_by_sa(struct wg_softc *, const struct sockaddr *,
655 struct psref *); 655 struct psref *);
656static struct wg_peer * 656static struct wg_peer *
657 wg_lookup_peer_by_pubkey(struct wg_softc *, 657 wg_lookup_peer_by_pubkey(struct wg_softc *,
658 const uint8_t [], struct psref *); 658 const uint8_t [], struct psref *);
659 659
660static struct wg_session * 660static struct wg_session *
661 wg_lookup_session_by_index(struct wg_softc *, 661 wg_lookup_session_by_index(struct wg_softc *,
662 const uint32_t, struct psref *); 662 const uint32_t, struct psref *);
663 663
664static void wg_update_endpoint_if_necessary(struct wg_peer *, 664static void wg_update_endpoint_if_necessary(struct wg_peer *,
665 const struct sockaddr *); 665 const struct sockaddr *);
666 666
667static void wg_schedule_rekey_timer(struct wg_peer *); 667static void wg_schedule_rekey_timer(struct wg_peer *);
668static void wg_schedule_session_dtor_timer(struct wg_peer *); 668static void wg_schedule_session_dtor_timer(struct wg_peer *);
669static void wg_stop_session_dtor_timer(struct wg_peer *); 669static void wg_stop_session_dtor_timer(struct wg_peer *);
670 670
671static bool wg_is_underload(struct wg_softc *, struct wg_peer *, int); 671static bool wg_is_underload(struct wg_softc *, struct wg_peer *, int);
672static void wg_calculate_keys(struct wg_session *, const bool); 672static void wg_calculate_keys(struct wg_session *, const bool);
673 673
674static void wg_clear_states(struct wg_session *); 674static void wg_clear_states(struct wg_session *);
675 675
676static void wg_get_peer(struct wg_peer *, struct psref *); 676static void wg_get_peer(struct wg_peer *, struct psref *);
677static void wg_put_peer(struct wg_peer *, struct psref *); 677static void wg_put_peer(struct wg_peer *, struct psref *);
678 678
679static int wg_send_so(struct wg_peer *, struct mbuf *); 679static int wg_send_so(struct wg_peer *, struct mbuf *);
680static int wg_send_udp(struct wg_peer *, struct mbuf *); 680static int wg_send_udp(struct wg_peer *, struct mbuf *);
681static int wg_output(struct ifnet *, struct mbuf *, 681static int wg_output(struct ifnet *, struct mbuf *,
682 const struct sockaddr *, const struct rtentry *); 682 const struct sockaddr *, const struct rtentry *);
683static void wg_input(struct ifnet *, struct mbuf *, const int); 683static void wg_input(struct ifnet *, struct mbuf *, const int);
684static int wg_ioctl(struct ifnet *, u_long, void *); 684static int wg_ioctl(struct ifnet *, u_long, void *);
685static int wg_bind_port(struct wg_softc *, const uint16_t); 685static int wg_bind_port(struct wg_softc *, const uint16_t);
686static int wg_init(struct ifnet *); 686static int wg_init(struct ifnet *);
687static void wg_stop(struct ifnet *, int); 687static void wg_stop(struct ifnet *, int);
688 688
689static int wg_clone_create(struct if_clone *, int); 689static int wg_clone_create(struct if_clone *, int);
690static int wg_clone_destroy(struct ifnet *); 690static int wg_clone_destroy(struct ifnet *);
691 691
692struct wg_ops { 692struct wg_ops {
693 int (*send_hs_msg)(struct wg_peer *, struct mbuf *); 693 int (*send_hs_msg)(struct wg_peer *, struct mbuf *);
694 int (*send_data_msg)(struct wg_peer *, struct mbuf *); 694 int (*send_data_msg)(struct wg_peer *, struct mbuf *);
695 void (*input)(struct ifnet *, struct mbuf *, const int); 695 void (*input)(struct ifnet *, struct mbuf *, const int);
696 int (*bind_port)(struct wg_softc *, const uint16_t); 696 int (*bind_port)(struct wg_softc *, const uint16_t);
697}; 697};
698 698
699struct wg_ops wg_ops_rumpkernel = { 699struct wg_ops wg_ops_rumpkernel = {
700 .send_hs_msg = wg_send_so, 700 .send_hs_msg = wg_send_so,
701 .send_data_msg = wg_send_udp, 701 .send_data_msg = wg_send_udp,
702 .input = wg_input, 702 .input = wg_input,
703 .bind_port = wg_bind_port, 703 .bind_port = wg_bind_port,
704}; 704};
705 705
706#ifdef WG_RUMPKERNEL 706#ifdef WG_RUMPKERNEL
707static bool wg_user_mode(struct wg_softc *); 707static bool wg_user_mode(struct wg_softc *);
708static int wg_ioctl_linkstr(struct wg_softc *, struct ifdrv *); 708static int wg_ioctl_linkstr(struct wg_softc *, struct ifdrv *);
709 709
710static int wg_send_user(struct wg_peer *, struct mbuf *); 710static int wg_send_user(struct wg_peer *, struct mbuf *);
711static void wg_input_user(struct ifnet *, struct mbuf *, const int); 711static void wg_input_user(struct ifnet *, struct mbuf *, const int);
712static int wg_bind_port_user(struct wg_softc *, const uint16_t); 712static int wg_bind_port_user(struct wg_softc *, const uint16_t);
713 713
714struct wg_ops wg_ops_rumpuser = { 714struct wg_ops wg_ops_rumpuser = {
715 .send_hs_msg = wg_send_user, 715 .send_hs_msg = wg_send_user,
716 .send_data_msg = wg_send_user, 716 .send_data_msg = wg_send_user,
717 .input = wg_input_user, 717 .input = wg_input_user,
718 .bind_port = wg_bind_port_user, 718 .bind_port = wg_bind_port_user,
719}; 719};
720#endif 720#endif
721 721
722#define WG_PEER_READER_FOREACH(wgp, wg) \ 722#define WG_PEER_READER_FOREACH(wgp, wg) \
723 PSLIST_READER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \ 723 PSLIST_READER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \
724 wgp_peerlist_entry) 724 wgp_peerlist_entry)
725#define WG_PEER_WRITER_FOREACH(wgp, wg) \ 725#define WG_PEER_WRITER_FOREACH(wgp, wg) \
726 PSLIST_WRITER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \ 726 PSLIST_WRITER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \
727 wgp_peerlist_entry) 727 wgp_peerlist_entry)
728#define WG_PEER_WRITER_INSERT_HEAD(wgp, wg) \ 728#define WG_PEER_WRITER_INSERT_HEAD(wgp, wg) \
729 PSLIST_WRITER_INSERT_HEAD(&(wg)->wg_peers, (wgp), wgp_peerlist_entry) 729 PSLIST_WRITER_INSERT_HEAD(&(wg)->wg_peers, (wgp), wgp_peerlist_entry)
730#define WG_PEER_WRITER_REMOVE(wgp) \ 730#define WG_PEER_WRITER_REMOVE(wgp) \
731 PSLIST_WRITER_REMOVE((wgp), wgp_peerlist_entry) 731 PSLIST_WRITER_REMOVE((wgp), wgp_peerlist_entry)
732 732
733struct wg_route { 733struct wg_route {
734 struct radix_node wgr_nodes[2]; 734 struct radix_node wgr_nodes[2];
735 struct wg_peer *wgr_peer; 735 struct wg_peer *wgr_peer;
736}; 736};
737 737
738static struct radix_node_head * 738static struct radix_node_head *
739wg_rnh(struct wg_softc *wg, const int family) 739wg_rnh(struct wg_softc *wg, const int family)
740{ 740{
741 741
742 switch (family) { 742 switch (family) {
743 case AF_INET: 743 case AF_INET:
744 return wg->wg_rtable_ipv4; 744 return wg->wg_rtable_ipv4;
745#ifdef INET6 745#ifdef INET6
746 case AF_INET6: 746 case AF_INET6:
747 return wg->wg_rtable_ipv6; 747 return wg->wg_rtable_ipv6;
748#endif 748#endif
749 default: 749 default:
750 return NULL; 750 return NULL;
751 } 751 }
752} 752}
753 753
754 754
755/* 755/*
756 * Global variables 756 * Global variables
757 */ 757 */
758LIST_HEAD(wg_sclist, wg_softc); 758LIST_HEAD(wg_sclist, wg_softc);
759static struct { 759static struct {
760 struct wg_sclist list; 760 struct wg_sclist list;
761 kmutex_t lock; 761 kmutex_t lock;
762} wg_softcs __cacheline_aligned; 762} wg_softcs __cacheline_aligned;
763 763
764struct psref_class *wg_psref_class __read_mostly; 764struct psref_class *wg_psref_class __read_mostly;
765 765
766static struct if_clone wg_cloner = 766static struct if_clone wg_cloner =
767 IF_CLONE_INITIALIZER("wg", wg_clone_create, wg_clone_destroy); 767 IF_CLONE_INITIALIZER("wg", wg_clone_create, wg_clone_destroy);
768 768
769 769
770void wgattach(int); 770void wgattach(int);
771/* ARGSUSED */ 771/* ARGSUSED */
772void 772void
773wgattach(int count) 773wgattach(int count)
774{ 774{
775 /* 775 /*
776 * Nothing to do here, initialization is handled by the 776 * Nothing to do here, initialization is handled by the
777 * module initialization code in wginit() below). 777 * module initialization code in wginit() below).
778 */ 778 */
779} 779}
780 780
781static void 781static void
782wginit(void) 782wginit(void)
783{ 783{
784 784
785 wg_psref_class = psref_class_create("wg", IPL_SOFTNET); 785 wg_psref_class = psref_class_create("wg", IPL_SOFTNET);
786 786
787 mutex_init(&wg_softcs.lock, MUTEX_DEFAULT, IPL_NONE); 787 mutex_init(&wg_softcs.lock, MUTEX_DEFAULT, IPL_NONE);
788 LIST_INIT(&wg_softcs.list); 788 LIST_INIT(&wg_softcs.list);
789 if_clone_attach(&wg_cloner); 789 if_clone_attach(&wg_cloner);
790} 790}
791 791
792static int 792static int
793wgdetach(void) 793wgdetach(void)
794{ 794{
795 int error = 0; 795 int error = 0;
796 796
797 mutex_enter(&wg_softcs.lock); 797 mutex_enter(&wg_softcs.lock);
798 if (!LIST_EMPTY(&wg_softcs.list)) { 798 if (!LIST_EMPTY(&wg_softcs.list)) {
799 mutex_exit(&wg_softcs.lock); 799 mutex_exit(&wg_softcs.lock);
800 error = EBUSY; 800 error = EBUSY;
801 } 801 }
802 802
803 if (error == 0) { 803 if (error == 0) {
804 psref_class_destroy(wg_psref_class); 804 psref_class_destroy(wg_psref_class);
805 805
806 if_clone_detach(&wg_cloner); 806 if_clone_detach(&wg_cloner);
807 } 807 }
808 808
809 return error; 809 return error;
810} 810}
811 811
812static void 812static void
813wg_init_key_and_hash(uint8_t ckey[WG_CHAINING_KEY_LEN], 813wg_init_key_and_hash(uint8_t ckey[WG_CHAINING_KEY_LEN],
814 uint8_t hash[WG_HASH_LEN]) 814 uint8_t hash[WG_HASH_LEN])
815{ 815{
816 /* [W] 5.4: CONSTRUCTION */ 816 /* [W] 5.4: CONSTRUCTION */
817 const char *signature = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; 817 const char *signature = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
818 /* [W] 5.4: IDENTIFIER */ 818 /* [W] 5.4: IDENTIFIER */
819 const char *id = "WireGuard v1 zx2c4 Jason@zx2c4.com"; 819 const char *id = "WireGuard v1 zx2c4 Jason@zx2c4.com";
820 struct blake2s state; 820 struct blake2s state;
821 821
822 blake2s(ckey, WG_CHAINING_KEY_LEN, NULL, 0, 822 blake2s(ckey, WG_CHAINING_KEY_LEN, NULL, 0,
823 signature, strlen(signature)); 823 signature, strlen(signature));
824 824
825 CTASSERT(WG_HASH_LEN == WG_CHAINING_KEY_LEN); 825 CTASSERT(WG_HASH_LEN == WG_CHAINING_KEY_LEN);
826 memcpy(hash, ckey, WG_CHAINING_KEY_LEN); 826 memcpy(hash, ckey, WG_CHAINING_KEY_LEN);
827 827
828 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 828 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
829 blake2s_update(&state, ckey, WG_CHAINING_KEY_LEN); 829 blake2s_update(&state, ckey, WG_CHAINING_KEY_LEN);
830 blake2s_update(&state, id, strlen(id)); 830 blake2s_update(&state, id, strlen(id));
831 blake2s_final(&state, hash); 831 blake2s_final(&state, hash);
832 832
833 WG_DUMP_HASH("ckey", ckey); 833 WG_DUMP_HASH("ckey", ckey);
834 WG_DUMP_HASH("hash", hash); 834 WG_DUMP_HASH("hash", hash);
835} 835}
836 836
837static void 837static void
838wg_algo_hash(uint8_t hash[WG_HASH_LEN], const uint8_t input[], 838wg_algo_hash(uint8_t hash[WG_HASH_LEN], const uint8_t input[],
839 const size_t inputsize) 839 const size_t inputsize)
840{ 840{
841 struct blake2s state; 841 struct blake2s state;
842 842
843 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 843 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
844 blake2s_update(&state, hash, WG_HASH_LEN); 844 blake2s_update(&state, hash, WG_HASH_LEN);
845 blake2s_update(&state, input, inputsize); 845 blake2s_update(&state, input, inputsize);
846 blake2s_final(&state, hash); 846 blake2s_final(&state, hash);
847} 847}
848 848
849static void 849static void
850wg_algo_mac(uint8_t out[], const size_t outsize, 850wg_algo_mac(uint8_t out[], const size_t outsize,
851 const uint8_t key[], const size_t keylen, 851 const uint8_t key[], const size_t keylen,
852 const uint8_t input1[], const size_t input1len, 852 const uint8_t input1[], const size_t input1len,
853 const uint8_t input2[], const size_t input2len) 853 const uint8_t input2[], const size_t input2len)
854{ 854{
855 struct blake2s state; 855 struct blake2s state;
856 856
857 blake2s_init(&state, outsize, key, keylen); 857 blake2s_init(&state, outsize, key, keylen);
858 858
859 blake2s_update(&state, input1, input1len); 859 blake2s_update(&state, input1, input1len);
860 if (input2 != NULL) 860 if (input2 != NULL)
861 blake2s_update(&state, input2, input2len); 861 blake2s_update(&state, input2, input2len);
862 blake2s_final(&state, out); 862 blake2s_final(&state, out);
863} 863}
864 864
865static void 865static void
866wg_algo_mac_mac1(uint8_t out[], const size_t outsize, 866wg_algo_mac_mac1(uint8_t out[], const size_t outsize,
867 const uint8_t input1[], const size_t input1len, 867 const uint8_t input1[], const size_t input1len,
868 const uint8_t input2[], const size_t input2len) 868 const uint8_t input2[], const size_t input2len)
869{ 869{
870 struct blake2s state; 870 struct blake2s state;
871 /* [W] 5.4: LABEL-MAC1 */ 871 /* [W] 5.4: LABEL-MAC1 */
872 const char *label = "mac1----"; 872 const char *label = "mac1----";
873 uint8_t key[WG_HASH_LEN]; 873 uint8_t key[WG_HASH_LEN];
874 874
875 blake2s_init(&state, sizeof(key), NULL, 0); 875 blake2s_init(&state, sizeof(key), NULL, 0);
876 blake2s_update(&state, label, strlen(label)); 876 blake2s_update(&state, label, strlen(label));
877 blake2s_update(&state, input1, input1len); 877 blake2s_update(&state, input1, input1len);
878 blake2s_final(&state, key); 878 blake2s_final(&state, key);
879 879
880 blake2s_init(&state, outsize, key, sizeof(key)); 880 blake2s_init(&state, outsize, key, sizeof(key));
881 if (input2 != NULL) 881 if (input2 != NULL)
882 blake2s_update(&state, input2, input2len); 882 blake2s_update(&state, input2, input2len);
883 blake2s_final(&state, out); 883 blake2s_final(&state, out);
884} 884}
885 885
886static void 886static void
887wg_algo_mac_cookie(uint8_t out[], const size_t outsize, 887wg_algo_mac_cookie(uint8_t out[], const size_t outsize,
888 const uint8_t input1[], const size_t input1len) 888 const uint8_t input1[], const size_t input1len)
889{ 889{
890 struct blake2s state; 890 struct blake2s state;
891 /* [W] 5.4: LABEL-COOKIE */ 891 /* [W] 5.4: LABEL-COOKIE */
892 const char *label = "cookie--"; 892 const char *label = "cookie--";
893 893
894 blake2s_init(&state, outsize, NULL, 0); 894 blake2s_init(&state, outsize, NULL, 0);
895 blake2s_update(&state, label, strlen(label)); 895 blake2s_update(&state, label, strlen(label));
896 blake2s_update(&state, input1, input1len); 896 blake2s_update(&state, input1, input1len);
897 blake2s_final(&state, out); 897 blake2s_final(&state, out);
898} 898}
899 899
900static void 900static void
901wg_algo_generate_keypair(uint8_t pubkey[WG_EPHEMERAL_KEY_LEN], 901wg_algo_generate_keypair(uint8_t pubkey[WG_EPHEMERAL_KEY_LEN],
902 uint8_t privkey[WG_EPHEMERAL_KEY_LEN]) 902 uint8_t privkey[WG_EPHEMERAL_KEY_LEN])
903{ 903{
904 904
905 CTASSERT(WG_EPHEMERAL_KEY_LEN == crypto_scalarmult_curve25519_BYTES); 905 CTASSERT(WG_EPHEMERAL_KEY_LEN == crypto_scalarmult_curve25519_BYTES);
906 906
907 cprng_strong(kern_cprng, privkey, WG_EPHEMERAL_KEY_LEN, 0); 907 cprng_strong(kern_cprng, privkey, WG_EPHEMERAL_KEY_LEN, 0);
908 crypto_scalarmult_base(pubkey, privkey); 908 crypto_scalarmult_base(pubkey, privkey);
909} 909}
910 910
911static void 911static void
912wg_algo_dh(uint8_t out[WG_DH_OUTPUT_LEN], 912wg_algo_dh(uint8_t out[WG_DH_OUTPUT_LEN],
913 const uint8_t privkey[WG_STATIC_KEY_LEN], 913 const uint8_t privkey[WG_STATIC_KEY_LEN],
914 const uint8_t pubkey[WG_STATIC_KEY_LEN]) 914 const uint8_t pubkey[WG_STATIC_KEY_LEN])
915{ 915{
916 916
917 CTASSERT(WG_STATIC_KEY_LEN == crypto_scalarmult_curve25519_BYTES); 917 CTASSERT(WG_STATIC_KEY_LEN == crypto_scalarmult_curve25519_BYTES);
918 918
919 int ret __diagused = crypto_scalarmult(out, privkey, pubkey); 919 int ret __diagused = crypto_scalarmult(out, privkey, pubkey);
920 KASSERT(ret == 0); 920 KASSERT(ret == 0);
921} 921}
922 922
923static void 923static void
924wg_algo_hmac(uint8_t out[], const size_t outlen, 924wg_algo_hmac(uint8_t out[], const size_t outlen,
925 const uint8_t key[], const size_t keylen, 925 const uint8_t key[], const size_t keylen,
926 const uint8_t in[], const size_t inlen) 926 const uint8_t in[], const size_t inlen)
927{ 927{
928#define IPAD 0x36 928#define IPAD 0x36
929#define OPAD 0x5c 929#define OPAD 0x5c
930 uint8_t hmackey[HMAC_BLOCK_LEN] = {0}; 930 uint8_t hmackey[HMAC_BLOCK_LEN] = {0};
931 uint8_t ipad[HMAC_BLOCK_LEN]; 931 uint8_t ipad[HMAC_BLOCK_LEN];
932 uint8_t opad[HMAC_BLOCK_LEN]; 932 uint8_t opad[HMAC_BLOCK_LEN];
933 int i; 933 int i;
934 struct blake2s state; 934 struct blake2s state;
935 935
936 KASSERT(outlen == WG_HASH_LEN); 936 KASSERT(outlen == WG_HASH_LEN);
937 KASSERT(keylen <= HMAC_BLOCK_LEN); 937 KASSERT(keylen <= HMAC_BLOCK_LEN);
938 938
939 memcpy(hmackey, key, keylen); 939 memcpy(hmackey, key, keylen);
940 940
941 for (i = 0; i < sizeof(hmackey); i++) { 941 for (i = 0; i < sizeof(hmackey); i++) {
942 ipad[i] = hmackey[i] ^ IPAD; 942 ipad[i] = hmackey[i] ^ IPAD;
943 opad[i] = hmackey[i] ^ OPAD; 943 opad[i] = hmackey[i] ^ OPAD;
944 } 944 }
945 945
946 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 946 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
947 blake2s_update(&state, ipad, sizeof(ipad)); 947 blake2s_update(&state, ipad, sizeof(ipad));
948 blake2s_update(&state, in, inlen); 948 blake2s_update(&state, in, inlen);
949 blake2s_final(&state, out); 949 blake2s_final(&state, out);
950 950
951 blake2s_init(&state, WG_HASH_LEN, NULL, 0); 951 blake2s_init(&state, WG_HASH_LEN, NULL, 0);
952 blake2s_update(&state, opad, sizeof(opad)); 952 blake2s_update(&state, opad, sizeof(opad));
953 blake2s_update(&state, out, WG_HASH_LEN); 953 blake2s_update(&state, out, WG_HASH_LEN);
954 blake2s_final(&state, out); 954 blake2s_final(&state, out);
955#undef IPAD 955#undef IPAD
956#undef OPAD 956#undef OPAD
957} 957}
958 958
959static void 959static void
960wg_algo_kdf(uint8_t out1[WG_KDF_OUTPUT_LEN], uint8_t out2[WG_KDF_OUTPUT_LEN], 960wg_algo_kdf(uint8_t out1[WG_KDF_OUTPUT_LEN], uint8_t out2[WG_KDF_OUTPUT_LEN],
961 uint8_t out3[WG_KDF_OUTPUT_LEN], const uint8_t ckey[WG_CHAINING_KEY_LEN], 961 uint8_t out3[WG_KDF_OUTPUT_LEN], const uint8_t ckey[WG_CHAINING_KEY_LEN],
962 const uint8_t input[], const size_t inputlen) 962 const uint8_t input[], const size_t inputlen)
963{ 963{
964 uint8_t tmp1[WG_KDF_OUTPUT_LEN], tmp2[WG_KDF_OUTPUT_LEN + 1]; 964 uint8_t tmp1[WG_KDF_OUTPUT_LEN], tmp2[WG_KDF_OUTPUT_LEN + 1];
965 uint8_t one[1]; 965 uint8_t one[1];
966 966
967 /* 967 /*
968 * [N] 4.3: "an input_key_material byte sequence with length 968 * [N] 4.3: "an input_key_material byte sequence with length
969 * either zero bytes, 32 bytes, or DHLEN bytes." 969 * either zero bytes, 32 bytes, or DHLEN bytes."
970 */ 970 */
971 KASSERT(inputlen == 0 || inputlen == 32 || inputlen == NOISE_DHLEN); 971 KASSERT(inputlen == 0 || inputlen == 32 || inputlen == NOISE_DHLEN);
972 972
973 WG_DUMP_HASH("ckey", ckey); 973 WG_DUMP_HASH("ckey", ckey);
974 if (input != NULL) 974 if (input != NULL)
975 WG_DUMP_HASH("input", input); 975 WG_DUMP_HASH("input", input);
976 wg_algo_hmac(tmp1, sizeof(tmp1), ckey, WG_CHAINING_KEY_LEN, 976 wg_algo_hmac(tmp1, sizeof(tmp1), ckey, WG_CHAINING_KEY_LEN,
977 input, inputlen); 977 input, inputlen);
978 WG_DUMP_HASH("tmp1", tmp1); 978 WG_DUMP_HASH("tmp1", tmp1);
979 one[0] = 1; 979 one[0] = 1;
980 wg_algo_hmac(out1, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 980 wg_algo_hmac(out1, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
981 one, sizeof(one)); 981 one, sizeof(one));
982 WG_DUMP_HASH("out1", out1); 982 WG_DUMP_HASH("out1", out1);
983 if (out2 == NULL) 983 if (out2 == NULL)
984 return; 984 return;
985 memcpy(tmp2, out1, WG_KDF_OUTPUT_LEN); 985 memcpy(tmp2, out1, WG_KDF_OUTPUT_LEN);
986 tmp2[WG_KDF_OUTPUT_LEN] = 2; 986 tmp2[WG_KDF_OUTPUT_LEN] = 2;
987 wg_algo_hmac(out2, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 987 wg_algo_hmac(out2, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
988 tmp2, sizeof(tmp2)); 988 tmp2, sizeof(tmp2));
989 WG_DUMP_HASH("out2", out2); 989 WG_DUMP_HASH("out2", out2);
990 if (out3 == NULL) 990 if (out3 == NULL)
991 return; 991 return;
992 memcpy(tmp2, out2, WG_KDF_OUTPUT_LEN); 992 memcpy(tmp2, out2, WG_KDF_OUTPUT_LEN);
993 tmp2[WG_KDF_OUTPUT_LEN] = 3; 993 tmp2[WG_KDF_OUTPUT_LEN] = 3;
994 wg_algo_hmac(out3, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 994 wg_algo_hmac(out3, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1),
995 tmp2, sizeof(tmp2)); 995 tmp2, sizeof(tmp2));
996 WG_DUMP_HASH("out3", out3); 996 WG_DUMP_HASH("out3", out3);
997} 997}
998 998
999static void 999static void
1000wg_algo_dh_kdf(uint8_t ckey[WG_CHAINING_KEY_LEN], 1000wg_algo_dh_kdf(uint8_t ckey[WG_CHAINING_KEY_LEN],
1001 uint8_t cipher_key[WG_CIPHER_KEY_LEN], 1001 uint8_t cipher_key[WG_CIPHER_KEY_LEN],
1002 const uint8_t local_key[WG_STATIC_KEY_LEN], 1002 const uint8_t local_key[WG_STATIC_KEY_LEN],
1003 const uint8_t remote_key[WG_STATIC_KEY_LEN]) 1003 const uint8_t remote_key[WG_STATIC_KEY_LEN])
1004{ 1004{
1005 uint8_t dhout[WG_DH_OUTPUT_LEN]; 1005 uint8_t dhout[WG_DH_OUTPUT_LEN];
1006 1006
1007 wg_algo_dh(dhout, local_key, remote_key); 1007 wg_algo_dh(dhout, local_key, remote_key);
1008 wg_algo_kdf(ckey, cipher_key, NULL, ckey, dhout, sizeof(dhout)); 1008 wg_algo_kdf(ckey, cipher_key, NULL, ckey, dhout, sizeof(dhout));
1009 1009
1010 WG_DUMP_HASH("dhout", dhout); 1010 WG_DUMP_HASH("dhout", dhout);
1011 WG_DUMP_HASH("ckey", ckey); 1011 WG_DUMP_HASH("ckey", ckey);
1012 if (cipher_key != NULL) 1012 if (cipher_key != NULL)
1013 WG_DUMP_HASH("cipher_key", cipher_key); 1013 WG_DUMP_HASH("cipher_key", cipher_key);
1014} 1014}
1015 1015
1016static void 1016static void
1017wg_algo_aead_enc(uint8_t out[], size_t expected_outsize, const uint8_t key[], 1017wg_algo_aead_enc(uint8_t out[], size_t expected_outsize, const uint8_t key[],
1018 const uint64_t counter, const uint8_t plain[], const size_t plainsize, 1018 const uint64_t counter, const uint8_t plain[], const size_t plainsize,
1019 const uint8_t auth[], size_t authlen) 1019 const uint8_t auth[], size_t authlen)
1020{ 1020{
1021 uint8_t nonce[(32 + 64) / 8] = {0}; 1021 uint8_t nonce[(32 + 64) / 8] = {0};
1022 long long unsigned int outsize; 1022 long long unsigned int outsize;
1023 int error __diagused; 1023 int error __diagused;
1024 1024
1025 memcpy(&nonce[4], &counter, sizeof(counter)); 1025 memcpy(&nonce[4], &counter, sizeof(counter));
1026 1026
1027 error = crypto_aead_chacha20poly1305_ietf_encrypt(out, &outsize, plain, 1027 error = crypto_aead_chacha20poly1305_ietf_encrypt(out, &outsize, plain,
1028 plainsize, auth, authlen, NULL, nonce, key); 1028 plainsize, auth, authlen, NULL, nonce, key);
1029 KASSERT(error == 0); 1029 KASSERT(error == 0);
1030 KASSERT(outsize == expected_outsize); 1030 KASSERT(outsize == expected_outsize);
1031} 1031}
1032 1032
1033static int 1033static int
1034wg_algo_aead_dec(uint8_t out[], size_t expected_outsize, const uint8_t key[], 1034wg_algo_aead_dec(uint8_t out[], size_t expected_outsize, const uint8_t key[],
1035 const uint64_t counter, const uint8_t encrypted[], 1035 const uint64_t counter, const uint8_t encrypted[],
1036 const size_t encryptedsize, const uint8_t auth[], size_t authlen) 1036 const size_t encryptedsize, const uint8_t auth[], size_t authlen)
1037{ 1037{
1038 uint8_t nonce[(32 + 64) / 8] = {0}; 1038 uint8_t nonce[(32 + 64) / 8] = {0};
1039 long long unsigned int outsize; 1039 long long unsigned int outsize;
1040 int error; 1040 int error;
1041 1041
1042 memcpy(&nonce[4], &counter, sizeof(counter)); 1042 memcpy(&nonce[4], &counter, sizeof(counter));
1043 1043
@@ -1959,1998 +1959,2003 @@ wg_fill_msg_cookie(struct wg_softc *wg,  @@ -1959,1998 +1959,2003 @@ wg_fill_msg_cookie(struct wg_softc *wg,
1959 break; 1959 break;
1960 } 1960 }
1961#endif 1961#endif
1962 default: 1962 default:
1963 panic("invalid af=%d", wgp->wgp_sa.sa_family); 1963 panic("invalid af=%d", wgp->wgp_sa.sa_family);
1964 } 1964 }
1965 1965
1966 wg_algo_mac(cookie, sizeof(cookie), 1966 wg_algo_mac(cookie, sizeof(cookie),
1967 (const uint8_t *)&wgp->wgp_randval, sizeof(wgp->wgp_randval), 1967 (const uint8_t *)&wgp->wgp_randval, sizeof(wgp->wgp_randval),
1968 addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport)); 1968 addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport));
1969 wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey, 1969 wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey,
1970 sizeof(wg->wg_pubkey)); 1970 sizeof(wg->wg_pubkey));
1971 wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key, 1971 wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key,
1972 cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt); 1972 cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt);
1973 1973
1974 /* Need to store to calculate mac2 */ 1974 /* Need to store to calculate mac2 */
1975 memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie)); 1975 memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie));
1976 wgp->wgp_last_sent_cookie_valid = true; 1976 wgp->wgp_last_sent_cookie_valid = true;
1977} 1977}
1978 1978
1979static int 1979static int
1980wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp, 1980wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp,
1981 const uint32_t sender, const uint8_t mac1[WG_MAC_LEN], 1981 const uint32_t sender, const uint8_t mac1[WG_MAC_LEN],
1982 const struct sockaddr *src) 1982 const struct sockaddr *src)
1983{ 1983{
1984 int error; 1984 int error;
1985 struct mbuf *m; 1985 struct mbuf *m;
1986 struct wg_msg_cookie *wgmc; 1986 struct wg_msg_cookie *wgmc;
1987 1987
1988 m = m_gethdr(M_WAIT, MT_DATA); 1988 m = m_gethdr(M_WAIT, MT_DATA);
1989 m->m_pkthdr.len = m->m_len = sizeof(*wgmc); 1989 m->m_pkthdr.len = m->m_len = sizeof(*wgmc);
1990 wgmc = mtod(m, struct wg_msg_cookie *); 1990 wgmc = mtod(m, struct wg_msg_cookie *);
1991 wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src); 1991 wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src);
1992 1992
1993 error = wg->wg_ops->send_hs_msg(wgp, m); 1993 error = wg->wg_ops->send_hs_msg(wgp, m);
1994 if (error == 0) 1994 if (error == 0)
1995 WG_TRACE("cookie msg sent"); 1995 WG_TRACE("cookie msg sent");
1996 return error; 1996 return error;
1997} 1997}
1998 1998
1999static bool 1999static bool
2000wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype) 2000wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype)
2001{ 2001{
2002#ifdef WG_DEBUG_PARAMS 2002#ifdef WG_DEBUG_PARAMS
2003 if (wg_force_underload) 2003 if (wg_force_underload)
2004 return true; 2004 return true;
2005#endif 2005#endif
2006 2006
2007 /* 2007 /*
2008 * XXX we don't have a means of a load estimation. The purpose of 2008 * XXX we don't have a means of a load estimation. The purpose of
2009 * the mechanism is a DoS mitigation, so we consider frequent handshake 2009 * the mechanism is a DoS mitigation, so we consider frequent handshake
2010 * messages as (a kind of) load; if a message of the same type comes 2010 * messages as (a kind of) load; if a message of the same type comes
2011 * to a peer within 1 second, we consider we are under load. 2011 * to a peer within 1 second, we consider we are under load.
2012 */ 2012 */
2013 time_t last = wgp->wgp_last_msg_received_time[msgtype]; 2013 time_t last = wgp->wgp_last_msg_received_time[msgtype];
2014 wgp->wgp_last_msg_received_time[msgtype] = time_uptime; 2014 wgp->wgp_last_msg_received_time[msgtype] = time_uptime;
2015 return (time_uptime - last) == 0; 2015 return (time_uptime - last) == 0;
2016} 2016}
2017 2017
2018static void 2018static void
2019wg_calculate_keys(struct wg_session *wgs, const bool initiator) 2019wg_calculate_keys(struct wg_session *wgs, const bool initiator)
2020{ 2020{
2021 2021
2022 /* 2022 /*
2023 * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e) 2023 * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e)
2024 */ 2024 */
2025 if (initiator) { 2025 if (initiator) {
2026 wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL, 2026 wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL,
2027 wgs->wgs_chaining_key, NULL, 0); 2027 wgs->wgs_chaining_key, NULL, 0);
2028 } else { 2028 } else {
2029 wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL, 2029 wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL,
2030 wgs->wgs_chaining_key, NULL, 0); 2030 wgs->wgs_chaining_key, NULL, 0);
2031 } 2031 }
2032 WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send); 2032 WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send);
2033 WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv); 2033 WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv);
2034} 2034}
2035 2035
2036static uint64_t 2036static uint64_t
2037wg_session_get_send_counter(struct wg_session *wgs) 2037wg_session_get_send_counter(struct wg_session *wgs)
2038{ 2038{
2039#ifdef __HAVE_ATOMIC64_LOADSTORE 2039#ifdef __HAVE_ATOMIC64_LOADSTORE
2040 return atomic_load_relaxed(&wgs->wgs_send_counter); 2040 return atomic_load_relaxed(&wgs->wgs_send_counter);
2041#else 2041#else
2042 uint64_t send_counter; 2042 uint64_t send_counter;
2043 2043
2044 mutex_enter(&wgs->wgs_send_counter_lock); 2044 mutex_enter(&wgs->wgs_send_counter_lock);
2045 send_counter = wgs->wgs_send_counter; 2045 send_counter = wgs->wgs_send_counter;
2046 mutex_exit(&wgs->wgs_send_counter_lock); 2046 mutex_exit(&wgs->wgs_send_counter_lock);
2047 2047
2048 return send_counter; 2048 return send_counter;
2049#endif 2049#endif
2050} 2050}
2051 2051
2052static uint64_t 2052static uint64_t
2053wg_session_inc_send_counter(struct wg_session *wgs) 2053wg_session_inc_send_counter(struct wg_session *wgs)
2054{ 2054{
2055#ifdef __HAVE_ATOMIC64_LOADSTORE 2055#ifdef __HAVE_ATOMIC64_LOADSTORE
2056 return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1; 2056 return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1;
2057#else 2057#else
2058 uint64_t send_counter; 2058 uint64_t send_counter;
2059 2059
2060 mutex_enter(&wgs->wgs_send_counter_lock); 2060 mutex_enter(&wgs->wgs_send_counter_lock);
2061 send_counter = wgs->wgs_send_counter++; 2061 send_counter = wgs->wgs_send_counter++;
2062 mutex_exit(&wgs->wgs_send_counter_lock); 2062 mutex_exit(&wgs->wgs_send_counter_lock);
2063 2063
2064 return send_counter; 2064 return send_counter;
2065#endif 2065#endif
2066} 2066}
2067 2067
2068static void 2068static void
2069wg_clear_states(struct wg_session *wgs) 2069wg_clear_states(struct wg_session *wgs)
2070{ 2070{
2071 2071
2072 wgs->wgs_send_counter = 0; 2072 wgs->wgs_send_counter = 0;
2073 sliwin_reset(&wgs->wgs_recvwin->window); 2073 sliwin_reset(&wgs->wgs_recvwin->window);
2074 2074
2075#define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v)) 2075#define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v))
2076 wgs_clear(handshake_hash); 2076 wgs_clear(handshake_hash);
2077 wgs_clear(chaining_key); 2077 wgs_clear(chaining_key);
2078 wgs_clear(ephemeral_key_pub); 2078 wgs_clear(ephemeral_key_pub);
2079 wgs_clear(ephemeral_key_priv); 2079 wgs_clear(ephemeral_key_priv);
2080 wgs_clear(ephemeral_key_peer); 2080 wgs_clear(ephemeral_key_peer);
2081#undef wgs_clear 2081#undef wgs_clear
2082} 2082}
2083 2083
2084static struct wg_session * 2084static struct wg_session *
2085wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index, 2085wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index,
2086 struct psref *psref) 2086 struct psref *psref)
2087{ 2087{
2088 struct wg_peer *wgp; 2088 struct wg_peer *wgp;
2089 struct wg_session *wgs; 2089 struct wg_session *wgs;
2090 2090
2091 int s = pserialize_read_enter(); 2091 int s = pserialize_read_enter();
2092 /* XXX O(n) */ 2092 /* XXX O(n) */
2093 WG_PEER_READER_FOREACH(wgp, wg) { 2093 WG_PEER_READER_FOREACH(wgp, wg) {
2094 wgs = wgp->wgp_session_stable; 2094 wgs = wgp->wgp_session_stable;
2095 WG_DLOG("index=%x wgs_sender_index=%x\n", 2095 WG_DLOG("index=%x wgs_sender_index=%x\n",
2096 index, wgs->wgs_sender_index); 2096 index, wgs->wgs_sender_index);
2097 if (wgs->wgs_sender_index == index) 2097 if (wgs->wgs_sender_index == index)
2098 break; 2098 break;
2099 wgs = wgp->wgp_session_unstable; 2099 wgs = wgp->wgp_session_unstable;
2100 WG_DLOG("index=%x wgs_sender_index=%x\n", 2100 WG_DLOG("index=%x wgs_sender_index=%x\n",
2101 index, wgs->wgs_sender_index); 2101 index, wgs->wgs_sender_index);
2102 if (wgs->wgs_sender_index == index) 2102 if (wgs->wgs_sender_index == index)
2103 break; 2103 break;
2104 wgs = NULL; 2104 wgs = NULL;
2105 } 2105 }
2106 if (wgs != NULL) 2106 if (wgs != NULL)
2107 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class); 2107 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class);
2108 pserialize_read_exit(s); 2108 pserialize_read_exit(s);
2109 2109
2110 return wgs; 2110 return wgs;
2111} 2111}
2112 2112
2113static void 2113static void
2114wg_schedule_rekey_timer(struct wg_peer *wgp) 2114wg_schedule_rekey_timer(struct wg_peer *wgp)
2115{ 2115{
2116 int timeout = MIN(wg_rekey_after_time, INT_MAX/hz); 2116 int timeout = MIN(wg_rekey_after_time, INT_MAX/hz);
2117 2117
2118 callout_schedule(&wgp->wgp_rekey_timer, timeout * hz); 2118 callout_schedule(&wgp->wgp_rekey_timer, timeout * hz);
2119} 2119}
2120 2120
2121static void 2121static void
2122wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs) 2122wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs)
2123{ 2123{
2124 struct mbuf *m; 2124 struct mbuf *m;
2125 2125
2126 /* 2126 /*
2127 * [W] 6.5 Passive Keepalive 2127 * [W] 6.5 Passive Keepalive
2128 * "A keepalive message is simply a transport data message with 2128 * "A keepalive message is simply a transport data message with
2129 * a zero-length encapsulated encrypted inner-packet." 2129 * a zero-length encapsulated encrypted inner-packet."
2130 */ 2130 */
2131 m = m_gethdr(M_WAIT, MT_DATA); 2131 m = m_gethdr(M_WAIT, MT_DATA);
2132 wg_send_data_msg(wgp, wgs, m); 2132 wg_send_data_msg(wgp, wgs, m);
2133} 2133}
2134 2134
2135static bool 2135static bool
2136wg_need_to_send_init_message(struct wg_session *wgs) 2136wg_need_to_send_init_message(struct wg_session *wgs)
2137{ 2137{
2138 /* 2138 /*
2139 * [W] 6.2 Transport Message Limits 2139 * [W] 6.2 Transport Message Limits
2140 * "if a peer is the initiator of a current secure session, 2140 * "if a peer is the initiator of a current secure session,
2141 * WireGuard will send a handshake initiation message to begin 2141 * WireGuard will send a handshake initiation message to begin
2142 * a new secure session ... if after receiving a transport data 2142 * a new secure session ... if after receiving a transport data
2143 * message, the current secure session is (REJECT-AFTER-TIME − 2143 * message, the current secure session is (REJECT-AFTER-TIME −
2144 * KEEPALIVE-TIMEOUT − REKEY-TIMEOUT) seconds old and it has 2144 * KEEPALIVE-TIMEOUT − REKEY-TIMEOUT) seconds old and it has
2145 * not yet acted upon this event." 2145 * not yet acted upon this event."
2146 */ 2146 */
2147 return wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0 && 2147 return wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0 &&
2148 (time_uptime - wgs->wgs_time_established) >= 2148 (time_uptime - wgs->wgs_time_established) >=
2149 (wg_reject_after_time - wg_keepalive_timeout - wg_rekey_timeout); 2149 (wg_reject_after_time - wg_keepalive_timeout - wg_rekey_timeout);
2150} 2150}
2151 2151
2152static void 2152static void
2153wg_schedule_peer_task(struct wg_peer *wgp, int task) 2153wg_schedule_peer_task(struct wg_peer *wgp, int task)
2154{ 2154{
2155 2155
2156 atomic_or_uint(&wgp->wgp_tasks, task); 2156 atomic_or_uint(&wgp->wgp_tasks, task);
2157 WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task); 2157 WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task);
2158 wg_wakeup_worker(wgp->wgp_sc->wg_worker, WG_WAKEUP_REASON_PEER); 2158 wg_wakeup_worker(wgp->wgp_sc->wg_worker, WG_WAKEUP_REASON_PEER);
2159} 2159}
2160 2160
2161static void 2161static void
2162wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new) 2162wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new)
2163{ 2163{
2164 2164
2165 KASSERT(mutex_owned(wgp->wgp_lock)); 2165 KASSERT(mutex_owned(wgp->wgp_lock));
2166 2166
2167 WG_TRACE("Changing endpoint"); 2167 WG_TRACE("Changing endpoint");
2168 2168
2169 memcpy(wgp->wgp_endpoint0, new, new->sa_len); 2169 memcpy(wgp->wgp_endpoint0, new, new->sa_len);
2170 wgp->wgp_endpoint0 = atomic_swap_ptr(&wgp->wgp_endpoint, 2170 wgp->wgp_endpoint0 = atomic_swap_ptr(&wgp->wgp_endpoint,
2171 wgp->wgp_endpoint0); 2171 wgp->wgp_endpoint0);
2172 if (!wgp->wgp_endpoint_available) 2172 if (!wgp->wgp_endpoint_available)
2173 wgp->wgp_endpoint_available = true; 2173 wgp->wgp_endpoint_available = true;
2174 wgp->wgp_endpoint_changing = true; 2174 wgp->wgp_endpoint_changing = true;
2175 wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED); 2175 wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED);
2176} 2176}
2177 2177
2178static bool 2178static bool
2179wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af) 2179wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af)
2180{ 2180{
2181 uint16_t packet_len; 2181 uint16_t packet_len;
2182 const struct ip *ip; 2182 const struct ip *ip;
2183 2183
2184 if (__predict_false(decrypted_len < sizeof(struct ip))) 2184 if (__predict_false(decrypted_len < sizeof(struct ip)))
2185 return false; 2185 return false;
2186 2186
2187 ip = (const struct ip *)packet; 2187 ip = (const struct ip *)packet;
2188 if (ip->ip_v == 4) 2188 if (ip->ip_v == 4)
2189 *af = AF_INET; 2189 *af = AF_INET;
2190 else if (ip->ip_v == 6) 2190 else if (ip->ip_v == 6)
2191 *af = AF_INET6; 2191 *af = AF_INET6;
2192 else 2192 else
2193 return false; 2193 return false;
2194 2194
2195 WG_DLOG("af=%d\n", *af); 2195 WG_DLOG("af=%d\n", *af);
2196 2196
2197 if (*af == AF_INET) { 2197 if (*af == AF_INET) {
2198 packet_len = ntohs(ip->ip_len); 2198 packet_len = ntohs(ip->ip_len);
2199 } else { 2199 } else {
2200 const struct ip6_hdr *ip6; 2200 const struct ip6_hdr *ip6;
2201 2201
2202 if (__predict_false(decrypted_len < sizeof(struct ip6_hdr))) 2202 if (__predict_false(decrypted_len < sizeof(struct ip6_hdr)))
2203 return false; 2203 return false;
2204 2204
2205 ip6 = (const struct ip6_hdr *)packet; 2205 ip6 = (const struct ip6_hdr *)packet;
2206 packet_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen); 2206 packet_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
2207 } 2207 }
2208 2208
2209 WG_DLOG("packet_len=%u\n", packet_len); 2209 WG_DLOG("packet_len=%u\n", packet_len);
2210 if (packet_len > decrypted_len) 2210 if (packet_len > decrypted_len)
2211 return false; 2211 return false;
2212 2212
2213 return true; 2213 return true;
2214} 2214}
2215 2215
2216static bool 2216static bool
2217wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected, 2217wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected,
2218 int af, char *packet) 2218 int af, char *packet)
2219{ 2219{
2220 struct sockaddr_storage ss; 2220 struct sockaddr_storage ss;
2221 struct sockaddr *sa; 2221 struct sockaddr *sa;
2222 struct psref psref; 2222 struct psref psref;
2223 struct wg_peer *wgp; 2223 struct wg_peer *wgp;
2224 bool ok; 2224 bool ok;
2225 2225
2226 /* 2226 /*
2227 * II CRYPTOKEY ROUTING 2227 * II CRYPTOKEY ROUTING
2228 * "it will only accept it if its source IP resolves in the 2228 * "it will only accept it if its source IP resolves in the
2229 * table to the public key used in the secure session for 2229 * table to the public key used in the secure session for
2230 * decrypting it." 2230 * decrypting it."
2231 */ 2231 */
2232 2232
2233 if (af == AF_INET) { 2233 if (af == AF_INET) {
2234 const struct ip *ip = (const struct ip *)packet; 2234 const struct ip *ip = (const struct ip *)packet;
2235 struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 2235 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
2236 sockaddr_in_init(sin, &ip->ip_src, 0); 2236 sockaddr_in_init(sin, &ip->ip_src, 0);
2237 sa = sintosa(sin); 2237 sa = sintosa(sin);
2238#ifdef INET6 2238#ifdef INET6
2239 } else { 2239 } else {
2240 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet; 2240 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet;
2241 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 2241 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
2242 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0); 2242 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0);
2243 sa = sin6tosa(sin6); 2243 sa = sin6tosa(sin6);
2244#endif 2244#endif
2245 } 2245 }
2246 2246
2247 wgp = wg_pick_peer_by_sa(wg, sa, &psref); 2247 wgp = wg_pick_peer_by_sa(wg, sa, &psref);
2248 ok = (wgp == wgp_expected); 2248 ok = (wgp == wgp_expected);
2249 if (wgp != NULL) 2249 if (wgp != NULL)
2250 wg_put_peer(wgp, &psref); 2250 wg_put_peer(wgp, &psref);
2251 2251
2252 return ok; 2252 return ok;
2253} 2253}
2254 2254
2255static void 2255static void
2256wg_session_dtor_timer(void *arg) 2256wg_session_dtor_timer(void *arg)
2257{ 2257{
2258 struct wg_peer *wgp = arg; 2258 struct wg_peer *wgp = arg;
2259 2259
2260 WG_TRACE("enter"); 2260 WG_TRACE("enter");
2261 2261
2262 mutex_enter(wgp->wgp_lock); 2262 mutex_enter(wgp->wgp_lock);
2263 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) { 2263 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
2264 mutex_exit(wgp->wgp_lock); 2264 mutex_exit(wgp->wgp_lock);
2265 return; 2265 return;
2266 } 2266 }
2267 mutex_exit(wgp->wgp_lock); 2267 mutex_exit(wgp->wgp_lock);
2268 2268
2269 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION); 2269 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION);
2270} 2270}
2271 2271
2272static void 2272static void
2273wg_schedule_session_dtor_timer(struct wg_peer *wgp) 2273wg_schedule_session_dtor_timer(struct wg_peer *wgp)
2274{ 2274{
2275 2275
2276 /* 1 second grace period */ 2276 /* 1 second grace period */
2277 callout_schedule(&wgp->wgp_session_dtor_timer, hz); 2277 callout_schedule(&wgp->wgp_session_dtor_timer, hz);
2278} 2278}
2279 2279
2280static void 2280static void
2281wg_stop_session_dtor_timer(struct wg_peer *wgp) 2281wg_stop_session_dtor_timer(struct wg_peer *wgp)
2282{ 2282{
2283 2283
2284 callout_halt(&wgp->wgp_session_dtor_timer, NULL); 2284 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
2285} 2285}
2286 2286
2287static bool 2287static bool
2288sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2) 2288sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2)
2289{ 2289{
2290 if (sa1->sa_family != sa2->sa_family) 2290 if (sa1->sa_family != sa2->sa_family)
2291 return false; 2291 return false;
2292 2292
2293 switch (sa1->sa_family) { 2293 switch (sa1->sa_family) {
2294 case AF_INET: 2294 case AF_INET:
2295 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port; 2295 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port;
2296 case AF_INET6: 2296 case AF_INET6:
2297 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port; 2297 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port;
2298 default: 2298 default:
2299 return true; 2299 return true;
2300 } 2300 }
2301} 2301}
2302 2302
2303static void 2303static void
2304wg_update_endpoint_if_necessary(struct wg_peer *wgp, 2304wg_update_endpoint_if_necessary(struct wg_peer *wgp,
2305 const struct sockaddr *src) 2305 const struct sockaddr *src)
2306{ 2306{
2307 2307
2308#ifdef WG_DEBUG_LOG 2308#ifdef WG_DEBUG_LOG
2309 char oldaddr[128], newaddr[128]; 2309 char oldaddr[128], newaddr[128];
2310 sockaddr_format(&wgp->wgp_sa, oldaddr, sizeof(oldaddr)); 2310 sockaddr_format(&wgp->wgp_sa, oldaddr, sizeof(oldaddr));
2311 sockaddr_format(src, newaddr, sizeof(newaddr)); 2311 sockaddr_format(src, newaddr, sizeof(newaddr));
2312 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr); 2312 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr);
2313#endif 2313#endif
2314 2314
2315 /* 2315 /*
2316 * III: "Since the packet has authenticated correctly, the source IP of 2316 * III: "Since the packet has authenticated correctly, the source IP of
2317 * the outer UDP/IP packet is used to update the endpoint for peer..." 2317 * the outer UDP/IP packet is used to update the endpoint for peer..."
2318 */ 2318 */
2319 if (__predict_false(sockaddr_cmp(src, &wgp->wgp_sa) != 0 || 2319 if (__predict_false(sockaddr_cmp(src, &wgp->wgp_sa) != 0 ||
2320 !sockaddr_port_match(src, &wgp->wgp_sa))) { 2320 !sockaddr_port_match(src, &wgp->wgp_sa))) {
2321 mutex_enter(wgp->wgp_lock); 2321 mutex_enter(wgp->wgp_lock);
2322 /* XXX We can't change the endpoint twice in a short period */ 2322 /* XXX We can't change the endpoint twice in a short period */
2323 if (!wgp->wgp_endpoint_changing) { 2323 if (!wgp->wgp_endpoint_changing) {
2324 wg_change_endpoint(wgp, src); 2324 wg_change_endpoint(wgp, src);
2325 } 2325 }
2326 mutex_exit(wgp->wgp_lock); 2326 mutex_exit(wgp->wgp_lock);
2327 } 2327 }
2328} 2328}
2329 2329
2330static void 2330static void
2331wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m, 2331wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m,
2332 const struct sockaddr *src) 2332 const struct sockaddr *src)
2333{ 2333{
2334 struct wg_msg_data *wgmd; 2334 struct wg_msg_data *wgmd;
2335 char *encrypted_buf = NULL, *decrypted_buf; 2335 char *encrypted_buf = NULL, *decrypted_buf;
2336 size_t encrypted_len, decrypted_len; 2336 size_t encrypted_len, decrypted_len;
2337 struct wg_session *wgs; 2337 struct wg_session *wgs;
2338 struct wg_peer *wgp; 2338 struct wg_peer *wgp;
2339 size_t mlen; 2339 size_t mlen;
2340 struct psref psref; 2340 struct psref psref;
2341 int error, af; 2341 int error, af;
2342 bool success, free_encrypted_buf = false, ok; 2342 bool success, free_encrypted_buf = false, ok;
2343 struct mbuf *n; 2343 struct mbuf *n;
2344 2344
2345 KASSERT(m->m_len >= sizeof(struct wg_msg_data)); 2345 KASSERT(m->m_len >= sizeof(struct wg_msg_data));
2346 wgmd = mtod(m, struct wg_msg_data *); 2346 wgmd = mtod(m, struct wg_msg_data *);
2347 2347
2348 KASSERT(wgmd->wgmd_type == WG_MSG_TYPE_DATA); 2348 KASSERT(wgmd->wgmd_type == WG_MSG_TYPE_DATA);
2349 WG_TRACE("data"); 2349 WG_TRACE("data");
2350 2350
2351 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref); 2351 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref);
2352 if (wgs == NULL) { 2352 if (wgs == NULL) {
2353 WG_TRACE("No session found"); 2353 WG_TRACE("No session found");
2354 m_freem(m); 2354 m_freem(m);
2355 return; 2355 return;
2356 } 2356 }
2357 wgp = wgs->wgs_peer; 2357 wgp = wgs->wgs_peer;
2358 2358
2359 error = sliwin_check_fast(&wgs->wgs_recvwin->window, 2359 error = sliwin_check_fast(&wgs->wgs_recvwin->window,
2360 wgmd->wgmd_counter); 2360 wgmd->wgmd_counter);
2361 if (error) { 2361 if (error) {
2362 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2362 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2363 "out-of-window packet: %"PRIu64"\n", 2363 "out-of-window packet: %"PRIu64"\n",
2364 wgmd->wgmd_counter); 2364 wgmd->wgmd_counter);
2365 goto out; 2365 goto out;
2366 } 2366 }
2367 2367
2368 mlen = m_length(m); 2368 mlen = m_length(m);
2369 encrypted_len = mlen - sizeof(*wgmd); 2369 encrypted_len = mlen - sizeof(*wgmd);
2370 2370
2371 if (encrypted_len < WG_AUTHTAG_LEN) { 2371 if (encrypted_len < WG_AUTHTAG_LEN) {
2372 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len); 2372 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len);
2373 goto out; 2373 goto out;
2374 } 2374 }
2375 2375
2376 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len); 2376 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len);
2377 if (success) { 2377 if (success) {
2378 encrypted_buf = mtod(m, char *) + sizeof(*wgmd); 2378 encrypted_buf = mtod(m, char *) + sizeof(*wgmd);
2379 } else { 2379 } else {
2380 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP); 2380 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP);
2381 if (encrypted_buf == NULL) { 2381 if (encrypted_buf == NULL) {
2382 WG_DLOG("failed to allocate encrypted_buf\n"); 2382 WG_DLOG("failed to allocate encrypted_buf\n");
2383 goto out; 2383 goto out;
2384 } 2384 }
2385 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf); 2385 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf);
2386 free_encrypted_buf = true; 2386 free_encrypted_buf = true;
2387 } 2387 }
2388 /* m_ensure_contig may change m regardless of its result */ 2388 /* m_ensure_contig may change m regardless of its result */
2389 KASSERT(m->m_len >= sizeof(*wgmd)); 2389 KASSERT(m->m_len >= sizeof(*wgmd));
2390 wgmd = mtod(m, struct wg_msg_data *); 2390 wgmd = mtod(m, struct wg_msg_data *);
2391 2391
2392 decrypted_len = encrypted_len - WG_AUTHTAG_LEN; 2392 decrypted_len = encrypted_len - WG_AUTHTAG_LEN;
2393 if (decrypted_len > MCLBYTES) { 2393 if (decrypted_len > MCLBYTES) {
2394 /* FIXME handle larger data than MCLBYTES */ 2394 /* FIXME handle larger data than MCLBYTES */
2395 WG_DLOG("couldn't handle larger data than MCLBYTES\n"); 2395 WG_DLOG("couldn't handle larger data than MCLBYTES\n");
2396 goto out; 2396 goto out;
2397 } 2397 }
2398 2398
2399 /* To avoid zero length */ 2399 /* To avoid zero length */
2400 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN); 2400 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN);
2401 if (n == NULL) { 2401 if (n == NULL) {
2402 WG_DLOG("wg_get_mbuf failed\n"); 2402 WG_DLOG("wg_get_mbuf failed\n");
2403 goto out; 2403 goto out;
2404 } 2404 }
2405 decrypted_buf = mtod(n, char *); 2405 decrypted_buf = mtod(n, char *);
2406 2406
2407 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len); 2407 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len);
2408 error = wg_algo_aead_dec(decrypted_buf, 2408 error = wg_algo_aead_dec(decrypted_buf,
2409 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */, 2409 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */,
2410 wgs->wgs_tkey_recv, wgmd->wgmd_counter, encrypted_buf, 2410 wgs->wgs_tkey_recv, wgmd->wgmd_counter, encrypted_buf,
2411 encrypted_len, NULL, 0); 2411 encrypted_len, NULL, 0);
2412 if (error != 0) { 2412 if (error != 0) {
2413 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2413 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2414 "failed to wg_algo_aead_dec\n"); 2414 "failed to wg_algo_aead_dec\n");
2415 m_freem(n); 2415 m_freem(n);
2416 goto out; 2416 goto out;
2417 } 2417 }
2418 WG_DLOG("outsize=%u\n", (u_int)decrypted_len); 2418 WG_DLOG("outsize=%u\n", (u_int)decrypted_len);
2419 2419
2420 mutex_enter(&wgs->wgs_recvwin->lock); 2420 mutex_enter(&wgs->wgs_recvwin->lock);
2421 error = sliwin_update(&wgs->wgs_recvwin->window, 2421 error = sliwin_update(&wgs->wgs_recvwin->window,
2422 wgmd->wgmd_counter); 2422 wgmd->wgmd_counter);
2423 mutex_exit(&wgs->wgs_recvwin->lock); 2423 mutex_exit(&wgs->wgs_recvwin->lock);
2424 if (error) { 2424 if (error) {
2425 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2425 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2426 "replay or out-of-window packet: %"PRIu64"\n", 2426 "replay or out-of-window packet: %"PRIu64"\n",
2427 wgmd->wgmd_counter); 2427 wgmd->wgmd_counter);
2428 m_freem(n); 2428 m_freem(n);
2429 goto out; 2429 goto out;
2430 } 2430 }
2431 2431
2432 m_freem(m); 2432 m_freem(m);
2433 m = NULL; 2433 m = NULL;
2434 wgmd = NULL; 2434 wgmd = NULL;
2435 2435
2436 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af); 2436 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af);
2437 if (!ok) { 2437 if (!ok) {
2438 /* something wrong... */ 2438 /* something wrong... */
2439 m_freem(n); 2439 m_freem(n);
2440 goto out; 2440 goto out;
2441 } 2441 }
2442 2442
2443 wg_update_endpoint_if_necessary(wgp, src); 2443 wg_update_endpoint_if_necessary(wgp, src);
2444 2444
2445 ok = wg_validate_route(wg, wgp, af, decrypted_buf); 2445 ok = wg_validate_route(wg, wgp, af, decrypted_buf);
2446 if (ok) { 2446 if (ok) {
2447 wg->wg_ops->input(&wg->wg_if, n, af); 2447 wg->wg_ops->input(&wg->wg_if, n, af);
2448 } else { 2448 } else {
2449 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2449 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2450 "invalid source address\n"); 2450 "invalid source address\n");
2451 m_freem(n); 2451 m_freem(n);
2452 /* 2452 /*
2453 * The inner address is invalid however the session is valid 2453 * The inner address is invalid however the session is valid
2454 * so continue the session processing below. 2454 * so continue the session processing below.
2455 */ 2455 */
2456 } 2456 }
2457 n = NULL; 2457 n = NULL;
2458 2458
2459 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) { 2459 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) {
2460 struct wg_session *wgs_prev; 2460 struct wg_session *wgs_prev;
2461 2461
2462 KASSERT(wgs == wgp->wgp_session_unstable); 2462 KASSERT(wgs == wgp->wgp_session_unstable);
2463 wgs->wgs_state = WGS_STATE_ESTABLISHED; 2463 wgs->wgs_state = WGS_STATE_ESTABLISHED;
2464 wgs->wgs_time_established = time_uptime; 2464 wgs->wgs_time_established = time_uptime;
2465 wgs->wgs_time_last_data_sent = 0; 2465 wgs->wgs_time_last_data_sent = 0;
2466 wgs->wgs_is_initiator = false; 2466 wgs->wgs_is_initiator = false;
2467 WG_TRACE("WGS_STATE_ESTABLISHED"); 2467 WG_TRACE("WGS_STATE_ESTABLISHED");
2468 2468
2469 mutex_enter(wgp->wgp_lock); 2469 mutex_enter(wgp->wgp_lock);
2470 wg_swap_sessions(wgp); 2470 wg_swap_sessions(wgp);
2471 wgs_prev = wgp->wgp_session_unstable; 2471 wgs_prev = wgp->wgp_session_unstable;
2472 mutex_enter(wgs_prev->wgs_lock); 2472 mutex_enter(wgs_prev->wgs_lock);
2473 getnanotime(&wgp->wgp_last_handshake_time); 2473 getnanotime(&wgp->wgp_last_handshake_time);
2474 wgp->wgp_handshake_start_time = 0; 2474 wgp->wgp_handshake_start_time = 0;
2475 wgp->wgp_last_sent_mac1_valid = false; 2475 wgp->wgp_last_sent_mac1_valid = false;
2476 wgp->wgp_last_sent_cookie_valid = false; 2476 wgp->wgp_last_sent_cookie_valid = false;
2477 mutex_exit(wgp->wgp_lock); 2477 mutex_exit(wgp->wgp_lock);
2478 2478
2479 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) { 2479 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) {
2480 wgs_prev->wgs_state = WGS_STATE_DESTROYING; 2480 wgs_prev->wgs_state = WGS_STATE_DESTROYING;
2481 /* We can't destroy the old session immediately */ 2481 /* We can't destroy the old session immediately */
2482 wg_schedule_session_dtor_timer(wgp); 2482 wg_schedule_session_dtor_timer(wgp);
2483 } else { 2483 } else {
2484 wg_clear_states(wgs_prev); 2484 wg_clear_states(wgs_prev);
2485 wgs_prev->wgs_state = WGS_STATE_UNKNOWN; 2485 wgs_prev->wgs_state = WGS_STATE_UNKNOWN;
2486 } 2486 }
2487 mutex_exit(wgs_prev->wgs_lock); 2487 mutex_exit(wgs_prev->wgs_lock);
2488 2488
2489 /* Anyway run a softint to flush pending packets */ 2489 /* Anyway run a softint to flush pending packets */
2490 kpreempt_disable(); 2490 kpreempt_disable();
2491 softint_schedule(wgp->wgp_si); 2491 softint_schedule(wgp->wgp_si);
2492 kpreempt_enable(); 2492 kpreempt_enable();
2493 } else { 2493 } else {
2494 if (__predict_false(wg_need_to_send_init_message(wgs))) { 2494 if (__predict_false(wg_need_to_send_init_message(wgs))) {
2495 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 2495 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2496 } 2496 }
2497 /* 2497 /*
2498 * [W] 6.5 Passive Keepalive 2498 * [W] 6.5 Passive Keepalive
2499 * "If a peer has received a validly-authenticated transport 2499 * "If a peer has received a validly-authenticated transport
2500 * data message (section 5.4.6), but does not have any packets 2500 * data message (section 5.4.6), but does not have any packets
2501 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends 2501 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends
2502 * a keepalive message." 2502 * a keepalive message."
2503 */ 2503 */
2504 WG_DLOG("time_uptime=%lu wgs_time_last_data_sent=%lu\n", 2504 WG_DLOG("time_uptime=%lu wgs_time_last_data_sent=%lu\n",
2505 time_uptime, wgs->wgs_time_last_data_sent); 2505 time_uptime, wgs->wgs_time_last_data_sent);
2506 if ((time_uptime - wgs->wgs_time_last_data_sent) >= 2506 if ((time_uptime - wgs->wgs_time_last_data_sent) >=
2507 wg_keepalive_timeout) { 2507 wg_keepalive_timeout) {
2508 WG_TRACE("Schedule sending keepalive message"); 2508 WG_TRACE("Schedule sending keepalive message");
2509 /* 2509 /*
2510 * We can't send a keepalive message here to avoid 2510 * We can't send a keepalive message here to avoid
2511 * a deadlock; we already hold the solock of a socket 2511 * a deadlock; we already hold the solock of a socket
2512 * that is used to send the message. 2512 * that is used to send the message.
2513 */ 2513 */
2514 wg_schedule_peer_task(wgp, 2514 wg_schedule_peer_task(wgp,
2515 WGP_TASK_SEND_KEEPALIVE_MESSAGE); 2515 WGP_TASK_SEND_KEEPALIVE_MESSAGE);
2516 } 2516 }
2517 } 2517 }
2518out: 2518out:
2519 wg_put_session(wgs, &psref); 2519 wg_put_session(wgs, &psref);
2520 if (m != NULL) 2520 if (m != NULL)
2521 m_freem(m); 2521 m_freem(m);
2522 if (free_encrypted_buf) 2522 if (free_encrypted_buf)
2523 kmem_intr_free(encrypted_buf, encrypted_len); 2523 kmem_intr_free(encrypted_buf, encrypted_len);
2524} 2524}
2525 2525
2526static void 2526static void
2527wg_handle_msg_cookie(struct wg_softc *wg, const struct wg_msg_cookie *wgmc) 2527wg_handle_msg_cookie(struct wg_softc *wg, const struct wg_msg_cookie *wgmc)
2528{ 2528{
2529 struct wg_session *wgs; 2529 struct wg_session *wgs;
2530 struct wg_peer *wgp; 2530 struct wg_peer *wgp;
2531 struct psref psref; 2531 struct psref psref;
2532 int error; 2532 int error;
2533 uint8_t key[WG_HASH_LEN]; 2533 uint8_t key[WG_HASH_LEN];
2534 uint8_t cookie[WG_COOKIE_LEN]; 2534 uint8_t cookie[WG_COOKIE_LEN];
2535 2535
2536 WG_TRACE("cookie msg received"); 2536 WG_TRACE("cookie msg received");
2537 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref); 2537 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref);
2538 if (wgs == NULL) { 2538 if (wgs == NULL) {
2539 WG_TRACE("No session found"); 2539 WG_TRACE("No session found");
2540 return; 2540 return;
2541 } 2541 }
2542 wgp = wgs->wgs_peer; 2542 wgp = wgs->wgs_peer;
2543 2543
2544 if (!wgp->wgp_last_sent_mac1_valid) { 2544 if (!wgp->wgp_last_sent_mac1_valid) {
2545 WG_TRACE("No valid mac1 sent (or expired)"); 2545 WG_TRACE("No valid mac1 sent (or expired)");
2546 goto out; 2546 goto out;
2547 } 2547 }
2548 2548
2549 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey, 2549 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey,
2550 sizeof(wgp->wgp_pubkey)); 2550 sizeof(wgp->wgp_pubkey));
2551 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 0, 2551 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 0,
2552 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), 2552 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie),
2553 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1), 2553 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1),
2554 wgmc->wgmc_salt); 2554 wgmc->wgmc_salt);
2555 if (error != 0) { 2555 if (error != 0) {
2556 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2556 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2557 "wg_algo_aead_dec for cookie failed: error=%d\n", error); 2557 "wg_algo_aead_dec for cookie failed: error=%d\n", error);
2558 goto out; 2558 goto out;
2559 } 2559 }
2560 /* 2560 /*
2561 * [W] 6.6: Interaction with Cookie Reply System 2561 * [W] 6.6: Interaction with Cookie Reply System
2562 * "it should simply store the decrypted cookie value from the cookie 2562 * "it should simply store the decrypted cookie value from the cookie
2563 * reply message, and wait for the expiration of the REKEY-TIMEOUT 2563 * reply message, and wait for the expiration of the REKEY-TIMEOUT
2564 * timer for retrying a handshake initiation message." 2564 * timer for retrying a handshake initiation message."
2565 */ 2565 */
2566 wgp->wgp_latest_cookie_time = time_uptime; 2566 wgp->wgp_latest_cookie_time = time_uptime;
2567 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie)); 2567 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie));
2568out: 2568out:
2569 wg_put_session(wgs, &psref); 2569 wg_put_session(wgs, &psref);
2570} 2570}
2571 2571
2572static struct mbuf * 2572static struct mbuf *
2573wg_validate_msg_header(struct wg_softc *wg, struct mbuf *m) 2573wg_validate_msg_header(struct wg_softc *wg, struct mbuf *m)
2574{ 2574{
2575 struct wg_msg wgm; 2575 struct wg_msg wgm;
2576 size_t mbuflen; 2576 size_t mbuflen;
2577 size_t msglen; 2577 size_t msglen;
2578 2578
2579 /* 2579 /*
2580 * Get the mbuf chain length. It is already guaranteed, by 2580 * Get the mbuf chain length. It is already guaranteed, by
2581 * wg_overudp_cb, to be large enough for a struct wg_msg. 2581 * wg_overudp_cb, to be large enough for a struct wg_msg.
2582 */ 2582 */
2583 mbuflen = m_length(m); 2583 mbuflen = m_length(m);
2584 KASSERT(mbuflen >= sizeof(struct wg_msg)); 2584 KASSERT(mbuflen >= sizeof(struct wg_msg));
2585 2585
2586 /* 2586 /*
2587 * Copy the message header (32-bit message type) out -- we'll 2587 * Copy the message header (32-bit message type) out -- we'll
2588 * worry about contiguity and alignment later. 2588 * worry about contiguity and alignment later.
2589 */ 2589 */
2590 m_copydata(m, 0, sizeof(wgm), &wgm); 2590 m_copydata(m, 0, sizeof(wgm), &wgm);
2591 switch (wgm.wgm_type) { 2591 switch (wgm.wgm_type) {
2592 case WG_MSG_TYPE_INIT: 2592 case WG_MSG_TYPE_INIT:
2593 msglen = sizeof(struct wg_msg_init); 2593 msglen = sizeof(struct wg_msg_init);
2594 break; 2594 break;
2595 case WG_MSG_TYPE_RESP: 2595 case WG_MSG_TYPE_RESP:
2596 msglen = sizeof(struct wg_msg_resp); 2596 msglen = sizeof(struct wg_msg_resp);
2597 break; 2597 break;
2598 case WG_MSG_TYPE_COOKIE: 2598 case WG_MSG_TYPE_COOKIE:
2599 msglen = sizeof(struct wg_msg_cookie); 2599 msglen = sizeof(struct wg_msg_cookie);
2600 break; 2600 break;
2601 case WG_MSG_TYPE_DATA: 2601 case WG_MSG_TYPE_DATA:
2602 msglen = sizeof(struct wg_msg_data); 2602 msglen = sizeof(struct wg_msg_data);
2603 break; 2603 break;
2604 default: 2604 default:
2605 WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG, 2605 WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG,
2606 "Unexpected msg type: %u\n", wgm.wgm_type); 2606 "Unexpected msg type: %u\n", wgm.wgm_type);
2607 goto error; 2607 goto error;
2608 } 2608 }
2609 2609
2610 /* Verify the mbuf chain is long enough for this type of message. */ 2610 /* Verify the mbuf chain is long enough for this type of message. */
2611 if (__predict_false(mbuflen < msglen)) { 2611 if (__predict_false(mbuflen < msglen)) {
2612 WG_DLOG("Invalid msg size: mbuflen=%lu type=%u\n", mbuflen, 2612 WG_DLOG("Invalid msg size: mbuflen=%lu type=%u\n", mbuflen,
2613 wgm.wgm_type); 2613 wgm.wgm_type);
2614 goto error; 2614 goto error;
2615 } 2615 }
2616 2616
2617 /* Make the message header contiguous if necessary. */ 2617 /* Make the message header contiguous if necessary. */
2618 if (__predict_false(m->m_len < msglen)) { 2618 if (__predict_false(m->m_len < msglen)) {
2619 m = m_pullup(m, msglen); 2619 m = m_pullup(m, msglen);
2620 if (m == NULL) 2620 if (m == NULL)
2621 return NULL; 2621 return NULL;
2622 } 2622 }
2623 2623
2624 return m; 2624 return m;
2625 2625
2626error: 2626error:
2627 m_freem(m); 2627 m_freem(m);
2628 return NULL; 2628 return NULL;
2629} 2629}
2630 2630
2631static void 2631static void
2632wg_handle_packet(struct wg_softc *wg, struct mbuf *m, 2632wg_handle_packet(struct wg_softc *wg, struct mbuf *m,
2633 const struct sockaddr *src) 2633 const struct sockaddr *src)
2634{ 2634{
2635 struct wg_msg *wgm; 2635 struct wg_msg *wgm;
2636 2636
2637 m = wg_validate_msg_header(wg, m); 2637 m = wg_validate_msg_header(wg, m);
2638 if (__predict_false(m == NULL)) 2638 if (__predict_false(m == NULL))
2639 return; 2639 return;
2640 2640
2641 KASSERT(m->m_len >= sizeof(struct wg_msg)); 2641 KASSERT(m->m_len >= sizeof(struct wg_msg));
2642 wgm = mtod(m, struct wg_msg *); 2642 wgm = mtod(m, struct wg_msg *);
2643 switch (wgm->wgm_type) { 2643 switch (wgm->wgm_type) {
2644 case WG_MSG_TYPE_INIT: 2644 case WG_MSG_TYPE_INIT:
2645 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src); 2645 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src);
2646 break; 2646 break;
2647 case WG_MSG_TYPE_RESP: 2647 case WG_MSG_TYPE_RESP:
2648 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src); 2648 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src);
2649 break; 2649 break;
2650 case WG_MSG_TYPE_COOKIE: 2650 case WG_MSG_TYPE_COOKIE:
2651 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm); 2651 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm);
2652 break; 2652 break;
2653 case WG_MSG_TYPE_DATA: 2653 case WG_MSG_TYPE_DATA:
2654 wg_handle_msg_data(wg, m, src); 2654 wg_handle_msg_data(wg, m, src);
2655 break; 2655 break;
2656 default: 2656 default:
2657 /* wg_validate_msg_header should already reject this case */ 2657 /* wg_validate_msg_header should already reject this case */
2658 break; 2658 break;
2659 } 2659 }
2660} 2660}
2661 2661
2662static void 2662static void
2663wg_receive_packets(struct wg_softc *wg, const int af) 2663wg_receive_packets(struct wg_softc *wg, const int af)
2664{ 2664{
2665 2665
2666 for (;;) { 2666 for (;;) {
2667 int error, flags; 2667 int error, flags;
2668 struct socket *so; 2668 struct socket *so;
2669 struct mbuf *m = NULL; 2669 struct mbuf *m = NULL;
2670 struct uio dummy_uio; 2670 struct uio dummy_uio;
2671 struct mbuf *paddr = NULL; 2671 struct mbuf *paddr = NULL;
2672 struct sockaddr *src; 2672 struct sockaddr *src;
2673 2673
2674 so = wg_get_so_by_af(wg->wg_worker, af); 2674 so = wg_get_so_by_af(wg->wg_worker, af);
2675 flags = MSG_DONTWAIT; 2675 flags = MSG_DONTWAIT;
2676 dummy_uio.uio_resid = 1000000000; 2676 dummy_uio.uio_resid = 1000000000;
2677 2677
2678 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL, 2678 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL,
2679 &flags); 2679 &flags);
2680 if (error || m == NULL) { 2680 if (error || m == NULL) {
2681 //if (error == EWOULDBLOCK) 2681 //if (error == EWOULDBLOCK)
2682 return; 2682 return;
2683 } 2683 }
2684 2684
2685 KASSERT(paddr != NULL); 2685 KASSERT(paddr != NULL);
2686 KASSERT(paddr->m_len >= sizeof(struct sockaddr)); 2686 KASSERT(paddr->m_len >= sizeof(struct sockaddr));
2687 src = mtod(paddr, struct sockaddr *); 2687 src = mtod(paddr, struct sockaddr *);
2688 2688
2689 wg_handle_packet(wg, m, src); 2689 wg_handle_packet(wg, m, src);
2690 } 2690 }
2691} 2691}
2692 2692
2693static void 2693static void
2694wg_get_peer(struct wg_peer *wgp, struct psref *psref) 2694wg_get_peer(struct wg_peer *wgp, struct psref *psref)
2695{ 2695{
2696 2696
2697 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class); 2697 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class);
2698} 2698}
2699 2699
2700static void 2700static void
2701wg_put_peer(struct wg_peer *wgp, struct psref *psref) 2701wg_put_peer(struct wg_peer *wgp, struct psref *psref)
2702{ 2702{
2703 2703
2704 psref_release(psref, &wgp->wgp_psref, wg_psref_class); 2704 psref_release(psref, &wgp->wgp_psref, wg_psref_class);
2705} 2705}
2706 2706
2707static void 2707static void
2708wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp) 2708wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp)
2709{ 2709{
2710 struct psref psref; 2710 struct psref psref;
2711 struct wg_session *wgs; 2711 struct wg_session *wgs;
2712 2712
2713 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE"); 2713 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE");
2714 2714
2715 if (!wgp->wgp_endpoint_available) { 2715 if (!wgp->wgp_endpoint_available) {
2716 WGLOG(LOG_DEBUG, "No endpoint available\n"); 2716 WGLOG(LOG_DEBUG, "No endpoint available\n");
2717 /* XXX should do something? */ 2717 /* XXX should do something? */
2718 return; 2718 return;
2719 } 2719 }
2720 2720
2721 wgs = wg_get_stable_session(wgp, &psref); 2721 wgs = wg_get_stable_session(wgp, &psref);
2722 if (wgs->wgs_state == WGS_STATE_UNKNOWN) { 2722 if (wgs->wgs_state == WGS_STATE_UNKNOWN) {
2723 wg_put_session(wgs, &psref); 2723 wg_put_session(wgs, &psref);
2724 wg_send_handshake_msg_init(wg, wgp); 2724 wg_send_handshake_msg_init(wg, wgp);
2725 } else { 2725 } else {
2726 wg_put_session(wgs, &psref); 2726 wg_put_session(wgs, &psref);
2727 /* rekey */ 2727 /* rekey */
2728 wgs = wg_get_unstable_session(wgp, &psref); 2728 wgs = wg_get_unstable_session(wgp, &psref);
2729 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE) 2729 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE)
2730 wg_send_handshake_msg_init(wg, wgp); 2730 wg_send_handshake_msg_init(wg, wgp);
2731 wg_put_session(wgs, &psref); 2731 wg_put_session(wgs, &psref);
2732 } 2732 }
2733} 2733}
2734 2734
2735static void 2735static void
2736wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp) 2736wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp)
2737{ 2737{
2738 2738
2739 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED"); 2739 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED");
2740 2740
2741 mutex_enter(wgp->wgp_lock); 2741 mutex_enter(wgp->wgp_lock);
2742 if (wgp->wgp_endpoint_changing) { 2742 if (wgp->wgp_endpoint_changing) {
2743 pserialize_perform(wgp->wgp_psz); 2743 pserialize_perform(wgp->wgp_psz);
2744 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, 2744 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref,
2745 wg_psref_class); 2745 wg_psref_class);
2746 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, 2746 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref,
2747 wg_psref_class); 2747 wg_psref_class);
2748 wgp->wgp_endpoint_changing = false; 2748 wgp->wgp_endpoint_changing = false;
2749 } 2749 }
2750 mutex_exit(wgp->wgp_lock); 2750 mutex_exit(wgp->wgp_lock);
2751} 2751}
2752 2752
2753static void 2753static void
2754wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp) 2754wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp)
2755{ 2755{
2756 struct psref psref; 2756 struct psref psref;
2757 struct wg_session *wgs; 2757 struct wg_session *wgs;
2758 2758
2759 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE"); 2759 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE");
2760 2760
2761 wgs = wg_get_stable_session(wgp, &psref); 2761 wgs = wg_get_stable_session(wgp, &psref);
2762 wg_send_keepalive_msg(wgp, wgs); 2762 wg_send_keepalive_msg(wgp, wgs);
2763 wg_put_session(wgs, &psref); 2763 wg_put_session(wgs, &psref);
2764} 2764}
2765 2765
2766static void 2766static void
2767wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp) 2767wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp)
2768{ 2768{
2769 struct wg_session *wgs; 2769 struct wg_session *wgs;
2770 2770
2771 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION"); 2771 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION");
2772 2772
2773 mutex_enter(wgp->wgp_lock); 2773 mutex_enter(wgp->wgp_lock);
2774 wgs = wgp->wgp_session_unstable; 2774 wgs = wgp->wgp_session_unstable;
2775 mutex_enter(wgs->wgs_lock); 2775 mutex_enter(wgs->wgs_lock);
2776 if (wgs->wgs_state == WGS_STATE_DESTROYING) { 2776 if (wgs->wgs_state == WGS_STATE_DESTROYING) {
2777 pserialize_perform(wgp->wgp_psz); 2777 pserialize_perform(wgp->wgp_psz);
2778 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 2778 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
2779 psref_target_init(&wgs->wgs_psref, wg_psref_class); 2779 psref_target_init(&wgs->wgs_psref, wg_psref_class);
2780 wg_clear_states(wgs); 2780 wg_clear_states(wgs);
2781 wgs->wgs_state = WGS_STATE_UNKNOWN; 2781 wgs->wgs_state = WGS_STATE_UNKNOWN;
2782 } 2782 }
2783 mutex_exit(wgs->wgs_lock); 2783 mutex_exit(wgs->wgs_lock);
2784 mutex_exit(wgp->wgp_lock); 2784 mutex_exit(wgp->wgp_lock);
2785} 2785}
2786 2786
2787static void 2787static void
2788wg_process_peer_tasks(struct wg_softc *wg) 2788wg_process_peer_tasks(struct wg_softc *wg)
2789{ 2789{
2790 struct wg_peer *wgp; 2790 struct wg_peer *wgp;
2791 int s; 2791 int s;
2792 2792
2793 /* XXX should avoid checking all peers */ 2793 /* XXX should avoid checking all peers */
2794 s = pserialize_read_enter(); 2794 s = pserialize_read_enter();
2795 WG_PEER_READER_FOREACH(wgp, wg) { 2795 WG_PEER_READER_FOREACH(wgp, wg) {
2796 struct psref psref; 2796 struct psref psref;
2797 unsigned int tasks; 2797 unsigned int tasks;
2798 2798
2799 if (wgp->wgp_tasks == 0) 2799 if (wgp->wgp_tasks == 0)
2800 continue; 2800 continue;
2801 2801
2802 wg_get_peer(wgp, &psref); 2802 wg_get_peer(wgp, &psref);
2803 pserialize_read_exit(s); 2803 pserialize_read_exit(s);
2804 2804
2805 restart: 2805 restart:
2806 tasks = atomic_swap_uint(&wgp->wgp_tasks, 0); 2806 tasks = atomic_swap_uint(&wgp->wgp_tasks, 0);
2807 KASSERT(tasks != 0); 2807 KASSERT(tasks != 0);
2808 2808
2809 WG_DLOG("tasks=%x\n", tasks); 2809 WG_DLOG("tasks=%x\n", tasks);
2810 2810
2811 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE)) 2811 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE))
2812 wg_task_send_init_message(wg, wgp); 2812 wg_task_send_init_message(wg, wgp);
2813 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED)) 2813 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED))
2814 wg_task_endpoint_changed(wg, wgp); 2814 wg_task_endpoint_changed(wg, wgp);
2815 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE)) 2815 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE))
2816 wg_task_send_keepalive_message(wg, wgp); 2816 wg_task_send_keepalive_message(wg, wgp);
2817 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION)) 2817 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION))
2818 wg_task_destroy_prev_session(wg, wgp); 2818 wg_task_destroy_prev_session(wg, wgp);
2819 2819
2820 /* New tasks may be scheduled during processing tasks */ 2820 /* New tasks may be scheduled during processing tasks */
2821 WG_DLOG("wgp_tasks=%d\n", wgp->wgp_tasks); 2821 WG_DLOG("wgp_tasks=%d\n", wgp->wgp_tasks);
2822 if (wgp->wgp_tasks != 0) 2822 if (wgp->wgp_tasks != 0)
2823 goto restart; 2823 goto restart;
2824 2824
2825 s = pserialize_read_enter(); 2825 s = pserialize_read_enter();
2826 wg_put_peer(wgp, &psref); 2826 wg_put_peer(wgp, &psref);
2827 } 2827 }
2828 pserialize_read_exit(s); 2828 pserialize_read_exit(s);
2829} 2829}
2830 2830
2831static void 2831static void
2832wg_worker(void *arg) 2832wg_worker(void *arg)
2833{ 2833{
2834 struct wg_softc *wg = arg; 2834 struct wg_softc *wg = arg;
2835 struct wg_worker *wgw = wg->wg_worker; 2835 struct wg_worker *wgw = wg->wg_worker;
2836 bool todie = false; 2836 bool todie = false;
2837 2837
2838 KASSERT(wg != NULL); 2838 KASSERT(wg != NULL);
2839 KASSERT(wgw != NULL); 2839 KASSERT(wgw != NULL);
2840 2840
2841 while (!todie) { 2841 while (!todie) {
2842 int reasons; 2842 int reasons;
2843 int bound; 2843 int bound;
2844 2844
2845 mutex_enter(&wgw->wgw_lock); 2845 mutex_enter(&wgw->wgw_lock);
2846 /* New tasks may come during task handling */ 2846 /* New tasks may come during task handling */
2847 while ((reasons = wgw->wgw_wakeup_reasons) == 0 && 2847 while ((reasons = wgw->wgw_wakeup_reasons) == 0 &&
2848 !(todie = wgw->wgw_todie)) 2848 !(todie = wgw->wgw_todie))
2849 cv_wait(&wgw->wgw_cv, &wgw->wgw_lock); 2849 cv_wait(&wgw->wgw_cv, &wgw->wgw_lock);
2850 wgw->wgw_wakeup_reasons = 0; 2850 wgw->wgw_wakeup_reasons = 0;
2851 mutex_exit(&wgw->wgw_lock); 2851 mutex_exit(&wgw->wgw_lock);
2852 2852
2853 bound = curlwp_bind(); 2853 bound = curlwp_bind();
2854 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4)) 2854 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4))
2855 wg_receive_packets(wg, AF_INET); 2855 wg_receive_packets(wg, AF_INET);
2856 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6)) 2856 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6))
2857 wg_receive_packets(wg, AF_INET6); 2857 wg_receive_packets(wg, AF_INET6);
2858 if (ISSET(reasons, WG_WAKEUP_REASON_PEER)) 2858 if (ISSET(reasons, WG_WAKEUP_REASON_PEER))
2859 wg_process_peer_tasks(wg); 2859 wg_process_peer_tasks(wg);
2860 curlwp_bindx(bound); 2860 curlwp_bindx(bound);
2861 } 2861 }
2862 kthread_exit(0); 2862 kthread_exit(0);
2863} 2863}
2864 2864
2865static void 2865static void
2866wg_wakeup_worker(struct wg_worker *wgw, const int reason) 2866wg_wakeup_worker(struct wg_worker *wgw, const int reason)
2867{ 2867{
2868 2868
2869 mutex_enter(&wgw->wgw_lock); 2869 mutex_enter(&wgw->wgw_lock);
2870 wgw->wgw_wakeup_reasons |= reason; 2870 wgw->wgw_wakeup_reasons |= reason;
2871 cv_broadcast(&wgw->wgw_cv); 2871 cv_broadcast(&wgw->wgw_cv);
2872 mutex_exit(&wgw->wgw_lock); 2872 mutex_exit(&wgw->wgw_lock);
2873} 2873}
2874 2874
2875static int 2875static int
2876wg_bind_port(struct wg_softc *wg, const uint16_t port) 2876wg_bind_port(struct wg_softc *wg, const uint16_t port)
2877{ 2877{
2878 int error; 2878 int error;
2879 struct wg_worker *wgw = wg->wg_worker; 2879 struct wg_worker *wgw = wg->wg_worker;
2880 uint16_t old_port = wg->wg_listen_port; 2880 uint16_t old_port = wg->wg_listen_port;
2881 2881
2882 if (port != 0 && old_port == port) 2882 if (port != 0 && old_port == port)
2883 return 0; 2883 return 0;
2884 2884
2885 struct sockaddr_in _sin, *sin = &_sin; 2885 struct sockaddr_in _sin, *sin = &_sin;
2886 sin->sin_len = sizeof(*sin); 2886 sin->sin_len = sizeof(*sin);
2887 sin->sin_family = AF_INET; 2887 sin->sin_family = AF_INET;
2888 sin->sin_addr.s_addr = INADDR_ANY; 2888 sin->sin_addr.s_addr = INADDR_ANY;
2889 sin->sin_port = htons(port); 2889 sin->sin_port = htons(port);
2890 2890
2891 error = sobind(wgw->wgw_so4, sintosa(sin), curlwp); 2891 error = sobind(wgw->wgw_so4, sintosa(sin), curlwp);
2892 if (error != 0) 2892 if (error != 0)
2893 return error; 2893 return error;
2894 2894
2895#ifdef INET6 2895#ifdef INET6
2896 struct sockaddr_in6 _sin6, *sin6 = &_sin6; 2896 struct sockaddr_in6 _sin6, *sin6 = &_sin6;
2897 sin6->sin6_len = sizeof(*sin6); 2897 sin6->sin6_len = sizeof(*sin6);
2898 sin6->sin6_family = AF_INET6; 2898 sin6->sin6_family = AF_INET6;
2899 sin6->sin6_addr = in6addr_any; 2899 sin6->sin6_addr = in6addr_any;
2900 sin6->sin6_port = htons(port); 2900 sin6->sin6_port = htons(port);
2901 2901
2902 error = sobind(wgw->wgw_so6, sin6tosa(sin6), curlwp); 2902 error = sobind(wgw->wgw_so6, sin6tosa(sin6), curlwp);
2903 if (error != 0) 2903 if (error != 0)
2904 return error; 2904 return error;
2905#endif 2905#endif
2906 2906
2907 wg->wg_listen_port = port; 2907 wg->wg_listen_port = port;
2908 2908
2909 return 0; 2909 return 0;
2910} 2910}
2911 2911
2912static void 2912static void
2913wg_so_upcall(struct socket *so, void *arg, int events, int waitflag) 2913wg_so_upcall(struct socket *so, void *arg, int events, int waitflag)
2914{ 2914{
2915 struct wg_worker *wgw = arg; 2915 struct wg_worker *wgw = arg;
2916 int reason; 2916 int reason;
2917 2917
2918 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ? 2918 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ?
2919 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 : 2919 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 :
2920 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6; 2920 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6;
2921 wg_wakeup_worker(wgw, reason); 2921 wg_wakeup_worker(wgw, reason);
2922} 2922}
2923 2923
2924static int 2924static int
2925wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so, 2925wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so,
2926 struct sockaddr *src, void *arg) 2926 struct sockaddr *src, void *arg)
2927{ 2927{
2928 struct wg_softc *wg = arg; 2928 struct wg_softc *wg = arg;
2929 struct wg_msg wgm; 2929 struct wg_msg wgm;
2930 struct mbuf *m = *mp; 2930 struct mbuf *m = *mp;
2931 2931
2932 WG_TRACE("enter"); 2932 WG_TRACE("enter");
2933 2933
2934 /* Verify the mbuf chain is long enough to have a wg msg header. */ 2934 /* Verify the mbuf chain is long enough to have a wg msg header. */
2935 KASSERT(offset <= m_length(m)); 2935 KASSERT(offset <= m_length(m));
2936 if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) { 2936 if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) {
2937 /* drop on the floor */ 2937 /* drop on the floor */
2938 m_freem(m); 2938 m_freem(m);
2939 return -1; 2939 return -1;
2940 } 2940 }
2941 2941
2942 /* 2942 /*
2943 * Copy the message header (32-bit message type) out -- we'll 2943 * Copy the message header (32-bit message type) out -- we'll
2944 * worry about contiguity and alignment later. 2944 * worry about contiguity and alignment later.
2945 */ 2945 */
2946 m_copydata(m, offset, sizeof(struct wg_msg), &wgm); 2946 m_copydata(m, offset, sizeof(struct wg_msg), &wgm);
2947 WG_DLOG("type=%d\n", wgm.wgm_type); 2947 WG_DLOG("type=%d\n", wgm.wgm_type);
2948 2948
2949 /* 2949 /*
2950 * Handle DATA packets promptly as they arrive. Other packets 2950 * Handle DATA packets promptly as they arrive. Other packets
2951 * may require expensive public-key crypto and are not as 2951 * may require expensive public-key crypto and are not as
2952 * sensitive to latency, so defer them to the worker thread. 2952 * sensitive to latency, so defer them to the worker thread.
2953 */ 2953 */
2954 switch (wgm.wgm_type) { 2954 switch (wgm.wgm_type) {
2955 case WG_MSG_TYPE_DATA: 2955 case WG_MSG_TYPE_DATA:
2956 /* handle immediately */ 2956 /* handle immediately */
2957 m_adj(m, offset); 2957 m_adj(m, offset);
 2958 if (__predict_false(m->m_len < sizeof(struct wg_msg_data))) {
 2959 m = m_pullup(m, sizeof(struct wg_msg_data));
 2960 if (m == NULL)
 2961 return -1;
 2962 }
2958 wg_handle_msg_data(wg, m, src); 2963 wg_handle_msg_data(wg, m, src);
2959 *mp = NULL; 2964 *mp = NULL;
2960 return 1; 2965 return 1;
2961 case WG_MSG_TYPE_INIT: 2966 case WG_MSG_TYPE_INIT:
2962 case WG_MSG_TYPE_RESP: 2967 case WG_MSG_TYPE_RESP:
2963 case WG_MSG_TYPE_COOKIE: 2968 case WG_MSG_TYPE_COOKIE:
2964 /* pass through to so_receive in wg_receive_packets */ 2969 /* pass through to so_receive in wg_receive_packets */
2965 return 0; 2970 return 0;
2966 default: 2971 default:
2967 /* drop on the floor */ 2972 /* drop on the floor */
2968 m_freem(m); 2973 m_freem(m);
2969 return -1; 2974 return -1;
2970 } 2975 }
2971} 2976}
2972 2977
2973static int 2978static int
2974wg_worker_socreate(struct wg_softc *wg, struct wg_worker *wgw, const int af, 2979wg_worker_socreate(struct wg_softc *wg, struct wg_worker *wgw, const int af,
2975 struct socket **sop) 2980 struct socket **sop)
2976{ 2981{
2977 int error; 2982 int error;
2978 struct socket *so; 2983 struct socket *so;
2979 2984
2980 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL); 2985 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL);
2981 if (error != 0) 2986 if (error != 0)
2982 return error; 2987 return error;
2983 2988
2984 solock(so); 2989 solock(so);
2985 so->so_upcallarg = wgw; 2990 so->so_upcallarg = wgw;
2986 so->so_upcall = wg_so_upcall; 2991 so->so_upcall = wg_so_upcall;
2987 so->so_rcv.sb_flags |= SB_UPCALL; 2992 so->so_rcv.sb_flags |= SB_UPCALL;
2988 if (af == AF_INET) 2993 if (af == AF_INET)
2989 in_pcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg); 2994 in_pcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg);
2990#if INET6 2995#if INET6
2991 else 2996 else
2992 in6_pcb_register_overudp_cb(sotoin6pcb(so), wg_overudp_cb, wg); 2997 in6_pcb_register_overudp_cb(sotoin6pcb(so), wg_overudp_cb, wg);
2993#endif 2998#endif
2994 sounlock(so); 2999 sounlock(so);
2995 3000
2996 *sop = so; 3001 *sop = so;
2997 3002
2998 return 0; 3003 return 0;
2999} 3004}
3000 3005
3001static int 3006static int
3002wg_worker_init(struct wg_softc *wg) 3007wg_worker_init(struct wg_softc *wg)
3003{ 3008{
3004 int error; 3009 int error;
3005 struct wg_worker *wgw; 3010 struct wg_worker *wgw;
3006 const char *ifname = wg->wg_if.if_xname; 3011 const char *ifname = wg->wg_if.if_xname;
3007 struct socket *so; 3012 struct socket *so;
3008 3013
3009 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP); 3014 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP);
3010 3015
3011 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_NONE); 3016 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_NONE);
3012 cv_init(&wgw->wgw_cv, ifname); 3017 cv_init(&wgw->wgw_cv, ifname);
3013 wgw->wgw_todie = false; 3018 wgw->wgw_todie = false;
3014 wgw->wgw_wakeup_reasons = 0; 3019 wgw->wgw_wakeup_reasons = 0;
3015 3020
3016 error = wg_worker_socreate(wg, wgw, AF_INET, &so); 3021 error = wg_worker_socreate(wg, wgw, AF_INET, &so);
3017 if (error != 0) 3022 if (error != 0)
3018 goto error; 3023 goto error;
3019 wgw->wgw_so4 = so; 3024 wgw->wgw_so4 = so;
3020#ifdef INET6 3025#ifdef INET6
3021 error = wg_worker_socreate(wg, wgw, AF_INET6, &so); 3026 error = wg_worker_socreate(wg, wgw, AF_INET6, &so);
3022 if (error != 0) 3027 if (error != 0)
3023 goto error; 3028 goto error;
3024 wgw->wgw_so6 = so; 3029 wgw->wgw_so6 = so;
3025#endif 3030#endif
3026 3031
3027 wg->wg_worker = wgw; 3032 wg->wg_worker = wgw;
3028 3033
3029 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, 3034 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN,
3030 NULL, wg_worker, wg, &wg->wg_worker_lwp, "%s", ifname); 3035 NULL, wg_worker, wg, &wg->wg_worker_lwp, "%s", ifname);
3031 if (error != 0) 3036 if (error != 0)
3032 goto error; 3037 goto error;
3033 3038
3034 return 0; 3039 return 0;
3035 3040
3036error: 3041error:
3037#ifdef INET6 3042#ifdef INET6
3038 if (wgw->wgw_so6 != NULL) 3043 if (wgw->wgw_so6 != NULL)
3039 soclose(wgw->wgw_so6); 3044 soclose(wgw->wgw_so6);
3040#endif 3045#endif
3041 if (wgw->wgw_so4 != NULL) 3046 if (wgw->wgw_so4 != NULL)
3042 soclose(wgw->wgw_so4); 3047 soclose(wgw->wgw_so4);
3043 cv_destroy(&wgw->wgw_cv); 3048 cv_destroy(&wgw->wgw_cv);
3044 mutex_destroy(&wgw->wgw_lock); 3049 mutex_destroy(&wgw->wgw_lock);
3045 3050
3046 return error; 3051 return error;
3047} 3052}
3048 3053
3049static void 3054static void
3050wg_worker_destroy(struct wg_softc *wg) 3055wg_worker_destroy(struct wg_softc *wg)
3051{ 3056{
3052 struct wg_worker *wgw = wg->wg_worker; 3057 struct wg_worker *wgw = wg->wg_worker;
3053 3058
3054 mutex_enter(&wgw->wgw_lock); 3059 mutex_enter(&wgw->wgw_lock);
3055 wgw->wgw_todie = true; 3060 wgw->wgw_todie = true;
3056 wgw->wgw_wakeup_reasons = 0; 3061 wgw->wgw_wakeup_reasons = 0;
3057 cv_broadcast(&wgw->wgw_cv); 3062 cv_broadcast(&wgw->wgw_cv);
3058 mutex_exit(&wgw->wgw_lock); 3063 mutex_exit(&wgw->wgw_lock);
3059 3064
3060 kthread_join(wg->wg_worker_lwp); 3065 kthread_join(wg->wg_worker_lwp);
3061 3066
3062#ifdef INET6 3067#ifdef INET6
3063 soclose(wgw->wgw_so6); 3068 soclose(wgw->wgw_so6);
3064#endif 3069#endif
3065 soclose(wgw->wgw_so4); 3070 soclose(wgw->wgw_so4);
3066 cv_destroy(&wgw->wgw_cv); 3071 cv_destroy(&wgw->wgw_cv);
3067 mutex_destroy(&wgw->wgw_lock); 3072 mutex_destroy(&wgw->wgw_lock);
3068 kmem_free(wg->wg_worker, sizeof(struct wg_worker)); 3073 kmem_free(wg->wg_worker, sizeof(struct wg_worker));
3069 wg->wg_worker = NULL; 3074 wg->wg_worker = NULL;
3070} 3075}
3071 3076
3072static bool 3077static bool
3073wg_session_hit_limits(struct wg_session *wgs) 3078wg_session_hit_limits(struct wg_session *wgs)
3074{ 3079{
3075 3080
3076 /* 3081 /*
3077 * [W] 6.2: Transport Message Limits 3082 * [W] 6.2: Transport Message Limits
3078 * "After REJECT-AFTER-MESSAGES transport data messages or after the 3083 * "After REJECT-AFTER-MESSAGES transport data messages or after the
3079 * current secure session is REJECT-AFTER-TIME seconds old, whichever 3084 * current secure session is REJECT-AFTER-TIME seconds old, whichever
3080 * comes first, WireGuard will refuse to send any more transport data 3085 * comes first, WireGuard will refuse to send any more transport data
3081 * messages using the current secure session, ..." 3086 * messages using the current secure session, ..."
3082 */ 3087 */
3083 KASSERT(wgs->wgs_time_established != 0); 3088 KASSERT(wgs->wgs_time_established != 0);
3084 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) { 3089 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) {
3085 WG_DLOG("The session hits REJECT_AFTER_TIME\n"); 3090 WG_DLOG("The session hits REJECT_AFTER_TIME\n");
3086 return true; 3091 return true;
3087 } else if (wg_session_get_send_counter(wgs) > 3092 } else if (wg_session_get_send_counter(wgs) >
3088 wg_reject_after_messages) { 3093 wg_reject_after_messages) {
3089 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n"); 3094 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n");
3090 return true; 3095 return true;
3091 } 3096 }
3092 3097
3093 return false; 3098 return false;
3094} 3099}
3095 3100
3096static void 3101static void
3097wg_peer_softint(void *arg) 3102wg_peer_softint(void *arg)
3098{ 3103{
3099 struct wg_peer *wgp = arg; 3104 struct wg_peer *wgp = arg;
3100 struct wg_session *wgs; 3105 struct wg_session *wgs;
3101 struct mbuf *m; 3106 struct mbuf *m;
3102 struct psref psref; 3107 struct psref psref;
3103 3108
3104 wgs = wg_get_stable_session(wgp, &psref); 3109 wgs = wg_get_stable_session(wgp, &psref);
3105 if (wgs->wgs_state != WGS_STATE_ESTABLISHED) { 3110 if (wgs->wgs_state != WGS_STATE_ESTABLISHED) {
3106 /* XXX how to treat? */ 3111 /* XXX how to treat? */
3107 WG_TRACE("skipped"); 3112 WG_TRACE("skipped");
3108 goto out; 3113 goto out;
3109 } 3114 }
3110 if (wg_session_hit_limits(wgs)) { 3115 if (wg_session_hit_limits(wgs)) {
3111 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3116 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3112 goto out; 3117 goto out;
3113 } 3118 }
3114 WG_TRACE("running"); 3119 WG_TRACE("running");
3115 3120
3116 while ((m = pcq_get(wgp->wgp_q)) != NULL) { 3121 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
3117 wg_send_data_msg(wgp, wgs, m); 3122 wg_send_data_msg(wgp, wgs, m);
3118 } 3123 }
3119out: 3124out:
3120 wg_put_session(wgs, &psref); 3125 wg_put_session(wgs, &psref);
3121} 3126}
3122 3127
3123static void 3128static void
3124wg_rekey_timer(void *arg) 3129wg_rekey_timer(void *arg)
3125{ 3130{
3126 struct wg_peer *wgp = arg; 3131 struct wg_peer *wgp = arg;
3127 3132
3128 mutex_enter(wgp->wgp_lock); 3133 mutex_enter(wgp->wgp_lock);
3129 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) { 3134 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) {
3130 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3135 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3131 } 3136 }
3132 mutex_exit(wgp->wgp_lock); 3137 mutex_exit(wgp->wgp_lock);
3133} 3138}
3134 3139
3135static void 3140static void
3136wg_purge_pending_packets(struct wg_peer *wgp) 3141wg_purge_pending_packets(struct wg_peer *wgp)
3137{ 3142{
3138 struct mbuf *m; 3143 struct mbuf *m;
3139 3144
3140 while ((m = pcq_get(wgp->wgp_q)) != NULL) { 3145 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
3141 m_freem(m); 3146 m_freem(m);
3142 } 3147 }
3143} 3148}
3144 3149
3145static void 3150static void
3146wg_handshake_timeout_timer(void *arg) 3151wg_handshake_timeout_timer(void *arg)
3147{ 3152{
3148 struct wg_peer *wgp = arg; 3153 struct wg_peer *wgp = arg;
3149 struct wg_session *wgs; 3154 struct wg_session *wgs;
3150 struct psref psref; 3155 struct psref psref;
3151 3156
3152 WG_TRACE("enter"); 3157 WG_TRACE("enter");
3153 3158
3154 mutex_enter(wgp->wgp_lock); 3159 mutex_enter(wgp->wgp_lock);
3155 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) { 3160 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
3156 mutex_exit(wgp->wgp_lock); 3161 mutex_exit(wgp->wgp_lock);
3157 return; 3162 return;
3158 } 3163 }
3159 mutex_exit(wgp->wgp_lock); 3164 mutex_exit(wgp->wgp_lock);
3160 3165
3161 KASSERT(wgp->wgp_handshake_start_time != 0); 3166 KASSERT(wgp->wgp_handshake_start_time != 0);
3162 wgs = wg_get_unstable_session(wgp, &psref); 3167 wgs = wg_get_unstable_session(wgp, &psref);
3163 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE); 3168 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE);
3164 3169
3165 /* [W] 6.4 Handshake Initiation Retransmission */ 3170 /* [W] 6.4 Handshake Initiation Retransmission */
3166 if ((time_uptime - wgp->wgp_handshake_start_time) > 3171 if ((time_uptime - wgp->wgp_handshake_start_time) >
3167 wg_rekey_attempt_time) { 3172 wg_rekey_attempt_time) {
3168 /* Give up handshaking */ 3173 /* Give up handshaking */
3169 wgs->wgs_state = WGS_STATE_UNKNOWN; 3174 wgs->wgs_state = WGS_STATE_UNKNOWN;
3170 wg_clear_states(wgs); 3175 wg_clear_states(wgs);
3171 wgp->wgp_state = WGP_STATE_GIVEUP; 3176 wgp->wgp_state = WGP_STATE_GIVEUP;
3172 wgp->wgp_handshake_start_time = 0; 3177 wgp->wgp_handshake_start_time = 0;
3173 wg_put_session(wgs, &psref); 3178 wg_put_session(wgs, &psref);
3174 WG_TRACE("give up"); 3179 WG_TRACE("give up");
3175 /* 3180 /*
3176 * If a new data packet comes, handshaking will be retried 3181 * If a new data packet comes, handshaking will be retried
3177 * and a new session would be established at that time, 3182 * and a new session would be established at that time,
3178 * however we don't want to send pending packets then. 3183 * however we don't want to send pending packets then.
3179 */ 3184 */
3180 wg_purge_pending_packets(wgp); 3185 wg_purge_pending_packets(wgp);
3181 return; 3186 return;
3182 } 3187 }
3183 3188
3184 /* No response for an initiation message sent, retry handshaking */ 3189 /* No response for an initiation message sent, retry handshaking */
3185 wgs->wgs_state = WGS_STATE_UNKNOWN; 3190 wgs->wgs_state = WGS_STATE_UNKNOWN;
3186 wg_clear_states(wgs); 3191 wg_clear_states(wgs);
3187 wg_put_session(wgs, &psref); 3192 wg_put_session(wgs, &psref);
3188 3193
3189 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3194 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3190} 3195}
3191 3196
3192static struct wg_peer * 3197static struct wg_peer *
3193wg_alloc_peer(struct wg_softc *wg) 3198wg_alloc_peer(struct wg_softc *wg)
3194{ 3199{
3195 struct wg_peer *wgp; 3200 struct wg_peer *wgp;
3196 3201
3197 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP); 3202 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP);
3198 3203
3199 wgp->wgp_sc = wg; 3204 wgp->wgp_sc = wg;
3200 wgp->wgp_state = WGP_STATE_INIT; 3205 wgp->wgp_state = WGP_STATE_INIT;
3201 wgp->wgp_q = pcq_create(1024, KM_SLEEP); 3206 wgp->wgp_q = pcq_create(1024, KM_SLEEP);
3202 wgp->wgp_si = softint_establish(SOFTINT_NET, wg_peer_softint, wgp); 3207 wgp->wgp_si = softint_establish(SOFTINT_NET, wg_peer_softint, wgp);
3203 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE); 3208 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE);
3204 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp); 3209 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp);
3205 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE); 3210 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE);
3206 callout_setfunc(&wgp->wgp_handshake_timeout_timer, 3211 callout_setfunc(&wgp->wgp_handshake_timeout_timer,
3207 wg_handshake_timeout_timer, wgp); 3212 wg_handshake_timeout_timer, wgp);
3208 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE); 3213 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE);
3209 callout_setfunc(&wgp->wgp_session_dtor_timer, 3214 callout_setfunc(&wgp->wgp_session_dtor_timer,
3210 wg_session_dtor_timer, wgp); 3215 wg_session_dtor_timer, wgp);
3211 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry); 3216 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry);
3212 wgp->wgp_endpoint_changing = false; 3217 wgp->wgp_endpoint_changing = false;
3213 wgp->wgp_endpoint_available = false; 3218 wgp->wgp_endpoint_available = false;
3214 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3219 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3215 wgp->wgp_psz = pserialize_create(); 3220 wgp->wgp_psz = pserialize_create();
3216 psref_target_init(&wgp->wgp_psref, wg_psref_class); 3221 psref_target_init(&wgp->wgp_psref, wg_psref_class);
3217 3222
3218 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP); 3223 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP);
3219 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP); 3224 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP);
3220 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3225 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3221 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3226 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3222 3227
3223 struct wg_session *wgs; 3228 struct wg_session *wgs;
3224 wgp->wgp_session_stable = 3229 wgp->wgp_session_stable =
3225 kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP); 3230 kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP);
3226 wgp->wgp_session_unstable = 3231 wgp->wgp_session_unstable =
3227 kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP); 3232 kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP);
3228 wgs = wgp->wgp_session_stable; 3233 wgs = wgp->wgp_session_stable;
3229 wgs->wgs_peer = wgp; 3234 wgs->wgs_peer = wgp;
3230 wgs->wgs_state = WGS_STATE_UNKNOWN; 3235 wgs->wgs_state = WGS_STATE_UNKNOWN;
3231 psref_target_init(&wgs->wgs_psref, wg_psref_class); 3236 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3232 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3237 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3233#ifndef __HAVE_ATOMIC64_LOADSTORE 3238#ifndef __HAVE_ATOMIC64_LOADSTORE
3234 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3239 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3235#endif 3240#endif
3236 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3241 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3237 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE); 3242 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE);
3238 3243
3239 wgs = wgp->wgp_session_unstable; 3244 wgs = wgp->wgp_session_unstable;
3240 wgs->wgs_peer = wgp; 3245 wgs->wgs_peer = wgp;
3241 wgs->wgs_state = WGS_STATE_UNKNOWN; 3246 wgs->wgs_state = WGS_STATE_UNKNOWN;
3242 psref_target_init(&wgs->wgs_psref, wg_psref_class); 3247 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3243 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3248 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3244#ifndef __HAVE_ATOMIC64_LOADSTORE 3249#ifndef __HAVE_ATOMIC64_LOADSTORE
3245 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3250 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3246#endif 3251#endif
3247 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3252 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3248 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE); 3253 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE);
3249 3254
3250 return wgp; 3255 return wgp;
3251} 3256}
3252 3257
3253static void 3258static void
3254wg_destroy_peer(struct wg_peer *wgp) 3259wg_destroy_peer(struct wg_peer *wgp)
3255{ 3260{
3256 struct wg_session *wgs; 3261 struct wg_session *wgs;
3257 struct wg_softc *wg = wgp->wgp_sc; 3262 struct wg_softc *wg = wgp->wgp_sc;
3258 3263
3259 rw_enter(wg->wg_rwlock, RW_WRITER); 3264 rw_enter(wg->wg_rwlock, RW_WRITER);
3260 for (int i = 0; i < wgp->wgp_n_allowedips; i++) { 3265 for (int i = 0; i < wgp->wgp_n_allowedips; i++) {
3261 struct wg_allowedip *wga = &wgp->wgp_allowedips[i]; 3266 struct wg_allowedip *wga = &wgp->wgp_allowedips[i];
3262 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family); 3267 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family);
3263 struct radix_node *rn; 3268 struct radix_node *rn;
3264 3269
3265 KASSERT(rnh != NULL); 3270 KASSERT(rnh != NULL);
3266 rn = rnh->rnh_deladdr(&wga->wga_sa_addr, 3271 rn = rnh->rnh_deladdr(&wga->wga_sa_addr,
3267 &wga->wga_sa_mask, rnh); 3272 &wga->wga_sa_mask, rnh);
3268 if (rn == NULL) { 3273 if (rn == NULL) {
3269 char addrstr[128]; 3274 char addrstr[128];
3270 sockaddr_format(&wga->wga_sa_addr, addrstr, 3275 sockaddr_format(&wga->wga_sa_addr, addrstr,
3271 sizeof(addrstr)); 3276 sizeof(addrstr));
3272 WGLOG(LOG_WARNING, "Couldn't delete %s", addrstr); 3277 WGLOG(LOG_WARNING, "Couldn't delete %s", addrstr);
3273 } 3278 }
3274 } 3279 }
3275 rw_exit(wg->wg_rwlock); 3280 rw_exit(wg->wg_rwlock);
3276 3281
3277 softint_disestablish(wgp->wgp_si); 3282 softint_disestablish(wgp->wgp_si);
3278 callout_halt(&wgp->wgp_rekey_timer, NULL); 3283 callout_halt(&wgp->wgp_rekey_timer, NULL);
3279 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL); 3284 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL);
3280 callout_halt(&wgp->wgp_session_dtor_timer, NULL); 3285 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
3281 3286
3282 wgs = wgp->wgp_session_unstable; 3287 wgs = wgp->wgp_session_unstable;
3283 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 3288 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3284 mutex_obj_free(wgs->wgs_lock); 3289 mutex_obj_free(wgs->wgs_lock);
3285 mutex_destroy(&wgs->wgs_recvwin->lock); 3290 mutex_destroy(&wgs->wgs_recvwin->lock);
3286 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3291 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3287#ifndef __HAVE_ATOMIC64_LOADSTORE 3292#ifndef __HAVE_ATOMIC64_LOADSTORE
3288 mutex_destroy(&wgs->wgs_send_counter_lock); 3293 mutex_destroy(&wgs->wgs_send_counter_lock);
3289#endif 3294#endif
3290 kmem_free(wgs, sizeof(*wgs)); 3295 kmem_free(wgs, sizeof(*wgs));
3291 wgs = wgp->wgp_session_stable; 3296 wgs = wgp->wgp_session_stable;
3292 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 3297 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3293 mutex_obj_free(wgs->wgs_lock); 3298 mutex_obj_free(wgs->wgs_lock);
3294 mutex_destroy(&wgs->wgs_recvwin->lock); 3299 mutex_destroy(&wgs->wgs_recvwin->lock);
3295 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3300 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3296#ifndef __HAVE_ATOMIC64_LOADSTORE 3301#ifndef __HAVE_ATOMIC64_LOADSTORE
3297 mutex_destroy(&wgs->wgs_send_counter_lock); 3302 mutex_destroy(&wgs->wgs_send_counter_lock);
3298#endif 3303#endif
3299 kmem_free(wgs, sizeof(*wgs)); 3304 kmem_free(wgs, sizeof(*wgs));
3300 3305
3301 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3306 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3302 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3307 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3303 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint)); 3308 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint));
3304 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0)); 3309 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0));
3305 3310
3306 pserialize_destroy(wgp->wgp_psz); 3311 pserialize_destroy(wgp->wgp_psz);
3307 pcq_destroy(wgp->wgp_q); 3312 pcq_destroy(wgp->wgp_q);
3308 mutex_obj_free(wgp->wgp_lock); 3313 mutex_obj_free(wgp->wgp_lock);
3309 3314
3310 kmem_free(wgp, sizeof(*wgp)); 3315 kmem_free(wgp, sizeof(*wgp));
3311} 3316}
3312 3317
3313static void 3318static void
3314wg_destroy_all_peers(struct wg_softc *wg) 3319wg_destroy_all_peers(struct wg_softc *wg)
3315{ 3320{
3316 struct wg_peer *wgp; 3321 struct wg_peer *wgp;
3317 3322
3318restart: 3323restart:
3319 mutex_enter(wg->wg_lock); 3324 mutex_enter(wg->wg_lock);
3320 WG_PEER_WRITER_FOREACH(wgp, wg) { 3325 WG_PEER_WRITER_FOREACH(wgp, wg) {
3321 WG_PEER_WRITER_REMOVE(wgp); 3326 WG_PEER_WRITER_REMOVE(wgp);
3322 mutex_enter(wgp->wgp_lock); 3327 mutex_enter(wgp->wgp_lock);
3323 wgp->wgp_state = WGP_STATE_DESTROYING; 3328 wgp->wgp_state = WGP_STATE_DESTROYING;
3324 pserialize_perform(wgp->wgp_psz); 3329 pserialize_perform(wgp->wgp_psz);
3325 mutex_exit(wgp->wgp_lock); 3330 mutex_exit(wgp->wgp_lock);
3326 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 3331 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3327 break; 3332 break;
3328 } 3333 }
3329 mutex_exit(wg->wg_lock); 3334 mutex_exit(wg->wg_lock);
3330 3335
3331 if (wgp == NULL) 3336 if (wgp == NULL)
3332 return; 3337 return;
3333 3338
3334 psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 3339 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3335 3340
3336 wg_destroy_peer(wgp); 3341 wg_destroy_peer(wgp);
3337 3342
3338 goto restart; 3343 goto restart;
3339} 3344}
3340 3345
3341static int 3346static int
3342wg_destroy_peer_name(struct wg_softc *wg, const char *name) 3347wg_destroy_peer_name(struct wg_softc *wg, const char *name)
3343{ 3348{
3344 struct wg_peer *wgp; 3349 struct wg_peer *wgp;
3345 3350
3346 mutex_enter(wg->wg_lock); 3351 mutex_enter(wg->wg_lock);
3347 WG_PEER_WRITER_FOREACH(wgp, wg) { 3352 WG_PEER_WRITER_FOREACH(wgp, wg) {
3348 if (strcmp(wgp->wgp_name, name) == 0) 3353 if (strcmp(wgp->wgp_name, name) == 0)
3349 break; 3354 break;
3350 } 3355 }
3351 if (wgp != NULL) { 3356 if (wgp != NULL) {
3352 WG_PEER_WRITER_REMOVE(wgp); 3357 WG_PEER_WRITER_REMOVE(wgp);
3353 wg->wg_npeers--; 3358 wg->wg_npeers--;
3354 mutex_enter(wgp->wgp_lock); 3359 mutex_enter(wgp->wgp_lock);
3355 wgp->wgp_state = WGP_STATE_DESTROYING; 3360 wgp->wgp_state = WGP_STATE_DESTROYING;
3356 pserialize_perform(wgp->wgp_psz); 3361 pserialize_perform(wgp->wgp_psz);
3357 mutex_exit(wgp->wgp_lock); 3362 mutex_exit(wgp->wgp_lock);
3358 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 3363 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3359 } 3364 }
3360 mutex_exit(wg->wg_lock); 3365 mutex_exit(wg->wg_lock);
3361 3366
3362 if (wgp == NULL) 3367 if (wgp == NULL)
3363 return ENOENT; 3368 return ENOENT;
3364 3369
3365 psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 3370 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3366 3371
3367 wg_destroy_peer(wgp); 3372 wg_destroy_peer(wgp);
3368 3373
3369 return 0; 3374 return 0;
3370} 3375}
3371 3376
3372static int 3377static int
3373wg_if_attach(struct wg_softc *wg) 3378wg_if_attach(struct wg_softc *wg)
3374{ 3379{
3375 int error; 3380 int error;
3376 3381
3377 wg->wg_if.if_addrlen = 0; 3382 wg->wg_if.if_addrlen = 0;
3378 wg->wg_if.if_mtu = WG_MTU; 3383 wg->wg_if.if_mtu = WG_MTU;
3379 wg->wg_if.if_flags = IFF_POINTOPOINT; 3384 wg->wg_if.if_flags = IFF_POINTOPOINT;
3380 wg->wg_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE; 3385 wg->wg_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE;
3381 wg->wg_if.if_extflags |= IFEF_MPSAFE; 3386 wg->wg_if.if_extflags |= IFEF_MPSAFE;
3382 wg->wg_if.if_ioctl = wg_ioctl; 3387 wg->wg_if.if_ioctl = wg_ioctl;
3383 wg->wg_if.if_output = wg_output; 3388 wg->wg_if.if_output = wg_output;
3384 wg->wg_if.if_init = wg_init; 3389 wg->wg_if.if_init = wg_init;
3385 wg->wg_if.if_stop = wg_stop; 3390 wg->wg_if.if_stop = wg_stop;
3386 wg->wg_if.if_type = IFT_OTHER; 3391 wg->wg_if.if_type = IFT_OTHER;
3387 wg->wg_if.if_dlt = DLT_NULL; 3392 wg->wg_if.if_dlt = DLT_NULL;
3388 wg->wg_if.if_softc = wg; 3393 wg->wg_if.if_softc = wg;
3389 IFQ_SET_READY(&wg->wg_if.if_snd); 3394 IFQ_SET_READY(&wg->wg_if.if_snd);
3390 3395
3391 error = if_initialize(&wg->wg_if); 3396 error = if_initialize(&wg->wg_if);
3392 if (error != 0) 3397 if (error != 0)
3393 return error; 3398 return error;
3394 3399
3395 if_alloc_sadl(&wg->wg_if); 3400 if_alloc_sadl(&wg->wg_if);
3396 if_register(&wg->wg_if); 3401 if_register(&wg->wg_if);
3397 3402
3398 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t)); 3403 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t));
3399 3404
3400 return 0; 3405 return 0;
3401} 3406}
3402 3407
3403static int 3408static int
3404wg_clone_create(struct if_clone *ifc, int unit) 3409wg_clone_create(struct if_clone *ifc, int unit)
3405{ 3410{
3406 struct wg_softc *wg; 3411 struct wg_softc *wg;
3407 int error; 3412 int error;
3408 3413
3409 wg = kmem_zalloc(sizeof(struct wg_softc), KM_SLEEP); 3414 wg = kmem_zalloc(sizeof(struct wg_softc), KM_SLEEP);
3410 3415
3411 if_initname(&wg->wg_if, ifc->ifc_name, unit); 3416 if_initname(&wg->wg_if, ifc->ifc_name, unit);
3412 3417
3413 error = wg_worker_init(wg); 3418 error = wg_worker_init(wg);
3414 if (error != 0) { 3419 if (error != 0) {
3415 kmem_free(wg, sizeof(struct wg_softc)); 3420 kmem_free(wg, sizeof(struct wg_softc));
3416 return error; 3421 return error;
3417 } 3422 }
3418 3423
3419 rn_inithead((void **)&wg->wg_rtable_ipv4, 3424 rn_inithead((void **)&wg->wg_rtable_ipv4,
3420 offsetof(struct sockaddr_in, sin_addr) * NBBY); 3425 offsetof(struct sockaddr_in, sin_addr) * NBBY);
3421#ifdef INET6 3426#ifdef INET6
3422 rn_inithead((void **)&wg->wg_rtable_ipv6, 3427 rn_inithead((void **)&wg->wg_rtable_ipv6,
3423 offsetof(struct sockaddr_in6, sin6_addr) * NBBY); 3428 offsetof(struct sockaddr_in6, sin6_addr) * NBBY);
3424#endif 3429#endif
3425 3430
3426 PSLIST_INIT(&wg->wg_peers); 3431 PSLIST_INIT(&wg->wg_peers);
3427 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3432 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3428 wg->wg_rwlock = rw_obj_alloc(); 3433 wg->wg_rwlock = rw_obj_alloc();
3429 wg->wg_ops = &wg_ops_rumpkernel; 3434 wg->wg_ops = &wg_ops_rumpkernel;
3430 3435
3431 error = wg_if_attach(wg); 3436 error = wg_if_attach(wg);
3432 if (error != 0) { 3437 if (error != 0) {
3433 wg_worker_destroy(wg); 3438 wg_worker_destroy(wg);
3434 if (wg->wg_rtable_ipv4 != NULL) 3439 if (wg->wg_rtable_ipv4 != NULL)
3435 free(wg->wg_rtable_ipv4, M_RTABLE); 3440 free(wg->wg_rtable_ipv4, M_RTABLE);
3436 if (wg->wg_rtable_ipv6 != NULL) 3441 if (wg->wg_rtable_ipv6 != NULL)
3437 free(wg->wg_rtable_ipv6, M_RTABLE); 3442 free(wg->wg_rtable_ipv6, M_RTABLE);
3438 PSLIST_DESTROY(&wg->wg_peers); 3443 PSLIST_DESTROY(&wg->wg_peers);
3439 mutex_obj_free(wg->wg_lock); 3444 mutex_obj_free(wg->wg_lock);
3440 kmem_free(wg, sizeof(struct wg_softc)); 3445 kmem_free(wg, sizeof(struct wg_softc));
3441 return error; 3446 return error;
3442 } 3447 }
3443 3448
3444 mutex_enter(&wg_softcs.lock); 3449 mutex_enter(&wg_softcs.lock);
3445 LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list); 3450 LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list);
3446 mutex_exit(&wg_softcs.lock); 3451 mutex_exit(&wg_softcs.lock);
3447 3452
3448 return 0; 3453 return 0;
3449} 3454}
3450 3455
3451static int 3456static int
3452wg_clone_destroy(struct ifnet *ifp) 3457wg_clone_destroy(struct ifnet *ifp)
3453{ 3458{
3454 struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if); 3459 struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if);
3455 3460
3456 mutex_enter(&wg_softcs.lock); 3461 mutex_enter(&wg_softcs.lock);
3457 LIST_REMOVE(wg, wg_list); 3462 LIST_REMOVE(wg, wg_list);
3458 mutex_exit(&wg_softcs.lock); 3463 mutex_exit(&wg_softcs.lock);
3459 3464
3460#ifdef WG_RUMPKERNEL 3465#ifdef WG_RUMPKERNEL
3461 if (wg_user_mode(wg)) { 3466 if (wg_user_mode(wg)) {
3462 rumpuser_wg_destroy(wg->wg_user); 3467 rumpuser_wg_destroy(wg->wg_user);
3463 wg->wg_user = NULL; 3468 wg->wg_user = NULL;
3464 } 3469 }
3465#endif 3470#endif
3466 3471
3467 bpf_detach(ifp); 3472 bpf_detach(ifp);
3468 if_detach(ifp); 3473 if_detach(ifp);
3469 wg_worker_destroy(wg); 3474 wg_worker_destroy(wg);
3470 wg_destroy_all_peers(wg); 3475 wg_destroy_all_peers(wg);
3471 if (wg->wg_rtable_ipv4 != NULL) 3476 if (wg->wg_rtable_ipv4 != NULL)
3472 free(wg->wg_rtable_ipv4, M_RTABLE); 3477 free(wg->wg_rtable_ipv4, M_RTABLE);
3473 if (wg->wg_rtable_ipv6 != NULL) 3478 if (wg->wg_rtable_ipv6 != NULL)
3474 free(wg->wg_rtable_ipv6, M_RTABLE); 3479 free(wg->wg_rtable_ipv6, M_RTABLE);
3475 3480
3476 PSLIST_DESTROY(&wg->wg_peers); 3481 PSLIST_DESTROY(&wg->wg_peers);
3477 mutex_obj_free(wg->wg_lock); 3482 mutex_obj_free(wg->wg_lock);
3478 rw_obj_free(wg->wg_rwlock); 3483 rw_obj_free(wg->wg_rwlock);
3479 3484
3480 kmem_free(wg, sizeof(struct wg_softc)); 3485 kmem_free(wg, sizeof(struct wg_softc));
3481 3486
3482 return 0; 3487 return 0;
3483} 3488}
3484 3489
3485static struct wg_peer * 3490static struct wg_peer *
3486wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa, 3491wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa,
3487 struct psref *psref) 3492 struct psref *psref)
3488{ 3493{
3489 struct radix_node_head *rnh; 3494 struct radix_node_head *rnh;
3490 struct radix_node *rn; 3495 struct radix_node *rn;
3491 struct wg_peer *wgp = NULL; 3496 struct wg_peer *wgp = NULL;
3492 struct wg_allowedip *wga; 3497 struct wg_allowedip *wga;
3493 3498
3494#ifdef WG_DEBUG_LOG 3499#ifdef WG_DEBUG_LOG
3495 char addrstr[128]; 3500 char addrstr[128];
3496 sockaddr_format(sa, addrstr, sizeof(addrstr)); 3501 sockaddr_format(sa, addrstr, sizeof(addrstr));
3497 WG_DLOG("sa=%s\n", addrstr); 3502 WG_DLOG("sa=%s\n", addrstr);
3498#endif 3503#endif
3499 3504
3500 rw_enter(wg->wg_rwlock, RW_READER); 3505 rw_enter(wg->wg_rwlock, RW_READER);
3501 3506
3502 rnh = wg_rnh(wg, sa->sa_family); 3507 rnh = wg_rnh(wg, sa->sa_family);
3503 if (rnh == NULL) 3508 if (rnh == NULL)
3504 goto out; 3509 goto out;
3505 3510
3506 rn = rnh->rnh_matchaddr(sa, rnh); 3511 rn = rnh->rnh_matchaddr(sa, rnh);
3507 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) 3512 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
3508 goto out; 3513 goto out;
3509 3514
3510 WG_TRACE("success"); 3515 WG_TRACE("success");
3511 3516
3512 wga = container_of(rn, struct wg_allowedip, wga_nodes[0]); 3517 wga = container_of(rn, struct wg_allowedip, wga_nodes[0]);
3513 wgp = wga->wga_peer; 3518 wgp = wga->wga_peer;
3514 wg_get_peer(wgp, psref); 3519 wg_get_peer(wgp, psref);
3515 3520
3516out: 3521out:
3517 rw_exit(wg->wg_rwlock); 3522 rw_exit(wg->wg_rwlock);
3518 return wgp; 3523 return wgp;
3519} 3524}
3520 3525
3521static void 3526static void
3522wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp, 3527wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp,
3523 struct wg_session *wgs, struct wg_msg_data *wgmd) 3528 struct wg_session *wgs, struct wg_msg_data *wgmd)
3524{ 3529{
3525 3530
3526 memset(wgmd, 0, sizeof(*wgmd)); 3531 memset(wgmd, 0, sizeof(*wgmd));
3527 wgmd->wgmd_type = WG_MSG_TYPE_DATA; 3532 wgmd->wgmd_type = WG_MSG_TYPE_DATA;
3528 wgmd->wgmd_receiver = wgs->wgs_receiver_index; 3533 wgmd->wgmd_receiver = wgs->wgs_receiver_index;
3529 /* [W] 5.4.6: msg.counter := Nm^send */ 3534 /* [W] 5.4.6: msg.counter := Nm^send */
3530 /* [W] 5.4.6: Nm^send := Nm^send + 1 */ 3535 /* [W] 5.4.6: Nm^send := Nm^send + 1 */
3531 wgmd->wgmd_counter = wg_session_inc_send_counter(wgs); 3536 wgmd->wgmd_counter = wg_session_inc_send_counter(wgs);
3532 WG_DLOG("counter=%"PRIu64"\n", wgmd->wgmd_counter); 3537 WG_DLOG("counter=%"PRIu64"\n", wgmd->wgmd_counter);
3533} 3538}
3534 3539
3535static int 3540static int
3536wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 3541wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
3537 const struct rtentry *rt) 3542 const struct rtentry *rt)
3538{ 3543{
3539 struct wg_softc *wg = ifp->if_softc; 3544 struct wg_softc *wg = ifp->if_softc;
3540 int error = 0; 3545 int error = 0;
3541 int bound; 3546 int bound;
3542 struct psref psref; 3547 struct psref psref;
3543 3548
3544 /* TODO make the nest limit configurable via sysctl */ 3549 /* TODO make the nest limit configurable via sysctl */
3545 error = if_tunnel_check_nesting(ifp, m, 1); 3550 error = if_tunnel_check_nesting(ifp, m, 1);
3546 if (error != 0) { 3551 if (error != 0) {
3547 m_freem(m); 3552 m_freem(m);
3548 WGLOG(LOG_ERR, "tunneling loop detected and packet dropped\n"); 3553 WGLOG(LOG_ERR, "tunneling loop detected and packet dropped\n");
3549 return error; 3554 return error;
3550 } 3555 }
3551 3556
3552 bound = curlwp_bind(); 3557 bound = curlwp_bind();
3553 3558
3554 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 3559 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
3555 3560
3556 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT); 3561 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT);
3557 3562
3558 m->m_flags &= ~(M_BCAST|M_MCAST); 3563 m->m_flags &= ~(M_BCAST|M_MCAST);
3559 3564
3560 struct wg_peer *wgp = wg_pick_peer_by_sa(wg, dst, &psref); 3565 struct wg_peer *wgp = wg_pick_peer_by_sa(wg, dst, &psref);
3561 if (wgp == NULL) { 3566 if (wgp == NULL) {
3562 WG_TRACE("peer not found"); 3567 WG_TRACE("peer not found");
3563 error = EHOSTUNREACH; 3568 error = EHOSTUNREACH;
3564 goto error; 3569 goto error;
3565 } 3570 }
3566 3571
3567 /* Clear checksum-offload flags. */ 3572 /* Clear checksum-offload flags. */
3568 m->m_pkthdr.csum_flags = 0; 3573 m->m_pkthdr.csum_flags = 0;
3569 m->m_pkthdr.csum_data = 0; 3574 m->m_pkthdr.csum_data = 0;
3570 3575
3571 if (!pcq_put(wgp->wgp_q, m)) { 3576 if (!pcq_put(wgp->wgp_q, m)) {
3572 error = ENOBUFS; 3577 error = ENOBUFS;
3573 goto error; 3578 goto error;
3574 } 3579 }
3575 3580
3576 struct psref psref_wgs; 3581 struct psref psref_wgs;
3577 struct wg_session *wgs; 3582 struct wg_session *wgs;
3578 wgs = wg_get_stable_session(wgp, &psref_wgs); 3583 wgs = wg_get_stable_session(wgp, &psref_wgs);
3579 if (wgs->wgs_state == WGS_STATE_ESTABLISHED && 3584 if (wgs->wgs_state == WGS_STATE_ESTABLISHED &&
3580 !wg_session_hit_limits(wgs)) { 3585 !wg_session_hit_limits(wgs)) {
3581 kpreempt_disable(); 3586 kpreempt_disable();
3582 softint_schedule(wgp->wgp_si); 3587 softint_schedule(wgp->wgp_si);
3583 kpreempt_enable(); 3588 kpreempt_enable();
3584 WG_TRACE("softint scheduled"); 3589 WG_TRACE("softint scheduled");
3585 } else { 3590 } else {
3586 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3591 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3587 WG_TRACE("softint NOT scheduled"); 3592 WG_TRACE("softint NOT scheduled");
3588 } 3593 }
3589 wg_put_session(wgs, &psref_wgs); 3594 wg_put_session(wgs, &psref_wgs);
3590 wg_put_peer(wgp, &psref); 3595 wg_put_peer(wgp, &psref);
3591 3596
3592 return 0; 3597 return 0;
3593 3598
3594error: 3599error:
3595 if (wgp != NULL) 3600 if (wgp != NULL)
3596 wg_put_peer(wgp, &psref); 3601 wg_put_peer(wgp, &psref);
3597 if (m != NULL) 3602 if (m != NULL)
3598 m_freem(m); 3603 m_freem(m);
3599 curlwp_bindx(bound); 3604 curlwp_bindx(bound);
3600 return error; 3605 return error;
3601} 3606}
3602 3607
3603static int 3608static int
3604wg_send_udp(struct wg_peer *wgp, struct mbuf *m) 3609wg_send_udp(struct wg_peer *wgp, struct mbuf *m)
3605{ 3610{
3606 struct psref psref; 3611 struct psref psref;
3607 struct wg_sockaddr *wgsa; 3612 struct wg_sockaddr *wgsa;
3608 int error; 3613 int error;
3609 struct socket *so = wg_get_so_by_peer(wgp); 3614 struct socket *so = wg_get_so_by_peer(wgp);
3610 3615
3611 solock(so); 3616 solock(so);
3612 wgsa = wg_get_endpoint_sa(wgp, &psref); 3617 wgsa = wg_get_endpoint_sa(wgp, &psref);
3613 if (wgsatosa(wgsa)->sa_family == AF_INET) { 3618 if (wgsatosa(wgsa)->sa_family == AF_INET) {
3614 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp); 3619 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp);
3615 } else { 3620 } else {
3616#ifdef INET6 3621#ifdef INET6
3617 error = udp6_output(sotoin6pcb(so), m, wgsatosin6(wgsa), 3622 error = udp6_output(sotoin6pcb(so), m, wgsatosin6(wgsa),
3618 NULL, curlwp); 3623 NULL, curlwp);
3619#else 3624#else
3620 error = EPROTONOSUPPORT; 3625 error = EPROTONOSUPPORT;
3621#endif 3626#endif
3622 } 3627 }
3623 wg_put_sa(wgp, wgsa, &psref); 3628 wg_put_sa(wgp, wgsa, &psref);
3624 sounlock(so); 3629 sounlock(so);
3625 3630
3626 return error; 3631 return error;
3627} 3632}
3628 3633
3629/* Inspired by pppoe_get_mbuf */ 3634/* Inspired by pppoe_get_mbuf */
3630static struct mbuf * 3635static struct mbuf *
3631wg_get_mbuf(size_t leading_len, size_t len) 3636wg_get_mbuf(size_t leading_len, size_t len)
3632{ 3637{
3633 struct mbuf *m; 3638 struct mbuf *m;
3634 3639
3635 m = m_gethdr(M_DONTWAIT, MT_DATA); 3640 m = m_gethdr(M_DONTWAIT, MT_DATA);
3636 if (m == NULL) 3641 if (m == NULL)
3637 return NULL; 3642 return NULL;
3638 if (len + leading_len > MHLEN) { 3643 if (len + leading_len > MHLEN) {
3639 m_clget(m, M_DONTWAIT); 3644 m_clget(m, M_DONTWAIT);
3640 if ((m->m_flags & M_EXT) == 0) { 3645 if ((m->m_flags & M_EXT) == 0) {
3641 m_free(m); 3646 m_free(m);
3642 return NULL; 3647 return NULL;
3643 } 3648 }
3644 } 3649 }
3645 m->m_data += leading_len; 3650 m->m_data += leading_len;
3646 m->m_pkthdr.len = m->m_len = len; 3651 m->m_pkthdr.len = m->m_len = len;
3647 3652
3648 return m; 3653 return m;
3649} 3654}
3650 3655
3651static int 3656static int
3652wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs, 3657wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs,
3653 struct mbuf *m) 3658 struct mbuf *m)
3654{ 3659{
3655 struct wg_softc *wg = wgp->wgp_sc; 3660 struct wg_softc *wg = wgp->wgp_sc;
3656 int error; 3661 int error;
3657 size_t inner_len, padded_len, encrypted_len; 3662 size_t inner_len, padded_len, encrypted_len;
3658 char *padded_buf = NULL; 3663 char *padded_buf = NULL;
3659 size_t mlen; 3664 size_t mlen;
3660 struct wg_msg_data *wgmd; 3665 struct wg_msg_data *wgmd;
3661 bool free_padded_buf = false; 3666 bool free_padded_buf = false;
3662 struct mbuf *n; 3667 struct mbuf *n;
3663 size_t leading_len = max_linkhdr + sizeof(struct ip6_hdr) + 3668 size_t leading_len = max_linkhdr + sizeof(struct ip6_hdr) +
3664 sizeof(struct udphdr); 3669 sizeof(struct udphdr);
3665 3670
3666 mlen = m_length(m); 3671 mlen = m_length(m);
3667 inner_len = mlen; 3672 inner_len = mlen;
3668 padded_len = roundup(mlen, 16); 3673 padded_len = roundup(mlen, 16);
3669 encrypted_len = padded_len + WG_AUTHTAG_LEN; 3674 encrypted_len = padded_len + WG_AUTHTAG_LEN;
3670 WG_DLOG("inner=%lu, padded=%lu, encrypted_len=%lu\n", 3675 WG_DLOG("inner=%lu, padded=%lu, encrypted_len=%lu\n",
3671 inner_len, padded_len, encrypted_len); 3676 inner_len, padded_len, encrypted_len);
3672 if (mlen != 0) { 3677 if (mlen != 0) {
3673 bool success; 3678 bool success;
3674 success = m_ensure_contig(&m, padded_len); 3679 success = m_ensure_contig(&m, padded_len);
3675 if (success) { 3680 if (success) {
3676 padded_buf = mtod(m, char *); 3681 padded_buf = mtod(m, char *);
3677 } else { 3682 } else {
3678 padded_buf = kmem_intr_alloc(padded_len, KM_NOSLEEP); 3683 padded_buf = kmem_intr_alloc(padded_len, KM_NOSLEEP);
3679 if (padded_buf == NULL) { 3684 if (padded_buf == NULL) {
3680 error = ENOBUFS; 3685 error = ENOBUFS;
3681 goto end; 3686 goto end;
3682 } 3687 }
3683 free_padded_buf = true; 3688 free_padded_buf = true;
3684 m_copydata(m, 0, mlen, padded_buf); 3689 m_copydata(m, 0, mlen, padded_buf);
3685 } 3690 }
3686 memset(padded_buf + mlen, 0, padded_len - inner_len); 3691 memset(padded_buf + mlen, 0, padded_len - inner_len);
3687 } 3692 }
3688 3693
3689 n = wg_get_mbuf(leading_len, sizeof(*wgmd) + encrypted_len); 3694 n = wg_get_mbuf(leading_len, sizeof(*wgmd) + encrypted_len);
3690 if (n == NULL) { 3695 if (n == NULL) {
3691 error = ENOBUFS; 3696 error = ENOBUFS;
3692 goto end; 3697 goto end;
3693 } 3698 }
3694 KASSERT(n->m_len >= sizeof(*wgmd)); 3699 KASSERT(n->m_len >= sizeof(*wgmd));
3695 wgmd = mtod(n, struct wg_msg_data *); 3700 wgmd = mtod(n, struct wg_msg_data *);
3696 wg_fill_msg_data(wg, wgp, wgs, wgmd); 3701 wg_fill_msg_data(wg, wgp, wgs, wgmd);
3697 /* [W] 5.4.6: AEAD(Tm^send, Nm^send, P, e) */ 3702 /* [W] 5.4.6: AEAD(Tm^send, Nm^send, P, e) */
3698 wg_algo_aead_enc((char *)wgmd + sizeof(*wgmd), encrypted_len, 3703 wg_algo_aead_enc((char *)wgmd + sizeof(*wgmd), encrypted_len,
3699 wgs->wgs_tkey_send, wgmd->wgmd_counter, padded_buf, padded_len, 3704 wgs->wgs_tkey_send, wgmd->wgmd_counter, padded_buf, padded_len,
3700 NULL, 0); 3705 NULL, 0);
3701 3706
3702 error = wg->wg_ops->send_data_msg(wgp, n); 3707 error = wg->wg_ops->send_data_msg(wgp, n);
3703 if (error == 0) { 3708 if (error == 0) {
3704 struct ifnet *ifp = &wg->wg_if; 3709 struct ifnet *ifp = &wg->wg_if;
3705 if_statadd(ifp, if_obytes, mlen); 3710 if_statadd(ifp, if_obytes, mlen);
3706 if_statinc(ifp, if_opackets); 3711 if_statinc(ifp, if_opackets);
3707 if (wgs->wgs_is_initiator && 3712 if (wgs->wgs_is_initiator &&
3708 wgs->wgs_time_last_data_sent == 0) { 3713 wgs->wgs_time_last_data_sent == 0) {
3709 /* 3714 /*
3710 * [W] 6.2 Transport Message Limits 3715 * [W] 6.2 Transport Message Limits
3711 * "if a peer is the initiator of a current secure 3716 * "if a peer is the initiator of a current secure
3712 * session, WireGuard will send a handshake initiation 3717 * session, WireGuard will send a handshake initiation
3713 * message to begin a new secure session if, after 3718 * message to begin a new secure session if, after
3714 * transmitting a transport data message, the current 3719 * transmitting a transport data message, the current
3715 * secure session is REKEY-AFTER-TIME seconds old," 3720 * secure session is REKEY-AFTER-TIME seconds old,"
3716 */ 3721 */
3717 wg_schedule_rekey_timer(wgp); 3722 wg_schedule_rekey_timer(wgp);
3718 } 3723 }
3719 wgs->wgs_time_last_data_sent = time_uptime; 3724 wgs->wgs_time_last_data_sent = time_uptime;
3720 if (wg_session_get_send_counter(wgs) >= 3725 if (wg_session_get_send_counter(wgs) >=
3721 wg_rekey_after_messages) { 3726 wg_rekey_after_messages) {
3722 /* 3727 /*
3723 * [W] 6.2 Transport Message Limits 3728 * [W] 6.2 Transport Message Limits
3724 * "WireGuard will try to create a new session, by 3729 * "WireGuard will try to create a new session, by
3725 * sending a handshake initiation message (section 3730 * sending a handshake initiation message (section
3726 * 5.4.2), after it has sent REKEY-AFTER-MESSAGES 3731 * 5.4.2), after it has sent REKEY-AFTER-MESSAGES
3727 * transport data messages..." 3732 * transport data messages..."
3728 */ 3733 */
3729 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3734 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3730 } 3735 }
3731 } 3736 }
3732end: 3737end:
3733 m_freem(m); 3738 m_freem(m);
3734 if (free_padded_buf) 3739 if (free_padded_buf)
3735 kmem_intr_free(padded_buf, padded_len); 3740 kmem_intr_free(padded_buf, padded_len);
3736 return error; 3741 return error;
3737} 3742}
3738 3743
3739static void 3744static void
3740wg_input(struct ifnet *ifp, struct mbuf *m, const int af) 3745wg_input(struct ifnet *ifp, struct mbuf *m, const int af)
3741{ 3746{
3742 pktqueue_t *pktq; 3747 pktqueue_t *pktq;
3743 size_t pktlen; 3748 size_t pktlen;
3744 3749
3745 KASSERT(af == AF_INET || af == AF_INET6); 3750 KASSERT(af == AF_INET || af == AF_INET6);
3746 3751
3747 WG_TRACE(""); 3752 WG_TRACE("");
3748 3753
3749 m_set_rcvif(m, ifp); 3754 m_set_rcvif(m, ifp);
3750 pktlen = m->m_pkthdr.len; 3755 pktlen = m->m_pkthdr.len;
3751 3756
3752 bpf_mtap_af(ifp, af, m, BPF_D_IN); 3757 bpf_mtap_af(ifp, af, m, BPF_D_IN);
3753 3758
3754 switch (af) { 3759 switch (af) {
3755 case AF_INET: 3760 case AF_INET:
3756 pktq = ip_pktq; 3761 pktq = ip_pktq;
3757 break; 3762 break;
3758#ifdef INET6 3763#ifdef INET6
3759 case AF_INET6: 3764 case AF_INET6:
3760 pktq = ip6_pktq; 3765 pktq = ip6_pktq;
3761 break; 3766 break;
3762#endif 3767#endif
3763 default: 3768 default:
3764 panic("invalid af=%d", af); 3769 panic("invalid af=%d", af);
3765 } 3770 }
3766 3771
3767 const u_int h = curcpu()->ci_index; 3772 const u_int h = curcpu()->ci_index;
3768 if (__predict_true(pktq_enqueue(pktq, m, h))) { 3773 if (__predict_true(pktq_enqueue(pktq, m, h))) {
3769 if_statadd(ifp, if_ibytes, pktlen); 3774 if_statadd(ifp, if_ibytes, pktlen);
3770 if_statinc(ifp, if_ipackets); 3775 if_statinc(ifp, if_ipackets);
3771 } else { 3776 } else {
3772 m_freem(m); 3777 m_freem(m);
3773 } 3778 }
3774} 3779}
3775 3780
3776static void 3781static void
3777wg_calc_pubkey(uint8_t pubkey[WG_STATIC_KEY_LEN], 3782wg_calc_pubkey(uint8_t pubkey[WG_STATIC_KEY_LEN],
3778 const uint8_t privkey[WG_STATIC_KEY_LEN]) 3783 const uint8_t privkey[WG_STATIC_KEY_LEN])
3779{ 3784{
3780 3785
3781 crypto_scalarmult_base(pubkey, privkey); 3786 crypto_scalarmult_base(pubkey, privkey);
3782} 3787}
3783 3788
3784static int 3789static int
3785wg_rtable_add_route(struct wg_softc *wg, struct wg_allowedip *wga) 3790wg_rtable_add_route(struct wg_softc *wg, struct wg_allowedip *wga)
3786{ 3791{
3787 struct radix_node_head *rnh; 3792 struct radix_node_head *rnh;
3788 struct radix_node *rn; 3793 struct radix_node *rn;
3789 int error = 0; 3794 int error = 0;
3790 3795
3791 rw_enter(wg->wg_rwlock, RW_WRITER); 3796 rw_enter(wg->wg_rwlock, RW_WRITER);
3792 rnh = wg_rnh(wg, wga->wga_family); 3797 rnh = wg_rnh(wg, wga->wga_family);
3793 KASSERT(rnh != NULL); 3798 KASSERT(rnh != NULL);
3794 rn = rnh->rnh_addaddr(&wga->wga_sa_addr, &wga->wga_sa_mask, rnh, 3799 rn = rnh->rnh_addaddr(&wga->wga_sa_addr, &wga->wga_sa_mask, rnh,
3795 wga->wga_nodes); 3800 wga->wga_nodes);
3796 rw_exit(wg->wg_rwlock); 3801 rw_exit(wg->wg_rwlock);
3797 3802
3798 if (rn == NULL) 3803 if (rn == NULL)
3799 error = EEXIST; 3804 error = EEXIST;
3800 3805
3801 return error; 3806 return error;
3802} 3807}
3803 3808
3804static int 3809static int
3805wg_handle_prop_peer(struct wg_softc *wg, prop_dictionary_t peer, 3810wg_handle_prop_peer(struct wg_softc *wg, prop_dictionary_t peer,
3806 struct wg_peer **wgpp) 3811 struct wg_peer **wgpp)
3807{ 3812{
3808 int error = 0; 3813 int error = 0;
3809 const void *pubkey; 3814 const void *pubkey;
3810 size_t pubkey_len; 3815 size_t pubkey_len;
3811 const void *psk; 3816 const void *psk;
3812 size_t psk_len; 3817 size_t psk_len;
3813 const char *name = NULL; 3818 const char *name = NULL;
3814 3819
3815 if (prop_dictionary_get_string(peer, "name", &name)) { 3820 if (prop_dictionary_get_string(peer, "name", &name)) {
3816 if (strlen(name) > WG_PEER_NAME_MAXLEN) { 3821 if (strlen(name) > WG_PEER_NAME_MAXLEN) {
3817 error = EINVAL; 3822 error = EINVAL;
3818 goto out; 3823 goto out;
3819 } 3824 }
3820 } 3825 }
3821 3826
3822 if (!prop_dictionary_get_data(peer, "public_key", 3827 if (!prop_dictionary_get_data(peer, "public_key",
3823 &pubkey, &pubkey_len)) { 3828 &pubkey, &pubkey_len)) {
3824 error = EINVAL; 3829 error = EINVAL;
3825 goto out; 3830 goto out;
3826 } 3831 }
3827#ifdef WG_DEBUG_DUMP 3832#ifdef WG_DEBUG_DUMP
3828 log(LOG_DEBUG, "pubkey=%p, pubkey_len=%lu\n", pubkey, pubkey_len); 3833 log(LOG_DEBUG, "pubkey=%p, pubkey_len=%lu\n", pubkey, pubkey_len);
3829 for (int _i = 0; _i < pubkey_len; _i++) 3834 for (int _i = 0; _i < pubkey_len; _i++)
3830 log(LOG_DEBUG, "%c", ((const char *)pubkey)[_i]); 3835 log(LOG_DEBUG, "%c", ((const char *)pubkey)[_i]);
3831 log(LOG_DEBUG, "\n"); 3836 log(LOG_DEBUG, "\n");
3832#endif 3837#endif
3833 3838
3834 struct wg_peer *wgp = wg_alloc_peer(wg); 3839 struct wg_peer *wgp = wg_alloc_peer(wg);
3835 memcpy(wgp->wgp_pubkey, pubkey, sizeof(wgp->wgp_pubkey)); 3840 memcpy(wgp->wgp_pubkey, pubkey, sizeof(wgp->wgp_pubkey));
3836 if (name != NULL) 3841 if (name != NULL)
3837 strncpy(wgp->wgp_name, name, sizeof(wgp->wgp_name)); 3842 strncpy(wgp->wgp_name, name, sizeof(wgp->wgp_name));
3838 3843
3839 if (prop_dictionary_get_data(peer, "preshared_key", &psk, &psk_len)) { 3844 if (prop_dictionary_get_data(peer, "preshared_key", &psk, &psk_len)) {
3840 if (psk_len != sizeof(wgp->wgp_psk)) { 3845 if (psk_len != sizeof(wgp->wgp_psk)) {
3841 error = EINVAL; 3846 error = EINVAL;
3842 goto out; 3847 goto out;
3843 } 3848 }
3844 memcpy(wgp->wgp_psk, psk, sizeof(wgp->wgp_psk)); 3849 memcpy(wgp->wgp_psk, psk, sizeof(wgp->wgp_psk));
3845 } 3850 }
3846 3851
3847 struct sockaddr_storage sockaddr; 3852 struct sockaddr_storage sockaddr;
3848 const void *addr; 3853 const void *addr;
3849 size_t addr_len; 3854 size_t addr_len;
3850 3855
3851 if (!prop_dictionary_get_data(peer, "endpoint", &addr, &addr_len)) 3856 if (!prop_dictionary_get_data(peer, "endpoint", &addr, &addr_len))
3852 goto skip_endpoint; 3857 goto skip_endpoint;
3853 memcpy(&sockaddr, addr, addr_len); 3858 memcpy(&sockaddr, addr, addr_len);
3854 switch (sockaddr.ss_family) { 3859 switch (sockaddr.ss_family) {
3855 case AF_INET: { 3860 case AF_INET: {
3856 struct sockaddr_in sin; 3861 struct sockaddr_in sin;
3857 sockaddr_copy(sintosa(&sin), sizeof(sin), 3862 sockaddr_copy(sintosa(&sin), sizeof(sin),
3858 (const struct sockaddr *)&sockaddr); 3863 (const struct sockaddr *)&sockaddr);
3859 sockaddr_copy(sintosa(&wgp->wgp_sin), 3864 sockaddr_copy(sintosa(&wgp->wgp_sin),
3860 sizeof(wgp->wgp_sin), (const struct sockaddr *)&sockaddr); 3865 sizeof(wgp->wgp_sin), (const struct sockaddr *)&sockaddr);
3861 char addrstr[128]; 3866 char addrstr[128];
3862 sockaddr_format(sintosa(&sin), addrstr, sizeof(addrstr)); 3867 sockaddr_format(sintosa(&sin), addrstr, sizeof(addrstr));
3863 WG_DLOG("addr=%s\n", addrstr); 3868 WG_DLOG("addr=%s\n", addrstr);
3864 break; 3869 break;
3865 } 3870 }
3866#ifdef INET6 3871#ifdef INET6
3867 case AF_INET6: { 3872 case AF_INET6: {
3868 struct sockaddr_in6 sin6; 3873 struct sockaddr_in6 sin6;
3869 char addrstr[128]; 3874 char addrstr[128];
3870 sockaddr_copy(sintosa(&sin6), sizeof(sin6), 3875 sockaddr_copy(sintosa(&sin6), sizeof(sin6),
3871 (const struct sockaddr *)&sockaddr); 3876 (const struct sockaddr *)&sockaddr);
3872 sockaddr_format(sintosa(&sin6), addrstr, sizeof(addrstr)); 3877 sockaddr_format(sintosa(&sin6), addrstr, sizeof(addrstr));
3873 WG_DLOG("addr=%s\n", addrstr); 3878 WG_DLOG("addr=%s\n", addrstr);
3874 sockaddr_copy(sin6tosa(&wgp->wgp_sin6), 3879 sockaddr_copy(sin6tosa(&wgp->wgp_sin6),
3875 sizeof(wgp->wgp_sin6), (const struct sockaddr *)&sockaddr); 3880 sizeof(wgp->wgp_sin6), (const struct sockaddr *)&sockaddr);
3876 break; 3881 break;
3877 } 3882 }
3878#endif 3883#endif
3879 default: 3884 default:
3880 break; 3885 break;
3881 } 3886 }
3882 wgp->wgp_endpoint_available = true; 3887 wgp->wgp_endpoint_available = true;
3883 3888
3884 prop_array_t allowedips; 3889 prop_array_t allowedips;
3885skip_endpoint: 3890skip_endpoint:
3886 allowedips = prop_dictionary_get(peer, "allowedips"); 3891 allowedips = prop_dictionary_get(peer, "allowedips");
3887 if (allowedips == NULL) 3892 if (allowedips == NULL)
3888 goto skip; 3893 goto skip;
3889 3894
3890 prop_object_iterator_t _it = prop_array_iterator(allowedips); 3895 prop_object_iterator_t _it = prop_array_iterator(allowedips);
3891 prop_dictionary_t prop_allowedip; 3896 prop_dictionary_t prop_allowedip;
3892 int j = 0; 3897 int j = 0;
3893 while ((prop_allowedip = prop_object_iterator_next(_it)) != NULL) { 3898 while ((prop_allowedip = prop_object_iterator_next(_it)) != NULL) {
3894 struct wg_allowedip *wga = &wgp->wgp_allowedips[j]; 3899 struct wg_allowedip *wga = &wgp->wgp_allowedips[j];
3895 3900
3896 if (!prop_dictionary_get_int(prop_allowedip, "family", 3901 if (!prop_dictionary_get_int(prop_allowedip, "family",
3897 &wga->wga_family)) 3902 &wga->wga_family))
3898 continue; 3903 continue;
3899 if (!prop_dictionary_get_data(prop_allowedip, "ip", 3904 if (!prop_dictionary_get_data(prop_allowedip, "ip",
3900 &addr, &addr_len)) 3905 &addr, &addr_len))
3901 continue; 3906 continue;
3902 if (!prop_dictionary_get_uint8(prop_allowedip, "cidr", 3907 if (!prop_dictionary_get_uint8(prop_allowedip, "cidr",
3903 &wga->wga_cidr)) 3908 &wga->wga_cidr))
3904 continue; 3909 continue;
3905 3910
3906 switch (wga->wga_family) { 3911 switch (wga->wga_family) {
3907 case AF_INET: { 3912 case AF_INET: {
3908 struct sockaddr_in sin; 3913 struct sockaddr_in sin;
3909 char addrstr[128]; 3914 char addrstr[128];
3910 struct in_addr mask; 3915 struct in_addr mask;
3911 struct sockaddr_in sin_mask; 3916 struct sockaddr_in sin_mask;
3912 3917
3913 if (addr_len != sizeof(struct in_addr)) 3918 if (addr_len != sizeof(struct in_addr))
3914 return EINVAL; 3919 return EINVAL;
3915 memcpy(&wga->wga_addr4, addr, addr_len); 3920 memcpy(&wga->wga_addr4, addr, addr_len);
3916 3921
3917 sockaddr_in_init(&sin, (const struct in_addr *)addr, 3922 sockaddr_in_init(&sin, (const struct in_addr *)addr,
3918 0); 3923 0);
3919 sockaddr_copy(&wga->wga_sa_addr, 3924 sockaddr_copy(&wga->wga_sa_addr,
3920 sizeof(sin), sintosa(&sin)); 3925 sizeof(sin), sintosa(&sin));
3921 3926
3922 sockaddr_format(sintosa(&sin), 3927 sockaddr_format(sintosa(&sin),
3923 addrstr, sizeof(addrstr)); 3928 addrstr, sizeof(addrstr));
3924 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr); 3929 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
3925 3930
3926 in_len2mask(&mask, wga->wga_cidr); 3931 in_len2mask(&mask, wga->wga_cidr);
3927 sockaddr_in_init(&sin_mask, &mask, 0); 3932 sockaddr_in_init(&sin_mask, &mask, 0);
3928 sockaddr_copy(&wga->wga_sa_mask, 3933 sockaddr_copy(&wga->wga_sa_mask,
3929 sizeof(sin_mask), sintosa(&sin_mask)); 3934 sizeof(sin_mask), sintosa(&sin_mask));
3930 3935
3931 break; 3936 break;
3932 } 3937 }
3933#ifdef INET6 3938#ifdef INET6
3934 case AF_INET6: { 3939 case AF_INET6: {
3935 struct sockaddr_in6 sin6; 3940 struct sockaddr_in6 sin6;
3936 char addrstr[128]; 3941 char addrstr[128];
3937 struct in6_addr mask; 3942 struct in6_addr mask;
3938 struct sockaddr_in6 sin6_mask; 3943 struct sockaddr_in6 sin6_mask;
3939 3944
3940 if (addr_len != sizeof(struct in6_addr)) 3945 if (addr_len != sizeof(struct in6_addr))
3941 return EINVAL; 3946 return EINVAL;
3942 memcpy(&wga->wga_addr6, addr, addr_len); 3947 memcpy(&wga->wga_addr6, addr, addr_len);
3943 3948
3944 sockaddr_in6_init(&sin6, (const struct in6_addr *)addr, 3949 sockaddr_in6_init(&sin6, (const struct in6_addr *)addr,
3945 0, 0, 0); 3950 0, 0, 0);
3946 sockaddr_copy(&wga->wga_sa_addr, 3951 sockaddr_copy(&wga->wga_sa_addr,
3947 sizeof(sin6), sin6tosa(&sin6)); 3952 sizeof(sin6), sin6tosa(&sin6));
3948 3953
3949 sockaddr_format(sin6tosa(&sin6), 3954 sockaddr_format(sin6tosa(&sin6),
3950 addrstr, sizeof(addrstr)); 3955 addrstr, sizeof(addrstr));
3951 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr); 3956 WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr);
3952 3957
3953 in6_prefixlen2mask(&mask, wga->wga_cidr); 3958 in6_prefixlen2mask(&mask, wga->wga_cidr);
3954 sockaddr_in6_init(&sin6_mask, &mask, 0, 0, 0); 3959 sockaddr_in6_init(&sin6_mask, &mask, 0, 0, 0);
3955 sockaddr_copy(&wga->wga_sa_mask, 3960 sockaddr_copy(&wga->wga_sa_mask,
3956 sizeof(sin6_mask), sin6tosa(&sin6_mask)); 3961 sizeof(sin6_mask), sin6tosa(&sin6_mask));