Mon Aug 31 20:33:58 2020 UTC ()
wg: Simplify locking.

Summary: Access to a stable established session is still allowed via
psref; all other access to peer and session state is now serialized
by struct wg_peer::wgp_lock, with no dancing around a per-session
lock.  This way, the handshake paths are locked, while the data
transmission paths are pserialized.

- Eliminate struct wg_session::wgs_lock.

- Eliminate wg_get_unstable_session -- access to the unstable session
  is allowed only with struct wgp_peer::wgp_lock held.

- Push INIT_PASSIVE->ESTABLISHED transition down into a thread task.

- Push rekey down into a thread task.

- Allocate session indices only on transition from UNKNOWN and free
  them only on transition back to UNKNOWN.

- Be a little more explicit about allowed state transitions, and
  reject some nonsensical ones.

- Sprinkle assertions and comments.

- Reduce atomic r/m/w swap operations that can just as well be
  store-release.


(riastradh)
diff -r1.48 -r1.49 src/sys/net/if_wg.c

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

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