Thu Aug 27 02:53:47 2020 UTC ()
wg: Use m_pullup to make message header contiguous before processing.


(riastradh)
diff -r1.25 -r1.26 src/sys/net/if_wg.c

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

--- src/sys/net/if_wg.c 2020/08/27 02:52:33 1.25
+++ src/sys/net/if_wg.c 2020/08/27 02:53:47 1.26
@@ -1,1043 +1,1043 @@ @@ -1,1043 +1,1043 @@
1/* $NetBSD: if_wg.c,v 1.25 2020/08/27 02:52:33 riastradh Exp $ */ 1/* $NetBSD: if_wg.c,v 1.26 2020/08/27 02:53:47 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.25 2020/08/27 02:52:33 riastradh Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.26 2020/08/27 02:53:47 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
@@ -1347,2295 +1347,2310 @@ wg_handle_msg_init(struct wg_softc *wg,  @@ -1347,2295 +1347,2310 @@ wg_handle_msg_init(struct wg_softc *wg,
1347 wg_clear_states(wgs); 1347 wg_clear_states(wgs);
1348 wgs->wgs_state = WGS_STATE_UNKNOWN; 1348 wgs->wgs_state = WGS_STATE_UNKNOWN;
1349 } 1349 }
1350 if (wgs->wgs_state == WGS_STATE_INIT_ACTIVE) { 1350 if (wgs->wgs_state == WGS_STATE_INIT_ACTIVE) {
1351 WG_TRACE("Sesssion already initializing, ignoring the message"); 1351 WG_TRACE("Sesssion already initializing, ignoring the message");
1352 mutex_exit(wgs->wgs_lock); 1352 mutex_exit(wgs->wgs_lock);
1353 goto out_wgp; 1353 goto out_wgp;
1354 } 1354 }
1355 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) { 1355 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) {
1356 WG_TRACE("Sesssion already initializing, destroying old states"); 1356 WG_TRACE("Sesssion already initializing, destroying old states");
1357 wg_clear_states(wgs); 1357 wg_clear_states(wgs);
1358 } 1358 }
1359 wgs->wgs_state = WGS_STATE_INIT_PASSIVE; 1359 wgs->wgs_state = WGS_STATE_INIT_PASSIVE;
1360 reset_state_on_error = true; 1360 reset_state_on_error = true;
1361 wg_get_session(wgs, &psref_session); 1361 wg_get_session(wgs, &psref_session);
1362 mutex_exit(wgs->wgs_lock); 1362 mutex_exit(wgs->wgs_lock);
1363 1363
1364 wg_algo_mac_mac1(mac1, sizeof(mac1), 1364 wg_algo_mac_mac1(mac1, sizeof(mac1),
1365 wg->wg_pubkey, sizeof(wg->wg_pubkey), 1365 wg->wg_pubkey, sizeof(wg->wg_pubkey),
1366 (const uint8_t *)wgmi, offsetof(struct wg_msg_init, wgmi_mac1)); 1366 (const uint8_t *)wgmi, offsetof(struct wg_msg_init, wgmi_mac1));
1367 1367
1368 /* 1368 /*
1369 * [W] 5.3: Denial of Service Mitigation & Cookies 1369 * [W] 5.3: Denial of Service Mitigation & Cookies
1370 * "the responder, ..., must always reject messages with an invalid 1370 * "the responder, ..., must always reject messages with an invalid
1371 * msg.mac1" 1371 * msg.mac1"
1372 */ 1372 */
1373 if (!consttime_memequal(mac1, wgmi->wgmi_mac1, sizeof(mac1))) { 1373 if (!consttime_memequal(mac1, wgmi->wgmi_mac1, sizeof(mac1))) {
1374 WG_DLOG("mac1 is invalid\n"); 1374 WG_DLOG("mac1 is invalid\n");
1375 goto out; 1375 goto out;
1376 } 1376 }
1377 1377
1378 if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_INIT))) { 1378 if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_INIT))) {
1379 WG_TRACE("under load"); 1379 WG_TRACE("under load");
1380 /* 1380 /*
1381 * [W] 5.3: Denial of Service Mitigation & Cookies 1381 * [W] 5.3: Denial of Service Mitigation & Cookies
1382 * "the responder, ..., and when under load may reject messages 1382 * "the responder, ..., and when under load may reject messages
1383 * with an invalid msg.mac2. If the responder receives a 1383 * with an invalid msg.mac2. If the responder receives a
1384 * message with a valid msg.mac1 yet with an invalid msg.mac2, 1384 * message with a valid msg.mac1 yet with an invalid msg.mac2,
1385 * and is under load, it may respond with a cookie reply 1385 * and is under load, it may respond with a cookie reply
1386 * message" 1386 * message"
1387 */ 1387 */
1388 uint8_t zero[WG_MAC_LEN] = {0}; 1388 uint8_t zero[WG_MAC_LEN] = {0};
1389 if (consttime_memequal(wgmi->wgmi_mac2, zero, sizeof(zero))) { 1389 if (consttime_memequal(wgmi->wgmi_mac2, zero, sizeof(zero))) {
1390 WG_TRACE("sending a cookie message: no cookie included"); 1390 WG_TRACE("sending a cookie message: no cookie included");
1391 (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender, 1391 (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender,
1392 wgmi->wgmi_mac1, src); 1392 wgmi->wgmi_mac1, src);
1393 goto out; 1393 goto out;
1394 } 1394 }
1395 if (!wgp->wgp_last_sent_cookie_valid) { 1395 if (!wgp->wgp_last_sent_cookie_valid) {
1396 WG_TRACE("sending a cookie message: no cookie sent ever"); 1396 WG_TRACE("sending a cookie message: no cookie sent ever");
1397 (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender, 1397 (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender,
1398 wgmi->wgmi_mac1, src); 1398 wgmi->wgmi_mac1, src);
1399 goto out; 1399 goto out;
1400 } 1400 }
1401 uint8_t mac2[WG_MAC_LEN]; 1401 uint8_t mac2[WG_MAC_LEN];
1402 wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie, 1402 wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie,
1403 WG_COOKIE_LEN, (const uint8_t *)wgmi, 1403 WG_COOKIE_LEN, (const uint8_t *)wgmi,
1404 offsetof(struct wg_msg_init, wgmi_mac2), NULL, 0); 1404 offsetof(struct wg_msg_init, wgmi_mac2), NULL, 0);
1405 if (!consttime_memequal(mac2, wgmi->wgmi_mac2, sizeof(mac2))) { 1405 if (!consttime_memequal(mac2, wgmi->wgmi_mac2, sizeof(mac2))) {
1406 WG_DLOG("mac2 is invalid\n"); 1406 WG_DLOG("mac2 is invalid\n");
1407 goto out; 1407 goto out;
1408 } 1408 }
1409 WG_TRACE("under load, but continue to sending"); 1409 WG_TRACE("under load, but continue to sending");
1410 } 1410 }
1411 1411
1412 /* [N] 2.2: "ss" */ 1412 /* [N] 2.2: "ss" */
1413 /* Ci, k := KDF2(Ci, DH(Si^priv, Sr^pub)) */ 1413 /* Ci, k := KDF2(Ci, DH(Si^priv, Sr^pub)) */
1414 wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey); 1414 wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey);
1415 1415
1416 /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */ 1416 /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */
1417 wg_timestamp_t timestamp; 1417 wg_timestamp_t timestamp;
1418 error = wg_algo_aead_dec(timestamp, sizeof(timestamp), cipher_key, 0, 1418 error = wg_algo_aead_dec(timestamp, sizeof(timestamp), cipher_key, 0,
1419 wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp), 1419 wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp),
1420 hash, sizeof(hash)); 1420 hash, sizeof(hash));
1421 if (error != 0) { 1421 if (error != 0) {
1422 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 1422 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
1423 "wg_algo_aead_dec for timestamp failed\n"); 1423 "wg_algo_aead_dec for timestamp failed\n");
1424 goto out; 1424 goto out;
1425 } 1425 }
1426 /* Hi := HASH(Hi || msg.timestamp) */ 1426 /* Hi := HASH(Hi || msg.timestamp) */
1427 wg_algo_hash(hash, wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp)); 1427 wg_algo_hash(hash, wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp));
1428 1428
1429 /* 1429 /*
1430 * [W] 5.1 "The responder keeps track of the greatest timestamp 1430 * [W] 5.1 "The responder keeps track of the greatest timestamp
1431 * received per peer and discards packets containing 1431 * received per peer and discards packets containing
1432 * timestamps less than or equal to it." 1432 * timestamps less than or equal to it."
1433 */ 1433 */
1434 ret = memcmp(timestamp, wgp->wgp_timestamp_latest_init, 1434 ret = memcmp(timestamp, wgp->wgp_timestamp_latest_init,
1435 sizeof(timestamp)); 1435 sizeof(timestamp));
1436 if (ret <= 0) { 1436 if (ret <= 0) {
1437 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 1437 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
1438 "invalid init msg: timestamp is old\n"); 1438 "invalid init msg: timestamp is old\n");
1439 goto out; 1439 goto out;
1440 } 1440 }
1441 memcpy(wgp->wgp_timestamp_latest_init, timestamp, sizeof(timestamp)); 1441 memcpy(wgp->wgp_timestamp_latest_init, timestamp, sizeof(timestamp));
1442 1442
1443 memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash)); 1443 memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash));
1444 memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey)); 1444 memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey));
1445 memcpy(wgs->wgs_ephemeral_key_peer, wgmi->wgmi_ephemeral, 1445 memcpy(wgs->wgs_ephemeral_key_peer, wgmi->wgmi_ephemeral,
1446 sizeof(wgmi->wgmi_ephemeral)); 1446 sizeof(wgmi->wgmi_ephemeral));
1447 1447
1448 wg_update_endpoint_if_necessary(wgp, src); 1448 wg_update_endpoint_if_necessary(wgp, src);
1449 1449
1450 (void)wg_send_handshake_msg_resp(wg, wgp, wgmi); 1450 (void)wg_send_handshake_msg_resp(wg, wgp, wgmi);
1451 1451
1452 wg_calculate_keys(wgs, false); 1452 wg_calculate_keys(wgs, false);
1453 wg_clear_states(wgs); 1453 wg_clear_states(wgs);
1454 1454
1455 wg_put_session(wgs, &psref_session); 1455 wg_put_session(wgs, &psref_session);
1456 wg_put_peer(wgp, &psref_peer); 1456 wg_put_peer(wgp, &psref_peer);
1457 return; 1457 return;
1458 1458
1459out: 1459out:
1460 if (reset_state_on_error) { 1460 if (reset_state_on_error) {
1461 mutex_enter(wgs->wgs_lock); 1461 mutex_enter(wgs->wgs_lock);
1462 KASSERT(wgs->wgs_state == WGS_STATE_INIT_PASSIVE); 1462 KASSERT(wgs->wgs_state == WGS_STATE_INIT_PASSIVE);
1463 wgs->wgs_state = WGS_STATE_UNKNOWN; 1463 wgs->wgs_state = WGS_STATE_UNKNOWN;
1464 mutex_exit(wgs->wgs_lock); 1464 mutex_exit(wgs->wgs_lock);
1465 } 1465 }
1466 wg_put_session(wgs, &psref_session); 1466 wg_put_session(wgs, &psref_session);
1467out_wgp: 1467out_wgp:
1468 wg_put_peer(wgp, &psref_peer); 1468 wg_put_peer(wgp, &psref_peer);
1469} 1469}
1470 1470
1471static void 1471static void
1472wg_schedule_handshake_timeout_timer(struct wg_peer *wgp) 1472wg_schedule_handshake_timeout_timer(struct wg_peer *wgp)
1473{ 1473{
1474 1474
1475 mutex_enter(wgp->wgp_lock); 1475 mutex_enter(wgp->wgp_lock);
1476 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) { 1476 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) {
1477 callout_schedule(&wgp->wgp_handshake_timeout_timer, 1477 callout_schedule(&wgp->wgp_handshake_timeout_timer,
1478 MIN(wg_rekey_timeout, INT_MAX/hz) * hz); 1478 MIN(wg_rekey_timeout, INT_MAX/hz) * hz);
1479 } 1479 }
1480 mutex_exit(wgp->wgp_lock); 1480 mutex_exit(wgp->wgp_lock);
1481} 1481}
1482 1482
1483static void 1483static void
1484wg_stop_handshake_timeout_timer(struct wg_peer *wgp) 1484wg_stop_handshake_timeout_timer(struct wg_peer *wgp)
1485{ 1485{
1486 1486
1487 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL); 1487 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL);
1488} 1488}
1489 1489
1490static struct socket * 1490static struct socket *
1491wg_get_so_by_af(struct wg_worker *wgw, const int af) 1491wg_get_so_by_af(struct wg_worker *wgw, const int af)
1492{ 1492{
1493 1493
1494 return (af == AF_INET) ? wgw->wgw_so4 : wgw->wgw_so6; 1494 return (af == AF_INET) ? wgw->wgw_so4 : wgw->wgw_so6;
1495} 1495}
1496 1496
1497static struct socket * 1497static struct socket *
1498wg_get_so_by_peer(struct wg_peer *wgp) 1498wg_get_so_by_peer(struct wg_peer *wgp)
1499{ 1499{
1500 1500
1501 return wg_get_so_by_af(wgp->wgp_sc->wg_worker, wgp->wgp_sa.sa_family); 1501 return wg_get_so_by_af(wgp->wgp_sc->wg_worker, wgp->wgp_sa.sa_family);
1502} 1502}
1503 1503
1504static struct wg_sockaddr * 1504static struct wg_sockaddr *
1505wg_get_endpoint_sa(struct wg_peer *wgp, struct psref *psref) 1505wg_get_endpoint_sa(struct wg_peer *wgp, struct psref *psref)
1506{ 1506{
1507 struct wg_sockaddr *wgsa; 1507 struct wg_sockaddr *wgsa;
1508 int s; 1508 int s;
1509 1509
1510 s = pserialize_read_enter(); 1510 s = pserialize_read_enter();
1511 wgsa = wgp->wgp_endpoint; 1511 wgsa = wgp->wgp_endpoint;
1512 psref_acquire(psref, &wgsa->wgsa_psref, wg_psref_class); 1512 psref_acquire(psref, &wgsa->wgsa_psref, wg_psref_class);
1513 pserialize_read_exit(s); 1513 pserialize_read_exit(s);
1514 1514
1515 return wgsa; 1515 return wgsa;
1516} 1516}
1517 1517
1518static void 1518static void
1519wg_put_sa(struct wg_peer *wgp, struct wg_sockaddr *wgsa, struct psref *psref) 1519wg_put_sa(struct wg_peer *wgp, struct wg_sockaddr *wgsa, struct psref *psref)
1520{ 1520{
1521 1521
1522 psref_release(psref, &wgsa->wgsa_psref, wg_psref_class); 1522 psref_release(psref, &wgsa->wgsa_psref, wg_psref_class);
1523} 1523}
1524 1524
1525static int 1525static int
1526wg_send_so(struct wg_peer *wgp, struct mbuf *m) 1526wg_send_so(struct wg_peer *wgp, struct mbuf *m)
1527{ 1527{
1528 int error; 1528 int error;
1529 struct socket *so; 1529 struct socket *so;
1530 struct psref psref; 1530 struct psref psref;
1531 struct wg_sockaddr *wgsa; 1531 struct wg_sockaddr *wgsa;
1532 1532
1533 so = wg_get_so_by_peer(wgp); 1533 so = wg_get_so_by_peer(wgp);
1534 wgsa = wg_get_endpoint_sa(wgp, &psref); 1534 wgsa = wg_get_endpoint_sa(wgp, &psref);
1535 error = sosend(so, wgsatosa(wgsa), NULL, m, NULL, 0, curlwp); 1535 error = sosend(so, wgsatosa(wgsa), NULL, m, NULL, 0, curlwp);
1536 wg_put_sa(wgp, wgsa, &psref); 1536 wg_put_sa(wgp, wgsa, &psref);
1537 1537
1538 return error; 1538 return error;
1539} 1539}
1540 1540
1541static int 1541static int
1542wg_send_handshake_msg_init(struct wg_softc *wg, struct wg_peer *wgp) 1542wg_send_handshake_msg_init(struct wg_softc *wg, struct wg_peer *wgp)
1543{ 1543{
1544 int error; 1544 int error;
1545 struct mbuf *m; 1545 struct mbuf *m;
1546 struct wg_msg_init *wgmi; 1546 struct wg_msg_init *wgmi;
1547 struct wg_session *wgs; 1547 struct wg_session *wgs;
1548 struct psref psref; 1548 struct psref psref;
1549 1549
1550 wgs = wg_lock_unstable_session(wgp); 1550 wgs = wg_lock_unstable_session(wgp);
1551 if (wgs->wgs_state == WGS_STATE_DESTROYING) { 1551 if (wgs->wgs_state == WGS_STATE_DESTROYING) {
1552 WG_TRACE("Session destroying"); 1552 WG_TRACE("Session destroying");
1553 mutex_exit(wgs->wgs_lock); 1553 mutex_exit(wgs->wgs_lock);
1554 /* XXX should wait? */ 1554 /* XXX should wait? */
1555 return EBUSY; 1555 return EBUSY;
1556 } 1556 }
1557 if (wgs->wgs_state == WGS_STATE_INIT_ACTIVE) { 1557 if (wgs->wgs_state == WGS_STATE_INIT_ACTIVE) {
1558 WG_TRACE("Sesssion already initializing, skip starting a new one"); 1558 WG_TRACE("Sesssion already initializing, skip starting a new one");
1559 mutex_exit(wgs->wgs_lock); 1559 mutex_exit(wgs->wgs_lock);
1560 return EBUSY; 1560 return EBUSY;
1561 } 1561 }
1562 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) { 1562 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) {
1563 WG_TRACE("Sesssion already initializing, destroying old states"); 1563 WG_TRACE("Sesssion already initializing, destroying old states");
1564 wg_clear_states(wgs); 1564 wg_clear_states(wgs);
1565 } 1565 }
1566 wgs->wgs_state = WGS_STATE_INIT_ACTIVE; 1566 wgs->wgs_state = WGS_STATE_INIT_ACTIVE;
1567 wg_get_session(wgs, &psref); 1567 wg_get_session(wgs, &psref);
1568 mutex_exit(wgs->wgs_lock); 1568 mutex_exit(wgs->wgs_lock);
1569 1569
1570 m = m_gethdr(M_WAIT, MT_DATA); 1570 m = m_gethdr(M_WAIT, MT_DATA);
1571 m->m_pkthdr.len = m->m_len = sizeof(*wgmi); 1571 m->m_pkthdr.len = m->m_len = sizeof(*wgmi);
1572 wgmi = mtod(m, struct wg_msg_init *); 1572 wgmi = mtod(m, struct wg_msg_init *);
1573 1573
1574 wg_fill_msg_init(wg, wgp, wgs, wgmi); 1574 wg_fill_msg_init(wg, wgp, wgs, wgmi);
1575 1575
1576 error = wg->wg_ops->send_hs_msg(wgp, m); 1576 error = wg->wg_ops->send_hs_msg(wgp, m);
1577 if (error == 0) { 1577 if (error == 0) {
1578 WG_TRACE("init msg sent"); 1578 WG_TRACE("init msg sent");
1579 1579
1580 if (wgp->wgp_handshake_start_time == 0) 1580 if (wgp->wgp_handshake_start_time == 0)
1581 wgp->wgp_handshake_start_time = time_uptime; 1581 wgp->wgp_handshake_start_time = time_uptime;
1582 wg_schedule_handshake_timeout_timer(wgp); 1582 wg_schedule_handshake_timeout_timer(wgp);
1583 } else { 1583 } else {
1584 mutex_enter(wgs->wgs_lock); 1584 mutex_enter(wgs->wgs_lock);
1585 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE); 1585 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE);
1586 wgs->wgs_state = WGS_STATE_UNKNOWN; 1586 wgs->wgs_state = WGS_STATE_UNKNOWN;
1587 mutex_exit(wgs->wgs_lock); 1587 mutex_exit(wgs->wgs_lock);
1588 } 1588 }
1589 wg_put_session(wgs, &psref); 1589 wg_put_session(wgs, &psref);
1590 1590
1591 return error; 1591 return error;
1592} 1592}
1593 1593
1594static void 1594static void
1595wg_fill_msg_resp(struct wg_softc *wg, struct wg_peer *wgp, 1595wg_fill_msg_resp(struct wg_softc *wg, struct wg_peer *wgp,
1596 struct wg_msg_resp *wgmr, const struct wg_msg_init *wgmi) 1596 struct wg_msg_resp *wgmr, const struct wg_msg_init *wgmi)
1597{ 1597{
1598 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */ 1598 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */
1599 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Hr */ 1599 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Hr */
1600 uint8_t cipher_key[WG_KDF_OUTPUT_LEN]; 1600 uint8_t cipher_key[WG_KDF_OUTPUT_LEN];
1601 uint8_t pubkey[WG_EPHEMERAL_KEY_LEN]; 1601 uint8_t pubkey[WG_EPHEMERAL_KEY_LEN];
1602 uint8_t privkey[WG_EPHEMERAL_KEY_LEN]; 1602 uint8_t privkey[WG_EPHEMERAL_KEY_LEN];
1603 struct wg_session *wgs; 1603 struct wg_session *wgs;
1604 struct psref psref; 1604 struct psref psref;
1605 1605
1606 wgs = wg_get_unstable_session(wgp, &psref); 1606 wgs = wg_get_unstable_session(wgp, &psref);
1607 memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash)); 1607 memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash));
1608 memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey)); 1608 memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey));
1609 1609
1610 wgmr->wgmr_type = WG_MSG_TYPE_RESP; 1610 wgmr->wgmr_type = WG_MSG_TYPE_RESP;
1611 wgmr->wgmr_sender = cprng_strong32(); 1611 wgmr->wgmr_sender = cprng_strong32();
1612 wgmr->wgmr_receiver = wgmi->wgmi_sender; 1612 wgmr->wgmr_receiver = wgmi->wgmi_sender;
1613 1613
1614 /* [W] 5.4.3 Second Message: Responder to Initiator */ 1614 /* [W] 5.4.3 Second Message: Responder to Initiator */
1615 1615
1616 /* [N] 2.2: "e" */ 1616 /* [N] 2.2: "e" */
1617 /* Er^priv, Er^pub := DH-GENERATE() */ 1617 /* Er^priv, Er^pub := DH-GENERATE() */
1618 wg_algo_generate_keypair(pubkey, privkey); 1618 wg_algo_generate_keypair(pubkey, privkey);
1619 /* Cr := KDF1(Cr, Er^pub) */ 1619 /* Cr := KDF1(Cr, Er^pub) */
1620 wg_algo_kdf(ckey, NULL, NULL, ckey, pubkey, sizeof(pubkey)); 1620 wg_algo_kdf(ckey, NULL, NULL, ckey, pubkey, sizeof(pubkey));
1621 /* msg.ephemeral := Er^pub */ 1621 /* msg.ephemeral := Er^pub */
1622 memcpy(wgmr->wgmr_ephemeral, pubkey, sizeof(wgmr->wgmr_ephemeral)); 1622 memcpy(wgmr->wgmr_ephemeral, pubkey, sizeof(wgmr->wgmr_ephemeral));
1623 /* Hr := HASH(Hr || msg.ephemeral) */ 1623 /* Hr := HASH(Hr || msg.ephemeral) */
1624 wg_algo_hash(hash, pubkey, sizeof(pubkey)); 1624 wg_algo_hash(hash, pubkey, sizeof(pubkey));
1625 1625
1626 WG_DUMP_HASH("ckey", ckey); 1626 WG_DUMP_HASH("ckey", ckey);
1627 WG_DUMP_HASH("hash", hash); 1627 WG_DUMP_HASH("hash", hash);
1628 1628
1629 /* [N] 2.2: "ee" */ 1629 /* [N] 2.2: "ee" */
1630 /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */ 1630 /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */
1631 wg_algo_dh_kdf(ckey, NULL, privkey, wgs->wgs_ephemeral_key_peer); 1631 wg_algo_dh_kdf(ckey, NULL, privkey, wgs->wgs_ephemeral_key_peer);
1632 1632
1633 /* [N] 2.2: "se" */ 1633 /* [N] 2.2: "se" */
1634 /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */ 1634 /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */
1635 wg_algo_dh_kdf(ckey, NULL, privkey, wgp->wgp_pubkey); 1635 wg_algo_dh_kdf(ckey, NULL, privkey, wgp->wgp_pubkey);
1636 1636
1637 /* [N] 9.2: "psk" */ 1637 /* [N] 9.2: "psk" */
1638 { 1638 {
1639 uint8_t kdfout[WG_KDF_OUTPUT_LEN]; 1639 uint8_t kdfout[WG_KDF_OUTPUT_LEN];
1640 /* Cr, r, k := KDF3(Cr, Q) */ 1640 /* Cr, r, k := KDF3(Cr, Q) */
1641 wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk, 1641 wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk,
1642 sizeof(wgp->wgp_psk)); 1642 sizeof(wgp->wgp_psk));
1643 /* Hr := HASH(Hr || r) */ 1643 /* Hr := HASH(Hr || r) */
1644 wg_algo_hash(hash, kdfout, sizeof(kdfout)); 1644 wg_algo_hash(hash, kdfout, sizeof(kdfout));
1645 } 1645 }
1646 1646
1647 /* msg.empty := AEAD(k, 0, e, Hr) */ 1647 /* msg.empty := AEAD(k, 0, e, Hr) */
1648 wg_algo_aead_enc(wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty), 1648 wg_algo_aead_enc(wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty),
1649 cipher_key, 0, NULL, 0, hash, sizeof(hash)); 1649 cipher_key, 0, NULL, 0, hash, sizeof(hash));
1650 /* Hr := HASH(Hr || msg.empty) */ 1650 /* Hr := HASH(Hr || msg.empty) */
1651 wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty)); 1651 wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty));
1652 1652
1653 WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty); 1653 WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty);
1654 1654
1655 /* [W] 5.4.4: Cookie MACs */ 1655 /* [W] 5.4.4: Cookie MACs */
1656 /* msg.mac1 := MAC(HASH(LABEL-MAC1 || Sm'^pub), msg_a) */ 1656 /* msg.mac1 := MAC(HASH(LABEL-MAC1 || Sm'^pub), msg_a) */
1657 wg_algo_mac_mac1(wgmr->wgmr_mac1, sizeof(wgmi->wgmi_mac1), 1657 wg_algo_mac_mac1(wgmr->wgmr_mac1, sizeof(wgmi->wgmi_mac1),
1658 wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey), 1658 wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey),
1659 (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1)); 1659 (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1));
1660 /* Need mac1 to decrypt a cookie from a cookie message */ 1660 /* Need mac1 to decrypt a cookie from a cookie message */
1661 memcpy(wgp->wgp_last_sent_mac1, wgmr->wgmr_mac1, 1661 memcpy(wgp->wgp_last_sent_mac1, wgmr->wgmr_mac1,
1662 sizeof(wgp->wgp_last_sent_mac1)); 1662 sizeof(wgp->wgp_last_sent_mac1));
1663 wgp->wgp_last_sent_mac1_valid = true; 1663 wgp->wgp_last_sent_mac1_valid = true;
1664 1664
1665 if (wgp->wgp_latest_cookie_time == 0 || 1665 if (wgp->wgp_latest_cookie_time == 0 ||
1666 (time_uptime - wgp->wgp_latest_cookie_time) >= WG_COOKIE_TIME) 1666 (time_uptime - wgp->wgp_latest_cookie_time) >= WG_COOKIE_TIME)
1667 /* msg.mac2 := 0^16 */ 1667 /* msg.mac2 := 0^16 */
1668 memset(wgmr->wgmr_mac2, 0, sizeof(wgmr->wgmr_mac2)); 1668 memset(wgmr->wgmr_mac2, 0, sizeof(wgmr->wgmr_mac2));
1669 else { 1669 else {
1670 /* msg.mac2 := MAC(Lm, msg_b) */ 1670 /* msg.mac2 := MAC(Lm, msg_b) */
1671 wg_algo_mac(wgmr->wgmr_mac2, sizeof(wgmi->wgmi_mac2), 1671 wg_algo_mac(wgmr->wgmr_mac2, sizeof(wgmi->wgmi_mac2),
1672 wgp->wgp_latest_cookie, WG_COOKIE_LEN, 1672 wgp->wgp_latest_cookie, WG_COOKIE_LEN,
1673 (const uint8_t *)wgmr, 1673 (const uint8_t *)wgmr,
1674 offsetof(struct wg_msg_resp, wgmr_mac2), 1674 offsetof(struct wg_msg_resp, wgmr_mac2),
1675 NULL, 0); 1675 NULL, 0);
1676 } 1676 }
1677 1677
1678 memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash)); 1678 memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash));
1679 memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey)); 1679 memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey));
1680 memcpy(wgs->wgs_ephemeral_key_pub, pubkey, sizeof(pubkey)); 1680 memcpy(wgs->wgs_ephemeral_key_pub, pubkey, sizeof(pubkey));
1681 memcpy(wgs->wgs_ephemeral_key_priv, privkey, sizeof(privkey)); 1681 memcpy(wgs->wgs_ephemeral_key_priv, privkey, sizeof(privkey));
1682 wgs->wgs_sender_index = wgmr->wgmr_sender; 1682 wgs->wgs_sender_index = wgmr->wgmr_sender;
1683 wgs->wgs_receiver_index = wgmi->wgmi_sender; 1683 wgs->wgs_receiver_index = wgmi->wgmi_sender;
1684 WG_DLOG("sender=%x\n", wgs->wgs_sender_index); 1684 WG_DLOG("sender=%x\n", wgs->wgs_sender_index);
1685 WG_DLOG("receiver=%x\n", wgs->wgs_receiver_index); 1685 WG_DLOG("receiver=%x\n", wgs->wgs_receiver_index);
1686 wg_put_session(wgs, &psref); 1686 wg_put_session(wgs, &psref);
1687} 1687}
1688 1688
1689static void 1689static void
1690wg_swap_sessions(struct wg_peer *wgp) 1690wg_swap_sessions(struct wg_peer *wgp)
1691{ 1691{
1692 1692
1693 KASSERT(mutex_owned(wgp->wgp_lock)); 1693 KASSERT(mutex_owned(wgp->wgp_lock));
1694 1694
1695 wgp->wgp_session_unstable = atomic_swap_ptr(&wgp->wgp_session_stable, 1695 wgp->wgp_session_unstable = atomic_swap_ptr(&wgp->wgp_session_stable,
1696 wgp->wgp_session_unstable); 1696 wgp->wgp_session_unstable);
1697 KASSERT(wgp->wgp_session_stable->wgs_state == WGS_STATE_ESTABLISHED); 1697 KASSERT(wgp->wgp_session_stable->wgs_state == WGS_STATE_ESTABLISHED);
1698} 1698}
1699 1699
1700static void 1700static void
1701wg_handle_msg_resp(struct wg_softc *wg, const struct wg_msg_resp *wgmr, 1701wg_handle_msg_resp(struct wg_softc *wg, const struct wg_msg_resp *wgmr,
1702 const struct sockaddr *src) 1702 const struct sockaddr *src)
1703{ 1703{
1704 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */ 1704 uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */
1705 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Kr */ 1705 uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Kr */
1706 uint8_t cipher_key[WG_KDF_OUTPUT_LEN]; 1706 uint8_t cipher_key[WG_KDF_OUTPUT_LEN];
1707 struct wg_peer *wgp; 1707 struct wg_peer *wgp;
1708 struct wg_session *wgs; 1708 struct wg_session *wgs;
1709 struct psref psref; 1709 struct psref psref;
1710 int error; 1710 int error;
1711 uint8_t mac1[WG_MAC_LEN]; 1711 uint8_t mac1[WG_MAC_LEN];
1712 struct wg_session *wgs_prev; 1712 struct wg_session *wgs_prev;
1713 1713
1714 WG_TRACE("resp msg received"); 1714 WG_TRACE("resp msg received");
1715 wgs = wg_lookup_session_by_index(wg, wgmr->wgmr_receiver, &psref); 1715 wgs = wg_lookup_session_by_index(wg, wgmr->wgmr_receiver, &psref);
1716 if (wgs == NULL) { 1716 if (wgs == NULL) {
1717 WG_TRACE("No session found"); 1717 WG_TRACE("No session found");
1718 return; 1718 return;
1719 } 1719 }
1720 1720
1721 wgp = wgs->wgs_peer; 1721 wgp = wgs->wgs_peer;
1722 1722
1723 wg_algo_mac_mac1(mac1, sizeof(mac1), 1723 wg_algo_mac_mac1(mac1, sizeof(mac1),
1724 wg->wg_pubkey, sizeof(wg->wg_pubkey), 1724 wg->wg_pubkey, sizeof(wg->wg_pubkey),
1725 (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1)); 1725 (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1));
1726 1726
1727 /* 1727 /*
1728 * [W] 5.3: Denial of Service Mitigation & Cookies 1728 * [W] 5.3: Denial of Service Mitigation & Cookies
1729 * "the responder, ..., must always reject messages with an invalid 1729 * "the responder, ..., must always reject messages with an invalid
1730 * msg.mac1" 1730 * msg.mac1"
1731 */ 1731 */
1732 if (!consttime_memequal(mac1, wgmr->wgmr_mac1, sizeof(mac1))) { 1732 if (!consttime_memequal(mac1, wgmr->wgmr_mac1, sizeof(mac1))) {
1733 WG_DLOG("mac1 is invalid\n"); 1733 WG_DLOG("mac1 is invalid\n");
1734 goto out; 1734 goto out;
1735 } 1735 }
1736 1736
1737 if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_RESP))) { 1737 if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_RESP))) {
1738 WG_TRACE("under load"); 1738 WG_TRACE("under load");
1739 /* 1739 /*
1740 * [W] 5.3: Denial of Service Mitigation & Cookies 1740 * [W] 5.3: Denial of Service Mitigation & Cookies
1741 * "the responder, ..., and when under load may reject messages 1741 * "the responder, ..., and when under load may reject messages
1742 * with an invalid msg.mac2. If the responder receives a 1742 * with an invalid msg.mac2. If the responder receives a
1743 * message with a valid msg.mac1 yet with an invalid msg.mac2, 1743 * message with a valid msg.mac1 yet with an invalid msg.mac2,
1744 * and is under load, it may respond with a cookie reply 1744 * and is under load, it may respond with a cookie reply
1745 * message" 1745 * message"
1746 */ 1746 */
1747 uint8_t zero[WG_MAC_LEN] = {0}; 1747 uint8_t zero[WG_MAC_LEN] = {0};
1748 if (consttime_memequal(wgmr->wgmr_mac2, zero, sizeof(zero))) { 1748 if (consttime_memequal(wgmr->wgmr_mac2, zero, sizeof(zero))) {
1749 WG_TRACE("sending a cookie message: no cookie included"); 1749 WG_TRACE("sending a cookie message: no cookie included");
1750 (void)wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender, 1750 (void)wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender,
1751 wgmr->wgmr_mac1, src); 1751 wgmr->wgmr_mac1, src);
1752 goto out; 1752 goto out;
1753 } 1753 }
1754 if (!wgp->wgp_last_sent_cookie_valid) { 1754 if (!wgp->wgp_last_sent_cookie_valid) {
1755 WG_TRACE("sending a cookie message: no cookie sent ever"); 1755 WG_TRACE("sending a cookie message: no cookie sent ever");
1756 (void)wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender, 1756 (void)wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender,
1757 wgmr->wgmr_mac1, src); 1757 wgmr->wgmr_mac1, src);
1758 goto out; 1758 goto out;
1759 } 1759 }
1760 uint8_t mac2[WG_MAC_LEN]; 1760 uint8_t mac2[WG_MAC_LEN];
1761 wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie, 1761 wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie,
1762 WG_COOKIE_LEN, (const uint8_t *)wgmr, 1762 WG_COOKIE_LEN, (const uint8_t *)wgmr,
1763 offsetof(struct wg_msg_resp, wgmr_mac2), NULL, 0); 1763 offsetof(struct wg_msg_resp, wgmr_mac2), NULL, 0);
1764 if (!consttime_memequal(mac2, wgmr->wgmr_mac2, sizeof(mac2))) { 1764 if (!consttime_memequal(mac2, wgmr->wgmr_mac2, sizeof(mac2))) {
1765 WG_DLOG("mac2 is invalid\n"); 1765 WG_DLOG("mac2 is invalid\n");
1766 goto out; 1766 goto out;
1767 } 1767 }
1768 WG_TRACE("under load, but continue to sending"); 1768 WG_TRACE("under load, but continue to sending");
1769 } 1769 }
1770 1770
1771 memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash)); 1771 memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash));
1772 memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey)); 1772 memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey));
1773 1773
1774 /* 1774 /*
1775 * [W] 5.4.3 Second Message: Responder to Initiator 1775 * [W] 5.4.3 Second Message: Responder to Initiator
1776 * "When the initiator receives this message, it does the same 1776 * "When the initiator receives this message, it does the same
1777 * operations so that its final state variables are identical, 1777 * operations so that its final state variables are identical,
1778 * replacing the operands of the DH function to produce equivalent 1778 * replacing the operands of the DH function to produce equivalent
1779 * values." 1779 * values."
1780 * Note that the following comments of operations are just copies of 1780 * Note that the following comments of operations are just copies of
1781 * the initiator's ones. 1781 * the initiator's ones.
1782 */ 1782 */
1783 1783
1784 /* [N] 2.2: "e" */ 1784 /* [N] 2.2: "e" */
1785 /* Cr := KDF1(Cr, Er^pub) */ 1785 /* Cr := KDF1(Cr, Er^pub) */
1786 wg_algo_kdf(ckey, NULL, NULL, ckey, wgmr->wgmr_ephemeral, 1786 wg_algo_kdf(ckey, NULL, NULL, ckey, wgmr->wgmr_ephemeral,
1787 sizeof(wgmr->wgmr_ephemeral)); 1787 sizeof(wgmr->wgmr_ephemeral));
1788 /* Hr := HASH(Hr || msg.ephemeral) */ 1788 /* Hr := HASH(Hr || msg.ephemeral) */
1789 wg_algo_hash(hash, wgmr->wgmr_ephemeral, sizeof(wgmr->wgmr_ephemeral)); 1789 wg_algo_hash(hash, wgmr->wgmr_ephemeral, sizeof(wgmr->wgmr_ephemeral));
1790 1790
1791 WG_DUMP_HASH("ckey", ckey); 1791 WG_DUMP_HASH("ckey", ckey);
1792 WG_DUMP_HASH("hash", hash); 1792 WG_DUMP_HASH("hash", hash);
1793 1793
1794 /* [N] 2.2: "ee" */ 1794 /* [N] 2.2: "ee" */
1795 /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */ 1795 /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */
1796 wg_algo_dh_kdf(ckey, NULL, wgs->wgs_ephemeral_key_priv, 1796 wg_algo_dh_kdf(ckey, NULL, wgs->wgs_ephemeral_key_priv,
1797 wgmr->wgmr_ephemeral); 1797 wgmr->wgmr_ephemeral);
1798 1798
1799 /* [N] 2.2: "se" */ 1799 /* [N] 2.2: "se" */
1800 /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */ 1800 /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */
1801 wg_algo_dh_kdf(ckey, NULL, wg->wg_privkey, wgmr->wgmr_ephemeral); 1801 wg_algo_dh_kdf(ckey, NULL, wg->wg_privkey, wgmr->wgmr_ephemeral);
1802 1802
1803 /* [N] 9.2: "psk" */ 1803 /* [N] 9.2: "psk" */
1804 { 1804 {
1805 uint8_t kdfout[WG_KDF_OUTPUT_LEN]; 1805 uint8_t kdfout[WG_KDF_OUTPUT_LEN];
1806 /* Cr, r, k := KDF3(Cr, Q) */ 1806 /* Cr, r, k := KDF3(Cr, Q) */
1807 wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk, 1807 wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk,
1808 sizeof(wgp->wgp_psk)); 1808 sizeof(wgp->wgp_psk));
1809 /* Hr := HASH(Hr || r) */ 1809 /* Hr := HASH(Hr || r) */
1810 wg_algo_hash(hash, kdfout, sizeof(kdfout)); 1810 wg_algo_hash(hash, kdfout, sizeof(kdfout));
1811 } 1811 }
1812 1812
1813 { 1813 {
1814 uint8_t out[sizeof(wgmr->wgmr_empty)]; /* for safety */ 1814 uint8_t out[sizeof(wgmr->wgmr_empty)]; /* for safety */
1815 /* msg.empty := AEAD(k, 0, e, Hr) */ 1815 /* msg.empty := AEAD(k, 0, e, Hr) */
1816 error = wg_algo_aead_dec(out, 0, cipher_key, 0, wgmr->wgmr_empty, 1816 error = wg_algo_aead_dec(out, 0, cipher_key, 0, wgmr->wgmr_empty,
1817 sizeof(wgmr->wgmr_empty), hash, sizeof(hash)); 1817 sizeof(wgmr->wgmr_empty), hash, sizeof(hash));
1818 WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty); 1818 WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty);
1819 if (error != 0) { 1819 if (error != 0) {
1820 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 1820 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
1821 "wg_algo_aead_dec for empty message failed\n"); 1821 "wg_algo_aead_dec for empty message failed\n");
1822 goto out; 1822 goto out;
1823 } 1823 }
1824 /* Hr := HASH(Hr || msg.empty) */ 1824 /* Hr := HASH(Hr || msg.empty) */
1825 wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty)); 1825 wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty));
1826 } 1826 }
1827 1827
1828 memcpy(wgs->wgs_handshake_hash, hash, sizeof(wgs->wgs_handshake_hash)); 1828 memcpy(wgs->wgs_handshake_hash, hash, sizeof(wgs->wgs_handshake_hash));
1829 memcpy(wgs->wgs_chaining_key, ckey, sizeof(wgs->wgs_chaining_key)); 1829 memcpy(wgs->wgs_chaining_key, ckey, sizeof(wgs->wgs_chaining_key));
1830 wgs->wgs_receiver_index = wgmr->wgmr_sender; 1830 wgs->wgs_receiver_index = wgmr->wgmr_sender;
1831 WG_DLOG("receiver=%x\n", wgs->wgs_receiver_index); 1831 WG_DLOG("receiver=%x\n", wgs->wgs_receiver_index);
1832 1832
1833 wgs->wgs_state = WGS_STATE_ESTABLISHED; 1833 wgs->wgs_state = WGS_STATE_ESTABLISHED;
1834 wgs->wgs_time_established = time_uptime; 1834 wgs->wgs_time_established = time_uptime;
1835 wgs->wgs_time_last_data_sent = 0; 1835 wgs->wgs_time_last_data_sent = 0;
1836 wgs->wgs_is_initiator = true; 1836 wgs->wgs_is_initiator = true;
1837 wg_calculate_keys(wgs, true); 1837 wg_calculate_keys(wgs, true);
1838 wg_clear_states(wgs); 1838 wg_clear_states(wgs);
1839 WG_TRACE("WGS_STATE_ESTABLISHED"); 1839 WG_TRACE("WGS_STATE_ESTABLISHED");
1840 1840
1841 wg_stop_handshake_timeout_timer(wgp); 1841 wg_stop_handshake_timeout_timer(wgp);
1842 1842
1843 mutex_enter(wgp->wgp_lock); 1843 mutex_enter(wgp->wgp_lock);
1844 wg_swap_sessions(wgp); 1844 wg_swap_sessions(wgp);
1845 wgs_prev = wgp->wgp_session_unstable; 1845 wgs_prev = wgp->wgp_session_unstable;
1846 mutex_enter(wgs_prev->wgs_lock); 1846 mutex_enter(wgs_prev->wgs_lock);
1847 1847
1848 getnanotime(&wgp->wgp_last_handshake_time); 1848 getnanotime(&wgp->wgp_last_handshake_time);
1849 wgp->wgp_handshake_start_time = 0; 1849 wgp->wgp_handshake_start_time = 0;
1850 wgp->wgp_last_sent_mac1_valid = false; 1850 wgp->wgp_last_sent_mac1_valid = false;
1851 wgp->wgp_last_sent_cookie_valid = false; 1851 wgp->wgp_last_sent_cookie_valid = false;
1852 mutex_exit(wgp->wgp_lock); 1852 mutex_exit(wgp->wgp_lock);
1853 1853
1854 wg_schedule_rekey_timer(wgp); 1854 wg_schedule_rekey_timer(wgp);
1855 1855
1856 wg_update_endpoint_if_necessary(wgp, src); 1856 wg_update_endpoint_if_necessary(wgp, src);
1857 1857
1858 /* 1858 /*
1859 * Send something immediately (same as the official implementation) 1859 * Send something immediately (same as the official implementation)
1860 * XXX if there are pending data packets, we don't need to send 1860 * XXX if there are pending data packets, we don't need to send
1861 * a keepalive message. 1861 * a keepalive message.
1862 */ 1862 */
1863 wg_send_keepalive_msg(wgp, wgs); 1863 wg_send_keepalive_msg(wgp, wgs);
1864 1864
1865 /* Anyway run a softint to flush pending packets */ 1865 /* Anyway run a softint to flush pending packets */
1866 kpreempt_disable(); 1866 kpreempt_disable();
1867 softint_schedule(wgp->wgp_si); 1867 softint_schedule(wgp->wgp_si);
1868 kpreempt_enable(); 1868 kpreempt_enable();
1869 WG_TRACE("softint scheduled"); 1869 WG_TRACE("softint scheduled");
1870 1870
1871 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) { 1871 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) {
1872 wgs_prev->wgs_state = WGS_STATE_DESTROYING; 1872 wgs_prev->wgs_state = WGS_STATE_DESTROYING;
1873 /* We can't destroy the old session immediately */ 1873 /* We can't destroy the old session immediately */
1874 wg_schedule_session_dtor_timer(wgp); 1874 wg_schedule_session_dtor_timer(wgp);
1875 } 1875 }
1876 mutex_exit(wgs_prev->wgs_lock); 1876 mutex_exit(wgs_prev->wgs_lock);
1877 1877
1878out: 1878out:
1879 wg_put_session(wgs, &psref); 1879 wg_put_session(wgs, &psref);
1880} 1880}
1881 1881
1882static int 1882static int
1883wg_send_handshake_msg_resp(struct wg_softc *wg, struct wg_peer *wgp, 1883wg_send_handshake_msg_resp(struct wg_softc *wg, struct wg_peer *wgp,
1884 const struct wg_msg_init *wgmi) 1884 const struct wg_msg_init *wgmi)
1885{ 1885{
1886 int error; 1886 int error;
1887 struct mbuf *m; 1887 struct mbuf *m;
1888 struct wg_msg_resp *wgmr; 1888 struct wg_msg_resp *wgmr;
1889 1889
1890 m = m_gethdr(M_WAIT, MT_DATA); 1890 m = m_gethdr(M_WAIT, MT_DATA);
1891 m->m_pkthdr.len = m->m_len = sizeof(*wgmr); 1891 m->m_pkthdr.len = m->m_len = sizeof(*wgmr);
1892 wgmr = mtod(m, struct wg_msg_resp *); 1892 wgmr = mtod(m, struct wg_msg_resp *);
1893 wg_fill_msg_resp(wg, wgp, wgmr, wgmi); 1893 wg_fill_msg_resp(wg, wgp, wgmr, wgmi);
1894 1894
1895 error = wg->wg_ops->send_hs_msg(wgp, m); 1895 error = wg->wg_ops->send_hs_msg(wgp, m);
1896 if (error == 0) 1896 if (error == 0)
1897 WG_TRACE("resp msg sent"); 1897 WG_TRACE("resp msg sent");
1898 return error; 1898 return error;
1899} 1899}
1900 1900
1901static struct wg_peer * 1901static struct wg_peer *
1902wg_lookup_peer_by_pubkey(struct wg_softc *wg, 1902wg_lookup_peer_by_pubkey(struct wg_softc *wg,
1903 const uint8_t pubkey[WG_STATIC_KEY_LEN], struct psref *psref) 1903 const uint8_t pubkey[WG_STATIC_KEY_LEN], struct psref *psref)
1904{ 1904{
1905 struct wg_peer *wgp; 1905 struct wg_peer *wgp;
1906 1906
1907 int s = pserialize_read_enter(); 1907 int s = pserialize_read_enter();
1908 /* XXX O(n) */ 1908 /* XXX O(n) */
1909 WG_PEER_READER_FOREACH(wgp, wg) { 1909 WG_PEER_READER_FOREACH(wgp, wg) {
1910 if (consttime_memequal(wgp->wgp_pubkey, pubkey, 1910 if (consttime_memequal(wgp->wgp_pubkey, pubkey,
1911 sizeof(wgp->wgp_pubkey))) 1911 sizeof(wgp->wgp_pubkey)))
1912 break; 1912 break;
1913 } 1913 }
1914 if (wgp != NULL) 1914 if (wgp != NULL)
1915 wg_get_peer(wgp, psref); 1915 wg_get_peer(wgp, psref);
1916 pserialize_read_exit(s); 1916 pserialize_read_exit(s);
1917 1917
1918 return wgp; 1918 return wgp;
1919} 1919}
1920 1920
1921static void 1921static void
1922wg_fill_msg_cookie(struct wg_softc *wg, struct wg_peer *wgp, 1922wg_fill_msg_cookie(struct wg_softc *wg, struct wg_peer *wgp,
1923 struct wg_msg_cookie *wgmc, const uint32_t sender, 1923 struct wg_msg_cookie *wgmc, const uint32_t sender,
1924 const uint8_t mac1[WG_MAC_LEN], const struct sockaddr *src) 1924 const uint8_t mac1[WG_MAC_LEN], const struct sockaddr *src)
1925{ 1925{
1926 uint8_t cookie[WG_COOKIE_LEN]; 1926 uint8_t cookie[WG_COOKIE_LEN];
1927 uint8_t key[WG_HASH_LEN]; 1927 uint8_t key[WG_HASH_LEN];
1928 uint8_t addr[sizeof(struct in6_addr)]; 1928 uint8_t addr[sizeof(struct in6_addr)];
1929 size_t addrlen; 1929 size_t addrlen;
1930 uint16_t uh_sport; /* be */ 1930 uint16_t uh_sport; /* be */
1931 1931
1932 wgmc->wgmc_type = WG_MSG_TYPE_COOKIE; 1932 wgmc->wgmc_type = WG_MSG_TYPE_COOKIE;
1933 wgmc->wgmc_receiver = sender; 1933 wgmc->wgmc_receiver = sender;
1934 cprng_fast(wgmc->wgmc_salt, sizeof(wgmc->wgmc_salt)); 1934 cprng_fast(wgmc->wgmc_salt, sizeof(wgmc->wgmc_salt));
1935 1935
1936 /* 1936 /*
1937 * [W] 5.4.7: Under Load: Cookie Reply Message 1937 * [W] 5.4.7: Under Load: Cookie Reply Message
1938 * "The secret variable, Rm, changes every two minutes to a 1938 * "The secret variable, Rm, changes every two minutes to a
1939 * random value" 1939 * random value"
1940 */ 1940 */
1941 if ((time_uptime - wgp->wgp_last_genrandval_time) > WG_RANDVAL_TIME) { 1941 if ((time_uptime - wgp->wgp_last_genrandval_time) > WG_RANDVAL_TIME) {
1942 wgp->wgp_randval = cprng_strong32(); 1942 wgp->wgp_randval = cprng_strong32();
1943 wgp->wgp_last_genrandval_time = time_uptime; 1943 wgp->wgp_last_genrandval_time = time_uptime;
1944 } 1944 }
1945 1945
1946 switch (src->sa_family) { 1946 switch (src->sa_family) {
1947 case AF_INET: { 1947 case AF_INET: {
1948 const struct sockaddr_in *sin = satocsin(src); 1948 const struct sockaddr_in *sin = satocsin(src);
1949 addrlen = sizeof(sin->sin_addr); 1949 addrlen = sizeof(sin->sin_addr);
1950 memcpy(addr, &sin->sin_addr, addrlen); 1950 memcpy(addr, &sin->sin_addr, addrlen);
1951 uh_sport = sin->sin_port; 1951 uh_sport = sin->sin_port;
1952 break; 1952 break;
1953 } 1953 }
1954#ifdef INET6 1954#ifdef INET6
1955 case AF_INET6: { 1955 case AF_INET6: {
1956 const struct sockaddr_in6 *sin6 = satocsin6(src); 1956 const struct sockaddr_in6 *sin6 = satocsin6(src);
1957 addrlen = sizeof(sin6->sin6_addr); 1957 addrlen = sizeof(sin6->sin6_addr);
1958 memcpy(addr, &sin6->sin6_addr, addrlen); 1958 memcpy(addr, &sin6->sin6_addr, addrlen);
1959 uh_sport = sin6->sin6_port; 1959 uh_sport = sin6->sin6_port;
1960 break; 1960 break;
1961 } 1961 }
1962#endif 1962#endif
1963 default: 1963 default:
1964 panic("invalid af=%d", wgp->wgp_sa.sa_family); 1964 panic("invalid af=%d", wgp->wgp_sa.sa_family);
1965 } 1965 }
1966 1966
1967 wg_algo_mac(cookie, sizeof(cookie), 1967 wg_algo_mac(cookie, sizeof(cookie),
1968 (const uint8_t *)&wgp->wgp_randval, sizeof(wgp->wgp_randval), 1968 (const uint8_t *)&wgp->wgp_randval, sizeof(wgp->wgp_randval),
1969 addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport)); 1969 addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport));
1970 wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey, 1970 wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey,
1971 sizeof(wg->wg_pubkey)); 1971 sizeof(wg->wg_pubkey));
1972 wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key, 1972 wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key,
1973 cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt); 1973 cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt);
1974 1974
1975 /* Need to store to calculate mac2 */ 1975 /* Need to store to calculate mac2 */
1976 memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie)); 1976 memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie));
1977 wgp->wgp_last_sent_cookie_valid = true; 1977 wgp->wgp_last_sent_cookie_valid = true;
1978} 1978}
1979 1979
1980static int 1980static int
1981wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp, 1981wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp,
1982 const uint32_t sender, const uint8_t mac1[WG_MAC_LEN], 1982 const uint32_t sender, const uint8_t mac1[WG_MAC_LEN],
1983 const struct sockaddr *src) 1983 const struct sockaddr *src)
1984{ 1984{
1985 int error; 1985 int error;
1986 struct mbuf *m; 1986 struct mbuf *m;
1987 struct wg_msg_cookie *wgmc; 1987 struct wg_msg_cookie *wgmc;
1988 1988
1989 m = m_gethdr(M_WAIT, MT_DATA); 1989 m = m_gethdr(M_WAIT, MT_DATA);
1990 m->m_pkthdr.len = m->m_len = sizeof(*wgmc); 1990 m->m_pkthdr.len = m->m_len = sizeof(*wgmc);
1991 wgmc = mtod(m, struct wg_msg_cookie *); 1991 wgmc = mtod(m, struct wg_msg_cookie *);
1992 wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src); 1992 wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src);
1993 1993
1994 error = wg->wg_ops->send_hs_msg(wgp, m); 1994 error = wg->wg_ops->send_hs_msg(wgp, m);
1995 if (error == 0) 1995 if (error == 0)
1996 WG_TRACE("cookie msg sent"); 1996 WG_TRACE("cookie msg sent");
1997 return error; 1997 return error;
1998} 1998}
1999 1999
2000static bool 2000static bool
2001wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype) 2001wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype)
2002{ 2002{
2003#ifdef WG_DEBUG_PARAMS 2003#ifdef WG_DEBUG_PARAMS
2004 if (wg_force_underload) 2004 if (wg_force_underload)
2005 return true; 2005 return true;
2006#endif 2006#endif
2007 2007
2008 /* 2008 /*
2009 * XXX we don't have a means of a load estimation. The purpose of 2009 * XXX we don't have a means of a load estimation. The purpose of
2010 * the mechanism is a DoS mitigation, so we consider frequent handshake 2010 * the mechanism is a DoS mitigation, so we consider frequent handshake
2011 * messages as (a kind of) load; if a message of the same type comes 2011 * messages as (a kind of) load; if a message of the same type comes
2012 * to a peer within 1 second, we consider we are under load. 2012 * to a peer within 1 second, we consider we are under load.
2013 */ 2013 */
2014 time_t last = wgp->wgp_last_msg_received_time[msgtype]; 2014 time_t last = wgp->wgp_last_msg_received_time[msgtype];
2015 wgp->wgp_last_msg_received_time[msgtype] = time_uptime; 2015 wgp->wgp_last_msg_received_time[msgtype] = time_uptime;
2016 return (time_uptime - last) == 0; 2016 return (time_uptime - last) == 0;
2017} 2017}
2018 2018
2019static void 2019static void
2020wg_calculate_keys(struct wg_session *wgs, const bool initiator) 2020wg_calculate_keys(struct wg_session *wgs, const bool initiator)
2021{ 2021{
2022 2022
2023 /* 2023 /*
2024 * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e) 2024 * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e)
2025 */ 2025 */
2026 if (initiator) { 2026 if (initiator) {
2027 wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL, 2027 wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL,
2028 wgs->wgs_chaining_key, NULL, 0); 2028 wgs->wgs_chaining_key, NULL, 0);
2029 } else { 2029 } else {
2030 wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL, 2030 wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL,
2031 wgs->wgs_chaining_key, NULL, 0); 2031 wgs->wgs_chaining_key, NULL, 0);
2032 } 2032 }
2033 WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send); 2033 WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send);
2034 WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv); 2034 WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv);
2035} 2035}
2036 2036
2037static uint64_t 2037static uint64_t
2038wg_session_get_send_counter(struct wg_session *wgs) 2038wg_session_get_send_counter(struct wg_session *wgs)
2039{ 2039{
2040#ifdef __HAVE_ATOMIC64_LOADSTORE 2040#ifdef __HAVE_ATOMIC64_LOADSTORE
2041 return atomic_load_relaxed(&wgs->wgs_send_counter); 2041 return atomic_load_relaxed(&wgs->wgs_send_counter);
2042#else 2042#else
2043 uint64_t send_counter; 2043 uint64_t send_counter;
2044 2044
2045 mutex_enter(&wgs->wgs_send_counter_lock); 2045 mutex_enter(&wgs->wgs_send_counter_lock);
2046 send_counter = wgs->wgs_send_counter; 2046 send_counter = wgs->wgs_send_counter;
2047 mutex_exit(&wgs->wgs_send_counter_lock); 2047 mutex_exit(&wgs->wgs_send_counter_lock);
2048 2048
2049 return send_counter; 2049 return send_counter;
2050#endif 2050#endif
2051} 2051}
2052 2052
2053static uint64_t 2053static uint64_t
2054wg_session_inc_send_counter(struct wg_session *wgs) 2054wg_session_inc_send_counter(struct wg_session *wgs)
2055{ 2055{
2056#ifdef __HAVE_ATOMIC64_LOADSTORE 2056#ifdef __HAVE_ATOMIC64_LOADSTORE
2057 return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1; 2057 return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1;
2058#else 2058#else
2059 uint64_t send_counter; 2059 uint64_t send_counter;
2060 2060
2061 mutex_enter(&wgs->wgs_send_counter_lock); 2061 mutex_enter(&wgs->wgs_send_counter_lock);
2062 send_counter = wgs->wgs_send_counter++; 2062 send_counter = wgs->wgs_send_counter++;
2063 mutex_exit(&wgs->wgs_send_counter_lock); 2063 mutex_exit(&wgs->wgs_send_counter_lock);
2064 2064
2065 return send_counter; 2065 return send_counter;
2066#endif 2066#endif
2067} 2067}
2068 2068
2069static void 2069static void
2070wg_clear_states(struct wg_session *wgs) 2070wg_clear_states(struct wg_session *wgs)
2071{ 2071{
2072 2072
2073 wgs->wgs_send_counter = 0; 2073 wgs->wgs_send_counter = 0;
2074 sliwin_reset(&wgs->wgs_recvwin->window); 2074 sliwin_reset(&wgs->wgs_recvwin->window);
2075 2075
2076#define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v)) 2076#define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v))
2077 wgs_clear(handshake_hash); 2077 wgs_clear(handshake_hash);
2078 wgs_clear(chaining_key); 2078 wgs_clear(chaining_key);
2079 wgs_clear(ephemeral_key_pub); 2079 wgs_clear(ephemeral_key_pub);
2080 wgs_clear(ephemeral_key_priv); 2080 wgs_clear(ephemeral_key_priv);
2081 wgs_clear(ephemeral_key_peer); 2081 wgs_clear(ephemeral_key_peer);
2082#undef wgs_clear 2082#undef wgs_clear
2083} 2083}
2084 2084
2085static struct wg_session * 2085static struct wg_session *
2086wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index, 2086wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index,
2087 struct psref *psref) 2087 struct psref *psref)
2088{ 2088{
2089 struct wg_peer *wgp; 2089 struct wg_peer *wgp;
2090 struct wg_session *wgs; 2090 struct wg_session *wgs;
2091 2091
2092 int s = pserialize_read_enter(); 2092 int s = pserialize_read_enter();
2093 /* XXX O(n) */ 2093 /* XXX O(n) */
2094 WG_PEER_READER_FOREACH(wgp, wg) { 2094 WG_PEER_READER_FOREACH(wgp, wg) {
2095 wgs = wgp->wgp_session_stable; 2095 wgs = wgp->wgp_session_stable;
2096 WG_DLOG("index=%x wgs_sender_index=%x\n", 2096 WG_DLOG("index=%x wgs_sender_index=%x\n",
2097 index, wgs->wgs_sender_index); 2097 index, wgs->wgs_sender_index);
2098 if (wgs->wgs_sender_index == index) 2098 if (wgs->wgs_sender_index == index)
2099 break; 2099 break;
2100 wgs = wgp->wgp_session_unstable; 2100 wgs = wgp->wgp_session_unstable;
2101 WG_DLOG("index=%x wgs_sender_index=%x\n", 2101 WG_DLOG("index=%x wgs_sender_index=%x\n",
2102 index, wgs->wgs_sender_index); 2102 index, wgs->wgs_sender_index);
2103 if (wgs->wgs_sender_index == index) 2103 if (wgs->wgs_sender_index == index)
2104 break; 2104 break;
2105 wgs = NULL; 2105 wgs = NULL;
2106 } 2106 }
2107 if (wgs != NULL) 2107 if (wgs != NULL)
2108 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class); 2108 psref_acquire(psref, &wgs->wgs_psref, wg_psref_class);
2109 pserialize_read_exit(s); 2109 pserialize_read_exit(s);
2110 2110
2111 return wgs; 2111 return wgs;
2112} 2112}
2113 2113
2114static void 2114static void
2115wg_schedule_rekey_timer(struct wg_peer *wgp) 2115wg_schedule_rekey_timer(struct wg_peer *wgp)
2116{ 2116{
2117 int timeout = MIN(wg_rekey_after_time, INT_MAX/hz); 2117 int timeout = MIN(wg_rekey_after_time, INT_MAX/hz);
2118 2118
2119 callout_schedule(&wgp->wgp_rekey_timer, timeout * hz); 2119 callout_schedule(&wgp->wgp_rekey_timer, timeout * hz);
2120} 2120}
2121 2121
2122static void 2122static void
2123wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs) 2123wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs)
2124{ 2124{
2125 struct mbuf *m; 2125 struct mbuf *m;
2126 2126
2127 /* 2127 /*
2128 * [W] 6.5 Passive Keepalive 2128 * [W] 6.5 Passive Keepalive
2129 * "A keepalive message is simply a transport data message with 2129 * "A keepalive message is simply a transport data message with
2130 * a zero-length encapsulated encrypted inner-packet." 2130 * a zero-length encapsulated encrypted inner-packet."
2131 */ 2131 */
2132 m = m_gethdr(M_WAIT, MT_DATA); 2132 m = m_gethdr(M_WAIT, MT_DATA);
2133 wg_send_data_msg(wgp, wgs, m); 2133 wg_send_data_msg(wgp, wgs, m);
2134} 2134}
2135 2135
2136static bool 2136static bool
2137wg_need_to_send_init_message(struct wg_session *wgs) 2137wg_need_to_send_init_message(struct wg_session *wgs)
2138{ 2138{
2139 /* 2139 /*
2140 * [W] 6.2 Transport Message Limits 2140 * [W] 6.2 Transport Message Limits
2141 * "if a peer is the initiator of a current secure session, 2141 * "if a peer is the initiator of a current secure session,
2142 * WireGuard will send a handshake initiation message to begin 2142 * WireGuard will send a handshake initiation message to begin
2143 * a new secure session ... if after receiving a transport data 2143 * a new secure session ... if after receiving a transport data
2144 * message, the current secure session is (REJECT-AFTER-TIME − 2144 * message, the current secure session is (REJECT-AFTER-TIME −
2145 * KEEPALIVE-TIMEOUT − REKEY-TIMEOUT) seconds old and it has 2145 * KEEPALIVE-TIMEOUT − REKEY-TIMEOUT) seconds old and it has
2146 * not yet acted upon this event." 2146 * not yet acted upon this event."
2147 */ 2147 */
2148 return wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0 && 2148 return wgs->wgs_is_initiator && wgs->wgs_time_last_data_sent == 0 &&
2149 (time_uptime - wgs->wgs_time_established) >= 2149 (time_uptime - wgs->wgs_time_established) >=
2150 (wg_reject_after_time - wg_keepalive_timeout - wg_rekey_timeout); 2150 (wg_reject_after_time - wg_keepalive_timeout - wg_rekey_timeout);
2151} 2151}
2152 2152
2153static void 2153static void
2154wg_schedule_peer_task(struct wg_peer *wgp, int task) 2154wg_schedule_peer_task(struct wg_peer *wgp, int task)
2155{ 2155{
2156 2156
2157 atomic_or_uint(&wgp->wgp_tasks, task); 2157 atomic_or_uint(&wgp->wgp_tasks, task);
2158 WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task); 2158 WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task);
2159 wg_wakeup_worker(wgp->wgp_sc->wg_worker, WG_WAKEUP_REASON_PEER); 2159 wg_wakeup_worker(wgp->wgp_sc->wg_worker, WG_WAKEUP_REASON_PEER);
2160} 2160}
2161 2161
2162static void 2162static void
2163wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new) 2163wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new)
2164{ 2164{
2165 2165
2166 KASSERT(mutex_owned(wgp->wgp_lock)); 2166 KASSERT(mutex_owned(wgp->wgp_lock));
2167 2167
2168 WG_TRACE("Changing endpoint"); 2168 WG_TRACE("Changing endpoint");
2169 2169
2170 memcpy(wgp->wgp_endpoint0, new, new->sa_len); 2170 memcpy(wgp->wgp_endpoint0, new, new->sa_len);
2171 wgp->wgp_endpoint0 = atomic_swap_ptr(&wgp->wgp_endpoint, 2171 wgp->wgp_endpoint0 = atomic_swap_ptr(&wgp->wgp_endpoint,
2172 wgp->wgp_endpoint0); 2172 wgp->wgp_endpoint0);
2173 if (!wgp->wgp_endpoint_available) 2173 if (!wgp->wgp_endpoint_available)
2174 wgp->wgp_endpoint_available = true; 2174 wgp->wgp_endpoint_available = true;
2175 wgp->wgp_endpoint_changing = true; 2175 wgp->wgp_endpoint_changing = true;
2176 wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED); 2176 wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED);
2177} 2177}
2178 2178
2179static bool 2179static bool
2180wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af) 2180wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af)
2181{ 2181{
2182 uint16_t packet_len; 2182 uint16_t packet_len;
2183 const struct ip *ip; 2183 const struct ip *ip;
2184 2184
2185 if (__predict_false(decrypted_len < sizeof(struct ip))) 2185 if (__predict_false(decrypted_len < sizeof(struct ip)))
2186 return false; 2186 return false;
2187 2187
2188 ip = (const struct ip *)packet; 2188 ip = (const struct ip *)packet;
2189 if (ip->ip_v == 4) 2189 if (ip->ip_v == 4)
2190 *af = AF_INET; 2190 *af = AF_INET;
2191 else if (ip->ip_v == 6) 2191 else if (ip->ip_v == 6)
2192 *af = AF_INET6; 2192 *af = AF_INET6;
2193 else 2193 else
2194 return false; 2194 return false;
2195 2195
2196 WG_DLOG("af=%d\n", *af); 2196 WG_DLOG("af=%d\n", *af);
2197 2197
2198 if (*af == AF_INET) { 2198 if (*af == AF_INET) {
2199 packet_len = ntohs(ip->ip_len); 2199 packet_len = ntohs(ip->ip_len);
2200 } else { 2200 } else {
2201 const struct ip6_hdr *ip6; 2201 const struct ip6_hdr *ip6;
2202 2202
2203 if (__predict_false(decrypted_len < sizeof(struct ip6_hdr))) 2203 if (__predict_false(decrypted_len < sizeof(struct ip6_hdr)))
2204 return false; 2204 return false;
2205 2205
2206 ip6 = (const struct ip6_hdr *)packet; 2206 ip6 = (const struct ip6_hdr *)packet;
2207 packet_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen); 2207 packet_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
2208 } 2208 }
2209 2209
2210 WG_DLOG("packet_len=%u\n", packet_len); 2210 WG_DLOG("packet_len=%u\n", packet_len);
2211 if (packet_len > decrypted_len) 2211 if (packet_len > decrypted_len)
2212 return false; 2212 return false;
2213 2213
2214 return true; 2214 return true;
2215} 2215}
2216 2216
2217static bool 2217static bool
2218wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected, 2218wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected,
2219 int af, char *packet) 2219 int af, char *packet)
2220{ 2220{
2221 struct sockaddr_storage ss; 2221 struct sockaddr_storage ss;
2222 struct sockaddr *sa; 2222 struct sockaddr *sa;
2223 struct psref psref; 2223 struct psref psref;
2224 struct wg_peer *wgp; 2224 struct wg_peer *wgp;
2225 bool ok; 2225 bool ok;
2226 2226
2227 /* 2227 /*
2228 * II CRYPTOKEY ROUTING 2228 * II CRYPTOKEY ROUTING
2229 * "it will only accept it if its source IP resolves in the 2229 * "it will only accept it if its source IP resolves in the
2230 * table to the public key used in the secure session for 2230 * table to the public key used in the secure session for
2231 * decrypting it." 2231 * decrypting it."
2232 */ 2232 */
2233 2233
2234 if (af == AF_INET) { 2234 if (af == AF_INET) {
2235 const struct ip *ip = (const struct ip *)packet; 2235 const struct ip *ip = (const struct ip *)packet;
2236 struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 2236 struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
2237 sockaddr_in_init(sin, &ip->ip_src, 0); 2237 sockaddr_in_init(sin, &ip->ip_src, 0);
2238 sa = sintosa(sin); 2238 sa = sintosa(sin);
2239#ifdef INET6 2239#ifdef INET6
2240 } else { 2240 } else {
2241 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet; 2241 const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet;
2242 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 2242 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss;
2243 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0); 2243 sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0);
2244 sa = sin6tosa(sin6); 2244 sa = sin6tosa(sin6);
2245#endif 2245#endif
2246 } 2246 }
2247 2247
2248 wgp = wg_pick_peer_by_sa(wg, sa, &psref); 2248 wgp = wg_pick_peer_by_sa(wg, sa, &psref);
2249 ok = (wgp == wgp_expected); 2249 ok = (wgp == wgp_expected);
2250 if (wgp != NULL) 2250 if (wgp != NULL)
2251 wg_put_peer(wgp, &psref); 2251 wg_put_peer(wgp, &psref);
2252 2252
2253 return ok; 2253 return ok;
2254} 2254}
2255 2255
2256static void 2256static void
2257wg_session_dtor_timer(void *arg) 2257wg_session_dtor_timer(void *arg)
2258{ 2258{
2259 struct wg_peer *wgp = arg; 2259 struct wg_peer *wgp = arg;
2260 2260
2261 WG_TRACE("enter"); 2261 WG_TRACE("enter");
2262 2262
2263 mutex_enter(wgp->wgp_lock); 2263 mutex_enter(wgp->wgp_lock);
2264 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) { 2264 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
2265 mutex_exit(wgp->wgp_lock); 2265 mutex_exit(wgp->wgp_lock);
2266 return; 2266 return;
2267 } 2267 }
2268 mutex_exit(wgp->wgp_lock); 2268 mutex_exit(wgp->wgp_lock);
2269 2269
2270 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION); 2270 wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION);
2271} 2271}
2272 2272
2273static void 2273static void
2274wg_schedule_session_dtor_timer(struct wg_peer *wgp) 2274wg_schedule_session_dtor_timer(struct wg_peer *wgp)
2275{ 2275{
2276 2276
2277 /* 1 second grace period */ 2277 /* 1 second grace period */
2278 callout_schedule(&wgp->wgp_session_dtor_timer, hz); 2278 callout_schedule(&wgp->wgp_session_dtor_timer, hz);
2279} 2279}
2280 2280
2281static void 2281static void
2282wg_stop_session_dtor_timer(struct wg_peer *wgp) 2282wg_stop_session_dtor_timer(struct wg_peer *wgp)
2283{ 2283{
2284 2284
2285 callout_halt(&wgp->wgp_session_dtor_timer, NULL); 2285 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
2286} 2286}
2287 2287
2288static bool 2288static bool
2289sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2) 2289sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2)
2290{ 2290{
2291 if (sa1->sa_family != sa2->sa_family) 2291 if (sa1->sa_family != sa2->sa_family)
2292 return false; 2292 return false;
2293 2293
2294 switch (sa1->sa_family) { 2294 switch (sa1->sa_family) {
2295 case AF_INET: 2295 case AF_INET:
2296 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port; 2296 return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port;
2297 case AF_INET6: 2297 case AF_INET6:
2298 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port; 2298 return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port;
2299 default: 2299 default:
2300 return true; 2300 return true;
2301 } 2301 }
2302} 2302}
2303 2303
2304static void 2304static void
2305wg_update_endpoint_if_necessary(struct wg_peer *wgp, 2305wg_update_endpoint_if_necessary(struct wg_peer *wgp,
2306 const struct sockaddr *src) 2306 const struct sockaddr *src)
2307{ 2307{
2308 2308
2309#ifdef WG_DEBUG_LOG 2309#ifdef WG_DEBUG_LOG
2310 char oldaddr[128], newaddr[128]; 2310 char oldaddr[128], newaddr[128];
2311 sockaddr_format(&wgp->wgp_sa, oldaddr, sizeof(oldaddr)); 2311 sockaddr_format(&wgp->wgp_sa, oldaddr, sizeof(oldaddr));
2312 sockaddr_format(src, newaddr, sizeof(newaddr)); 2312 sockaddr_format(src, newaddr, sizeof(newaddr));
2313 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr); 2313 WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr);
2314#endif 2314#endif
2315 2315
2316 /* 2316 /*
2317 * III: "Since the packet has authenticated correctly, the source IP of 2317 * III: "Since the packet has authenticated correctly, the source IP of
2318 * the outer UDP/IP packet is used to update the endpoint for peer..." 2318 * the outer UDP/IP packet is used to update the endpoint for peer..."
2319 */ 2319 */
2320 if (__predict_false(sockaddr_cmp(src, &wgp->wgp_sa) != 0 || 2320 if (__predict_false(sockaddr_cmp(src, &wgp->wgp_sa) != 0 ||
2321 !sockaddr_port_match(src, &wgp->wgp_sa))) { 2321 !sockaddr_port_match(src, &wgp->wgp_sa))) {
2322 mutex_enter(wgp->wgp_lock); 2322 mutex_enter(wgp->wgp_lock);
2323 /* XXX We can't change the endpoint twice in a short period */ 2323 /* XXX We can't change the endpoint twice in a short period */
2324 if (!wgp->wgp_endpoint_changing) { 2324 if (!wgp->wgp_endpoint_changing) {
2325 wg_change_endpoint(wgp, src); 2325 wg_change_endpoint(wgp, src);
2326 } 2326 }
2327 mutex_exit(wgp->wgp_lock); 2327 mutex_exit(wgp->wgp_lock);
2328 } 2328 }
2329} 2329}
2330 2330
2331static void 2331static void
2332wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m, 2332wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m,
2333 const struct sockaddr *src) 2333 const struct sockaddr *src)
2334{ 2334{
2335 struct wg_msg_data *wgmd; 2335 struct wg_msg_data *wgmd;
2336 char *encrypted_buf = NULL, *decrypted_buf; 2336 char *encrypted_buf = NULL, *decrypted_buf;
2337 size_t encrypted_len, decrypted_len; 2337 size_t encrypted_len, decrypted_len;
2338 struct wg_session *wgs; 2338 struct wg_session *wgs;
2339 struct wg_peer *wgp; 2339 struct wg_peer *wgp;
2340 size_t mlen; 2340 size_t mlen;
2341 struct psref psref; 2341 struct psref psref;
2342 int error, af; 2342 int error, af;
2343 bool success, free_encrypted_buf = false, ok; 2343 bool success, free_encrypted_buf = false, ok;
2344 struct mbuf *n; 2344 struct mbuf *n;
2345 2345
2346 if (m->m_len < sizeof(struct wg_msg_data)) { 2346 KASSERT(m->m_len >= sizeof(struct wg_msg_data));
2347 m = m_pullup(m, sizeof(struct wg_msg_data)); 
2348 if (m == NULL) 
2349 return; 
2350 } 
2351 wgmd = mtod(m, struct wg_msg_data *); 2347 wgmd = mtod(m, struct wg_msg_data *);
2352 2348
2353 KASSERT(wgmd->wgmd_type == WG_MSG_TYPE_DATA); 2349 KASSERT(wgmd->wgmd_type == WG_MSG_TYPE_DATA);
2354 WG_TRACE("data"); 2350 WG_TRACE("data");
2355 2351
2356 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref); 2352 wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref);
2357 if (wgs == NULL) { 2353 if (wgs == NULL) {
2358 WG_TRACE("No session found"); 2354 WG_TRACE("No session found");
2359 m_freem(m); 2355 m_freem(m);
2360 return; 2356 return;
2361 } 2357 }
2362 wgp = wgs->wgs_peer; 2358 wgp = wgs->wgs_peer;
2363 2359
2364 error = sliwin_check_fast(&wgs->wgs_recvwin->window, 2360 error = sliwin_check_fast(&wgs->wgs_recvwin->window,
2365 wgmd->wgmd_counter); 2361 wgmd->wgmd_counter);
2366 if (error) { 2362 if (error) {
2367 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2363 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2368 "out-of-window packet: %"PRIu64"\n", 2364 "out-of-window packet: %"PRIu64"\n",
2369 wgmd->wgmd_counter); 2365 wgmd->wgmd_counter);
2370 goto out; 2366 goto out;
2371 } 2367 }
2372 2368
2373 mlen = m_length(m); 2369 mlen = m_length(m);
2374 encrypted_len = mlen - sizeof(*wgmd); 2370 encrypted_len = mlen - sizeof(*wgmd);
2375 2371
2376 if (encrypted_len < WG_AUTHTAG_LEN) { 2372 if (encrypted_len < WG_AUTHTAG_LEN) {
2377 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len); 2373 WG_DLOG("Short encrypted_len: %lu\n", encrypted_len);
2378 goto out; 2374 goto out;
2379 } 2375 }
2380 2376
2381 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len); 2377 success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len);
2382 if (success) { 2378 if (success) {
2383 encrypted_buf = mtod(m, char *) + sizeof(*wgmd); 2379 encrypted_buf = mtod(m, char *) + sizeof(*wgmd);
2384 } else { 2380 } else {
2385 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP); 2381 encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP);
2386 if (encrypted_buf == NULL) { 2382 if (encrypted_buf == NULL) {
2387 WG_DLOG("failed to allocate encrypted_buf\n"); 2383 WG_DLOG("failed to allocate encrypted_buf\n");
2388 goto out; 2384 goto out;
2389 } 2385 }
2390 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf); 2386 m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf);
2391 free_encrypted_buf = true; 2387 free_encrypted_buf = true;
2392 } 2388 }
2393 /* m_ensure_contig may change m regardless of its result */ 2389 /* m_ensure_contig may change m regardless of its result */
2394 wgmd = mtod(m, struct wg_msg_data *); 2390 wgmd = mtod(m, struct wg_msg_data *);
2395 2391
2396 decrypted_len = encrypted_len - WG_AUTHTAG_LEN; 2392 decrypted_len = encrypted_len - WG_AUTHTAG_LEN;
2397 if (decrypted_len > MCLBYTES) { 2393 if (decrypted_len > MCLBYTES) {
2398 /* FIXME handle larger data than MCLBYTES */ 2394 /* FIXME handle larger data than MCLBYTES */
2399 WG_DLOG("couldn't handle larger data than MCLBYTES\n"); 2395 WG_DLOG("couldn't handle larger data than MCLBYTES\n");
2400 goto out; 2396 goto out;
2401 } 2397 }
2402 2398
2403 /* To avoid zero length */ 2399 /* To avoid zero length */
2404 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN); 2400 n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN);
2405 if (n == NULL) { 2401 if (n == NULL) {
2406 WG_DLOG("wg_get_mbuf failed\n"); 2402 WG_DLOG("wg_get_mbuf failed\n");
2407 goto out; 2403 goto out;
2408 } 2404 }
2409 decrypted_buf = mtod(n, char *); 2405 decrypted_buf = mtod(n, char *);
2410 2406
2411 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len); 2407 WG_DLOG("mlen=%lu, encrypted_len=%lu\n", mlen, encrypted_len);
2412 error = wg_algo_aead_dec(decrypted_buf, 2408 error = wg_algo_aead_dec(decrypted_buf,
2413 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */, 2409 encrypted_len - WG_AUTHTAG_LEN /* can be 0 */,
2414 wgs->wgs_tkey_recv, wgmd->wgmd_counter, encrypted_buf, 2410 wgs->wgs_tkey_recv, wgmd->wgmd_counter, encrypted_buf,
2415 encrypted_len, NULL, 0); 2411 encrypted_len, NULL, 0);
2416 if (error != 0) { 2412 if (error != 0) {
2417 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2413 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2418 "failed to wg_algo_aead_dec\n"); 2414 "failed to wg_algo_aead_dec\n");
2419 m_freem(n); 2415 m_freem(n);
2420 goto out; 2416 goto out;
2421 } 2417 }
2422 WG_DLOG("outsize=%u\n", (u_int)decrypted_len); 2418 WG_DLOG("outsize=%u\n", (u_int)decrypted_len);
2423 2419
2424 mutex_enter(&wgs->wgs_recvwin->lock); 2420 mutex_enter(&wgs->wgs_recvwin->lock);
2425 error = sliwin_update(&wgs->wgs_recvwin->window, 2421 error = sliwin_update(&wgs->wgs_recvwin->window,
2426 wgmd->wgmd_counter); 2422 wgmd->wgmd_counter);
2427 mutex_exit(&wgs->wgs_recvwin->lock); 2423 mutex_exit(&wgs->wgs_recvwin->lock);
2428 if (error) { 2424 if (error) {
2429 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2425 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2430 "replay or out-of-window packet: %"PRIu64"\n", 2426 "replay or out-of-window packet: %"PRIu64"\n",
2431 wgmd->wgmd_counter); 2427 wgmd->wgmd_counter);
2432 m_freem(n); 2428 m_freem(n);
2433 goto out; 2429 goto out;
2434 } 2430 }
2435 2431
2436 m_freem(m); 2432 m_freem(m);
2437 m = NULL; 2433 m = NULL;
2438 wgmd = NULL; 2434 wgmd = NULL;
2439 2435
2440 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af); 2436 ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af);
2441 if (!ok) { 2437 if (!ok) {
2442 /* something wrong... */ 2438 /* something wrong... */
2443 m_freem(n); 2439 m_freem(n);
2444 goto out; 2440 goto out;
2445 } 2441 }
2446 2442
2447 wg_update_endpoint_if_necessary(wgp, src); 2443 wg_update_endpoint_if_necessary(wgp, src);
2448 2444
2449 ok = wg_validate_route(wg, wgp, af, decrypted_buf); 2445 ok = wg_validate_route(wg, wgp, af, decrypted_buf);
2450 if (ok) { 2446 if (ok) {
2451 wg->wg_ops->input(&wg->wg_if, n, af); 2447 wg->wg_ops->input(&wg->wg_if, n, af);
2452 } else { 2448 } else {
2453 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2449 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2454 "invalid source address\n"); 2450 "invalid source address\n");
2455 m_freem(n); 2451 m_freem(n);
2456 /* 2452 /*
2457 * The inner address is invalid however the session is valid 2453 * The inner address is invalid however the session is valid
2458 * so continue the session processing below. 2454 * so continue the session processing below.
2459 */ 2455 */
2460 } 2456 }
2461 n = NULL; 2457 n = NULL;
2462 2458
2463 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) { 2459 if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) {
2464 struct wg_session *wgs_prev; 2460 struct wg_session *wgs_prev;
2465 2461
2466 KASSERT(wgs == wgp->wgp_session_unstable); 2462 KASSERT(wgs == wgp->wgp_session_unstable);
2467 wgs->wgs_state = WGS_STATE_ESTABLISHED; 2463 wgs->wgs_state = WGS_STATE_ESTABLISHED;
2468 wgs->wgs_time_established = time_uptime; 2464 wgs->wgs_time_established = time_uptime;
2469 wgs->wgs_time_last_data_sent = 0; 2465 wgs->wgs_time_last_data_sent = 0;
2470 wgs->wgs_is_initiator = false; 2466 wgs->wgs_is_initiator = false;
2471 WG_TRACE("WGS_STATE_ESTABLISHED"); 2467 WG_TRACE("WGS_STATE_ESTABLISHED");
2472 2468
2473 mutex_enter(wgp->wgp_lock); 2469 mutex_enter(wgp->wgp_lock);
2474 wg_swap_sessions(wgp); 2470 wg_swap_sessions(wgp);
2475 wgs_prev = wgp->wgp_session_unstable; 2471 wgs_prev = wgp->wgp_session_unstable;
2476 mutex_enter(wgs_prev->wgs_lock); 2472 mutex_enter(wgs_prev->wgs_lock);
2477 getnanotime(&wgp->wgp_last_handshake_time); 2473 getnanotime(&wgp->wgp_last_handshake_time);
2478 wgp->wgp_handshake_start_time = 0; 2474 wgp->wgp_handshake_start_time = 0;
2479 wgp->wgp_last_sent_mac1_valid = false; 2475 wgp->wgp_last_sent_mac1_valid = false;
2480 wgp->wgp_last_sent_cookie_valid = false; 2476 wgp->wgp_last_sent_cookie_valid = false;
2481 mutex_exit(wgp->wgp_lock); 2477 mutex_exit(wgp->wgp_lock);
2482 2478
2483 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) { 2479 if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) {
2484 wgs_prev->wgs_state = WGS_STATE_DESTROYING; 2480 wgs_prev->wgs_state = WGS_STATE_DESTROYING;
2485 /* We can't destroy the old session immediately */ 2481 /* We can't destroy the old session immediately */
2486 wg_schedule_session_dtor_timer(wgp); 2482 wg_schedule_session_dtor_timer(wgp);
2487 } else { 2483 } else {
2488 wg_clear_states(wgs_prev); 2484 wg_clear_states(wgs_prev);
2489 wgs_prev->wgs_state = WGS_STATE_UNKNOWN; 2485 wgs_prev->wgs_state = WGS_STATE_UNKNOWN;
2490 } 2486 }
2491 mutex_exit(wgs_prev->wgs_lock); 2487 mutex_exit(wgs_prev->wgs_lock);
2492 2488
2493 /* Anyway run a softint to flush pending packets */ 2489 /* Anyway run a softint to flush pending packets */
2494 kpreempt_disable(); 2490 kpreempt_disable();
2495 softint_schedule(wgp->wgp_si); 2491 softint_schedule(wgp->wgp_si);
2496 kpreempt_enable(); 2492 kpreempt_enable();
2497 } else { 2493 } else {
2498 if (__predict_false(wg_need_to_send_init_message(wgs))) { 2494 if (__predict_false(wg_need_to_send_init_message(wgs))) {
2499 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 2495 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
2500 } 2496 }
2501 /* 2497 /*
2502 * [W] 6.5 Passive Keepalive 2498 * [W] 6.5 Passive Keepalive
2503 * "If a peer has received a validly-authenticated transport 2499 * "If a peer has received a validly-authenticated transport
2504 * 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
2505 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends 2501 * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends
2506 * a keepalive message." 2502 * a keepalive message."
2507 */ 2503 */
2508 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",
2509 time_uptime, wgs->wgs_time_last_data_sent); 2505 time_uptime, wgs->wgs_time_last_data_sent);
2510 if ((time_uptime - wgs->wgs_time_last_data_sent) >= 2506 if ((time_uptime - wgs->wgs_time_last_data_sent) >=
2511 wg_keepalive_timeout) { 2507 wg_keepalive_timeout) {
2512 WG_TRACE("Schedule sending keepalive message"); 2508 WG_TRACE("Schedule sending keepalive message");
2513 /* 2509 /*
2514 * We can't send a keepalive message here to avoid 2510 * We can't send a keepalive message here to avoid
2515 * a deadlock; we already hold the solock of a socket 2511 * a deadlock; we already hold the solock of a socket
2516 * that is used to send the message. 2512 * that is used to send the message.
2517 */ 2513 */
2518 wg_schedule_peer_task(wgp, 2514 wg_schedule_peer_task(wgp,
2519 WGP_TASK_SEND_KEEPALIVE_MESSAGE); 2515 WGP_TASK_SEND_KEEPALIVE_MESSAGE);
2520 } 2516 }
2521 } 2517 }
2522out: 2518out:
2523 wg_put_session(wgs, &psref); 2519 wg_put_session(wgs, &psref);
2524 if (m != NULL) 2520 if (m != NULL)
2525 m_freem(m); 2521 m_freem(m);
2526 if (free_encrypted_buf) 2522 if (free_encrypted_buf)
2527 kmem_intr_free(encrypted_buf, encrypted_len); 2523 kmem_intr_free(encrypted_buf, encrypted_len);
2528} 2524}
2529 2525
2530static void 2526static void
2531wg_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)
2532{ 2528{
2533 struct wg_session *wgs; 2529 struct wg_session *wgs;
2534 struct wg_peer *wgp; 2530 struct wg_peer *wgp;
2535 struct psref psref; 2531 struct psref psref;
2536 int error; 2532 int error;
2537 uint8_t key[WG_HASH_LEN]; 2533 uint8_t key[WG_HASH_LEN];
2538 uint8_t cookie[WG_COOKIE_LEN]; 2534 uint8_t cookie[WG_COOKIE_LEN];
2539 2535
2540 WG_TRACE("cookie msg received"); 2536 WG_TRACE("cookie msg received");
2541 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref); 2537 wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref);
2542 if (wgs == NULL) { 2538 if (wgs == NULL) {
2543 WG_TRACE("No session found"); 2539 WG_TRACE("No session found");
2544 return; 2540 return;
2545 } 2541 }
2546 wgp = wgs->wgs_peer; 2542 wgp = wgs->wgs_peer;
2547 2543
2548 if (!wgp->wgp_last_sent_mac1_valid) { 2544 if (!wgp->wgp_last_sent_mac1_valid) {
2549 WG_TRACE("No valid mac1 sent (or expired)"); 2545 WG_TRACE("No valid mac1 sent (or expired)");
2550 goto out; 2546 goto out;
2551 } 2547 }
2552 2548
2553 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey, 2549 wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey,
2554 sizeof(wgp->wgp_pubkey)); 2550 sizeof(wgp->wgp_pubkey));
2555 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 0, 2551 error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 0,
2556 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), 2552 wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie),
2557 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1), 2553 wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1),
2558 wgmc->wgmc_salt); 2554 wgmc->wgmc_salt);
2559 if (error != 0) { 2555 if (error != 0) {
2560 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2556 WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG,
2561 "wg_algo_aead_dec for cookie failed: error=%d\n", error); 2557 "wg_algo_aead_dec for cookie failed: error=%d\n", error);
2562 goto out; 2558 goto out;
2563 } 2559 }
2564 /* 2560 /*
2565 * [W] 6.6: Interaction with Cookie Reply System 2561 * [W] 6.6: Interaction with Cookie Reply System
2566 * "it should simply store the decrypted cookie value from the cookie 2562 * "it should simply store the decrypted cookie value from the cookie
2567 * reply message, and wait for the expiration of the REKEY-TIMEOUT 2563 * reply message, and wait for the expiration of the REKEY-TIMEOUT
2568 * timer for retrying a handshake initiation message." 2564 * timer for retrying a handshake initiation message."
2569 */ 2565 */
2570 wgp->wgp_latest_cookie_time = time_uptime; 2566 wgp->wgp_latest_cookie_time = time_uptime;
2571 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie)); 2567 memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie));
2572out: 2568out:
2573 wg_put_session(wgs, &psref); 2569 wg_put_session(wgs, &psref);
2574} 2570}
2575 2571
2576static bool 2572static struct mbuf *
2577wg_validate_msg_length(struct wg_softc *wg, const struct mbuf *m) 2573wg_validate_msg_header(struct wg_softc *wg, struct mbuf *m)
2578{ 2574{
2579 struct wg_msg *wgm; 2575 struct wg_msg wgm;
2580 size_t mlen; 2576 size_t mbuflen;
 2577 size_t msglen;
2581 2578
2582 mlen = m_length(m); 2579 /*
2583 if (__predict_false(mlen < sizeof(struct wg_msg))) 2580 * Get the mbuf chain length. It is already guaranteed, by
2584 return false; 2581 * wg_overudp_cb, to be large enough for a struct wg_msg.
 2582 */
 2583 mbuflen = m_length(m);
 2584 KASSERT(mbuflen >= sizeof(struct wg_msg));
2585 2585
2586 wgm = mtod(m, struct wg_msg *); 2586 /*
2587 switch (wgm->wgm_type) { 2587 * Copy the message header (32-bit message type) out -- we'll
 2588 * worry about contiguity and alignment later.
 2589 */
 2590 m_copydata(m, 0, sizeof(wgm), &wgm);
 2591 switch (wgm.wgm_type) {
2588 case WG_MSG_TYPE_INIT: 2592 case WG_MSG_TYPE_INIT:
2589 if (__predict_true(mlen >= sizeof(struct wg_msg_init))) 2593 msglen = sizeof(struct wg_msg_init);
2590 return true; 
2591 break; 2594 break;
2592 case WG_MSG_TYPE_RESP: 2595 case WG_MSG_TYPE_RESP:
2593 if (__predict_true(mlen >= sizeof(struct wg_msg_resp))) 2596 msglen = sizeof(struct wg_msg_resp);
2594 return true; 
2595 break; 2597 break;
2596 case WG_MSG_TYPE_COOKIE: 2598 case WG_MSG_TYPE_COOKIE:
2597 if (__predict_true(mlen >= sizeof(struct wg_msg_cookie))) 2599 msglen = sizeof(struct wg_msg_cookie);
2598 return true; 
2599 break; 2600 break;
2600 case WG_MSG_TYPE_DATA: 2601 case WG_MSG_TYPE_DATA:
2601 if (__predict_true(mlen >= sizeof(struct wg_msg_data))) 2602 msglen = sizeof(struct wg_msg_data);
2602 return true; 
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 return false; 2607 goto error;
2608 } 2608 }
2609 WG_DLOG("Invalid msg size: mlen=%lu type=%u\n", mlen, wgm->wgm_type); 
2610 2609
2611 return false; 2610 /* Verify the mbuf chain is long enough for this type of message. */
 2611 if (__predict_false(mbuflen < msglen)) {
 2612 WG_DLOG("Invalid msg size: mbuflen=%lu type=%u\n", mbuflen,
 2613 wgm.wgm_type);
 2614 goto error;
 2615 }
 2616
 2617 /* Make the message header contiguous if necessary. */
 2618 if (__predict_false(m->m_len < msglen)) {
 2619 m = m_pullup(m, msglen);
 2620 if (m == NULL)
 2621 return NULL;
 2622 }
 2623
 2624 return m;
 2625
 2626error:
 2627 m_freem(m);
 2628 return NULL;
2612} 2629}
2613 2630
2614static void 2631static void
2615wg_handle_packet(struct wg_softc *wg, struct mbuf *m, 2632wg_handle_packet(struct wg_softc *wg, struct mbuf *m,
2616 const struct sockaddr *src) 2633 const struct sockaddr *src)
2617{ 2634{
2618 struct wg_msg *wgm; 2635 struct wg_msg *wgm;
2619 bool valid; 
2620 2636
2621 valid = wg_validate_msg_length(wg, m); 2637 m = wg_validate_msg_header(wg, m);
2622 if (!valid) { 2638 if (__predict_false(m == NULL))
2623 m_freem(m); 
2624 return; 2639 return;
2625 } 
2626 2640
 2641 KASSERT(m->m_len >= sizeof(struct wg_msg));
2627 wgm = mtod(m, struct wg_msg *); 2642 wgm = mtod(m, struct wg_msg *);
2628 switch (wgm->wgm_type) { 2643 switch (wgm->wgm_type) {
2629 case WG_MSG_TYPE_INIT: 2644 case WG_MSG_TYPE_INIT:
2630 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src); 2645 wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src);
2631 break; 2646 break;
2632 case WG_MSG_TYPE_RESP: 2647 case WG_MSG_TYPE_RESP:
2633 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src); 2648 wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src);
2634 break; 2649 break;
2635 case WG_MSG_TYPE_COOKIE: 2650 case WG_MSG_TYPE_COOKIE:
2636 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm); 2651 wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm);
2637 break; 2652 break;
2638 case WG_MSG_TYPE_DATA: 2653 case WG_MSG_TYPE_DATA:
2639 wg_handle_msg_data(wg, m, src); 2654 wg_handle_msg_data(wg, m, src);
2640 break; 2655 break;
2641 default: 2656 default:
2642 /* wg_validate_msg_length should already reject this case */ 2657 /* wg_validate_msg_header should already reject this case */
2643 break; 2658 break;
2644 } 2659 }
2645} 2660}
2646 2661
2647static void 2662static void
2648wg_receive_packets(struct wg_softc *wg, const int af) 2663wg_receive_packets(struct wg_softc *wg, const int af)
2649{ 2664{
2650 2665
2651 for (;;) { 2666 for (;;) {
2652 int error, flags; 2667 int error, flags;
2653 struct socket *so; 2668 struct socket *so;
2654 struct mbuf *m = NULL; 2669 struct mbuf *m = NULL;
2655 struct uio dummy_uio; 2670 struct uio dummy_uio;
2656 struct mbuf *paddr = NULL; 2671 struct mbuf *paddr = NULL;
2657 struct sockaddr *src; 2672 struct sockaddr *src;
2658 2673
2659 so = wg_get_so_by_af(wg->wg_worker, af); 2674 so = wg_get_so_by_af(wg->wg_worker, af);
2660 flags = MSG_DONTWAIT; 2675 flags = MSG_DONTWAIT;
2661 dummy_uio.uio_resid = 1000000000; 2676 dummy_uio.uio_resid = 1000000000;
2662 2677
2663 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL, 2678 error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL,
2664 &flags); 2679 &flags);
2665 if (error || m == NULL) { 2680 if (error || m == NULL) {
2666 //if (error == EWOULDBLOCK) 2681 //if (error == EWOULDBLOCK)
2667 return; 2682 return;
2668 } 2683 }
2669 2684
2670 KASSERT(paddr != NULL); 2685 KASSERT(paddr != NULL);
2671 src = mtod(paddr, struct sockaddr *); 2686 src = mtod(paddr, struct sockaddr *);
2672 2687
2673 wg_handle_packet(wg, m, src); 2688 wg_handle_packet(wg, m, src);
2674 } 2689 }
2675} 2690}
2676 2691
2677static void 2692static void
2678wg_get_peer(struct wg_peer *wgp, struct psref *psref) 2693wg_get_peer(struct wg_peer *wgp, struct psref *psref)
2679{ 2694{
2680 2695
2681 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class); 2696 psref_acquire(psref, &wgp->wgp_psref, wg_psref_class);
2682} 2697}
2683 2698
2684static void 2699static void
2685wg_put_peer(struct wg_peer *wgp, struct psref *psref) 2700wg_put_peer(struct wg_peer *wgp, struct psref *psref)
2686{ 2701{
2687 2702
2688 psref_release(psref, &wgp->wgp_psref, wg_psref_class); 2703 psref_release(psref, &wgp->wgp_psref, wg_psref_class);
2689} 2704}
2690 2705
2691static void 2706static void
2692wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp) 2707wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp)
2693{ 2708{
2694 struct psref psref; 2709 struct psref psref;
2695 struct wg_session *wgs; 2710 struct wg_session *wgs;
2696 2711
2697 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE"); 2712 WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE");
2698 2713
2699 if (!wgp->wgp_endpoint_available) { 2714 if (!wgp->wgp_endpoint_available) {
2700 WGLOG(LOG_DEBUG, "No endpoint available\n"); 2715 WGLOG(LOG_DEBUG, "No endpoint available\n");
2701 /* XXX should do something? */ 2716 /* XXX should do something? */
2702 return; 2717 return;
2703 } 2718 }
2704 2719
2705 wgs = wg_get_stable_session(wgp, &psref); 2720 wgs = wg_get_stable_session(wgp, &psref);
2706 if (wgs->wgs_state == WGS_STATE_UNKNOWN) { 2721 if (wgs->wgs_state == WGS_STATE_UNKNOWN) {
2707 wg_put_session(wgs, &psref); 2722 wg_put_session(wgs, &psref);
2708 wg_send_handshake_msg_init(wg, wgp); 2723 wg_send_handshake_msg_init(wg, wgp);
2709 } else { 2724 } else {
2710 wg_put_session(wgs, &psref); 2725 wg_put_session(wgs, &psref);
2711 /* rekey */ 2726 /* rekey */
2712 wgs = wg_get_unstable_session(wgp, &psref); 2727 wgs = wg_get_unstable_session(wgp, &psref);
2713 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE) 2728 if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE)
2714 wg_send_handshake_msg_init(wg, wgp); 2729 wg_send_handshake_msg_init(wg, wgp);
2715 wg_put_session(wgs, &psref); 2730 wg_put_session(wgs, &psref);
2716 } 2731 }
2717} 2732}
2718 2733
2719static void 2734static void
2720wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp) 2735wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp)
2721{ 2736{
2722 2737
2723 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED"); 2738 WG_TRACE("WGP_TASK_ENDPOINT_CHANGED");
2724 2739
2725 mutex_enter(wgp->wgp_lock); 2740 mutex_enter(wgp->wgp_lock);
2726 if (wgp->wgp_endpoint_changing) { 2741 if (wgp->wgp_endpoint_changing) {
2727 pserialize_perform(wgp->wgp_psz); 2742 pserialize_perform(wgp->wgp_psz);
2728 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, 2743 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref,
2729 wg_psref_class); 2744 wg_psref_class);
2730 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, 2745 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref,
2731 wg_psref_class); 2746 wg_psref_class);
2732 wgp->wgp_endpoint_changing = false; 2747 wgp->wgp_endpoint_changing = false;
2733 } 2748 }
2734 mutex_exit(wgp->wgp_lock); 2749 mutex_exit(wgp->wgp_lock);
2735} 2750}
2736 2751
2737static void 2752static void
2738wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp) 2753wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp)
2739{ 2754{
2740 struct psref psref; 2755 struct psref psref;
2741 struct wg_session *wgs; 2756 struct wg_session *wgs;
2742 2757
2743 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE"); 2758 WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE");
2744 2759
2745 wgs = wg_get_stable_session(wgp, &psref); 2760 wgs = wg_get_stable_session(wgp, &psref);
2746 wg_send_keepalive_msg(wgp, wgs); 2761 wg_send_keepalive_msg(wgp, wgs);
2747 wg_put_session(wgs, &psref); 2762 wg_put_session(wgs, &psref);
2748} 2763}
2749 2764
2750static void 2765static void
2751wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp) 2766wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp)
2752{ 2767{
2753 struct wg_session *wgs; 2768 struct wg_session *wgs;
2754 2769
2755 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION"); 2770 WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION");
2756 2771
2757 mutex_enter(wgp->wgp_lock); 2772 mutex_enter(wgp->wgp_lock);
2758 wgs = wgp->wgp_session_unstable; 2773 wgs = wgp->wgp_session_unstable;
2759 mutex_enter(wgs->wgs_lock); 2774 mutex_enter(wgs->wgs_lock);
2760 if (wgs->wgs_state == WGS_STATE_DESTROYING) { 2775 if (wgs->wgs_state == WGS_STATE_DESTROYING) {
2761 pserialize_perform(wgp->wgp_psz); 2776 pserialize_perform(wgp->wgp_psz);
2762 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 2777 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
2763 psref_target_init(&wgs->wgs_psref, wg_psref_class); 2778 psref_target_init(&wgs->wgs_psref, wg_psref_class);
2764 wg_clear_states(wgs); 2779 wg_clear_states(wgs);
2765 wgs->wgs_state = WGS_STATE_UNKNOWN; 2780 wgs->wgs_state = WGS_STATE_UNKNOWN;
2766 } 2781 }
2767 mutex_exit(wgs->wgs_lock); 2782 mutex_exit(wgs->wgs_lock);
2768 mutex_exit(wgp->wgp_lock); 2783 mutex_exit(wgp->wgp_lock);
2769} 2784}
2770 2785
2771static void 2786static void
2772wg_process_peer_tasks(struct wg_softc *wg) 2787wg_process_peer_tasks(struct wg_softc *wg)
2773{ 2788{
2774 struct wg_peer *wgp; 2789 struct wg_peer *wgp;
2775 int s; 2790 int s;
2776 2791
2777 /* XXX should avoid checking all peers */ 2792 /* XXX should avoid checking all peers */
2778 s = pserialize_read_enter(); 2793 s = pserialize_read_enter();
2779 WG_PEER_READER_FOREACH(wgp, wg) { 2794 WG_PEER_READER_FOREACH(wgp, wg) {
2780 struct psref psref; 2795 struct psref psref;
2781 unsigned int tasks; 2796 unsigned int tasks;
2782 2797
2783 if (wgp->wgp_tasks == 0) 2798 if (wgp->wgp_tasks == 0)
2784 continue; 2799 continue;
2785 2800
2786 wg_get_peer(wgp, &psref); 2801 wg_get_peer(wgp, &psref);
2787 pserialize_read_exit(s); 2802 pserialize_read_exit(s);
2788 2803
2789 restart: 2804 restart:
2790 tasks = atomic_swap_uint(&wgp->wgp_tasks, 0); 2805 tasks = atomic_swap_uint(&wgp->wgp_tasks, 0);
2791 KASSERT(tasks != 0); 2806 KASSERT(tasks != 0);
2792 2807
2793 WG_DLOG("tasks=%x\n", tasks); 2808 WG_DLOG("tasks=%x\n", tasks);
2794 2809
2795 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE)) 2810 if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE))
2796 wg_task_send_init_message(wg, wgp); 2811 wg_task_send_init_message(wg, wgp);
2797 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED)) 2812 if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED))
2798 wg_task_endpoint_changed(wg, wgp); 2813 wg_task_endpoint_changed(wg, wgp);
2799 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE)) 2814 if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE))
2800 wg_task_send_keepalive_message(wg, wgp); 2815 wg_task_send_keepalive_message(wg, wgp);
2801 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION)) 2816 if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION))
2802 wg_task_destroy_prev_session(wg, wgp); 2817 wg_task_destroy_prev_session(wg, wgp);
2803 2818
2804 /* New tasks may be scheduled during processing tasks */ 2819 /* New tasks may be scheduled during processing tasks */
2805 WG_DLOG("wgp_tasks=%d\n", wgp->wgp_tasks); 2820 WG_DLOG("wgp_tasks=%d\n", wgp->wgp_tasks);
2806 if (wgp->wgp_tasks != 0) 2821 if (wgp->wgp_tasks != 0)
2807 goto restart; 2822 goto restart;
2808 2823
2809 s = pserialize_read_enter(); 2824 s = pserialize_read_enter();
2810 wg_put_peer(wgp, &psref); 2825 wg_put_peer(wgp, &psref);
2811 } 2826 }
2812 pserialize_read_exit(s); 2827 pserialize_read_exit(s);
2813} 2828}
2814 2829
2815static void 2830static void
2816wg_worker(void *arg) 2831wg_worker(void *arg)
2817{ 2832{
2818 struct wg_softc *wg = arg; 2833 struct wg_softc *wg = arg;
2819 struct wg_worker *wgw = wg->wg_worker; 2834 struct wg_worker *wgw = wg->wg_worker;
2820 bool todie = false; 2835 bool todie = false;
2821 2836
2822 KASSERT(wg != NULL); 2837 KASSERT(wg != NULL);
2823 KASSERT(wgw != NULL); 2838 KASSERT(wgw != NULL);
2824 2839
2825 while (!todie) { 2840 while (!todie) {
2826 int reasons; 2841 int reasons;
2827 int bound; 2842 int bound;
2828 2843
2829 mutex_enter(&wgw->wgw_lock); 2844 mutex_enter(&wgw->wgw_lock);
2830 /* New tasks may come during task handling */ 2845 /* New tasks may come during task handling */
2831 while ((reasons = wgw->wgw_wakeup_reasons) == 0 && 2846 while ((reasons = wgw->wgw_wakeup_reasons) == 0 &&
2832 !(todie = wgw->wgw_todie)) 2847 !(todie = wgw->wgw_todie))
2833 cv_wait(&wgw->wgw_cv, &wgw->wgw_lock); 2848 cv_wait(&wgw->wgw_cv, &wgw->wgw_lock);
2834 wgw->wgw_wakeup_reasons = 0; 2849 wgw->wgw_wakeup_reasons = 0;
2835 mutex_exit(&wgw->wgw_lock); 2850 mutex_exit(&wgw->wgw_lock);
2836 2851
2837 bound = curlwp_bind(); 2852 bound = curlwp_bind();
2838 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4)) 2853 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4))
2839 wg_receive_packets(wg, AF_INET); 2854 wg_receive_packets(wg, AF_INET);
2840 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6)) 2855 if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6))
2841 wg_receive_packets(wg, AF_INET6); 2856 wg_receive_packets(wg, AF_INET6);
2842 if (ISSET(reasons, WG_WAKEUP_REASON_PEER)) 2857 if (ISSET(reasons, WG_WAKEUP_REASON_PEER))
2843 wg_process_peer_tasks(wg); 2858 wg_process_peer_tasks(wg);
2844 curlwp_bindx(bound); 2859 curlwp_bindx(bound);
2845 } 2860 }
2846 kthread_exit(0); 2861 kthread_exit(0);
2847} 2862}
2848 2863
2849static void 2864static void
2850wg_wakeup_worker(struct wg_worker *wgw, const int reason) 2865wg_wakeup_worker(struct wg_worker *wgw, const int reason)
2851{ 2866{
2852 2867
2853 mutex_enter(&wgw->wgw_lock); 2868 mutex_enter(&wgw->wgw_lock);
2854 wgw->wgw_wakeup_reasons |= reason; 2869 wgw->wgw_wakeup_reasons |= reason;
2855 cv_broadcast(&wgw->wgw_cv); 2870 cv_broadcast(&wgw->wgw_cv);
2856 mutex_exit(&wgw->wgw_lock); 2871 mutex_exit(&wgw->wgw_lock);
2857} 2872}
2858 2873
2859static int 2874static int
2860wg_bind_port(struct wg_softc *wg, const uint16_t port) 2875wg_bind_port(struct wg_softc *wg, const uint16_t port)
2861{ 2876{
2862 int error; 2877 int error;
2863 struct wg_worker *wgw = wg->wg_worker; 2878 struct wg_worker *wgw = wg->wg_worker;
2864 uint16_t old_port = wg->wg_listen_port; 2879 uint16_t old_port = wg->wg_listen_port;
2865 2880
2866 if (port != 0 && old_port == port) 2881 if (port != 0 && old_port == port)
2867 return 0; 2882 return 0;
2868 2883
2869 struct sockaddr_in _sin, *sin = &_sin; 2884 struct sockaddr_in _sin, *sin = &_sin;
2870 sin->sin_len = sizeof(*sin); 2885 sin->sin_len = sizeof(*sin);
2871 sin->sin_family = AF_INET; 2886 sin->sin_family = AF_INET;
2872 sin->sin_addr.s_addr = INADDR_ANY; 2887 sin->sin_addr.s_addr = INADDR_ANY;
2873 sin->sin_port = htons(port); 2888 sin->sin_port = htons(port);
2874 2889
2875 error = sobind(wgw->wgw_so4, sintosa(sin), curlwp); 2890 error = sobind(wgw->wgw_so4, sintosa(sin), curlwp);
2876 if (error != 0) 2891 if (error != 0)
2877 return error; 2892 return error;
2878 2893
2879#ifdef INET6 2894#ifdef INET6
2880 struct sockaddr_in6 _sin6, *sin6 = &_sin6; 2895 struct sockaddr_in6 _sin6, *sin6 = &_sin6;
2881 sin6->sin6_len = sizeof(*sin6); 2896 sin6->sin6_len = sizeof(*sin6);
2882 sin6->sin6_family = AF_INET6; 2897 sin6->sin6_family = AF_INET6;
2883 sin6->sin6_addr = in6addr_any; 2898 sin6->sin6_addr = in6addr_any;
2884 sin6->sin6_port = htons(port); 2899 sin6->sin6_port = htons(port);
2885 2900
2886 error = sobind(wgw->wgw_so6, sin6tosa(sin6), curlwp); 2901 error = sobind(wgw->wgw_so6, sin6tosa(sin6), curlwp);
2887 if (error != 0) 2902 if (error != 0)
2888 return error; 2903 return error;
2889#endif 2904#endif
2890 2905
2891 wg->wg_listen_port = port; 2906 wg->wg_listen_port = port;
2892 2907
2893 return 0; 2908 return 0;
2894} 2909}
2895 2910
2896static void 2911static void
2897wg_so_upcall(struct socket *so, void *arg, int events, int waitflag) 2912wg_so_upcall(struct socket *so, void *arg, int events, int waitflag)
2898{ 2913{
2899 struct wg_worker *wgw = arg; 2914 struct wg_worker *wgw = arg;
2900 int reason; 2915 int reason;
2901 2916
2902 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ? 2917 reason = (so->so_proto->pr_domain->dom_family == AF_INET) ?
2903 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 : 2918 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4 :
2904 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6; 2919 WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6;
2905 wg_wakeup_worker(wgw, reason); 2920 wg_wakeup_worker(wgw, reason);
2906} 2921}
2907 2922
2908static int 2923static int
2909wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so, 2924wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so,
2910 struct sockaddr *src, void *arg) 2925 struct sockaddr *src, void *arg)
2911{ 2926{
2912 struct wg_softc *wg = arg; 2927 struct wg_softc *wg = arg;
2913 struct wg_msg wgm; 2928 struct wg_msg wgm;
2914 struct mbuf *m = *mp; 2929 struct mbuf *m = *mp;
2915 2930
2916 WG_TRACE("enter"); 2931 WG_TRACE("enter");
2917 2932
2918 /* Verify the mbuf chain is long enough to have a wg msg header. */ 2933 /* Verify the mbuf chain is long enough to have a wg msg header. */
2919 KASSERT(offset <= m_length(m)); 2934 KASSERT(offset <= m_length(m));
2920 if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) { 2935 if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) {
2921 m_freem(m); 2936 m_freem(m);
2922 return -1; 2937 return -1;
2923 } 2938 }
2924 2939
2925 /* 2940 /*
2926 * Copy the message header (32-bit message type) out -- we'll 2941 * Copy the message header (32-bit message type) out -- we'll
2927 * worry about contiguity and alignment later. 2942 * worry about contiguity and alignment later.
2928 */ 2943 */
2929 m_copydata(m, offset, sizeof(struct wg_msg), &wgm); 2944 m_copydata(m, offset, sizeof(struct wg_msg), &wgm);
2930 WG_DLOG("type=%d\n", wgm.wgm_type); 2945 WG_DLOG("type=%d\n", wgm.wgm_type);
2931 2946
2932 /* 2947 /*
2933 * Handle DATA packets promptly as they arrive. Other packets 2948 * Handle DATA packets promptly as they arrive. Other packets
2934 * may require expensive public-key crypto and are not as 2949 * may require expensive public-key crypto and are not as
2935 * sensitive to latency, so defer them to the worker thread. 2950 * sensitive to latency, so defer them to the worker thread.
2936 */ 2951 */
2937 switch (wgm.wgm_type) { 2952 switch (wgm.wgm_type) {
2938 case WG_MSG_TYPE_DATA: 2953 case WG_MSG_TYPE_DATA:
2939 m_adj(m, offset); 2954 m_adj(m, offset);
2940 wg_handle_msg_data(wg, m, src); 2955 wg_handle_msg_data(wg, m, src);
2941 *mp = NULL; 2956 *mp = NULL;
2942 return 1; 2957 return 1;
2943 default: 2958 default:
2944 break; 2959 break;
2945 } 2960 }
2946 2961
2947 return 0; 2962 return 0;
2948} 2963}
2949 2964
2950static int 2965static int
2951wg_worker_socreate(struct wg_softc *wg, struct wg_worker *wgw, const int af, 2966wg_worker_socreate(struct wg_softc *wg, struct wg_worker *wgw, const int af,
2952 struct socket **sop) 2967 struct socket **sop)
2953{ 2968{
2954 int error; 2969 int error;
2955 struct socket *so; 2970 struct socket *so;
2956 2971
2957 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL); 2972 error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL);
2958 if (error != 0) 2973 if (error != 0)
2959 return error; 2974 return error;
2960 2975
2961 solock(so); 2976 solock(so);
2962 so->so_upcallarg = wgw; 2977 so->so_upcallarg = wgw;
2963 so->so_upcall = wg_so_upcall; 2978 so->so_upcall = wg_so_upcall;
2964 so->so_rcv.sb_flags |= SB_UPCALL; 2979 so->so_rcv.sb_flags |= SB_UPCALL;
2965 if (af == AF_INET) 2980 if (af == AF_INET)
2966 in_pcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg); 2981 in_pcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg);
2967#if INET6 2982#if INET6
2968 else 2983 else
2969 in6_pcb_register_overudp_cb(sotoin6pcb(so), wg_overudp_cb, wg); 2984 in6_pcb_register_overudp_cb(sotoin6pcb(so), wg_overudp_cb, wg);
2970#endif 2985#endif
2971 sounlock(so); 2986 sounlock(so);
2972 2987
2973 *sop = so; 2988 *sop = so;
2974 2989
2975 return 0; 2990 return 0;
2976} 2991}
2977 2992
2978static int 2993static int
2979wg_worker_init(struct wg_softc *wg) 2994wg_worker_init(struct wg_softc *wg)
2980{ 2995{
2981 int error; 2996 int error;
2982 struct wg_worker *wgw; 2997 struct wg_worker *wgw;
2983 const char *ifname = wg->wg_if.if_xname; 2998 const char *ifname = wg->wg_if.if_xname;
2984 struct socket *so; 2999 struct socket *so;
2985 3000
2986 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP); 3001 wgw = kmem_zalloc(sizeof(struct wg_worker), KM_SLEEP);
2987 3002
2988 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_NONE); 3003 mutex_init(&wgw->wgw_lock, MUTEX_DEFAULT, IPL_NONE);
2989 cv_init(&wgw->wgw_cv, ifname); 3004 cv_init(&wgw->wgw_cv, ifname);
2990 wgw->wgw_todie = false; 3005 wgw->wgw_todie = false;
2991 wgw->wgw_wakeup_reasons = 0; 3006 wgw->wgw_wakeup_reasons = 0;
2992 3007
2993 error = wg_worker_socreate(wg, wgw, AF_INET, &so); 3008 error = wg_worker_socreate(wg, wgw, AF_INET, &so);
2994 if (error != 0) 3009 if (error != 0)
2995 goto error; 3010 goto error;
2996 wgw->wgw_so4 = so; 3011 wgw->wgw_so4 = so;
2997#ifdef INET6 3012#ifdef INET6
2998 error = wg_worker_socreate(wg, wgw, AF_INET6, &so); 3013 error = wg_worker_socreate(wg, wgw, AF_INET6, &so);
2999 if (error != 0) 3014 if (error != 0)
3000 goto error; 3015 goto error;
3001 wgw->wgw_so6 = so; 3016 wgw->wgw_so6 = so;
3002#endif 3017#endif
3003 3018
3004 wg->wg_worker = wgw; 3019 wg->wg_worker = wgw;
3005 3020
3006 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, 3021 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN,
3007 NULL, wg_worker, wg, &wg->wg_worker_lwp, "%s", ifname); 3022 NULL, wg_worker, wg, &wg->wg_worker_lwp, "%s", ifname);
3008 if (error != 0) 3023 if (error != 0)
3009 goto error; 3024 goto error;
3010 3025
3011 return 0; 3026 return 0;
3012 3027
3013error: 3028error:
3014#ifdef INET6 3029#ifdef INET6
3015 if (wgw->wgw_so6 != NULL) 3030 if (wgw->wgw_so6 != NULL)
3016 soclose(wgw->wgw_so6); 3031 soclose(wgw->wgw_so6);
3017#endif 3032#endif
3018 if (wgw->wgw_so4 != NULL) 3033 if (wgw->wgw_so4 != NULL)
3019 soclose(wgw->wgw_so4); 3034 soclose(wgw->wgw_so4);
3020 cv_destroy(&wgw->wgw_cv); 3035 cv_destroy(&wgw->wgw_cv);
3021 mutex_destroy(&wgw->wgw_lock); 3036 mutex_destroy(&wgw->wgw_lock);
3022 3037
3023 return error; 3038 return error;
3024} 3039}
3025 3040
3026static void 3041static void
3027wg_worker_destroy(struct wg_softc *wg) 3042wg_worker_destroy(struct wg_softc *wg)
3028{ 3043{
3029 struct wg_worker *wgw = wg->wg_worker; 3044 struct wg_worker *wgw = wg->wg_worker;
3030 3045
3031 mutex_enter(&wgw->wgw_lock); 3046 mutex_enter(&wgw->wgw_lock);
3032 wgw->wgw_todie = true; 3047 wgw->wgw_todie = true;
3033 wgw->wgw_wakeup_reasons = 0; 3048 wgw->wgw_wakeup_reasons = 0;
3034 cv_broadcast(&wgw->wgw_cv); 3049 cv_broadcast(&wgw->wgw_cv);
3035 mutex_exit(&wgw->wgw_lock); 3050 mutex_exit(&wgw->wgw_lock);
3036 3051
3037 kthread_join(wg->wg_worker_lwp); 3052 kthread_join(wg->wg_worker_lwp);
3038 3053
3039#ifdef INET6 3054#ifdef INET6
3040 soclose(wgw->wgw_so6); 3055 soclose(wgw->wgw_so6);
3041#endif 3056#endif
3042 soclose(wgw->wgw_so4); 3057 soclose(wgw->wgw_so4);
3043 cv_destroy(&wgw->wgw_cv); 3058 cv_destroy(&wgw->wgw_cv);
3044 mutex_destroy(&wgw->wgw_lock); 3059 mutex_destroy(&wgw->wgw_lock);
3045 kmem_free(wg->wg_worker, sizeof(struct wg_worker)); 3060 kmem_free(wg->wg_worker, sizeof(struct wg_worker));
3046 wg->wg_worker = NULL; 3061 wg->wg_worker = NULL;
3047} 3062}
3048 3063
3049static bool 3064static bool
3050wg_session_hit_limits(struct wg_session *wgs) 3065wg_session_hit_limits(struct wg_session *wgs)
3051{ 3066{
3052 3067
3053 /* 3068 /*
3054 * [W] 6.2: Transport Message Limits 3069 * [W] 6.2: Transport Message Limits
3055 * "After REJECT-AFTER-MESSAGES transport data messages or after the 3070 * "After REJECT-AFTER-MESSAGES transport data messages or after the
3056 * current secure session is REJECT-AFTER-TIME seconds old, whichever 3071 * current secure session is REJECT-AFTER-TIME seconds old, whichever
3057 * comes first, WireGuard will refuse to send any more transport data 3072 * comes first, WireGuard will refuse to send any more transport data
3058 * messages using the current secure session, ..." 3073 * messages using the current secure session, ..."
3059 */ 3074 */
3060 KASSERT(wgs->wgs_time_established != 0); 3075 KASSERT(wgs->wgs_time_established != 0);
3061 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) { 3076 if ((time_uptime - wgs->wgs_time_established) > wg_reject_after_time) {
3062 WG_DLOG("The session hits REJECT_AFTER_TIME\n"); 3077 WG_DLOG("The session hits REJECT_AFTER_TIME\n");
3063 return true; 3078 return true;
3064 } else if (wg_session_get_send_counter(wgs) > 3079 } else if (wg_session_get_send_counter(wgs) >
3065 wg_reject_after_messages) { 3080 wg_reject_after_messages) {
3066 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n"); 3081 WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n");
3067 return true; 3082 return true;
3068 } 3083 }
3069 3084
3070 return false; 3085 return false;
3071} 3086}
3072 3087
3073static void 3088static void
3074wg_peer_softint(void *arg) 3089wg_peer_softint(void *arg)
3075{ 3090{
3076 struct wg_peer *wgp = arg; 3091 struct wg_peer *wgp = arg;
3077 struct wg_session *wgs; 3092 struct wg_session *wgs;
3078 struct mbuf *m; 3093 struct mbuf *m;
3079 struct psref psref; 3094 struct psref psref;
3080 3095
3081 wgs = wg_get_stable_session(wgp, &psref); 3096 wgs = wg_get_stable_session(wgp, &psref);
3082 if (wgs->wgs_state != WGS_STATE_ESTABLISHED) { 3097 if (wgs->wgs_state != WGS_STATE_ESTABLISHED) {
3083 /* XXX how to treat? */ 3098 /* XXX how to treat? */
3084 WG_TRACE("skipped"); 3099 WG_TRACE("skipped");
3085 goto out; 3100 goto out;
3086 } 3101 }
3087 if (wg_session_hit_limits(wgs)) { 3102 if (wg_session_hit_limits(wgs)) {
3088 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3103 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3089 goto out; 3104 goto out;
3090 } 3105 }
3091 WG_TRACE("running"); 3106 WG_TRACE("running");
3092 3107
3093 while ((m = pcq_get(wgp->wgp_q)) != NULL) { 3108 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
3094 wg_send_data_msg(wgp, wgs, m); 3109 wg_send_data_msg(wgp, wgs, m);
3095 } 3110 }
3096out: 3111out:
3097 wg_put_session(wgs, &psref); 3112 wg_put_session(wgs, &psref);
3098} 3113}
3099 3114
3100static void 3115static void
3101wg_rekey_timer(void *arg) 3116wg_rekey_timer(void *arg)
3102{ 3117{
3103 struct wg_peer *wgp = arg; 3118 struct wg_peer *wgp = arg;
3104 3119
3105 mutex_enter(wgp->wgp_lock); 3120 mutex_enter(wgp->wgp_lock);
3106 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) { 3121 if (__predict_true(wgp->wgp_state != WGP_STATE_DESTROYING)) {
3107 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3122 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3108 } 3123 }
3109 mutex_exit(wgp->wgp_lock); 3124 mutex_exit(wgp->wgp_lock);
3110} 3125}
3111 3126
3112static void 3127static void
3113wg_purge_pending_packets(struct wg_peer *wgp) 3128wg_purge_pending_packets(struct wg_peer *wgp)
3114{ 3129{
3115 struct mbuf *m; 3130 struct mbuf *m;
3116 3131
3117 while ((m = pcq_get(wgp->wgp_q)) != NULL) { 3132 while ((m = pcq_get(wgp->wgp_q)) != NULL) {
3118 m_freem(m); 3133 m_freem(m);
3119 } 3134 }
3120} 3135}
3121 3136
3122static void 3137static void
3123wg_handshake_timeout_timer(void *arg) 3138wg_handshake_timeout_timer(void *arg)
3124{ 3139{
3125 struct wg_peer *wgp = arg; 3140 struct wg_peer *wgp = arg;
3126 struct wg_session *wgs; 3141 struct wg_session *wgs;
3127 struct psref psref; 3142 struct psref psref;
3128 3143
3129 WG_TRACE("enter"); 3144 WG_TRACE("enter");
3130 3145
3131 mutex_enter(wgp->wgp_lock); 3146 mutex_enter(wgp->wgp_lock);
3132 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) { 3147 if (__predict_false(wgp->wgp_state == WGP_STATE_DESTROYING)) {
3133 mutex_exit(wgp->wgp_lock); 3148 mutex_exit(wgp->wgp_lock);
3134 return; 3149 return;
3135 } 3150 }
3136 mutex_exit(wgp->wgp_lock); 3151 mutex_exit(wgp->wgp_lock);
3137 3152
3138 KASSERT(wgp->wgp_handshake_start_time != 0); 3153 KASSERT(wgp->wgp_handshake_start_time != 0);
3139 wgs = wg_get_unstable_session(wgp, &psref); 3154 wgs = wg_get_unstable_session(wgp, &psref);
3140 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE); 3155 KASSERT(wgs->wgs_state == WGS_STATE_INIT_ACTIVE);
3141 3156
3142 /* [W] 6.4 Handshake Initiation Retransmission */ 3157 /* [W] 6.4 Handshake Initiation Retransmission */
3143 if ((time_uptime - wgp->wgp_handshake_start_time) > 3158 if ((time_uptime - wgp->wgp_handshake_start_time) >
3144 wg_rekey_attempt_time) { 3159 wg_rekey_attempt_time) {
3145 /* Give up handshaking */ 3160 /* Give up handshaking */
3146 wgs->wgs_state = WGS_STATE_UNKNOWN; 3161 wgs->wgs_state = WGS_STATE_UNKNOWN;
3147 wg_clear_states(wgs); 3162 wg_clear_states(wgs);
3148 wgp->wgp_state = WGP_STATE_GIVEUP; 3163 wgp->wgp_state = WGP_STATE_GIVEUP;
3149 wgp->wgp_handshake_start_time = 0; 3164 wgp->wgp_handshake_start_time = 0;
3150 wg_put_session(wgs, &psref); 3165 wg_put_session(wgs, &psref);
3151 WG_TRACE("give up"); 3166 WG_TRACE("give up");
3152 /* 3167 /*
3153 * If a new data packet comes, handshaking will be retried 3168 * If a new data packet comes, handshaking will be retried
3154 * and a new session would be established at that time, 3169 * and a new session would be established at that time,
3155 * however we don't want to send pending packets then. 3170 * however we don't want to send pending packets then.
3156 */ 3171 */
3157 wg_purge_pending_packets(wgp); 3172 wg_purge_pending_packets(wgp);
3158 return; 3173 return;
3159 } 3174 }
3160 3175
3161 /* No response for an initiation message sent, retry handshaking */ 3176 /* No response for an initiation message sent, retry handshaking */
3162 wgs->wgs_state = WGS_STATE_UNKNOWN; 3177 wgs->wgs_state = WGS_STATE_UNKNOWN;
3163 wg_clear_states(wgs); 3178 wg_clear_states(wgs);
3164 wg_put_session(wgs, &psref); 3179 wg_put_session(wgs, &psref);
3165 3180
3166 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3181 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3167} 3182}
3168 3183
3169static struct wg_peer * 3184static struct wg_peer *
3170wg_alloc_peer(struct wg_softc *wg) 3185wg_alloc_peer(struct wg_softc *wg)
3171{ 3186{
3172 struct wg_peer *wgp; 3187 struct wg_peer *wgp;
3173 3188
3174 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP); 3189 wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP);
3175 3190
3176 wgp->wgp_sc = wg; 3191 wgp->wgp_sc = wg;
3177 wgp->wgp_state = WGP_STATE_INIT; 3192 wgp->wgp_state = WGP_STATE_INIT;
3178 wgp->wgp_q = pcq_create(1024, KM_SLEEP); 3193 wgp->wgp_q = pcq_create(1024, KM_SLEEP);
3179 wgp->wgp_si = softint_establish(SOFTINT_NET, wg_peer_softint, wgp); 3194 wgp->wgp_si = softint_establish(SOFTINT_NET, wg_peer_softint, wgp);
3180 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE); 3195 callout_init(&wgp->wgp_rekey_timer, CALLOUT_MPSAFE);
3181 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp); 3196 callout_setfunc(&wgp->wgp_rekey_timer, wg_rekey_timer, wgp);
3182 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE); 3197 callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE);
3183 callout_setfunc(&wgp->wgp_handshake_timeout_timer, 3198 callout_setfunc(&wgp->wgp_handshake_timeout_timer,
3184 wg_handshake_timeout_timer, wgp); 3199 wg_handshake_timeout_timer, wgp);
3185 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE); 3200 callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE);
3186 callout_setfunc(&wgp->wgp_session_dtor_timer, 3201 callout_setfunc(&wgp->wgp_session_dtor_timer,
3187 wg_session_dtor_timer, wgp); 3202 wg_session_dtor_timer, wgp);
3188 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry); 3203 PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry);
3189 wgp->wgp_endpoint_changing = false; 3204 wgp->wgp_endpoint_changing = false;
3190 wgp->wgp_endpoint_available = false; 3205 wgp->wgp_endpoint_available = false;
3191 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3206 wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3192 wgp->wgp_psz = pserialize_create(); 3207 wgp->wgp_psz = pserialize_create();
3193 psref_target_init(&wgp->wgp_psref, wg_psref_class); 3208 psref_target_init(&wgp->wgp_psref, wg_psref_class);
3194 3209
3195 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP); 3210 wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP);
3196 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP); 3211 wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP);
3197 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3212 psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3198 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3213 psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3199 3214
3200 struct wg_session *wgs; 3215 struct wg_session *wgs;
3201 wgp->wgp_session_stable = 3216 wgp->wgp_session_stable =
3202 kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP); 3217 kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP);
3203 wgp->wgp_session_unstable = 3218 wgp->wgp_session_unstable =
3204 kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP); 3219 kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP);
3205 wgs = wgp->wgp_session_stable; 3220 wgs = wgp->wgp_session_stable;
3206 wgs->wgs_peer = wgp; 3221 wgs->wgs_peer = wgp;
3207 wgs->wgs_state = WGS_STATE_UNKNOWN; 3222 wgs->wgs_state = WGS_STATE_UNKNOWN;
3208 psref_target_init(&wgs->wgs_psref, wg_psref_class); 3223 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3209 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3224 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3210#ifndef __HAVE_ATOMIC64_LOADSTORE 3225#ifndef __HAVE_ATOMIC64_LOADSTORE
3211 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3226 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3212#endif 3227#endif
3213 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3228 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3214 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE); 3229 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE);
3215 3230
3216 wgs = wgp->wgp_session_unstable; 3231 wgs = wgp->wgp_session_unstable;
3217 wgs->wgs_peer = wgp; 3232 wgs->wgs_peer = wgp;
3218 wgs->wgs_state = WGS_STATE_UNKNOWN; 3233 wgs->wgs_state = WGS_STATE_UNKNOWN;
3219 psref_target_init(&wgs->wgs_psref, wg_psref_class); 3234 psref_target_init(&wgs->wgs_psref, wg_psref_class);
3220 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3235 wgs->wgs_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3221#ifndef __HAVE_ATOMIC64_LOADSTORE 3236#ifndef __HAVE_ATOMIC64_LOADSTORE
3222 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3237 mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET);
3223#endif 3238#endif
3224 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3239 wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP);
3225 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE); 3240 mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_NONE);
3226 3241
3227 return wgp; 3242 return wgp;
3228} 3243}
3229 3244
3230static void 3245static void
3231wg_destroy_peer(struct wg_peer *wgp) 3246wg_destroy_peer(struct wg_peer *wgp)
3232{ 3247{
3233 struct wg_session *wgs; 3248 struct wg_session *wgs;
3234 struct wg_softc *wg = wgp->wgp_sc; 3249 struct wg_softc *wg = wgp->wgp_sc;
3235 3250
3236 rw_enter(wg->wg_rwlock, RW_WRITER); 3251 rw_enter(wg->wg_rwlock, RW_WRITER);
3237 for (int i = 0; i < wgp->wgp_n_allowedips; i++) { 3252 for (int i = 0; i < wgp->wgp_n_allowedips; i++) {
3238 struct wg_allowedip *wga = &wgp->wgp_allowedips[i]; 3253 struct wg_allowedip *wga = &wgp->wgp_allowedips[i];
3239 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family); 3254 struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family);
3240 struct radix_node *rn; 3255 struct radix_node *rn;
3241 3256
3242 KASSERT(rnh != NULL); 3257 KASSERT(rnh != NULL);
3243 rn = rnh->rnh_deladdr(&wga->wga_sa_addr, 3258 rn = rnh->rnh_deladdr(&wga->wga_sa_addr,
3244 &wga->wga_sa_mask, rnh); 3259 &wga->wga_sa_mask, rnh);
3245 if (rn == NULL) { 3260 if (rn == NULL) {
3246 char addrstr[128]; 3261 char addrstr[128];
3247 sockaddr_format(&wga->wga_sa_addr, addrstr, 3262 sockaddr_format(&wga->wga_sa_addr, addrstr,
3248 sizeof(addrstr)); 3263 sizeof(addrstr));
3249 WGLOG(LOG_WARNING, "Couldn't delete %s", addrstr); 3264 WGLOG(LOG_WARNING, "Couldn't delete %s", addrstr);
3250 } 3265 }
3251 } 3266 }
3252 rw_exit(wg->wg_rwlock); 3267 rw_exit(wg->wg_rwlock);
3253 3268
3254 softint_disestablish(wgp->wgp_si); 3269 softint_disestablish(wgp->wgp_si);
3255 callout_halt(&wgp->wgp_rekey_timer, NULL); 3270 callout_halt(&wgp->wgp_rekey_timer, NULL);
3256 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL); 3271 callout_halt(&wgp->wgp_handshake_timeout_timer, NULL);
3257 callout_halt(&wgp->wgp_session_dtor_timer, NULL); 3272 callout_halt(&wgp->wgp_session_dtor_timer, NULL);
3258 3273
3259 wgs = wgp->wgp_session_unstable; 3274 wgs = wgp->wgp_session_unstable;
3260 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 3275 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3261 mutex_obj_free(wgs->wgs_lock); 3276 mutex_obj_free(wgs->wgs_lock);
3262 mutex_destroy(&wgs->wgs_recvwin->lock); 3277 mutex_destroy(&wgs->wgs_recvwin->lock);
3263 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3278 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3264#ifndef __HAVE_ATOMIC64_LOADSTORE 3279#ifndef __HAVE_ATOMIC64_LOADSTORE
3265 mutex_destroy(&wgs->wgs_send_counter_lock); 3280 mutex_destroy(&wgs->wgs_send_counter_lock);
3266#endif 3281#endif
3267 kmem_free(wgs, sizeof(*wgs)); 3282 kmem_free(wgs, sizeof(*wgs));
3268 wgs = wgp->wgp_session_stable; 3283 wgs = wgp->wgp_session_stable;
3269 psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 3284 psref_target_destroy(&wgs->wgs_psref, wg_psref_class);
3270 mutex_obj_free(wgs->wgs_lock); 3285 mutex_obj_free(wgs->wgs_lock);
3271 mutex_destroy(&wgs->wgs_recvwin->lock); 3286 mutex_destroy(&wgs->wgs_recvwin->lock);
3272 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3287 kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin));
3273#ifndef __HAVE_ATOMIC64_LOADSTORE 3288#ifndef __HAVE_ATOMIC64_LOADSTORE
3274 mutex_destroy(&wgs->wgs_send_counter_lock); 3289 mutex_destroy(&wgs->wgs_send_counter_lock);
3275#endif 3290#endif
3276 kmem_free(wgs, sizeof(*wgs)); 3291 kmem_free(wgs, sizeof(*wgs));
3277 3292
3278 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3293 psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class);
3279 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3294 psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class);
3280 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint)); 3295 kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint));
3281 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0)); 3296 kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0));
3282 3297
3283 pserialize_destroy(wgp->wgp_psz); 3298 pserialize_destroy(wgp->wgp_psz);
3284 pcq_destroy(wgp->wgp_q); 3299 pcq_destroy(wgp->wgp_q);
3285 mutex_obj_free(wgp->wgp_lock); 3300 mutex_obj_free(wgp->wgp_lock);
3286 3301
3287 kmem_free(wgp, sizeof(*wgp)); 3302 kmem_free(wgp, sizeof(*wgp));
3288} 3303}
3289 3304
3290static void 3305static void
3291wg_destroy_all_peers(struct wg_softc *wg) 3306wg_destroy_all_peers(struct wg_softc *wg)
3292{ 3307{
3293 struct wg_peer *wgp; 3308 struct wg_peer *wgp;
3294 3309
3295restart: 3310restart:
3296 mutex_enter(wg->wg_lock); 3311 mutex_enter(wg->wg_lock);
3297 WG_PEER_WRITER_FOREACH(wgp, wg) { 3312 WG_PEER_WRITER_FOREACH(wgp, wg) {
3298 WG_PEER_WRITER_REMOVE(wgp); 3313 WG_PEER_WRITER_REMOVE(wgp);
3299 mutex_enter(wgp->wgp_lock); 3314 mutex_enter(wgp->wgp_lock);
3300 wgp->wgp_state = WGP_STATE_DESTROYING; 3315 wgp->wgp_state = WGP_STATE_DESTROYING;
3301 pserialize_perform(wgp->wgp_psz); 3316 pserialize_perform(wgp->wgp_psz);
3302 mutex_exit(wgp->wgp_lock); 3317 mutex_exit(wgp->wgp_lock);
3303 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 3318 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3304 break; 3319 break;
3305 } 3320 }
3306 mutex_exit(wg->wg_lock); 3321 mutex_exit(wg->wg_lock);
3307 3322
3308 if (wgp == NULL) 3323 if (wgp == NULL)
3309 return; 3324 return;
3310 3325
3311 psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 3326 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3312 3327
3313 wg_destroy_peer(wgp); 3328 wg_destroy_peer(wgp);
3314 3329
3315 goto restart; 3330 goto restart;
3316} 3331}
3317 3332
3318static int 3333static int
3319wg_destroy_peer_name(struct wg_softc *wg, const char *name) 3334wg_destroy_peer_name(struct wg_softc *wg, const char *name)
3320{ 3335{
3321 struct wg_peer *wgp; 3336 struct wg_peer *wgp;
3322 3337
3323 mutex_enter(wg->wg_lock); 3338 mutex_enter(wg->wg_lock);
3324 WG_PEER_WRITER_FOREACH(wgp, wg) { 3339 WG_PEER_WRITER_FOREACH(wgp, wg) {
3325 if (strcmp(wgp->wgp_name, name) == 0) 3340 if (strcmp(wgp->wgp_name, name) == 0)
3326 break; 3341 break;
3327 } 3342 }
3328 if (wgp != NULL) { 3343 if (wgp != NULL) {
3329 WG_PEER_WRITER_REMOVE(wgp); 3344 WG_PEER_WRITER_REMOVE(wgp);
3330 wg->wg_npeers--; 3345 wg->wg_npeers--;
3331 mutex_enter(wgp->wgp_lock); 3346 mutex_enter(wgp->wgp_lock);
3332 wgp->wgp_state = WGP_STATE_DESTROYING; 3347 wgp->wgp_state = WGP_STATE_DESTROYING;
3333 pserialize_perform(wgp->wgp_psz); 3348 pserialize_perform(wgp->wgp_psz);
3334 mutex_exit(wgp->wgp_lock); 3349 mutex_exit(wgp->wgp_lock);
3335 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 3350 PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry);
3336 } 3351 }
3337 mutex_exit(wg->wg_lock); 3352 mutex_exit(wg->wg_lock);
3338 3353
3339 if (wgp == NULL) 3354 if (wgp == NULL)
3340 return ENOENT; 3355 return ENOENT;
3341 3356
3342 psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 3357 psref_target_destroy(&wgp->wgp_psref, wg_psref_class);
3343 3358
3344 wg_destroy_peer(wgp); 3359 wg_destroy_peer(wgp);
3345 3360
3346 return 0; 3361 return 0;
3347} 3362}
3348 3363
3349static int 3364static int
3350wg_if_attach(struct wg_softc *wg) 3365wg_if_attach(struct wg_softc *wg)
3351{ 3366{
3352 int error; 3367 int error;
3353 3368
3354 wg->wg_if.if_addrlen = 0; 3369 wg->wg_if.if_addrlen = 0;
3355 wg->wg_if.if_mtu = WG_MTU; 3370 wg->wg_if.if_mtu = WG_MTU;
3356 wg->wg_if.if_flags = IFF_POINTOPOINT; 3371 wg->wg_if.if_flags = IFF_POINTOPOINT;
3357 wg->wg_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE; 3372 wg->wg_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE;
3358 wg->wg_if.if_extflags |= IFEF_MPSAFE; 3373 wg->wg_if.if_extflags |= IFEF_MPSAFE;
3359 wg->wg_if.if_ioctl = wg_ioctl; 3374 wg->wg_if.if_ioctl = wg_ioctl;
3360 wg->wg_if.if_output = wg_output; 3375 wg->wg_if.if_output = wg_output;
3361 wg->wg_if.if_init = wg_init; 3376 wg->wg_if.if_init = wg_init;
3362 wg->wg_if.if_stop = wg_stop; 3377 wg->wg_if.if_stop = wg_stop;
3363 wg->wg_if.if_type = IFT_OTHER; 3378 wg->wg_if.if_type = IFT_OTHER;
3364 wg->wg_if.if_dlt = DLT_NULL; 3379 wg->wg_if.if_dlt = DLT_NULL;
3365 wg->wg_if.if_softc = wg; 3380 wg->wg_if.if_softc = wg;
3366 IFQ_SET_READY(&wg->wg_if.if_snd); 3381 IFQ_SET_READY(&wg->wg_if.if_snd);
3367 3382
3368 error = if_initialize(&wg->wg_if); 3383 error = if_initialize(&wg->wg_if);
3369 if (error != 0) 3384 if (error != 0)
3370 return error; 3385 return error;
3371 3386
3372 if_alloc_sadl(&wg->wg_if); 3387 if_alloc_sadl(&wg->wg_if);
3373 if_register(&wg->wg_if); 3388 if_register(&wg->wg_if);
3374 3389
3375 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t)); 3390 bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t));
3376 3391
3377 return 0; 3392 return 0;
3378} 3393}
3379 3394
3380static int 3395static int
3381wg_clone_create(struct if_clone *ifc, int unit) 3396wg_clone_create(struct if_clone *ifc, int unit)
3382{ 3397{
3383 struct wg_softc *wg; 3398 struct wg_softc *wg;
3384 int error; 3399 int error;
3385 3400
3386 wg = kmem_zalloc(sizeof(struct wg_softc), KM_SLEEP); 3401 wg = kmem_zalloc(sizeof(struct wg_softc), KM_SLEEP);
3387 3402
3388 if_initname(&wg->wg_if, ifc->ifc_name, unit); 3403 if_initname(&wg->wg_if, ifc->ifc_name, unit);
3389 3404
3390 error = wg_worker_init(wg); 3405 error = wg_worker_init(wg);
3391 if (error != 0) { 3406 if (error != 0) {
3392 kmem_free(wg, sizeof(struct wg_softc)); 3407 kmem_free(wg, sizeof(struct wg_softc));
3393 return error; 3408 return error;
3394 } 3409 }
3395 3410
3396 rn_inithead((void **)&wg->wg_rtable_ipv4, 3411 rn_inithead((void **)&wg->wg_rtable_ipv4,
3397 offsetof(struct sockaddr_in, sin_addr) * NBBY); 3412 offsetof(struct sockaddr_in, sin_addr) * NBBY);
3398#ifdef INET6 3413#ifdef INET6
3399 rn_inithead((void **)&wg->wg_rtable_ipv6, 3414 rn_inithead((void **)&wg->wg_rtable_ipv6,
3400 offsetof(struct sockaddr_in6, sin6_addr) * NBBY); 3415 offsetof(struct sockaddr_in6, sin6_addr) * NBBY);
3401#endif 3416#endif
3402 3417
3403 PSLIST_INIT(&wg->wg_peers); 3418 PSLIST_INIT(&wg->wg_peers);
3404 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3419 wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
3405 wg->wg_rwlock = rw_obj_alloc(); 3420 wg->wg_rwlock = rw_obj_alloc();
3406 wg->wg_ops = &wg_ops_rumpkernel; 3421 wg->wg_ops = &wg_ops_rumpkernel;
3407 3422
3408 error = wg_if_attach(wg); 3423 error = wg_if_attach(wg);
3409 if (error != 0) { 3424 if (error != 0) {
3410 wg_worker_destroy(wg); 3425 wg_worker_destroy(wg);
3411 if (wg->wg_rtable_ipv4 != NULL) 3426 if (wg->wg_rtable_ipv4 != NULL)
3412 free(wg->wg_rtable_ipv4, M_RTABLE); 3427 free(wg->wg_rtable_ipv4, M_RTABLE);
3413 if (wg->wg_rtable_ipv6 != NULL) 3428 if (wg->wg_rtable_ipv6 != NULL)
3414 free(wg->wg_rtable_ipv6, M_RTABLE); 3429 free(wg->wg_rtable_ipv6, M_RTABLE);
3415 PSLIST_DESTROY(&wg->wg_peers); 3430 PSLIST_DESTROY(&wg->wg_peers);
3416 mutex_obj_free(wg->wg_lock); 3431 mutex_obj_free(wg->wg_lock);
3417 kmem_free(wg, sizeof(struct wg_softc)); 3432 kmem_free(wg, sizeof(struct wg_softc));
3418 return error; 3433 return error;
3419 } 3434 }
3420 3435
3421 mutex_enter(&wg_softcs.lock); 3436 mutex_enter(&wg_softcs.lock);
3422 LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list); 3437 LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list);
3423 mutex_exit(&wg_softcs.lock); 3438 mutex_exit(&wg_softcs.lock);
3424 3439
3425 return 0; 3440 return 0;
3426} 3441}
3427 3442
3428static int 3443static int
3429wg_clone_destroy(struct ifnet *ifp) 3444wg_clone_destroy(struct ifnet *ifp)
3430{ 3445{
3431 struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if); 3446 struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if);
3432 3447
3433 mutex_enter(&wg_softcs.lock); 3448 mutex_enter(&wg_softcs.lock);
3434 LIST_REMOVE(wg, wg_list); 3449 LIST_REMOVE(wg, wg_list);
3435 mutex_exit(&wg_softcs.lock); 3450 mutex_exit(&wg_softcs.lock);
3436 3451
3437#ifdef WG_RUMPKERNEL 3452#ifdef WG_RUMPKERNEL
3438 if (wg_user_mode(wg)) { 3453 if (wg_user_mode(wg)) {
3439 rumpuser_wg_destroy(wg->wg_user); 3454 rumpuser_wg_destroy(wg->wg_user);
3440 wg->wg_user = NULL; 3455 wg->wg_user = NULL;
3441 } 3456 }
3442#endif 3457#endif
3443 3458
3444 bpf_detach(ifp); 3459 bpf_detach(ifp);
3445 if_detach(ifp); 3460 if_detach(ifp);
3446 wg_worker_destroy(wg); 3461 wg_worker_destroy(wg);
3447 wg_destroy_all_peers(wg); 3462 wg_destroy_all_peers(wg);
3448 if (wg->wg_rtable_ipv4 != NULL) 3463 if (wg->wg_rtable_ipv4 != NULL)
3449 free(wg->wg_rtable_ipv4, M_RTABLE); 3464 free(wg->wg_rtable_ipv4, M_RTABLE);
3450 if (wg->wg_rtable_ipv6 != NULL) 3465 if (wg->wg_rtable_ipv6 != NULL)
3451 free(wg->wg_rtable_ipv6, M_RTABLE); 3466 free(wg->wg_rtable_ipv6, M_RTABLE);
3452 3467
3453 PSLIST_DESTROY(&wg->wg_peers); 3468 PSLIST_DESTROY(&wg->wg_peers);
3454 mutex_obj_free(wg->wg_lock); 3469 mutex_obj_free(wg->wg_lock);
3455 rw_obj_free(wg->wg_rwlock); 3470 rw_obj_free(wg->wg_rwlock);
3456 3471
3457 kmem_free(wg, sizeof(struct wg_softc)); 3472 kmem_free(wg, sizeof(struct wg_softc));
3458 3473
3459 return 0; 3474 return 0;
3460} 3475}
3461 3476
3462static struct wg_peer * 3477static struct wg_peer *
3463wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa, 3478wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa,
3464 struct psref *psref) 3479 struct psref *psref)
3465{ 3480{
3466 struct radix_node_head *rnh; 3481 struct radix_node_head *rnh;
3467 struct radix_node *rn; 3482 struct radix_node *rn;
3468 struct wg_peer *wgp = NULL; 3483 struct wg_peer *wgp = NULL;
3469 struct wg_allowedip *wga; 3484 struct wg_allowedip *wga;
3470 3485
3471#ifdef WG_DEBUG_LOG 3486#ifdef WG_DEBUG_LOG
3472 char addrstr[128]; 3487 char addrstr[128];
3473 sockaddr_format(sa, addrstr, sizeof(addrstr)); 3488 sockaddr_format(sa, addrstr, sizeof(addrstr));
3474 WG_DLOG("sa=%s\n", addrstr); 3489 WG_DLOG("sa=%s\n", addrstr);
3475#endif 3490#endif
3476 3491
3477 rw_enter(wg->wg_rwlock, RW_READER); 3492 rw_enter(wg->wg_rwlock, RW_READER);
3478 3493
3479 rnh = wg_rnh(wg, sa->sa_family); 3494 rnh = wg_rnh(wg, sa->sa_family);
3480 if (rnh == NULL) 3495 if (rnh == NULL)
3481 goto out; 3496 goto out;
3482 3497
3483 rn = rnh->rnh_matchaddr(sa, rnh); 3498 rn = rnh->rnh_matchaddr(sa, rnh);
3484 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) 3499 if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
3485 goto out; 3500 goto out;
3486 3501
3487 WG_TRACE("success"); 3502 WG_TRACE("success");
3488 3503
3489 wga = container_of(rn, struct wg_allowedip, wga_nodes[0]); 3504 wga = container_of(rn, struct wg_allowedip, wga_nodes[0]);
3490 wgp = wga->wga_peer; 3505 wgp = wga->wga_peer;
3491 wg_get_peer(wgp, psref); 3506 wg_get_peer(wgp, psref);
3492 3507
3493out: 3508out:
3494 rw_exit(wg->wg_rwlock); 3509 rw_exit(wg->wg_rwlock);
3495 return wgp; 3510 return wgp;
3496} 3511}
3497 3512
3498static void 3513static void
3499wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp, 3514wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp,
3500 struct wg_session *wgs, struct wg_msg_data *wgmd) 3515 struct wg_session *wgs, struct wg_msg_data *wgmd)
3501{ 3516{
3502 3517
3503 memset(wgmd, 0, sizeof(*wgmd)); 3518 memset(wgmd, 0, sizeof(*wgmd));
3504 wgmd->wgmd_type = WG_MSG_TYPE_DATA; 3519 wgmd->wgmd_type = WG_MSG_TYPE_DATA;
3505 wgmd->wgmd_receiver = wgs->wgs_receiver_index; 3520 wgmd->wgmd_receiver = wgs->wgs_receiver_index;
3506 /* [W] 5.4.6: msg.counter := Nm^send */ 3521 /* [W] 5.4.6: msg.counter := Nm^send */
3507 /* [W] 5.4.6: Nm^send := Nm^send + 1 */ 3522 /* [W] 5.4.6: Nm^send := Nm^send + 1 */
3508 wgmd->wgmd_counter = wg_session_inc_send_counter(wgs); 3523 wgmd->wgmd_counter = wg_session_inc_send_counter(wgs);
3509 WG_DLOG("counter=%"PRIu64"\n", wgmd->wgmd_counter); 3524 WG_DLOG("counter=%"PRIu64"\n", wgmd->wgmd_counter);
3510} 3525}
3511 3526
3512static int 3527static int
3513wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 3528wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
3514 const struct rtentry *rt) 3529 const struct rtentry *rt)
3515{ 3530{
3516 struct wg_softc *wg = ifp->if_softc; 3531 struct wg_softc *wg = ifp->if_softc;
3517 int error = 0; 3532 int error = 0;
3518 int bound; 3533 int bound;
3519 struct psref psref; 3534 struct psref psref;
3520 3535
3521 /* TODO make the nest limit configurable via sysctl */ 3536 /* TODO make the nest limit configurable via sysctl */
3522 error = if_tunnel_check_nesting(ifp, m, 1); 3537 error = if_tunnel_check_nesting(ifp, m, 1);
3523 if (error != 0) { 3538 if (error != 0) {
3524 m_freem(m); 3539 m_freem(m);
3525 WGLOG(LOG_ERR, "tunneling loop detected and packet dropped\n"); 3540 WGLOG(LOG_ERR, "tunneling loop detected and packet dropped\n");
3526 return error; 3541 return error;
3527 } 3542 }
3528 3543
3529 bound = curlwp_bind(); 3544 bound = curlwp_bind();
3530 3545
3531 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 3546 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
3532 3547
3533 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT); 3548 bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT);
3534 3549
3535 m->m_flags &= ~(M_BCAST|M_MCAST); 3550 m->m_flags &= ~(M_BCAST|M_MCAST);
3536 3551
3537 struct wg_peer *wgp = wg_pick_peer_by_sa(wg, dst, &psref); 3552 struct wg_peer *wgp = wg_pick_peer_by_sa(wg, dst, &psref);
3538 if (wgp == NULL) { 3553 if (wgp == NULL) {
3539 WG_TRACE("peer not found"); 3554 WG_TRACE("peer not found");
3540 error = EHOSTUNREACH; 3555 error = EHOSTUNREACH;
3541 goto error; 3556 goto error;
3542 } 3557 }
3543 3558
3544 /* Clear checksum-offload flags. */ 3559 /* Clear checksum-offload flags. */
3545 m->m_pkthdr.csum_flags = 0; 3560 m->m_pkthdr.csum_flags = 0;
3546 m->m_pkthdr.csum_data = 0; 3561 m->m_pkthdr.csum_data = 0;
3547 3562
3548 if (!pcq_put(wgp->wgp_q, m)) { 3563 if (!pcq_put(wgp->wgp_q, m)) {
3549 error = ENOBUFS; 3564 error = ENOBUFS;
3550 goto error; 3565 goto error;
3551 } 3566 }
3552 3567
3553 struct psref psref_wgs; 3568 struct psref psref_wgs;
3554 struct wg_session *wgs; 3569 struct wg_session *wgs;
3555 wgs = wg_get_stable_session(wgp, &psref_wgs); 3570 wgs = wg_get_stable_session(wgp, &psref_wgs);
3556 if (wgs->wgs_state == WGS_STATE_ESTABLISHED && 3571 if (wgs->wgs_state == WGS_STATE_ESTABLISHED &&
3557 !wg_session_hit_limits(wgs)) { 3572 !wg_session_hit_limits(wgs)) {
3558 kpreempt_disable(); 3573 kpreempt_disable();
3559 softint_schedule(wgp->wgp_si); 3574 softint_schedule(wgp->wgp_si);
3560 kpreempt_enable(); 3575 kpreempt_enable();
3561 WG_TRACE("softint scheduled"); 3576 WG_TRACE("softint scheduled");
3562 } else { 3577 } else {
3563 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3578 wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE);
3564 WG_TRACE("softint NOT scheduled"); 3579 WG_TRACE("softint NOT scheduled");
3565 } 3580 }
3566 wg_put_session(wgs, &psref_wgs); 3581 wg_put_session(wgs, &psref_wgs);
3567 wg_put_peer(wgp, &psref); 3582 wg_put_peer(wgp, &psref);
3568 3583
3569 return 0; 3584 return 0;
3570 3585
3571error: 3586error:
3572 if (wgp != NULL) 3587 if (wgp != NULL)
3573 wg_put_peer(wgp, &psref); 3588 wg_put_peer(wgp, &psref);
3574 if (m != NULL) 3589 if (m != NULL)
3575 m_freem(m); 3590 m_freem(m);
3576 curlwp_bindx(bound); 3591 curlwp_bindx(bound);
3577 return error; 3592 return error;
3578} 3593}
3579 3594
3580static int 3595static int
3581wg_send_udp(struct wg_peer *wgp, struct mbuf *m) 3596wg_send_udp(struct wg_peer *wgp, struct mbuf *m)
3582{ 3597{
3583 struct psref psref; 3598 struct psref psref;
3584 struct wg_sockaddr *wgsa; 3599 struct wg_sockaddr *wgsa;
3585 int error; 3600 int error;
3586 struct socket *so = wg_get_so_by_peer(wgp); 3601 struct socket *so = wg_get_so_by_peer(wgp);
3587 3602
3588 solock(so); 3603 solock(so);
3589 wgsa = wg_get_endpoint_sa(wgp, &psref); 3604 wgsa = wg_get_endpoint_sa(wgp, &psref);
3590 if (wgsatosa(wgsa)->sa_family == AF_INET) { 3605 if (wgsatosa(wgsa)->sa_family == AF_INET) {
3591 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp); 3606 error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp);
3592 } else { 3607 } else {
3593#ifdef INET6 3608#ifdef INET6
3594 error = udp6_output(sotoin6pcb(so), m, wgsatosin6(wgsa), 3609 error = udp6_output(sotoin6pcb(so), m, wgsatosin6(wgsa),
3595 NULL, curlwp); 3610 NULL, curlwp);
3596#else 3611#else
3597 error = EPROTONOSUPPORT; 3612 error = EPROTONOSUPPORT;
3598#endif 3613#endif
3599 } 3614 }
3600 wg_put_sa(wgp, wgsa, &psref); 3615 wg_put_sa(wgp, wgsa, &psref);
3601 sounlock(so); 3616 sounlock(so);
3602 3617
3603 return error; 3618 return error;
3604} 3619}
3605 3620
3606/* Inspired by pppoe_get_mbuf */ 3621/* Inspired by pppoe_get_mbuf */
3607static struct mbuf * 3622static struct mbuf *
3608wg_get_mbuf(size_t leading_len, size_t len) 3623wg_get_mbuf(size_t leading_len, size_t len)
3609{ 3624{
3610 struct mbuf *m; 3625 struct mbuf *m;
3611 3626
3612 m = m_gethdr(M_DONTWAIT, MT_DATA); 3627 m = m_gethdr(M_DONTWAIT, MT_DATA);
3613 if (m == NULL) 3628 if (m == NULL)
3614 return NULL; 3629 return NULL;
3615 if (len + leading_len > MHLEN) { 3630 if (len + leading_len > MHLEN) {
3616 m_clget(m, M_DONTWAIT); 3631 m_clget(m, M_DONTWAIT);
3617 if ((m->m_flags & M_EXT) == 0) { 3632 if ((m->m_flags & M_EXT) == 0) {
3618 m_free(m); 3633 m_free(m);
3619 return NULL; 3634 return NULL;
3620 } 3635 }
3621 } 3636 }
3622 m->m_data += leading_len; 3637 m->m_data += leading_len;
3623 m->m_pkthdr.len = m->m_len = len; 3638 m->m_pkthdr.len = m->m_len = len;
3624 3639
3625 return m; 3640 return m;
3626} 3641}
3627 3642
3628static int 3643static int
3629wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs, 3644wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs,
3630 struct mbuf *m) 3645 struct mbuf *m)
3631{ 3646{
3632 struct wg_softc *wg = wgp->wgp_sc; 3647 struct wg_softc *wg = wgp->wgp_sc;
3633 int error; 3648 int error;
3634 size_t inner_len, padded_len, encrypted_len; 3649 size_t inner_len, padded_len, encrypted_len;
3635 char *padded_buf = NULL; 3650 char *padded_buf = NULL;
3636 size_t mlen; 3651 size_t mlen;
3637 struct wg_msg_data *wgmd; 3652 struct wg_msg_data *wgmd;
3638 bool free_padded_buf = false; 3653 bool free_padded_buf = false;
3639 struct mbuf *n; 3654 struct mbuf *n;
3640 size_t leading_len = max_linkhdr + sizeof(struct ip6_hdr) + 3655 size_t leading_len = max_linkhdr + sizeof(struct ip6_hdr) +
3641 sizeof(struct udphdr); 3656 sizeof(struct udphdr);