1 1.135 riastrad /* $NetBSD: if_wg.c,v 1.135 2024/12/27 16:42:28 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright (C) Ryota Ozaki <ozaki.ryota (at) gmail.com> 5 1.1 riastrad * All rights reserved. 6 1.1 riastrad * 7 1.1 riastrad * Redistribution and use in source and binary forms, with or without 8 1.1 riastrad * modification, are permitted provided that the following conditions 9 1.1 riastrad * are met: 10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright 11 1.1 riastrad * notice, this list of conditions and the following disclaimer. 12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the 14 1.1 riastrad * documentation and/or other materials provided with the distribution. 15 1.1 riastrad * 3. Neither the name of the project nor the names of its contributors 16 1.1 riastrad * may be used to endorse or promote products derived from this software 17 1.1 riastrad * without specific prior written permission. 18 1.1 riastrad * 19 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 1.1 riastrad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 riastrad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 riastrad * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 1.1 riastrad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 riastrad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 riastrad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 riastrad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 riastrad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 riastrad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 riastrad * SUCH DAMAGE. 30 1.1 riastrad */ 31 1.1 riastrad 32 1.1 riastrad /* 33 1.24 riastrad * This network interface aims to implement the WireGuard protocol. 34 1.24 riastrad * The implementation is based on the paper of WireGuard as of 35 1.24 riastrad * 2018-06-30 [1]. The paper is referred in the source code with label 36 1.24 riastrad * [W]. Also the specification of the Noise protocol framework as of 37 1.24 riastrad * 2018-07-11 [2] is referred with label [N]. 38 1.1 riastrad * 39 1.1 riastrad * [1] https://www.wireguard.com/papers/wireguard.pdf 40 1.131 riastrad * https://web.archive.org/web/20180805103233/https://www.wireguard.com/papers/wireguard.pdf 41 1.1 riastrad * [2] http://noiseprotocol.org/noise.pdf 42 1.131 riastrad * https://web.archive.org/web/20180727193154/https://noiseprotocol.org/noise.pdf 43 1.1 riastrad */ 44 1.1 riastrad 45 1.1 riastrad #include <sys/cdefs.h> 46 1.135 riastrad __KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.135 2024/12/27 16:42:28 riastradh Exp $"); 47 1.1 riastrad 48 1.1 riastrad #ifdef _KERNEL_OPT 49 1.60 riastrad #include "opt_altq_enabled.h" 50 1.1 riastrad #include "opt_inet.h" 51 1.1 riastrad #endif 52 1.1 riastrad 53 1.1 riastrad #include <sys/param.h> 54 1.32 riastrad #include <sys/types.h> 55 1.32 riastrad 56 1.32 riastrad #include <sys/atomic.h> 57 1.32 riastrad #include <sys/callout.h> 58 1.32 riastrad #include <sys/cprng.h> 59 1.32 riastrad #include <sys/cpu.h> 60 1.32 riastrad #include <sys/device.h> 61 1.32 riastrad #include <sys/domain.h> 62 1.1 riastrad #include <sys/errno.h> 63 1.32 riastrad #include <sys/intr.h> 64 1.1 riastrad #include <sys/ioctl.h> 65 1.32 riastrad #include <sys/kernel.h> 66 1.1 riastrad #include <sys/kmem.h> 67 1.32 riastrad #include <sys/mbuf.h> 68 1.1 riastrad #include <sys/module.h> 69 1.1 riastrad #include <sys/mutex.h> 70 1.58 riastrad #include <sys/once.h> 71 1.32 riastrad #include <sys/percpu.h> 72 1.1 riastrad #include <sys/pserialize.h> 73 1.1 riastrad #include <sys/psref.h> 74 1.32 riastrad #include <sys/queue.h> 75 1.32 riastrad #include <sys/rwlock.h> 76 1.32 riastrad #include <sys/socket.h> 77 1.32 riastrad #include <sys/socketvar.h> 78 1.32 riastrad #include <sys/sockio.h> 79 1.1 riastrad #include <sys/sysctl.h> 80 1.32 riastrad #include <sys/syslog.h> 81 1.32 riastrad #include <sys/systm.h> 82 1.37 riastrad #include <sys/thmap.h> 83 1.55 riastrad #include <sys/threadpool.h> 84 1.32 riastrad #include <sys/time.h> 85 1.32 riastrad #include <sys/timespec.h> 86 1.55 riastrad #include <sys/workqueue.h> 87 1.1 riastrad 88 1.86 christos #include <lib/libkern/libkern.h> 89 1.86 christos 90 1.1 riastrad #include <net/bpf.h> 91 1.1 riastrad #include <net/if.h> 92 1.1 riastrad #include <net/if_types.h> 93 1.32 riastrad #include <net/if_wg.h> 94 1.54 riastrad #include <net/pktqueue.h> 95 1.1 riastrad #include <net/route.h> 96 1.1 riastrad 97 1.109 riastrad #ifdef INET 98 1.1 riastrad #include <netinet/in.h> 99 1.32 riastrad #include <netinet/in_pcb.h> 100 1.32 riastrad #include <netinet/in_var.h> 101 1.1 riastrad #include <netinet/ip.h> 102 1.1 riastrad #include <netinet/ip_var.h> 103 1.1 riastrad #include <netinet/udp.h> 104 1.1 riastrad #include <netinet/udp_var.h> 105 1.109 riastrad #endif /* INET */ 106 1.1 riastrad 107 1.1 riastrad #ifdef INET6 108 1.32 riastrad #include <netinet/ip6.h> 109 1.32 riastrad #include <netinet6/in6_pcb.h> 110 1.1 riastrad #include <netinet6/in6_var.h> 111 1.1 riastrad #include <netinet6/ip6_var.h> 112 1.1 riastrad #include <netinet6/udp6_var.h> 113 1.109 riastrad #endif /* INET6 */ 114 1.1 riastrad 115 1.1 riastrad #include <prop/proplib.h> 116 1.1 riastrad 117 1.1 riastrad #include <crypto/blake2/blake2s.h> 118 1.1 riastrad #include <crypto/sodium/crypto_aead_chacha20poly1305.h> 119 1.1 riastrad #include <crypto/sodium/crypto_aead_xchacha20poly1305.h> 120 1.32 riastrad #include <crypto/sodium/crypto_scalarmult.h> 121 1.1 riastrad 122 1.1 riastrad #include "ioconf.h" 123 1.1 riastrad 124 1.1 riastrad #ifdef WG_RUMPKERNEL 125 1.1 riastrad #include "wg_user.h" 126 1.1 riastrad #endif 127 1.1 riastrad 128 1.105 riastrad #ifndef time_uptime32 129 1.105 riastrad #define time_uptime32 ((uint32_t)time_uptime) 130 1.105 riastrad #endif 131 1.105 riastrad 132 1.1 riastrad /* 133 1.1 riastrad * Data structures 134 1.1 riastrad * - struct wg_softc is an instance of wg interfaces 135 1.1 riastrad * - It has a list of peers (struct wg_peer) 136 1.55 riastrad * - It has a threadpool job that sends/receives handshake messages and 137 1.1 riastrad * runs event handlers 138 1.1 riastrad * - It has its own two routing tables: one is for IPv4 and the other IPv6 139 1.1 riastrad * - struct wg_peer is a representative of a peer 140 1.55 riastrad * - It has a struct work to handle handshakes and timer tasks 141 1.1 riastrad * - It has a pair of session instances (struct wg_session) 142 1.1 riastrad * - It has a pair of endpoint instances (struct wg_sockaddr) 143 1.1 riastrad * - Normally one endpoint is used and the second one is used only on 144 1.1 riastrad * a peer migration (a change of peer's IP address) 145 1.1 riastrad * - It has a list of IP addresses and sub networks called allowedips 146 1.1 riastrad * (struct wg_allowedip) 147 1.1 riastrad * - A packets sent over a session is allowed if its destination matches 148 1.1 riastrad * any IP addresses or sub networks of the list 149 1.1 riastrad * - struct wg_session represents a session of a secure tunnel with a peer 150 1.1 riastrad * - Two instances of sessions belong to a peer; a stable session and a 151 1.1 riastrad * unstable session 152 1.49 riastrad * - A handshake process of a session always starts with a unstable instance 153 1.1 riastrad * - Once a session is established, its instance becomes stable and the 154 1.1 riastrad * other becomes unstable instead 155 1.1 riastrad * - Data messages are always sent via a stable session 156 1.1 riastrad * 157 1.1 riastrad * Locking notes: 158 1.49 riastrad * - Each wg has a mutex(9) wg_lock, and a rwlock(9) wg_rwlock 159 1.49 riastrad * - Changes to the peer list are serialized by wg_lock 160 1.49 riastrad * - The peer list may be read with pserialize(9) and psref(9) 161 1.1 riastrad * - The rwlock (wg_rwlock) protects the routing tables (wg_rtable_ipv[46]) 162 1.49 riastrad * => XXX replace by pserialize when routing table is psz-safe 163 1.49 riastrad * - Each peer (struct wg_peer, wgp) has a mutex wgp_lock, which can be taken 164 1.49 riastrad * only in thread context and serializes: 165 1.49 riastrad * - the stable and unstable session pointers 166 1.49 riastrad * - all unstable session state 167 1.49 riastrad * - Packet processing may be done in softint context: 168 1.49 riastrad * - The stable session can be read under pserialize(9) or psref(9) 169 1.49 riastrad * - The stable session is always ESTABLISHED 170 1.14 riastrad * - On a session swap, we must wait for all readers to release a 171 1.14 riastrad * reference to a stable session before changing wgs_state and 172 1.14 riastrad * session states 173 1.49 riastrad * - Lock order: wg_lock -> wgp_lock 174 1.1 riastrad */ 175 1.1 riastrad 176 1.1 riastrad 177 1.14 riastrad #define WGLOG(level, fmt, args...) \ 178 1.14 riastrad log(level, "%s: " fmt, __func__, ##args) 179 1.1 riastrad 180 1.85 christos #define WG_DEBUG 181 1.80 christos 182 1.1 riastrad /* Debug options */ 183 1.1 riastrad #ifdef WG_DEBUG 184 1.1 riastrad /* Output debug logs */ 185 1.1 riastrad #ifndef WG_DEBUG_LOG 186 1.1 riastrad #define WG_DEBUG_LOG 187 1.1 riastrad #endif 188 1.1 riastrad /* Output trace logs */ 189 1.1 riastrad #ifndef WG_DEBUG_TRACE 190 1.1 riastrad #define WG_DEBUG_TRACE 191 1.1 riastrad #endif 192 1.1 riastrad /* Output hash values, etc. */ 193 1.1 riastrad #ifndef WG_DEBUG_DUMP 194 1.1 riastrad #define WG_DEBUG_DUMP 195 1.1 riastrad #endif 196 1.1 riastrad /* Make some internal parameters configurable for testing and debugging */ 197 1.1 riastrad #ifndef WG_DEBUG_PARAMS 198 1.1 riastrad #define WG_DEBUG_PARAMS 199 1.1 riastrad #endif 200 1.83 kre #endif /* WG_DEBUG */ 201 1.83 kre 202 1.83 kre #ifndef WG_DEBUG 203 1.83 kre # if defined(WG_DEBUG_LOG) || defined(WG_DEBUG_TRACE) || \ 204 1.111 riastrad defined(WG_DEBUG_DUMP) || defined(WG_DEBUG_PARAMS) 205 1.83 kre # define WG_DEBUG 206 1.83 kre # endif 207 1.83 kre #endif 208 1.83 kre 209 1.83 kre #ifdef WG_DEBUG 210 1.80 christos int wg_debug; 211 1.80 christos #define WG_DEBUG_FLAGS_LOG 1 212 1.80 christos #define WG_DEBUG_FLAGS_TRACE 2 213 1.80 christos #define WG_DEBUG_FLAGS_DUMP 4 214 1.1 riastrad #endif 215 1.1 riastrad 216 1.1 riastrad #ifdef WG_DEBUG_TRACE 217 1.80 christos #define WG_TRACE(msg) do { \ 218 1.80 christos if (wg_debug & WG_DEBUG_FLAGS_TRACE) \ 219 1.80 christos log(LOG_DEBUG, "%s:%d: %s\n", __func__, __LINE__, (msg)); \ 220 1.80 christos } while (0) 221 1.1 riastrad #else 222 1.1 riastrad #define WG_TRACE(msg) __nothing 223 1.1 riastrad #endif 224 1.1 riastrad 225 1.1 riastrad #ifdef WG_DEBUG_LOG 226 1.80 christos #define WG_DLOG(fmt, args...) do { \ 227 1.80 christos if (wg_debug & WG_DEBUG_FLAGS_LOG) \ 228 1.80 christos log(LOG_DEBUG, "%s: " fmt, __func__, ##args); \ 229 1.80 christos } while (0) 230 1.1 riastrad #else 231 1.1 riastrad #define WG_DLOG(fmt, args...) __nothing 232 1.1 riastrad #endif 233 1.1 riastrad 234 1.1 riastrad #define WG_LOG_RATECHECK(wgprc, level, fmt, args...) do { \ 235 1.81 christos if (ppsratecheck(&(wgprc)->wgprc_lasttime, \ 236 1.1 riastrad &(wgprc)->wgprc_curpps, 1)) { \ 237 1.1 riastrad log(level, fmt, ##args); \ 238 1.1 riastrad } \ 239 1.1 riastrad } while (0) 240 1.1 riastrad 241 1.1 riastrad #ifdef WG_DEBUG_PARAMS 242 1.1 riastrad static bool wg_force_underload = false; 243 1.1 riastrad #endif 244 1.1 riastrad 245 1.1 riastrad #ifdef WG_DEBUG_DUMP 246 1.7 riastrad 247 1.89 kre static char enomem[10] = "[enomem]"; 248 1.89 kre 249 1.93 christos #define MAX_HDUMP_LEN 10000 /* large enough */ 250 1.93 christos 251 1.112 riastrad /* 252 1.112 riastrad * gethexdump(p, n) 253 1.112 riastrad * 254 1.112 riastrad * Allocate a string returning a hexdump of bytes p[0..n), 255 1.112 riastrad * truncated to MAX_HDUMP_LEN. Must be freed with puthexdump. 256 1.112 riastrad * 257 1.112 riastrad * We use this instead of libkern hexdump() because the result is 258 1.112 riastrad * logged with log(LOG_DEBUG, ...), which puts a priority tag on 259 1.112 riastrad * every message, so it can't be done incrementally. 260 1.112 riastrad */ 261 1.53 riastrad static char * 262 1.84 christos gethexdump(const void *vp, size_t n) 263 1.53 riastrad { 264 1.53 riastrad char *buf; 265 1.84 christos const uint8_t *p = vp; 266 1.93 christos size_t i, alloc; 267 1.53 riastrad 268 1.93 christos alloc = n; 269 1.93 christos if (n > MAX_HDUMP_LEN) 270 1.93 christos alloc = MAX_HDUMP_LEN; 271 1.112 riastrad buf = kmem_alloc(3*alloc + 5, KM_NOSLEEP); 272 1.53 riastrad if (buf == NULL) 273 1.89 kre return enomem; 274 1.93 christos for (i = 0; i < alloc; i++) 275 1.112 riastrad snprintf(buf + 3*i, 3 + 1, " %02hhx", p[i]); 276 1.93 christos if (alloc != n) 277 1.112 riastrad snprintf(buf + 3*i, 4 + 1, " ..."); 278 1.53 riastrad return buf; 279 1.53 riastrad } 280 1.53 riastrad 281 1.53 riastrad static void 282 1.53 riastrad puthexdump(char *buf, const void *p, size_t n) 283 1.53 riastrad { 284 1.53 riastrad 285 1.89 kre if (buf == NULL || buf == enomem) 286 1.53 riastrad return; 287 1.93 christos if (n > MAX_HDUMP_LEN) 288 1.93 christos n = MAX_HDUMP_LEN; 289 1.112 riastrad kmem_free(buf, 3*n + 5); 290 1.53 riastrad } 291 1.53 riastrad 292 1.7 riastrad #ifdef WG_RUMPKERNEL 293 1.1 riastrad static void 294 1.1 riastrad wg_dump_buf(const char *func, const char *buf, const size_t size) 295 1.1 riastrad { 296 1.80 christos if ((wg_debug & WG_DEBUG_FLAGS_DUMP) == 0) 297 1.80 christos return; 298 1.80 christos 299 1.53 riastrad char *hex = gethexdump(buf, size); 300 1.1 riastrad 301 1.89 kre log(LOG_DEBUG, "%s: %s\n", func, hex); 302 1.53 riastrad puthexdump(hex, buf, size); 303 1.1 riastrad } 304 1.7 riastrad #endif 305 1.1 riastrad 306 1.1 riastrad static void 307 1.1 riastrad wg_dump_hash(const uint8_t *func, const uint8_t *name, const uint8_t *hash, 308 1.1 riastrad const size_t size) 309 1.1 riastrad { 310 1.80 christos if ((wg_debug & WG_DEBUG_FLAGS_DUMP) == 0) 311 1.80 christos return; 312 1.80 christos 313 1.53 riastrad char *hex = gethexdump(hash, size); 314 1.1 riastrad 315 1.89 kre log(LOG_DEBUG, "%s: %s: %s\n", func, name, hex); 316 1.53 riastrad puthexdump(hex, hash, size); 317 1.1 riastrad } 318 1.1 riastrad 319 1.1 riastrad #define WG_DUMP_HASH(name, hash) \ 320 1.1 riastrad wg_dump_hash(__func__, name, hash, WG_HASH_LEN) 321 1.1 riastrad #define WG_DUMP_HASH48(name, hash) \ 322 1.1 riastrad wg_dump_hash(__func__, name, hash, 48) 323 1.1 riastrad #define WG_DUMP_BUF(buf, size) \ 324 1.1 riastrad wg_dump_buf(__func__, buf, size) 325 1.1 riastrad #else 326 1.1 riastrad #define WG_DUMP_HASH(name, hash) __nothing 327 1.1 riastrad #define WG_DUMP_HASH48(name, hash) __nothing 328 1.1 riastrad #define WG_DUMP_BUF(buf, size) __nothing 329 1.1 riastrad #endif /* WG_DEBUG_DUMP */ 330 1.1 riastrad 331 1.75 andvar /* chosen somewhat arbitrarily -- fits in signed 16 bits NUL-terminated */ 332 1.68 riastrad #define WG_MAX_PROPLEN 32766 333 1.68 riastrad 334 1.1 riastrad #define WG_MTU 1420 335 1.1 riastrad #define WG_ALLOWEDIPS 16 336 1.1 riastrad 337 1.1 riastrad #define CURVE25519_KEY_LEN 32 338 1.110 riastrad #define TAI64N_LEN (sizeof(uint32_t) * 3) 339 1.1 riastrad #define POLY1305_AUTHTAG_LEN 16 340 1.1 riastrad #define HMAC_BLOCK_LEN 64 341 1.1 riastrad 342 1.1 riastrad /* [N] 4.1: "DHLEN must be 32 or greater." WireGuard chooses 32. */ 343 1.1 riastrad /* [N] 4.3: Hash functions */ 344 1.1 riastrad #define NOISE_DHLEN 32 345 1.1 riastrad /* [N] 4.3: "Must be 32 or 64." WireGuard chooses 32. */ 346 1.1 riastrad #define NOISE_HASHLEN 32 347 1.1 riastrad #define NOISE_BLOCKLEN 64 348 1.1 riastrad #define NOISE_HKDF_OUTPUT_LEN NOISE_HASHLEN 349 1.1 riastrad /* [N] 5.1: "k" */ 350 1.1 riastrad #define NOISE_CIPHER_KEY_LEN 32 351 1.1 riastrad /* 352 1.1 riastrad * [N] 9.2: "psk" 353 1.1 riastrad * "... psk is a 32-byte secret value provided by the application." 354 1.1 riastrad */ 355 1.1 riastrad #define NOISE_PRESHARED_KEY_LEN 32 356 1.1 riastrad 357 1.1 riastrad #define WG_STATIC_KEY_LEN CURVE25519_KEY_LEN 358 1.1 riastrad #define WG_TIMESTAMP_LEN TAI64N_LEN 359 1.1 riastrad 360 1.1 riastrad #define WG_PRESHARED_KEY_LEN NOISE_PRESHARED_KEY_LEN 361 1.1 riastrad 362 1.1 riastrad #define WG_COOKIE_LEN 16 363 1.1 riastrad #define WG_MAC_LEN 16 364 1.98 riastrad #define WG_COOKIESECRET_LEN 32 365 1.1 riastrad 366 1.1 riastrad #define WG_EPHEMERAL_KEY_LEN CURVE25519_KEY_LEN 367 1.1 riastrad /* [N] 5.2: "ck: A chaining key of HASHLEN bytes" */ 368 1.1 riastrad #define WG_CHAINING_KEY_LEN NOISE_HASHLEN 369 1.1 riastrad /* [N] 5.2: "h: A hash output of HASHLEN bytes" */ 370 1.1 riastrad #define WG_HASH_LEN NOISE_HASHLEN 371 1.1 riastrad #define WG_CIPHER_KEY_LEN NOISE_CIPHER_KEY_LEN 372 1.1 riastrad #define WG_DH_OUTPUT_LEN NOISE_DHLEN 373 1.1 riastrad #define WG_KDF_OUTPUT_LEN NOISE_HKDF_OUTPUT_LEN 374 1.1 riastrad #define WG_AUTHTAG_LEN POLY1305_AUTHTAG_LEN 375 1.1 riastrad #define WG_DATA_KEY_LEN 32 376 1.1 riastrad #define WG_SALT_LEN 24 377 1.1 riastrad 378 1.1 riastrad /* 379 1.1 riastrad * The protocol messages 380 1.1 riastrad */ 381 1.14 riastrad struct wg_msg { 382 1.1 riastrad uint32_t wgm_type; 383 1.1 riastrad } __packed; 384 1.1 riastrad 385 1.1 riastrad /* [W] 5.4.2 First Message: Initiator to Responder */ 386 1.1 riastrad struct wg_msg_init { 387 1.1 riastrad uint32_t wgmi_type; 388 1.1 riastrad uint32_t wgmi_sender; 389 1.1 riastrad uint8_t wgmi_ephemeral[WG_EPHEMERAL_KEY_LEN]; 390 1.1 riastrad uint8_t wgmi_static[WG_STATIC_KEY_LEN + WG_AUTHTAG_LEN]; 391 1.1 riastrad uint8_t wgmi_timestamp[WG_TIMESTAMP_LEN + WG_AUTHTAG_LEN]; 392 1.1 riastrad uint8_t wgmi_mac1[WG_MAC_LEN]; 393 1.1 riastrad uint8_t wgmi_mac2[WG_MAC_LEN]; 394 1.1 riastrad } __packed; 395 1.1 riastrad 396 1.1 riastrad /* [W] 5.4.3 Second Message: Responder to Initiator */ 397 1.1 riastrad struct wg_msg_resp { 398 1.1 riastrad uint32_t wgmr_type; 399 1.1 riastrad uint32_t wgmr_sender; 400 1.1 riastrad uint32_t wgmr_receiver; 401 1.1 riastrad uint8_t wgmr_ephemeral[WG_EPHEMERAL_KEY_LEN]; 402 1.1 riastrad uint8_t wgmr_empty[0 + WG_AUTHTAG_LEN]; 403 1.1 riastrad uint8_t wgmr_mac1[WG_MAC_LEN]; 404 1.1 riastrad uint8_t wgmr_mac2[WG_MAC_LEN]; 405 1.1 riastrad } __packed; 406 1.1 riastrad 407 1.1 riastrad /* [W] 5.4.6 Subsequent Messages: Transport Data Messages */ 408 1.1 riastrad struct wg_msg_data { 409 1.1 riastrad uint32_t wgmd_type; 410 1.1 riastrad uint32_t wgmd_receiver; 411 1.1 riastrad uint64_t wgmd_counter; 412 1.114 riastrad uint32_t wgmd_packet[]; 413 1.1 riastrad } __packed; 414 1.1 riastrad 415 1.1 riastrad /* [W] 5.4.7 Under Load: Cookie Reply Message */ 416 1.1 riastrad struct wg_msg_cookie { 417 1.1 riastrad uint32_t wgmc_type; 418 1.1 riastrad uint32_t wgmc_receiver; 419 1.1 riastrad uint8_t wgmc_salt[WG_SALT_LEN]; 420 1.1 riastrad uint8_t wgmc_cookie[WG_COOKIE_LEN + WG_AUTHTAG_LEN]; 421 1.1 riastrad } __packed; 422 1.1 riastrad 423 1.1 riastrad #define WG_MSG_TYPE_INIT 1 424 1.1 riastrad #define WG_MSG_TYPE_RESP 2 425 1.1 riastrad #define WG_MSG_TYPE_COOKIE 3 426 1.1 riastrad #define WG_MSG_TYPE_DATA 4 427 1.1 riastrad #define WG_MSG_TYPE_MAX WG_MSG_TYPE_DATA 428 1.1 riastrad 429 1.6 riastrad /* Sliding windows */ 430 1.6 riastrad 431 1.6 riastrad #define SLIWIN_BITS 2048u 432 1.6 riastrad #define SLIWIN_TYPE uint32_t 433 1.110 riastrad #define SLIWIN_BPW (NBBY*sizeof(SLIWIN_TYPE)) 434 1.6 riastrad #define SLIWIN_WORDS howmany(SLIWIN_BITS, SLIWIN_BPW) 435 1.6 riastrad #define SLIWIN_NPKT (SLIWIN_BITS - NBBY*sizeof(SLIWIN_TYPE)) 436 1.6 riastrad 437 1.6 riastrad struct sliwin { 438 1.6 riastrad SLIWIN_TYPE B[SLIWIN_WORDS]; 439 1.6 riastrad uint64_t T; 440 1.6 riastrad }; 441 1.6 riastrad 442 1.121 riastrad /* 443 1.121 riastrad * sliwin_reset(W) 444 1.121 riastrad * 445 1.121 riastrad * Reset sliding window state to a blank history with no observed 446 1.121 riastrad * sequence numbers. 447 1.121 riastrad * 448 1.121 riastrad * Caller must have exclusive access to W. 449 1.121 riastrad */ 450 1.6 riastrad static void 451 1.6 riastrad sliwin_reset(struct sliwin *W) 452 1.6 riastrad { 453 1.6 riastrad 454 1.6 riastrad memset(W, 0, sizeof(*W)); 455 1.6 riastrad } 456 1.6 riastrad 457 1.121 riastrad /* 458 1.121 riastrad * sliwin_check_fast(W, S) 459 1.121 riastrad * 460 1.121 riastrad * Do a fast check of the sliding window W to validate sequence 461 1.121 riastrad * number S. No state is recorded. Return 0 on accept, nonzero 462 1.121 riastrad * error code on reject. 463 1.121 riastrad * 464 1.121 riastrad * May be called concurrently with other calls to 465 1.121 riastrad * sliwin_check_fast and sliwin_update. 466 1.121 riastrad */ 467 1.6 riastrad static int 468 1.6 riastrad sliwin_check_fast(const volatile struct sliwin *W, uint64_t S) 469 1.6 riastrad { 470 1.6 riastrad 471 1.6 riastrad /* 472 1.6 riastrad * If it's more than one window older than the highest sequence 473 1.6 riastrad * number we've seen, reject. 474 1.6 riastrad */ 475 1.20 riastrad #ifdef __HAVE_ATOMIC64_LOADSTORE 476 1.6 riastrad if (S + SLIWIN_NPKT < atomic_load_relaxed(&W->T)) 477 1.6 riastrad return EAUTH; 478 1.20 riastrad #endif 479 1.6 riastrad 480 1.6 riastrad /* 481 1.6 riastrad * Otherwise, we need to take the lock to decide, so don't 482 1.6 riastrad * reject just yet. Caller must serialize a call to 483 1.6 riastrad * sliwin_update in this case. 484 1.6 riastrad */ 485 1.6 riastrad return 0; 486 1.6 riastrad } 487 1.6 riastrad 488 1.121 riastrad /* 489 1.121 riastrad * sliwin_update(W, S) 490 1.121 riastrad * 491 1.121 riastrad * Check the sliding window W to validate sequence number S, and 492 1.121 riastrad * if accepted, update it to reflect having observed S. Return 0 493 1.121 riastrad * on accept, nonzero error code on reject. 494 1.121 riastrad * 495 1.121 riastrad * May be called concurrently with other calls to 496 1.121 riastrad * sliwin_check_fast, but caller must exclude other calls to 497 1.121 riastrad * sliwin_update. 498 1.121 riastrad */ 499 1.6 riastrad static int 500 1.6 riastrad sliwin_update(struct sliwin *W, uint64_t S) 501 1.6 riastrad { 502 1.6 riastrad unsigned word, bit; 503 1.6 riastrad 504 1.6 riastrad /* 505 1.6 riastrad * If it's more than one window older than the highest sequence 506 1.6 riastrad * number we've seen, reject. 507 1.6 riastrad */ 508 1.6 riastrad if (S + SLIWIN_NPKT < W->T) 509 1.6 riastrad return EAUTH; 510 1.6 riastrad 511 1.6 riastrad /* 512 1.6 riastrad * If it's higher than the highest sequence number we've seen, 513 1.6 riastrad * advance the window. 514 1.6 riastrad */ 515 1.6 riastrad if (S > W->T) { 516 1.6 riastrad uint64_t i = W->T / SLIWIN_BPW; 517 1.6 riastrad uint64_t j = S / SLIWIN_BPW; 518 1.6 riastrad unsigned k; 519 1.6 riastrad 520 1.6 riastrad for (k = 0; k < MIN(j - i, SLIWIN_WORDS); k++) 521 1.6 riastrad W->B[(i + k + 1) % SLIWIN_WORDS] = 0; 522 1.20 riastrad #ifdef __HAVE_ATOMIC64_LOADSTORE 523 1.6 riastrad atomic_store_relaxed(&W->T, S); 524 1.20 riastrad #else 525 1.20 riastrad W->T = S; 526 1.20 riastrad #endif 527 1.6 riastrad } 528 1.6 riastrad 529 1.6 riastrad /* Test and set the bit -- if already set, reject. */ 530 1.6 riastrad word = (S / SLIWIN_BPW) % SLIWIN_WORDS; 531 1.6 riastrad bit = S % SLIWIN_BPW; 532 1.6 riastrad if (W->B[word] & (1UL << bit)) 533 1.6 riastrad return EAUTH; 534 1.65 christos W->B[word] |= 1U << bit; 535 1.6 riastrad 536 1.6 riastrad /* Accept! */ 537 1.6 riastrad return 0; 538 1.6 riastrad } 539 1.6 riastrad 540 1.1 riastrad struct wg_session { 541 1.1 riastrad struct wg_peer *wgs_peer; 542 1.1 riastrad struct psref_target 543 1.1 riastrad wgs_psref; 544 1.1 riastrad 545 1.129 riastrad volatile int wgs_state; 546 1.1 riastrad #define WGS_STATE_UNKNOWN 0 547 1.1 riastrad #define WGS_STATE_INIT_ACTIVE 1 548 1.1 riastrad #define WGS_STATE_INIT_PASSIVE 2 549 1.1 riastrad #define WGS_STATE_ESTABLISHED 3 550 1.1 riastrad #define WGS_STATE_DESTROYING 4 551 1.1 riastrad 552 1.117 riastrad uint32_t wgs_time_established; 553 1.104 riastrad volatile uint32_t 554 1.104 riastrad wgs_time_last_data_sent; 555 1.113 riastrad volatile bool wgs_force_rekey; 556 1.1 riastrad bool wgs_is_initiator; 557 1.1 riastrad 558 1.49 riastrad uint32_t wgs_local_index; 559 1.49 riastrad uint32_t wgs_remote_index; 560 1.22 riastrad #ifdef __HAVE_ATOMIC64_LOADSTORE 561 1.1 riastrad volatile uint64_t 562 1.1 riastrad wgs_send_counter; 563 1.22 riastrad #else 564 1.22 riastrad kmutex_t wgs_send_counter_lock; 565 1.22 riastrad uint64_t wgs_send_counter; 566 1.22 riastrad #endif 567 1.6 riastrad 568 1.6 riastrad struct { 569 1.6 riastrad kmutex_t lock; 570 1.6 riastrad struct sliwin window; 571 1.6 riastrad } *wgs_recvwin; 572 1.1 riastrad 573 1.1 riastrad uint8_t wgs_handshake_hash[WG_HASH_LEN]; 574 1.1 riastrad uint8_t wgs_chaining_key[WG_CHAINING_KEY_LEN]; 575 1.1 riastrad uint8_t wgs_ephemeral_key_pub[WG_EPHEMERAL_KEY_LEN]; 576 1.1 riastrad uint8_t wgs_ephemeral_key_priv[WG_EPHEMERAL_KEY_LEN]; 577 1.1 riastrad uint8_t wgs_ephemeral_key_peer[WG_EPHEMERAL_KEY_LEN]; 578 1.1 riastrad uint8_t wgs_tkey_send[WG_DATA_KEY_LEN]; 579 1.1 riastrad uint8_t wgs_tkey_recv[WG_DATA_KEY_LEN]; 580 1.1 riastrad }; 581 1.1 riastrad 582 1.1 riastrad struct wg_sockaddr { 583 1.1 riastrad union { 584 1.1 riastrad struct sockaddr_storage _ss; 585 1.1 riastrad struct sockaddr _sa; 586 1.1 riastrad struct sockaddr_in _sin; 587 1.1 riastrad struct sockaddr_in6 _sin6; 588 1.1 riastrad }; 589 1.1 riastrad struct psref_target wgsa_psref; 590 1.1 riastrad }; 591 1.1 riastrad 592 1.47 riastrad #define wgsatoss(wgsa) (&(wgsa)->_ss) 593 1.1 riastrad #define wgsatosa(wgsa) (&(wgsa)->_sa) 594 1.1 riastrad #define wgsatosin(wgsa) (&(wgsa)->_sin) 595 1.1 riastrad #define wgsatosin6(wgsa) (&(wgsa)->_sin6) 596 1.1 riastrad 597 1.47 riastrad #define wgsa_family(wgsa) (wgsatosa(wgsa)->sa_family) 598 1.47 riastrad 599 1.1 riastrad struct wg_peer; 600 1.1 riastrad struct wg_allowedip { 601 1.1 riastrad struct radix_node wga_nodes[2]; 602 1.1 riastrad struct wg_sockaddr _wga_sa_addr; 603 1.1 riastrad struct wg_sockaddr _wga_sa_mask; 604 1.1 riastrad #define wga_sa_addr _wga_sa_addr._sa 605 1.1 riastrad #define wga_sa_mask _wga_sa_mask._sa 606 1.1 riastrad 607 1.1 riastrad int wga_family; 608 1.1 riastrad uint8_t wga_cidr; 609 1.1 riastrad union { 610 1.1 riastrad struct in_addr _ip4; 611 1.1 riastrad struct in6_addr _ip6; 612 1.1 riastrad } wga_addr; 613 1.1 riastrad #define wga_addr4 wga_addr._ip4 614 1.1 riastrad #define wga_addr6 wga_addr._ip6 615 1.1 riastrad 616 1.1 riastrad struct wg_peer *wga_peer; 617 1.1 riastrad }; 618 1.1 riastrad 619 1.1 riastrad typedef uint8_t wg_timestamp_t[WG_TIMESTAMP_LEN]; 620 1.1 riastrad 621 1.1 riastrad struct wg_ppsratecheck { 622 1.1 riastrad struct timeval wgprc_lasttime; 623 1.1 riastrad int wgprc_curpps; 624 1.1 riastrad }; 625 1.1 riastrad 626 1.1 riastrad struct wg_softc; 627 1.1 riastrad struct wg_peer { 628 1.1 riastrad struct wg_softc *wgp_sc; 629 1.1 riastrad char wgp_name[WG_PEER_NAME_MAXLEN + 1]; 630 1.1 riastrad struct pslist_entry wgp_peerlist_entry; 631 1.1 riastrad pserialize_t wgp_psz; 632 1.1 riastrad struct psref_target wgp_psref; 633 1.1 riastrad kmutex_t *wgp_lock; 634 1.55 riastrad kmutex_t *wgp_intr_lock; 635 1.1 riastrad 636 1.1 riastrad uint8_t wgp_pubkey[WG_STATIC_KEY_LEN]; 637 1.129 riastrad struct wg_sockaddr *volatile wgp_endpoint; 638 1.1 riastrad struct wg_sockaddr *wgp_endpoint0; 639 1.49 riastrad volatile unsigned wgp_endpoint_changing; 640 1.129 riastrad volatile bool wgp_endpoint_available; 641 1.1 riastrad 642 1.1 riastrad /* The preshared key (optional) */ 643 1.1 riastrad uint8_t wgp_psk[WG_PRESHARED_KEY_LEN]; 644 1.1 riastrad 645 1.129 riastrad struct wg_session *volatile wgp_session_stable; 646 1.1 riastrad struct wg_session *wgp_session_unstable; 647 1.1 riastrad 648 1.54 riastrad /* first outgoing packet awaiting session initiation */ 649 1.99 riastrad struct mbuf *volatile wgp_pending; 650 1.54 riastrad 651 1.1 riastrad /* timestamp in big-endian */ 652 1.1 riastrad wg_timestamp_t wgp_timestamp_latest_init; 653 1.1 riastrad 654 1.1 riastrad struct timespec wgp_last_handshake_time; 655 1.1 riastrad 656 1.1 riastrad callout_t wgp_handshake_timeout_timer; 657 1.1 riastrad callout_t wgp_session_dtor_timer; 658 1.1 riastrad 659 1.1 riastrad time_t wgp_handshake_start_time; 660 1.1 riastrad 661 1.14 riastrad int wgp_n_allowedips; 662 1.1 riastrad struct wg_allowedip wgp_allowedips[WG_ALLOWEDIPS]; 663 1.1 riastrad 664 1.1 riastrad time_t wgp_latest_cookie_time; 665 1.1 riastrad uint8_t wgp_latest_cookie[WG_COOKIE_LEN]; 666 1.1 riastrad uint8_t wgp_last_sent_mac1[WG_MAC_LEN]; 667 1.1 riastrad bool wgp_last_sent_mac1_valid; 668 1.1 riastrad uint8_t wgp_last_sent_cookie[WG_COOKIE_LEN]; 669 1.1 riastrad bool wgp_last_sent_cookie_valid; 670 1.1 riastrad 671 1.1 riastrad time_t wgp_last_msg_received_time[WG_MSG_TYPE_MAX]; 672 1.1 riastrad 673 1.98 riastrad time_t wgp_last_cookiesecret_time; 674 1.98 riastrad uint8_t wgp_cookiesecret[WG_COOKIESECRET_LEN]; 675 1.1 riastrad 676 1.1 riastrad struct wg_ppsratecheck wgp_ppsratecheck; 677 1.1 riastrad 678 1.55 riastrad struct work wgp_work; 679 1.55 riastrad unsigned int wgp_tasks; 680 1.1 riastrad #define WGP_TASK_SEND_INIT_MESSAGE __BIT(0) 681 1.49 riastrad #define WGP_TASK_RETRY_HANDSHAKE __BIT(1) 682 1.49 riastrad #define WGP_TASK_ESTABLISH_SESSION __BIT(2) 683 1.49 riastrad #define WGP_TASK_ENDPOINT_CHANGED __BIT(3) 684 1.49 riastrad #define WGP_TASK_SEND_KEEPALIVE_MESSAGE __BIT(4) 685 1.49 riastrad #define WGP_TASK_DESTROY_PREV_SESSION __BIT(5) 686 1.1 riastrad }; 687 1.1 riastrad 688 1.1 riastrad struct wg_ops; 689 1.1 riastrad 690 1.1 riastrad struct wg_softc { 691 1.1 riastrad struct ifnet wg_if; 692 1.1 riastrad LIST_ENTRY(wg_softc) wg_list; 693 1.1 riastrad kmutex_t *wg_lock; 694 1.55 riastrad kmutex_t *wg_intr_lock; 695 1.1 riastrad krwlock_t *wg_rwlock; 696 1.1 riastrad 697 1.1 riastrad uint8_t wg_privkey[WG_STATIC_KEY_LEN]; 698 1.1 riastrad uint8_t wg_pubkey[WG_STATIC_KEY_LEN]; 699 1.1 riastrad 700 1.1 riastrad int wg_npeers; 701 1.1 riastrad struct pslist_head wg_peers; 702 1.37 riastrad struct thmap *wg_peers_bypubkey; 703 1.37 riastrad struct thmap *wg_peers_byname; 704 1.37 riastrad struct thmap *wg_sessions_byindex; 705 1.1 riastrad uint16_t wg_listen_port; 706 1.1 riastrad 707 1.55 riastrad struct threadpool *wg_threadpool; 708 1.1 riastrad 709 1.55 riastrad struct threadpool_job wg_job; 710 1.55 riastrad int wg_upcalls; 711 1.55 riastrad #define WG_UPCALL_INET __BIT(0) 712 1.55 riastrad #define WG_UPCALL_INET6 __BIT(1) 713 1.55 riastrad 714 1.55 riastrad #ifdef INET 715 1.55 riastrad struct socket *wg_so4; 716 1.1 riastrad struct radix_node_head *wg_rtable_ipv4; 717 1.55 riastrad #endif 718 1.55 riastrad #ifdef INET6 719 1.55 riastrad struct socket *wg_so6; 720 1.1 riastrad struct radix_node_head *wg_rtable_ipv6; 721 1.55 riastrad #endif 722 1.1 riastrad 723 1.1 riastrad struct wg_ppsratecheck wg_ppsratecheck; 724 1.1 riastrad 725 1.1 riastrad struct wg_ops *wg_ops; 726 1.1 riastrad 727 1.1 riastrad #ifdef WG_RUMPKERNEL 728 1.1 riastrad struct wg_user *wg_user; 729 1.1 riastrad #endif 730 1.1 riastrad }; 731 1.1 riastrad 732 1.21 riastrad /* [W] 6.1 Preliminaries */ 733 1.21 riastrad #define WG_REKEY_AFTER_MESSAGES (1ULL << 60) 734 1.21 riastrad #define WG_REJECT_AFTER_MESSAGES (UINT64_MAX - (1 << 13)) 735 1.1 riastrad #define WG_REKEY_AFTER_TIME 120 736 1.1 riastrad #define WG_REJECT_AFTER_TIME 180 737 1.1 riastrad #define WG_REKEY_ATTEMPT_TIME 90 738 1.1 riastrad #define WG_REKEY_TIMEOUT 5 739 1.1 riastrad #define WG_KEEPALIVE_TIMEOUT 10 740 1.1 riastrad 741 1.1 riastrad #define WG_COOKIE_TIME 120 742 1.98 riastrad #define WG_COOKIESECRET_TIME (2 * 60) 743 1.1 riastrad 744 1.1 riastrad static uint64_t wg_rekey_after_messages = WG_REKEY_AFTER_MESSAGES; 745 1.1 riastrad static uint64_t wg_reject_after_messages = WG_REJECT_AFTER_MESSAGES; 746 1.21 riastrad static unsigned wg_rekey_after_time = WG_REKEY_AFTER_TIME; 747 1.21 riastrad static unsigned wg_reject_after_time = WG_REJECT_AFTER_TIME; 748 1.21 riastrad static unsigned wg_rekey_attempt_time = WG_REKEY_ATTEMPT_TIME; 749 1.21 riastrad static unsigned wg_rekey_timeout = WG_REKEY_TIMEOUT; 750 1.21 riastrad static unsigned wg_keepalive_timeout = WG_KEEPALIVE_TIMEOUT; 751 1.1 riastrad 752 1.1 riastrad static struct mbuf * 753 1.1 riastrad wg_get_mbuf(size_t, size_t); 754 1.1 riastrad 755 1.108 riastrad static void wg_send_data_msg(struct wg_peer *, struct wg_session *, 756 1.1 riastrad struct mbuf *); 757 1.108 riastrad static void wg_send_cookie_msg(struct wg_softc *, struct wg_peer *, 758 1.114 riastrad const uint32_t, const uint8_t[static WG_MAC_LEN], 759 1.77 mrg const struct sockaddr *); 760 1.108 riastrad static void wg_send_handshake_msg_resp(struct wg_softc *, struct wg_peer *, 761 1.49 riastrad struct wg_session *, const struct wg_msg_init *); 762 1.1 riastrad static void wg_send_keepalive_msg(struct wg_peer *, struct wg_session *); 763 1.1 riastrad 764 1.1 riastrad static struct wg_peer * 765 1.1 riastrad wg_pick_peer_by_sa(struct wg_softc *, const struct sockaddr *, 766 1.1 riastrad struct psref *); 767 1.1 riastrad static struct wg_peer * 768 1.1 riastrad wg_lookup_peer_by_pubkey(struct wg_softc *, 769 1.114 riastrad const uint8_t[static WG_STATIC_KEY_LEN], struct psref *); 770 1.1 riastrad 771 1.1 riastrad static struct wg_session * 772 1.1 riastrad wg_lookup_session_by_index(struct wg_softc *, 773 1.1 riastrad const uint32_t, struct psref *); 774 1.1 riastrad 775 1.1 riastrad static void wg_update_endpoint_if_necessary(struct wg_peer *, 776 1.1 riastrad const struct sockaddr *); 777 1.1 riastrad 778 1.1 riastrad static void wg_schedule_session_dtor_timer(struct wg_peer *); 779 1.1 riastrad 780 1.1 riastrad static bool wg_is_underload(struct wg_softc *, struct wg_peer *, int); 781 1.1 riastrad static void wg_calculate_keys(struct wg_session *, const bool); 782 1.1 riastrad 783 1.1 riastrad static void wg_clear_states(struct wg_session *); 784 1.1 riastrad 785 1.1 riastrad static void wg_get_peer(struct wg_peer *, struct psref *); 786 1.1 riastrad static void wg_put_peer(struct wg_peer *, struct psref *); 787 1.1 riastrad 788 1.134 riastrad static int wg_send_hs(struct wg_peer *, struct mbuf *); 789 1.134 riastrad static int wg_send_data(struct wg_peer *, struct mbuf *); 790 1.1 riastrad static int wg_output(struct ifnet *, struct mbuf *, 791 1.1 riastrad const struct sockaddr *, const struct rtentry *); 792 1.1 riastrad static void wg_input(struct ifnet *, struct mbuf *, const int); 793 1.1 riastrad static int wg_ioctl(struct ifnet *, u_long, void *); 794 1.1 riastrad static int wg_bind_port(struct wg_softc *, const uint16_t); 795 1.1 riastrad static int wg_init(struct ifnet *); 796 1.60 riastrad #ifdef ALTQ 797 1.60 riastrad static void wg_start(struct ifnet *); 798 1.60 riastrad #endif 799 1.1 riastrad static void wg_stop(struct ifnet *, int); 800 1.1 riastrad 801 1.55 riastrad static void wg_peer_work(struct work *, void *); 802 1.55 riastrad static void wg_job(struct threadpool_job *); 803 1.54 riastrad static void wgintr(void *); 804 1.49 riastrad static void wg_purge_pending_packets(struct wg_peer *); 805 1.49 riastrad 806 1.1 riastrad static int wg_clone_create(struct if_clone *, int); 807 1.1 riastrad static int wg_clone_destroy(struct ifnet *); 808 1.1 riastrad 809 1.1 riastrad struct wg_ops { 810 1.1 riastrad int (*send_hs_msg)(struct wg_peer *, struct mbuf *); 811 1.1 riastrad int (*send_data_msg)(struct wg_peer *, struct mbuf *); 812 1.1 riastrad void (*input)(struct ifnet *, struct mbuf *, const int); 813 1.1 riastrad int (*bind_port)(struct wg_softc *, const uint16_t); 814 1.1 riastrad }; 815 1.1 riastrad 816 1.1 riastrad struct wg_ops wg_ops_rumpkernel = { 817 1.134 riastrad .send_hs_msg = wg_send_hs, 818 1.134 riastrad .send_data_msg = wg_send_data, 819 1.1 riastrad .input = wg_input, 820 1.1 riastrad .bind_port = wg_bind_port, 821 1.1 riastrad }; 822 1.1 riastrad 823 1.1 riastrad #ifdef WG_RUMPKERNEL 824 1.1 riastrad static bool wg_user_mode(struct wg_softc *); 825 1.1 riastrad static int wg_ioctl_linkstr(struct wg_softc *, struct ifdrv *); 826 1.1 riastrad 827 1.134 riastrad static int wg_send_hs_user(struct wg_peer *, struct mbuf *); 828 1.134 riastrad static int wg_send_data_user(struct wg_peer *, struct mbuf *); 829 1.1 riastrad static void wg_input_user(struct ifnet *, struct mbuf *, const int); 830 1.1 riastrad static int wg_bind_port_user(struct wg_softc *, const uint16_t); 831 1.1 riastrad 832 1.1 riastrad struct wg_ops wg_ops_rumpuser = { 833 1.134 riastrad .send_hs_msg = wg_send_hs_user, 834 1.134 riastrad .send_data_msg = wg_send_data_user, 835 1.1 riastrad .input = wg_input_user, 836 1.1 riastrad .bind_port = wg_bind_port_user, 837 1.1 riastrad }; 838 1.1 riastrad #endif 839 1.1 riastrad 840 1.1 riastrad #define WG_PEER_READER_FOREACH(wgp, wg) \ 841 1.1 riastrad PSLIST_READER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \ 842 1.1 riastrad wgp_peerlist_entry) 843 1.1 riastrad #define WG_PEER_WRITER_FOREACH(wgp, wg) \ 844 1.1 riastrad PSLIST_WRITER_FOREACH((wgp), &(wg)->wg_peers, struct wg_peer, \ 845 1.1 riastrad wgp_peerlist_entry) 846 1.1 riastrad #define WG_PEER_WRITER_INSERT_HEAD(wgp, wg) \ 847 1.1 riastrad PSLIST_WRITER_INSERT_HEAD(&(wg)->wg_peers, (wgp), wgp_peerlist_entry) 848 1.1 riastrad #define WG_PEER_WRITER_REMOVE(wgp) \ 849 1.1 riastrad PSLIST_WRITER_REMOVE((wgp), wgp_peerlist_entry) 850 1.1 riastrad 851 1.1 riastrad struct wg_route { 852 1.1 riastrad struct radix_node wgr_nodes[2]; 853 1.1 riastrad struct wg_peer *wgr_peer; 854 1.1 riastrad }; 855 1.1 riastrad 856 1.1 riastrad static struct radix_node_head * 857 1.1 riastrad wg_rnh(struct wg_softc *wg, const int family) 858 1.1 riastrad { 859 1.1 riastrad 860 1.1 riastrad switch (family) { 861 1.109 riastrad #ifdef INET 862 1.1 riastrad case AF_INET: 863 1.1 riastrad return wg->wg_rtable_ipv4; 864 1.109 riastrad #endif 865 1.1 riastrad #ifdef INET6 866 1.1 riastrad case AF_INET6: 867 1.1 riastrad return wg->wg_rtable_ipv6; 868 1.1 riastrad #endif 869 1.1 riastrad default: 870 1.1 riastrad return NULL; 871 1.1 riastrad } 872 1.1 riastrad } 873 1.1 riastrad 874 1.1 riastrad 875 1.1 riastrad /* 876 1.1 riastrad * Global variables 877 1.1 riastrad */ 878 1.59 riastrad static volatile unsigned wg_count __cacheline_aligned; 879 1.1 riastrad 880 1.1 riastrad struct psref_class *wg_psref_class __read_mostly; 881 1.1 riastrad 882 1.1 riastrad static struct if_clone wg_cloner = 883 1.1 riastrad IF_CLONE_INITIALIZER("wg", wg_clone_create, wg_clone_destroy); 884 1.1 riastrad 885 1.54 riastrad static struct pktqueue *wg_pktq __read_mostly; 886 1.55 riastrad static struct workqueue *wg_wq __read_mostly; 887 1.1 riastrad 888 1.1 riastrad void wgattach(int); 889 1.1 riastrad /* ARGSUSED */ 890 1.1 riastrad void 891 1.1 riastrad wgattach(int count) 892 1.1 riastrad { 893 1.1 riastrad /* 894 1.1 riastrad * Nothing to do here, initialization is handled by the 895 1.1 riastrad * module initialization code in wginit() below). 896 1.1 riastrad */ 897 1.1 riastrad } 898 1.1 riastrad 899 1.1 riastrad static void 900 1.1 riastrad wginit(void) 901 1.1 riastrad { 902 1.1 riastrad 903 1.1 riastrad wg_psref_class = psref_class_create("wg", IPL_SOFTNET); 904 1.1 riastrad 905 1.58 riastrad if_clone_attach(&wg_cloner); 906 1.58 riastrad } 907 1.58 riastrad 908 1.58 riastrad /* 909 1.58 riastrad * XXX Kludge: This should just happen in wginit, but workqueue_create 910 1.58 riastrad * cannot be run until after CPUs have been detected, and wginit runs 911 1.58 riastrad * before configure. 912 1.58 riastrad */ 913 1.58 riastrad static int 914 1.58 riastrad wginitqueues(void) 915 1.58 riastrad { 916 1.58 riastrad int error __diagused; 917 1.58 riastrad 918 1.54 riastrad wg_pktq = pktq_create(IFQ_MAXLEN, wgintr, NULL); 919 1.54 riastrad KASSERT(wg_pktq != NULL); 920 1.54 riastrad 921 1.55 riastrad error = workqueue_create(&wg_wq, "wgpeer", wg_peer_work, NULL, 922 1.55 riastrad PRI_NONE, IPL_SOFTNET, WQ_MPSAFE|WQ_PERCPU); 923 1.108 riastrad KASSERTMSG(error == 0, "error=%d", error); 924 1.55 riastrad 925 1.58 riastrad return 0; 926 1.58 riastrad } 927 1.58 riastrad 928 1.58 riastrad static void 929 1.58 riastrad wg_guarantee_initialized(void) 930 1.58 riastrad { 931 1.58 riastrad static ONCE_DECL(init); 932 1.58 riastrad int error __diagused; 933 1.58 riastrad 934 1.58 riastrad error = RUN_ONCE(&init, wginitqueues); 935 1.108 riastrad KASSERTMSG(error == 0, "error=%d", error); 936 1.1 riastrad } 937 1.1 riastrad 938 1.1 riastrad static int 939 1.59 riastrad wg_count_inc(void) 940 1.59 riastrad { 941 1.59 riastrad unsigned o, n; 942 1.59 riastrad 943 1.59 riastrad do { 944 1.59 riastrad o = atomic_load_relaxed(&wg_count); 945 1.59 riastrad if (o == UINT_MAX) 946 1.59 riastrad return ENFILE; 947 1.59 riastrad n = o + 1; 948 1.59 riastrad } while (atomic_cas_uint(&wg_count, o, n) != o); 949 1.59 riastrad 950 1.59 riastrad return 0; 951 1.59 riastrad } 952 1.59 riastrad 953 1.59 riastrad static void 954 1.59 riastrad wg_count_dec(void) 955 1.59 riastrad { 956 1.59 riastrad unsigned c __diagused; 957 1.59 riastrad 958 1.118 riastrad membar_release(); /* match atomic_load_acquire in wgdetach */ 959 1.59 riastrad c = atomic_dec_uint_nv(&wg_count); 960 1.59 riastrad KASSERT(c != UINT_MAX); 961 1.59 riastrad } 962 1.59 riastrad 963 1.59 riastrad static int 964 1.1 riastrad wgdetach(void) 965 1.1 riastrad { 966 1.1 riastrad 967 1.59 riastrad /* Prevent new interface creation. */ 968 1.59 riastrad if_clone_detach(&wg_cloner); 969 1.59 riastrad 970 1.118 riastrad /* 971 1.118 riastrad * Check whether there are any existing interfaces. Matches 972 1.118 riastrad * membar_release and atomic_dec_uint_nv in wg_count_dec. 973 1.118 riastrad */ 974 1.118 riastrad if (atomic_load_acquire(&wg_count)) { 975 1.59 riastrad /* Back out -- reattach the cloner. */ 976 1.59 riastrad if_clone_attach(&wg_cloner); 977 1.59 riastrad return EBUSY; 978 1.1 riastrad } 979 1.1 riastrad 980 1.59 riastrad /* No interfaces left. Nuke it. */ 981 1.92 riastrad if (wg_wq) 982 1.92 riastrad workqueue_destroy(wg_wq); 983 1.92 riastrad if (wg_pktq) 984 1.92 riastrad pktq_destroy(wg_pktq); 985 1.59 riastrad psref_class_destroy(wg_psref_class); 986 1.1 riastrad 987 1.59 riastrad return 0; 988 1.1 riastrad } 989 1.1 riastrad 990 1.1 riastrad static void 991 1.114 riastrad wg_init_key_and_hash(uint8_t ckey[static WG_CHAINING_KEY_LEN], 992 1.114 riastrad uint8_t hash[static WG_HASH_LEN]) 993 1.1 riastrad { 994 1.1 riastrad /* [W] 5.4: CONSTRUCTION */ 995 1.1 riastrad const char *signature = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; 996 1.1 riastrad /* [W] 5.4: IDENTIFIER */ 997 1.1 riastrad const char *id = "WireGuard v1 zx2c4 Jason (at) zx2c4.com"; 998 1.1 riastrad struct blake2s state; 999 1.1 riastrad 1000 1.1 riastrad blake2s(ckey, WG_CHAINING_KEY_LEN, NULL, 0, 1001 1.1 riastrad signature, strlen(signature)); 1002 1.1 riastrad 1003 1.1 riastrad CTASSERT(WG_HASH_LEN == WG_CHAINING_KEY_LEN); 1004 1.1 riastrad memcpy(hash, ckey, WG_CHAINING_KEY_LEN); 1005 1.1 riastrad 1006 1.1 riastrad blake2s_init(&state, WG_HASH_LEN, NULL, 0); 1007 1.1 riastrad blake2s_update(&state, ckey, WG_CHAINING_KEY_LEN); 1008 1.1 riastrad blake2s_update(&state, id, strlen(id)); 1009 1.1 riastrad blake2s_final(&state, hash); 1010 1.1 riastrad 1011 1.1 riastrad WG_DUMP_HASH("ckey", ckey); 1012 1.1 riastrad WG_DUMP_HASH("hash", hash); 1013 1.1 riastrad } 1014 1.1 riastrad 1015 1.1 riastrad static void 1016 1.114 riastrad wg_algo_hash(uint8_t hash[static WG_HASH_LEN], const uint8_t input[], 1017 1.1 riastrad const size_t inputsize) 1018 1.1 riastrad { 1019 1.1 riastrad struct blake2s state; 1020 1.1 riastrad 1021 1.1 riastrad blake2s_init(&state, WG_HASH_LEN, NULL, 0); 1022 1.1 riastrad blake2s_update(&state, hash, WG_HASH_LEN); 1023 1.1 riastrad blake2s_update(&state, input, inputsize); 1024 1.1 riastrad blake2s_final(&state, hash); 1025 1.1 riastrad } 1026 1.1 riastrad 1027 1.1 riastrad static void 1028 1.1 riastrad wg_algo_mac(uint8_t out[], const size_t outsize, 1029 1.1 riastrad const uint8_t key[], const size_t keylen, 1030 1.1 riastrad const uint8_t input1[], const size_t input1len, 1031 1.1 riastrad const uint8_t input2[], const size_t input2len) 1032 1.1 riastrad { 1033 1.1 riastrad struct blake2s state; 1034 1.1 riastrad 1035 1.1 riastrad blake2s_init(&state, outsize, key, keylen); 1036 1.1 riastrad 1037 1.1 riastrad blake2s_update(&state, input1, input1len); 1038 1.1 riastrad if (input2 != NULL) 1039 1.1 riastrad blake2s_update(&state, input2, input2len); 1040 1.1 riastrad blake2s_final(&state, out); 1041 1.1 riastrad } 1042 1.1 riastrad 1043 1.1 riastrad static void 1044 1.1 riastrad wg_algo_mac_mac1(uint8_t out[], const size_t outsize, 1045 1.1 riastrad const uint8_t input1[], const size_t input1len, 1046 1.1 riastrad const uint8_t input2[], const size_t input2len) 1047 1.1 riastrad { 1048 1.1 riastrad struct blake2s state; 1049 1.1 riastrad /* [W] 5.4: LABEL-MAC1 */ 1050 1.1 riastrad const char *label = "mac1----"; 1051 1.1 riastrad uint8_t key[WG_HASH_LEN]; 1052 1.1 riastrad 1053 1.1 riastrad blake2s_init(&state, sizeof(key), NULL, 0); 1054 1.1 riastrad blake2s_update(&state, label, strlen(label)); 1055 1.1 riastrad blake2s_update(&state, input1, input1len); 1056 1.1 riastrad blake2s_final(&state, key); 1057 1.1 riastrad 1058 1.1 riastrad blake2s_init(&state, outsize, key, sizeof(key)); 1059 1.1 riastrad if (input2 != NULL) 1060 1.1 riastrad blake2s_update(&state, input2, input2len); 1061 1.1 riastrad blake2s_final(&state, out); 1062 1.1 riastrad } 1063 1.1 riastrad 1064 1.1 riastrad static void 1065 1.1 riastrad wg_algo_mac_cookie(uint8_t out[], const size_t outsize, 1066 1.1 riastrad const uint8_t input1[], const size_t input1len) 1067 1.1 riastrad { 1068 1.1 riastrad struct blake2s state; 1069 1.1 riastrad /* [W] 5.4: LABEL-COOKIE */ 1070 1.1 riastrad const char *label = "cookie--"; 1071 1.1 riastrad 1072 1.1 riastrad blake2s_init(&state, outsize, NULL, 0); 1073 1.1 riastrad blake2s_update(&state, label, strlen(label)); 1074 1.1 riastrad blake2s_update(&state, input1, input1len); 1075 1.1 riastrad blake2s_final(&state, out); 1076 1.1 riastrad } 1077 1.1 riastrad 1078 1.1 riastrad static void 1079 1.114 riastrad wg_algo_generate_keypair(uint8_t pubkey[static WG_EPHEMERAL_KEY_LEN], 1080 1.114 riastrad uint8_t privkey[static WG_EPHEMERAL_KEY_LEN]) 1081 1.1 riastrad { 1082 1.1 riastrad 1083 1.1 riastrad CTASSERT(WG_EPHEMERAL_KEY_LEN == crypto_scalarmult_curve25519_BYTES); 1084 1.1 riastrad 1085 1.3 riastrad cprng_strong(kern_cprng, privkey, WG_EPHEMERAL_KEY_LEN, 0); 1086 1.1 riastrad crypto_scalarmult_base(pubkey, privkey); 1087 1.1 riastrad } 1088 1.1 riastrad 1089 1.1 riastrad static void 1090 1.114 riastrad wg_algo_dh(uint8_t out[static WG_DH_OUTPUT_LEN], 1091 1.114 riastrad const uint8_t privkey[static WG_STATIC_KEY_LEN], 1092 1.114 riastrad const uint8_t pubkey[static WG_STATIC_KEY_LEN]) 1093 1.1 riastrad { 1094 1.1 riastrad 1095 1.1 riastrad CTASSERT(WG_STATIC_KEY_LEN == crypto_scalarmult_curve25519_BYTES); 1096 1.1 riastrad 1097 1.19 riastrad int ret __diagused = crypto_scalarmult(out, privkey, pubkey); 1098 1.1 riastrad KASSERT(ret == 0); 1099 1.1 riastrad } 1100 1.1 riastrad 1101 1.1 riastrad static void 1102 1.1 riastrad wg_algo_hmac(uint8_t out[], const size_t outlen, 1103 1.1 riastrad const uint8_t key[], const size_t keylen, 1104 1.1 riastrad const uint8_t in[], const size_t inlen) 1105 1.1 riastrad { 1106 1.1 riastrad #define IPAD 0x36 1107 1.1 riastrad #define OPAD 0x5c 1108 1.1 riastrad uint8_t hmackey[HMAC_BLOCK_LEN] = {0}; 1109 1.1 riastrad uint8_t ipad[HMAC_BLOCK_LEN]; 1110 1.1 riastrad uint8_t opad[HMAC_BLOCK_LEN]; 1111 1.65 christos size_t i; 1112 1.1 riastrad struct blake2s state; 1113 1.1 riastrad 1114 1.1 riastrad KASSERT(outlen == WG_HASH_LEN); 1115 1.1 riastrad KASSERT(keylen <= HMAC_BLOCK_LEN); 1116 1.1 riastrad 1117 1.1 riastrad memcpy(hmackey, key, keylen); 1118 1.1 riastrad 1119 1.1 riastrad for (i = 0; i < sizeof(hmackey); i++) { 1120 1.1 riastrad ipad[i] = hmackey[i] ^ IPAD; 1121 1.1 riastrad opad[i] = hmackey[i] ^ OPAD; 1122 1.1 riastrad } 1123 1.1 riastrad 1124 1.1 riastrad blake2s_init(&state, WG_HASH_LEN, NULL, 0); 1125 1.1 riastrad blake2s_update(&state, ipad, sizeof(ipad)); 1126 1.1 riastrad blake2s_update(&state, in, inlen); 1127 1.1 riastrad blake2s_final(&state, out); 1128 1.1 riastrad 1129 1.1 riastrad blake2s_init(&state, WG_HASH_LEN, NULL, 0); 1130 1.1 riastrad blake2s_update(&state, opad, sizeof(opad)); 1131 1.1 riastrad blake2s_update(&state, out, WG_HASH_LEN); 1132 1.1 riastrad blake2s_final(&state, out); 1133 1.1 riastrad #undef IPAD 1134 1.1 riastrad #undef OPAD 1135 1.1 riastrad } 1136 1.1 riastrad 1137 1.1 riastrad static void 1138 1.114 riastrad wg_algo_kdf(uint8_t out1[static WG_KDF_OUTPUT_LEN], 1139 1.114 riastrad uint8_t out2[WG_KDF_OUTPUT_LEN], 1140 1.114 riastrad uint8_t out3[WG_KDF_OUTPUT_LEN], 1141 1.114 riastrad const uint8_t ckey[static WG_CHAINING_KEY_LEN], 1142 1.1 riastrad const uint8_t input[], const size_t inputlen) 1143 1.1 riastrad { 1144 1.1 riastrad uint8_t tmp1[WG_KDF_OUTPUT_LEN], tmp2[WG_KDF_OUTPUT_LEN + 1]; 1145 1.1 riastrad uint8_t one[1]; 1146 1.1 riastrad 1147 1.1 riastrad /* 1148 1.14 riastrad * [N] 4.3: "an input_key_material byte sequence with length 1149 1.14 riastrad * either zero bytes, 32 bytes, or DHLEN bytes." 1150 1.1 riastrad */ 1151 1.1 riastrad KASSERT(inputlen == 0 || inputlen == 32 || inputlen == NOISE_DHLEN); 1152 1.1 riastrad 1153 1.1 riastrad WG_DUMP_HASH("ckey", ckey); 1154 1.1 riastrad if (input != NULL) 1155 1.1 riastrad WG_DUMP_HASH("input", input); 1156 1.1 riastrad wg_algo_hmac(tmp1, sizeof(tmp1), ckey, WG_CHAINING_KEY_LEN, 1157 1.1 riastrad input, inputlen); 1158 1.1 riastrad WG_DUMP_HASH("tmp1", tmp1); 1159 1.1 riastrad one[0] = 1; 1160 1.1 riastrad wg_algo_hmac(out1, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 1161 1.1 riastrad one, sizeof(one)); 1162 1.1 riastrad WG_DUMP_HASH("out1", out1); 1163 1.1 riastrad if (out2 == NULL) 1164 1.1 riastrad return; 1165 1.1 riastrad memcpy(tmp2, out1, WG_KDF_OUTPUT_LEN); 1166 1.1 riastrad tmp2[WG_KDF_OUTPUT_LEN] = 2; 1167 1.1 riastrad wg_algo_hmac(out2, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 1168 1.1 riastrad tmp2, sizeof(tmp2)); 1169 1.1 riastrad WG_DUMP_HASH("out2", out2); 1170 1.1 riastrad if (out3 == NULL) 1171 1.1 riastrad return; 1172 1.1 riastrad memcpy(tmp2, out2, WG_KDF_OUTPUT_LEN); 1173 1.1 riastrad tmp2[WG_KDF_OUTPUT_LEN] = 3; 1174 1.1 riastrad wg_algo_hmac(out3, WG_KDF_OUTPUT_LEN, tmp1, sizeof(tmp1), 1175 1.1 riastrad tmp2, sizeof(tmp2)); 1176 1.1 riastrad WG_DUMP_HASH("out3", out3); 1177 1.1 riastrad } 1178 1.1 riastrad 1179 1.63 riastrad static void __noinline 1180 1.114 riastrad wg_algo_dh_kdf(uint8_t ckey[static WG_CHAINING_KEY_LEN], 1181 1.1 riastrad uint8_t cipher_key[WG_CIPHER_KEY_LEN], 1182 1.114 riastrad const uint8_t local_key[static WG_STATIC_KEY_LEN], 1183 1.114 riastrad const uint8_t remote_key[static WG_STATIC_KEY_LEN]) 1184 1.1 riastrad { 1185 1.1 riastrad uint8_t dhout[WG_DH_OUTPUT_LEN]; 1186 1.1 riastrad 1187 1.1 riastrad wg_algo_dh(dhout, local_key, remote_key); 1188 1.1 riastrad wg_algo_kdf(ckey, cipher_key, NULL, ckey, dhout, sizeof(dhout)); 1189 1.1 riastrad 1190 1.1 riastrad WG_DUMP_HASH("dhout", dhout); 1191 1.1 riastrad WG_DUMP_HASH("ckey", ckey); 1192 1.1 riastrad if (cipher_key != NULL) 1193 1.1 riastrad WG_DUMP_HASH("cipher_key", cipher_key); 1194 1.1 riastrad } 1195 1.1 riastrad 1196 1.1 riastrad static void 1197 1.114 riastrad wg_algo_aead_enc(uint8_t out[], size_t expected_outsize, 1198 1.114 riastrad const uint8_t key[static crypto_aead_chacha20poly1305_ietf_KEYBYTES], 1199 1.114 riastrad const uint64_t counter, 1200 1.114 riastrad const uint8_t plain[], const size_t plainsize, 1201 1.1 riastrad const uint8_t auth[], size_t authlen) 1202 1.1 riastrad { 1203 1.1 riastrad uint8_t nonce[(32 + 64) / 8] = {0}; 1204 1.1 riastrad long long unsigned int outsize; 1205 1.1 riastrad int error __diagused; 1206 1.1 riastrad 1207 1.39 riastrad le64enc(&nonce[4], counter); 1208 1.1 riastrad 1209 1.1 riastrad error = crypto_aead_chacha20poly1305_ietf_encrypt(out, &outsize, plain, 1210 1.1 riastrad plainsize, auth, authlen, NULL, nonce, key); 1211 1.1 riastrad KASSERT(error == 0); 1212 1.1 riastrad KASSERT(outsize == expected_outsize); 1213 1.1 riastrad } 1214 1.1 riastrad 1215 1.1 riastrad static int 1216 1.114 riastrad wg_algo_aead_dec(uint8_t out[], size_t expected_outsize, 1217 1.114 riastrad const uint8_t key[static crypto_aead_chacha20poly1305_ietf_KEYBYTES], 1218 1.114 riastrad const uint64_t counter, 1219 1.114 riastrad const uint8_t encrypted[], const size_t encryptedsize, 1220 1.114 riastrad const uint8_t auth[], size_t authlen) 1221 1.1 riastrad { 1222 1.1 riastrad uint8_t nonce[(32 + 64) / 8] = {0}; 1223 1.1 riastrad long long unsigned int outsize; 1224 1.1 riastrad int error; 1225 1.1 riastrad 1226 1.39 riastrad le64enc(&nonce[4], counter); 1227 1.1 riastrad 1228 1.1 riastrad error = crypto_aead_chacha20poly1305_ietf_decrypt(out, &outsize, NULL, 1229 1.1 riastrad encrypted, encryptedsize, auth, authlen, nonce, key); 1230 1.1 riastrad if (error == 0) 1231 1.1 riastrad KASSERT(outsize == expected_outsize); 1232 1.1 riastrad return error; 1233 1.1 riastrad } 1234 1.1 riastrad 1235 1.1 riastrad static void 1236 1.1 riastrad wg_algo_xaead_enc(uint8_t out[], const size_t expected_outsize, 1237 1.114 riastrad const uint8_t key[static crypto_aead_xchacha20poly1305_ietf_KEYBYTES], 1238 1.114 riastrad const uint8_t plain[], const size_t plainsize, 1239 1.1 riastrad const uint8_t auth[], size_t authlen, 1240 1.114 riastrad const uint8_t nonce[static WG_SALT_LEN]) 1241 1.1 riastrad { 1242 1.1 riastrad long long unsigned int outsize; 1243 1.1 riastrad int error __diagused; 1244 1.1 riastrad 1245 1.1 riastrad CTASSERT(WG_SALT_LEN == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES); 1246 1.14 riastrad error = crypto_aead_xchacha20poly1305_ietf_encrypt(out, &outsize, 1247 1.14 riastrad plain, plainsize, auth, authlen, NULL, nonce, key); 1248 1.1 riastrad KASSERT(error == 0); 1249 1.1 riastrad KASSERT(outsize == expected_outsize); 1250 1.1 riastrad } 1251 1.1 riastrad 1252 1.1 riastrad static int 1253 1.1 riastrad wg_algo_xaead_dec(uint8_t out[], const size_t expected_outsize, 1254 1.114 riastrad const uint8_t key[static crypto_aead_xchacha20poly1305_ietf_KEYBYTES], 1255 1.114 riastrad const uint8_t encrypted[], const size_t encryptedsize, 1256 1.1 riastrad const uint8_t auth[], size_t authlen, 1257 1.114 riastrad const uint8_t nonce[static WG_SALT_LEN]) 1258 1.1 riastrad { 1259 1.1 riastrad long long unsigned int outsize; 1260 1.1 riastrad int error; 1261 1.1 riastrad 1262 1.1 riastrad error = crypto_aead_xchacha20poly1305_ietf_decrypt(out, &outsize, NULL, 1263 1.1 riastrad encrypted, encryptedsize, auth, authlen, nonce, key); 1264 1.1 riastrad if (error == 0) 1265 1.1 riastrad KASSERT(outsize == expected_outsize); 1266 1.1 riastrad return error; 1267 1.1 riastrad } 1268 1.1 riastrad 1269 1.1 riastrad static void 1270 1.15 riastrad wg_algo_tai64n(wg_timestamp_t timestamp) 1271 1.1 riastrad { 1272 1.1 riastrad struct timespec ts; 1273 1.1 riastrad 1274 1.1 riastrad /* FIXME strict TAI64N (https://cr.yp.to/libtai/tai64.html) */ 1275 1.1 riastrad getnanotime(&ts); 1276 1.1 riastrad /* TAI64 label in external TAI64 format */ 1277 1.65 christos be32enc(timestamp, 0x40000000U + (uint32_t)(ts.tv_sec >> 32)); 1278 1.1 riastrad /* second beginning from 1970 TAI */ 1279 1.65 christos be32enc(timestamp + 4, (uint32_t)(ts.tv_sec & 0xffffffffU)); 1280 1.1 riastrad /* nanosecond in big-endian format */ 1281 1.65 christos be32enc(timestamp + 8, (uint32_t)ts.tv_nsec); 1282 1.1 riastrad } 1283 1.1 riastrad 1284 1.49 riastrad /* 1285 1.49 riastrad * wg_get_stable_session(wgp, psref) 1286 1.49 riastrad * 1287 1.49 riastrad * Get a passive reference to the current stable session, or 1288 1.49 riastrad * return NULL if there is no current stable session. 1289 1.49 riastrad * 1290 1.49 riastrad * The pointer is always there but the session is not necessarily 1291 1.49 riastrad * ESTABLISHED; if it is not ESTABLISHED, return NULL. However, 1292 1.49 riastrad * the session may transition from ESTABLISHED to DESTROYING while 1293 1.49 riastrad * holding the passive reference. 1294 1.49 riastrad */ 1295 1.1 riastrad static struct wg_session * 1296 1.49 riastrad wg_get_stable_session(struct wg_peer *wgp, struct psref *psref) 1297 1.1 riastrad { 1298 1.1 riastrad int s; 1299 1.1 riastrad struct wg_session *wgs; 1300 1.1 riastrad 1301 1.1 riastrad s = pserialize_read_enter(); 1302 1.49 riastrad wgs = atomic_load_consume(&wgp->wgp_session_stable); 1303 1.123 riastrad if (__predict_false(atomic_load_relaxed(&wgs->wgs_state) != 1304 1.123 riastrad WGS_STATE_ESTABLISHED)) 1305 1.49 riastrad wgs = NULL; 1306 1.49 riastrad else 1307 1.49 riastrad psref_acquire(psref, &wgs->wgs_psref, wg_psref_class); 1308 1.1 riastrad pserialize_read_exit(s); 1309 1.1 riastrad 1310 1.1 riastrad return wgs; 1311 1.1 riastrad } 1312 1.1 riastrad 1313 1.1 riastrad static void 1314 1.49 riastrad wg_put_session(struct wg_session *wgs, struct psref *psref) 1315 1.1 riastrad { 1316 1.1 riastrad 1317 1.49 riastrad psref_release(psref, &wgs->wgs_psref, wg_psref_class); 1318 1.1 riastrad } 1319 1.1 riastrad 1320 1.1 riastrad static void 1321 1.49 riastrad wg_destroy_session(struct wg_softc *wg, struct wg_session *wgs) 1322 1.1 riastrad { 1323 1.49 riastrad struct wg_peer *wgp = wgs->wgs_peer; 1324 1.49 riastrad struct wg_session *wgs0 __diagused; 1325 1.49 riastrad void *garbage; 1326 1.49 riastrad 1327 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 1328 1.49 riastrad KASSERT(wgs->wgs_state != WGS_STATE_UNKNOWN); 1329 1.1 riastrad 1330 1.49 riastrad /* Remove the session from the table. */ 1331 1.49 riastrad wgs0 = thmap_del(wg->wg_sessions_byindex, 1332 1.49 riastrad &wgs->wgs_local_index, sizeof(wgs->wgs_local_index)); 1333 1.49 riastrad KASSERT(wgs0 == wgs); 1334 1.49 riastrad garbage = thmap_stage_gc(wg->wg_sessions_byindex); 1335 1.1 riastrad 1336 1.49 riastrad /* Wait for passive references to drain. */ 1337 1.49 riastrad pserialize_perform(wgp->wgp_psz); 1338 1.49 riastrad psref_target_destroy(&wgs->wgs_psref, wg_psref_class); 1339 1.1 riastrad 1340 1.94 riastrad /* 1341 1.94 riastrad * Free memory, zero state, and transition to UNKNOWN. We have 1342 1.94 riastrad * exclusive access to the session now, so there is no need for 1343 1.94 riastrad * an atomic store. 1344 1.94 riastrad */ 1345 1.49 riastrad thmap_gc(wg->wg_sessions_byindex, garbage); 1346 1.94 riastrad WG_DLOG("session[L=%"PRIx32" R=%"PRIx32"] -> WGS_STATE_UNKNOWN\n", 1347 1.94 riastrad wgs->wgs_local_index, wgs->wgs_remote_index); 1348 1.94 riastrad wgs->wgs_local_index = 0; 1349 1.94 riastrad wgs->wgs_remote_index = 0; 1350 1.49 riastrad wg_clear_states(wgs); 1351 1.49 riastrad wgs->wgs_state = WGS_STATE_UNKNOWN; 1352 1.113 riastrad wgs->wgs_force_rekey = false; 1353 1.1 riastrad } 1354 1.1 riastrad 1355 1.49 riastrad /* 1356 1.49 riastrad * wg_get_session_index(wg, wgs) 1357 1.49 riastrad * 1358 1.49 riastrad * Choose a session index for wgs->wgs_local_index, and store it 1359 1.49 riastrad * in wg's table of sessions by index. 1360 1.49 riastrad * 1361 1.49 riastrad * wgs must be the unstable session of its peer, and must be 1362 1.49 riastrad * transitioning out of the UNKNOWN state. 1363 1.49 riastrad */ 1364 1.1 riastrad static void 1365 1.49 riastrad wg_get_session_index(struct wg_softc *wg, struct wg_session *wgs) 1366 1.1 riastrad { 1367 1.49 riastrad struct wg_peer *wgp __diagused = wgs->wgs_peer; 1368 1.37 riastrad struct wg_session *wgs0; 1369 1.37 riastrad uint32_t index; 1370 1.37 riastrad 1371 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 1372 1.49 riastrad KASSERT(wgs == wgp->wgp_session_unstable); 1373 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 1374 1.94 riastrad wgs->wgs_state); 1375 1.37 riastrad 1376 1.49 riastrad do { 1377 1.49 riastrad /* Pick a uniform random index. */ 1378 1.49 riastrad index = cprng_strong32(); 1379 1.49 riastrad 1380 1.49 riastrad /* Try to take it. */ 1381 1.49 riastrad wgs->wgs_local_index = index; 1382 1.49 riastrad wgs0 = thmap_put(wg->wg_sessions_byindex, 1383 1.49 riastrad &wgs->wgs_local_index, sizeof wgs->wgs_local_index, wgs); 1384 1.37 riastrad 1385 1.49 riastrad /* If someone else beat us, start over. */ 1386 1.49 riastrad } while (__predict_false(wgs0 != wgs)); 1387 1.49 riastrad } 1388 1.37 riastrad 1389 1.49 riastrad /* 1390 1.49 riastrad * wg_put_session_index(wg, wgs) 1391 1.49 riastrad * 1392 1.49 riastrad * Remove wgs from the table of sessions by index, wait for any 1393 1.49 riastrad * passive references to drain, and transition the session to the 1394 1.49 riastrad * UNKNOWN state. 1395 1.49 riastrad * 1396 1.49 riastrad * wgs must be the unstable session of its peer, and must not be 1397 1.49 riastrad * UNKNOWN or ESTABLISHED. 1398 1.49 riastrad */ 1399 1.49 riastrad static void 1400 1.49 riastrad wg_put_session_index(struct wg_softc *wg, struct wg_session *wgs) 1401 1.49 riastrad { 1402 1.52 riastrad struct wg_peer *wgp __diagused = wgs->wgs_peer; 1403 1.37 riastrad 1404 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 1405 1.49 riastrad KASSERT(wgs->wgs_state != WGS_STATE_UNKNOWN); 1406 1.49 riastrad KASSERT(wgs->wgs_state != WGS_STATE_ESTABLISHED); 1407 1.37 riastrad 1408 1.49 riastrad wg_destroy_session(wg, wgs); 1409 1.49 riastrad psref_target_init(&wgs->wgs_psref, wg_psref_class); 1410 1.37 riastrad } 1411 1.37 riastrad 1412 1.1 riastrad /* 1413 1.1 riastrad * Handshake patterns 1414 1.1 riastrad * 1415 1.1 riastrad * [W] 5: "These messages use the "IK" pattern from Noise" 1416 1.1 riastrad * [N] 7.5. Interactive handshake patterns (fundamental) 1417 1.1 riastrad * "The first character refers to the initiators static key:" 1418 1.1 riastrad * "I = Static key for initiator Immediately transmitted to responder, 1419 1.1 riastrad * despite reduced or absent identity hiding" 1420 1.1 riastrad * "The second character refers to the responders static key:" 1421 1.1 riastrad * "K = Static key for responder Known to initiator" 1422 1.1 riastrad * "IK: 1423 1.1 riastrad * <- s 1424 1.1 riastrad * ... 1425 1.1 riastrad * -> e, es, s, ss 1426 1.1 riastrad * <- e, ee, se" 1427 1.1 riastrad * [N] 9.4. Pattern modifiers 1428 1.1 riastrad * "IKpsk2: 1429 1.1 riastrad * <- s 1430 1.1 riastrad * ... 1431 1.1 riastrad * -> e, es, s, ss 1432 1.1 riastrad * <- e, ee, se, psk" 1433 1.1 riastrad */ 1434 1.1 riastrad static void 1435 1.1 riastrad wg_fill_msg_init(struct wg_softc *wg, struct wg_peer *wgp, 1436 1.1 riastrad struct wg_session *wgs, struct wg_msg_init *wgmi) 1437 1.1 riastrad { 1438 1.1 riastrad uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.2: Ci */ 1439 1.1 riastrad uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.2: Hi */ 1440 1.1 riastrad uint8_t cipher_key[WG_CIPHER_KEY_LEN]; 1441 1.1 riastrad uint8_t pubkey[WG_EPHEMERAL_KEY_LEN]; 1442 1.1 riastrad uint8_t privkey[WG_EPHEMERAL_KEY_LEN]; 1443 1.1 riastrad 1444 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 1445 1.49 riastrad KASSERT(wgs == wgp->wgp_session_unstable); 1446 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_INIT_ACTIVE, "state=%d", 1447 1.94 riastrad wgs->wgs_state); 1448 1.49 riastrad 1449 1.39 riastrad wgmi->wgmi_type = htole32(WG_MSG_TYPE_INIT); 1450 1.49 riastrad wgmi->wgmi_sender = wgs->wgs_local_index; 1451 1.1 riastrad 1452 1.1 riastrad /* [W] 5.4.2: First Message: Initiator to Responder */ 1453 1.1 riastrad 1454 1.1 riastrad /* Ci := HASH(CONSTRUCTION) */ 1455 1.1 riastrad /* Hi := HASH(Ci || IDENTIFIER) */ 1456 1.1 riastrad wg_init_key_and_hash(ckey, hash); 1457 1.1 riastrad /* Hi := HASH(Hi || Sr^pub) */ 1458 1.1 riastrad wg_algo_hash(hash, wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey)); 1459 1.1 riastrad 1460 1.1 riastrad WG_DUMP_HASH("hash", hash); 1461 1.1 riastrad 1462 1.1 riastrad /* [N] 2.2: "e" */ 1463 1.1 riastrad /* Ei^priv, Ei^pub := DH-GENERATE() */ 1464 1.1 riastrad wg_algo_generate_keypair(pubkey, privkey); 1465 1.1 riastrad /* Ci := KDF1(Ci, Ei^pub) */ 1466 1.1 riastrad wg_algo_kdf(ckey, NULL, NULL, ckey, pubkey, sizeof(pubkey)); 1467 1.1 riastrad /* msg.ephemeral := Ei^pub */ 1468 1.1 riastrad memcpy(wgmi->wgmi_ephemeral, pubkey, sizeof(wgmi->wgmi_ephemeral)); 1469 1.1 riastrad /* Hi := HASH(Hi || msg.ephemeral) */ 1470 1.1 riastrad wg_algo_hash(hash, pubkey, sizeof(pubkey)); 1471 1.1 riastrad 1472 1.1 riastrad WG_DUMP_HASH("ckey", ckey); 1473 1.1 riastrad WG_DUMP_HASH("hash", hash); 1474 1.1 riastrad 1475 1.1 riastrad /* [N] 2.2: "es" */ 1476 1.1 riastrad /* Ci, k := KDF2(Ci, DH(Ei^priv, Sr^pub)) */ 1477 1.1 riastrad wg_algo_dh_kdf(ckey, cipher_key, privkey, wgp->wgp_pubkey); 1478 1.1 riastrad 1479 1.1 riastrad /* [N] 2.2: "s" */ 1480 1.1 riastrad /* msg.static := AEAD(k, 0, Si^pub, Hi) */ 1481 1.1 riastrad wg_algo_aead_enc(wgmi->wgmi_static, sizeof(wgmi->wgmi_static), 1482 1.1 riastrad cipher_key, 0, wg->wg_pubkey, sizeof(wg->wg_pubkey), 1483 1.1 riastrad hash, sizeof(hash)); 1484 1.1 riastrad /* Hi := HASH(Hi || msg.static) */ 1485 1.1 riastrad wg_algo_hash(hash, wgmi->wgmi_static, sizeof(wgmi->wgmi_static)); 1486 1.1 riastrad 1487 1.1 riastrad WG_DUMP_HASH48("wgmi_static", wgmi->wgmi_static); 1488 1.1 riastrad 1489 1.1 riastrad /* [N] 2.2: "ss" */ 1490 1.1 riastrad /* Ci, k := KDF2(Ci, DH(Si^priv, Sr^pub)) */ 1491 1.1 riastrad wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey); 1492 1.1 riastrad 1493 1.1 riastrad /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */ 1494 1.1 riastrad wg_timestamp_t timestamp; 1495 1.1 riastrad wg_algo_tai64n(timestamp); 1496 1.1 riastrad wg_algo_aead_enc(wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp), 1497 1.1 riastrad cipher_key, 0, timestamp, sizeof(timestamp), hash, sizeof(hash)); 1498 1.1 riastrad /* Hi := HASH(Hi || msg.timestamp) */ 1499 1.1 riastrad wg_algo_hash(hash, wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp)); 1500 1.1 riastrad 1501 1.1 riastrad /* [W] 5.4.4 Cookie MACs */ 1502 1.1 riastrad wg_algo_mac_mac1(wgmi->wgmi_mac1, sizeof(wgmi->wgmi_mac1), 1503 1.1 riastrad wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey), 1504 1.17 riastrad (const uint8_t *)wgmi, offsetof(struct wg_msg_init, wgmi_mac1)); 1505 1.1 riastrad /* Need mac1 to decrypt a cookie from a cookie message */ 1506 1.1 riastrad memcpy(wgp->wgp_last_sent_mac1, wgmi->wgmi_mac1, 1507 1.1 riastrad sizeof(wgp->wgp_last_sent_mac1)); 1508 1.1 riastrad wgp->wgp_last_sent_mac1_valid = true; 1509 1.1 riastrad 1510 1.1 riastrad if (wgp->wgp_latest_cookie_time == 0 || 1511 1.1 riastrad (time_uptime - wgp->wgp_latest_cookie_time) >= WG_COOKIE_TIME) 1512 1.1 riastrad memset(wgmi->wgmi_mac2, 0, sizeof(wgmi->wgmi_mac2)); 1513 1.1 riastrad else { 1514 1.1 riastrad wg_algo_mac(wgmi->wgmi_mac2, sizeof(wgmi->wgmi_mac2), 1515 1.1 riastrad wgp->wgp_latest_cookie, WG_COOKIE_LEN, 1516 1.17 riastrad (const uint8_t *)wgmi, 1517 1.17 riastrad offsetof(struct wg_msg_init, wgmi_mac2), 1518 1.1 riastrad NULL, 0); 1519 1.1 riastrad } 1520 1.1 riastrad 1521 1.1 riastrad memcpy(wgs->wgs_ephemeral_key_pub, pubkey, sizeof(pubkey)); 1522 1.1 riastrad memcpy(wgs->wgs_ephemeral_key_priv, privkey, sizeof(privkey)); 1523 1.1 riastrad memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash)); 1524 1.1 riastrad memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey)); 1525 1.49 riastrad WG_DLOG("%s: sender=%x\n", __func__, wgs->wgs_local_index); 1526 1.1 riastrad } 1527 1.1 riastrad 1528 1.130 riastrad /* 1529 1.130 riastrad * wg_initiator_priority(wg, wgp) 1530 1.130 riastrad * 1531 1.130 riastrad * Return true if we claim priority over peer wgp as initiator at 1532 1.130 riastrad * the moment, false if not. That is, if we and our peer are 1533 1.130 riastrad * trying to initiate a session, do we ignore the peer's attempt 1534 1.130 riastrad * and barge ahead with ours, or discard our attempt and accept 1535 1.130 riastrad * the peer's? 1536 1.130 riastrad * 1537 1.130 riastrad * We jointly flip a coin by computing 1538 1.130 riastrad * 1539 1.130 riastrad * H(pubkey A) ^ H(pubkey B) ^ H(posix minutes as le64), 1540 1.130 riastrad * 1541 1.130 riastrad * and taking the low-order bit. If our public key hash, as a 1542 1.130 riastrad * 256-bit integer in little-endian, is less than the peer's 1543 1.130 riastrad * public key hash, also as a 256-bit integer in little-endian, we 1544 1.130 riastrad * claim priority iff the bit is 0; otherwise we claim priority 1545 1.130 riastrad * iff the bit is 1. 1546 1.130 riastrad * 1547 1.130 riastrad * This way, it is essentially arbitrary who claims priority, and 1548 1.130 riastrad * it may change (by a coin toss) minute to minute, but both 1549 1.130 riastrad * parties agree at any given moment -- except possibly at the 1550 1.130 riastrad * boundary of a minute -- who will take priority. 1551 1.130 riastrad * 1552 1.130 riastrad * This is an extension to the WireGuard protocol -- as far as I 1553 1.130 riastrad * can tell, the protocol whitepaper has no resolution to this 1554 1.130 riastrad * deadlock scenario. According to the author, `the deadlock 1555 1.130 riastrad * doesn't happen because of some additional state machine logic, 1556 1.130 riastrad * and on very small chances that it does, it quickly undoes 1557 1.130 riastrad * itself.', but this additional state machine logic does not 1558 1.130 riastrad * appear to be anywhere in the whitepaper, and I don't see how it 1559 1.130 riastrad * can undo itself until both sides have given up and one side is 1560 1.130 riastrad * quicker to initiate the next time around. 1561 1.130 riastrad * 1562 1.130 riastrad * XXX It might be prudent to put a prefix in the hash input, so 1563 1.130 riastrad * we avoid accidentally colliding with any other uses of the same 1564 1.130 riastrad * hash on the same input. But it's best if any changes are 1565 1.130 riastrad * coordinated, so that peers generally agree on what coin is 1566 1.130 riastrad * being tossed, instead of tossing their own independent coins 1567 1.130 riastrad * (which will also converge to working but more slowly over more 1568 1.130 riastrad * handshake retries). 1569 1.130 riastrad */ 1570 1.130 riastrad static bool 1571 1.130 riastrad wg_initiator_priority(struct wg_softc *wg, struct wg_peer *wgp) 1572 1.130 riastrad { 1573 1.130 riastrad const uint64_t now = time_second/60, now_le = htole64(now); 1574 1.130 riastrad uint8_t h_min; 1575 1.130 riastrad uint8_t h_local[BLAKE2S_MAX_DIGEST]; 1576 1.130 riastrad uint8_t h_peer[BLAKE2S_MAX_DIGEST]; 1577 1.130 riastrad int borrow; 1578 1.130 riastrad unsigned i; 1579 1.130 riastrad 1580 1.130 riastrad blake2s(&h_min, 1, NULL, 0, &now_le, sizeof(now_le)); 1581 1.130 riastrad blake2s(h_local, sizeof(h_local), NULL, 0, 1582 1.130 riastrad wg->wg_pubkey, sizeof(wg->wg_pubkey)); 1583 1.130 riastrad blake2s(h_peer, sizeof(h_peer), NULL, 0, 1584 1.130 riastrad wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey)); 1585 1.130 riastrad 1586 1.130 riastrad for (borrow = 0, i = 0; i < BLAKE2S_MAX_DIGEST; i++) 1587 1.130 riastrad borrow = (h_local[i] - h_peer[i] + borrow) >> 8; 1588 1.130 riastrad 1589 1.130 riastrad return 1 & (h_local[0] ^ h_peer[0] ^ h_min ^ borrow); 1590 1.130 riastrad } 1591 1.130 riastrad 1592 1.63 riastrad static void __noinline 1593 1.1 riastrad wg_handle_msg_init(struct wg_softc *wg, const struct wg_msg_init *wgmi, 1594 1.1 riastrad const struct sockaddr *src) 1595 1.1 riastrad { 1596 1.1 riastrad uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.2: Ci */ 1597 1.1 riastrad uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.2: Hi */ 1598 1.1 riastrad uint8_t cipher_key[WG_CIPHER_KEY_LEN]; 1599 1.1 riastrad uint8_t peer_pubkey[WG_STATIC_KEY_LEN]; 1600 1.1 riastrad struct wg_peer *wgp; 1601 1.1 riastrad struct wg_session *wgs; 1602 1.1 riastrad int error, ret; 1603 1.1 riastrad struct psref psref_peer; 1604 1.1 riastrad uint8_t mac1[WG_MAC_LEN]; 1605 1.1 riastrad 1606 1.1 riastrad WG_TRACE("init msg received"); 1607 1.1 riastrad 1608 1.44 riastrad wg_algo_mac_mac1(mac1, sizeof(mac1), 1609 1.44 riastrad wg->wg_pubkey, sizeof(wg->wg_pubkey), 1610 1.44 riastrad (const uint8_t *)wgmi, offsetof(struct wg_msg_init, wgmi_mac1)); 1611 1.44 riastrad 1612 1.44 riastrad /* 1613 1.44 riastrad * [W] 5.3: Denial of Service Mitigation & Cookies 1614 1.44 riastrad * "the responder, ..., must always reject messages with an invalid 1615 1.44 riastrad * msg.mac1" 1616 1.44 riastrad */ 1617 1.44 riastrad if (!consttime_memequal(mac1, wgmi->wgmi_mac1, sizeof(mac1))) { 1618 1.44 riastrad WG_DLOG("mac1 is invalid\n"); 1619 1.44 riastrad return; 1620 1.44 riastrad } 1621 1.44 riastrad 1622 1.1 riastrad /* 1623 1.1 riastrad * [W] 5.4.2: First Message: Initiator to Responder 1624 1.1 riastrad * "When the responder receives this message, it does the same 1625 1.1 riastrad * operations so that its final state variables are identical, 1626 1.1 riastrad * replacing the operands of the DH function to produce equivalent 1627 1.1 riastrad * values." 1628 1.1 riastrad * Note that the following comments of operations are just copies of 1629 1.1 riastrad * the initiator's ones. 1630 1.1 riastrad */ 1631 1.1 riastrad 1632 1.1 riastrad /* Ci := HASH(CONSTRUCTION) */ 1633 1.1 riastrad /* Hi := HASH(Ci || IDENTIFIER) */ 1634 1.1 riastrad wg_init_key_and_hash(ckey, hash); 1635 1.1 riastrad /* Hi := HASH(Hi || Sr^pub) */ 1636 1.1 riastrad wg_algo_hash(hash, wg->wg_pubkey, sizeof(wg->wg_pubkey)); 1637 1.1 riastrad 1638 1.1 riastrad /* [N] 2.2: "e" */ 1639 1.1 riastrad /* Ci := KDF1(Ci, Ei^pub) */ 1640 1.1 riastrad wg_algo_kdf(ckey, NULL, NULL, ckey, wgmi->wgmi_ephemeral, 1641 1.1 riastrad sizeof(wgmi->wgmi_ephemeral)); 1642 1.1 riastrad /* Hi := HASH(Hi || msg.ephemeral) */ 1643 1.1 riastrad wg_algo_hash(hash, wgmi->wgmi_ephemeral, sizeof(wgmi->wgmi_ephemeral)); 1644 1.1 riastrad 1645 1.1 riastrad WG_DUMP_HASH("ckey", ckey); 1646 1.1 riastrad 1647 1.1 riastrad /* [N] 2.2: "es" */ 1648 1.1 riastrad /* Ci, k := KDF2(Ci, DH(Ei^priv, Sr^pub)) */ 1649 1.1 riastrad wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgmi->wgmi_ephemeral); 1650 1.1 riastrad 1651 1.1 riastrad WG_DUMP_HASH48("wgmi_static", wgmi->wgmi_static); 1652 1.1 riastrad 1653 1.1 riastrad /* [N] 2.2: "s" */ 1654 1.1 riastrad /* msg.static := AEAD(k, 0, Si^pub, Hi) */ 1655 1.1 riastrad error = wg_algo_aead_dec(peer_pubkey, WG_STATIC_KEY_LEN, cipher_key, 0, 1656 1.1 riastrad wgmi->wgmi_static, sizeof(wgmi->wgmi_static), hash, sizeof(hash)); 1657 1.1 riastrad if (error != 0) { 1658 1.1 riastrad WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG, 1659 1.76 jakllsch "%s: wg_algo_aead_dec for secret key failed\n", 1660 1.76 jakllsch if_name(&wg->wg_if)); 1661 1.1 riastrad return; 1662 1.1 riastrad } 1663 1.1 riastrad /* Hi := HASH(Hi || msg.static) */ 1664 1.1 riastrad wg_algo_hash(hash, wgmi->wgmi_static, sizeof(wgmi->wgmi_static)); 1665 1.1 riastrad 1666 1.1 riastrad wgp = wg_lookup_peer_by_pubkey(wg, peer_pubkey, &psref_peer); 1667 1.1 riastrad if (wgp == NULL) { 1668 1.1 riastrad WG_DLOG("peer not found\n"); 1669 1.1 riastrad return; 1670 1.1 riastrad } 1671 1.1 riastrad 1672 1.49 riastrad /* 1673 1.49 riastrad * Lock the peer to serialize access to cookie state. 1674 1.49 riastrad * 1675 1.49 riastrad * XXX Can we safely avoid holding the lock across DH? Take it 1676 1.49 riastrad * just to verify mac2 and then unlock/DH/lock? 1677 1.49 riastrad */ 1678 1.49 riastrad mutex_enter(wgp->wgp_lock); 1679 1.49 riastrad 1680 1.1 riastrad if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_INIT))) { 1681 1.1 riastrad WG_TRACE("under load"); 1682 1.1 riastrad /* 1683 1.1 riastrad * [W] 5.3: Denial of Service Mitigation & Cookies 1684 1.1 riastrad * "the responder, ..., and when under load may reject messages 1685 1.1 riastrad * with an invalid msg.mac2. If the responder receives a 1686 1.1 riastrad * message with a valid msg.mac1 yet with an invalid msg.mac2, 1687 1.1 riastrad * and is under load, it may respond with a cookie reply 1688 1.1 riastrad * message" 1689 1.1 riastrad */ 1690 1.1 riastrad uint8_t zero[WG_MAC_LEN] = {0}; 1691 1.13 riastrad if (consttime_memequal(wgmi->wgmi_mac2, zero, sizeof(zero))) { 1692 1.1 riastrad WG_TRACE("sending a cookie message: no cookie included"); 1693 1.108 riastrad wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender, 1694 1.1 riastrad wgmi->wgmi_mac1, src); 1695 1.49 riastrad goto out; 1696 1.1 riastrad } 1697 1.1 riastrad if (!wgp->wgp_last_sent_cookie_valid) { 1698 1.1 riastrad WG_TRACE("sending a cookie message: no cookie sent ever"); 1699 1.108 riastrad wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender, 1700 1.1 riastrad wgmi->wgmi_mac1, src); 1701 1.49 riastrad goto out; 1702 1.1 riastrad } 1703 1.1 riastrad uint8_t mac2[WG_MAC_LEN]; 1704 1.1 riastrad wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie, 1705 1.1 riastrad WG_COOKIE_LEN, (const uint8_t *)wgmi, 1706 1.1 riastrad offsetof(struct wg_msg_init, wgmi_mac2), NULL, 0); 1707 1.13 riastrad if (!consttime_memequal(mac2, wgmi->wgmi_mac2, sizeof(mac2))) { 1708 1.1 riastrad WG_DLOG("mac2 is invalid\n"); 1709 1.49 riastrad goto out; 1710 1.1 riastrad } 1711 1.1 riastrad WG_TRACE("under load, but continue to sending"); 1712 1.1 riastrad } 1713 1.1 riastrad 1714 1.46 riastrad /* [N] 2.2: "ss" */ 1715 1.46 riastrad /* Ci, k := KDF2(Ci, DH(Si^priv, Sr^pub)) */ 1716 1.46 riastrad wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey); 1717 1.46 riastrad 1718 1.46 riastrad /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */ 1719 1.46 riastrad wg_timestamp_t timestamp; 1720 1.46 riastrad error = wg_algo_aead_dec(timestamp, sizeof(timestamp), cipher_key, 0, 1721 1.46 riastrad wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp), 1722 1.46 riastrad hash, sizeof(hash)); 1723 1.46 riastrad if (error != 0) { 1724 1.46 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 1725 1.76 jakllsch "%s: peer %s: wg_algo_aead_dec for timestamp failed\n", 1726 1.76 jakllsch if_name(&wg->wg_if), wgp->wgp_name); 1727 1.49 riastrad goto out; 1728 1.46 riastrad } 1729 1.46 riastrad /* Hi := HASH(Hi || msg.timestamp) */ 1730 1.46 riastrad wg_algo_hash(hash, wgmi->wgmi_timestamp, sizeof(wgmi->wgmi_timestamp)); 1731 1.46 riastrad 1732 1.1 riastrad /* 1733 1.14 riastrad * [W] 5.1 "The responder keeps track of the greatest timestamp 1734 1.14 riastrad * received per peer and discards packets containing 1735 1.14 riastrad * timestamps less than or equal to it." 1736 1.1 riastrad */ 1737 1.1 riastrad ret = memcmp(timestamp, wgp->wgp_timestamp_latest_init, 1738 1.1 riastrad sizeof(timestamp)); 1739 1.1 riastrad if (ret <= 0) { 1740 1.1 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 1741 1.76 jakllsch "%s: peer %s: invalid init msg: timestamp is old\n", 1742 1.76 jakllsch if_name(&wg->wg_if), wgp->wgp_name); 1743 1.1 riastrad goto out; 1744 1.1 riastrad } 1745 1.1 riastrad memcpy(wgp->wgp_timestamp_latest_init, timestamp, sizeof(timestamp)); 1746 1.1 riastrad 1747 1.49 riastrad /* 1748 1.49 riastrad * Message is good -- we're committing to handle it now, unless 1749 1.49 riastrad * we were already initiating a session. 1750 1.49 riastrad */ 1751 1.49 riastrad wgs = wgp->wgp_session_unstable; 1752 1.49 riastrad switch (wgs->wgs_state) { 1753 1.49 riastrad case WGS_STATE_UNKNOWN: /* new session initiated by peer */ 1754 1.49 riastrad break; 1755 1.130 riastrad case WGS_STATE_INIT_ACTIVE: /* we're already initiating */ 1756 1.130 riastrad if (wg_initiator_priority(wg, wgp)) { 1757 1.130 riastrad WG_TRACE("Session already initializing," 1758 1.130 riastrad " ignoring the message"); 1759 1.130 riastrad goto out; 1760 1.130 riastrad } 1761 1.130 riastrad WG_TRACE("Yielding session initiation to peer"); 1762 1.130 riastrad wg_put_session_index(wg, wgs); 1763 1.130 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 1764 1.130 riastrad wgs->wgs_state); 1765 1.130 riastrad break; 1766 1.49 riastrad case WGS_STATE_INIT_PASSIVE: /* peer is retrying, start over */ 1767 1.49 riastrad WG_TRACE("Session already initializing, destroying old states"); 1768 1.94 riastrad /* 1769 1.94 riastrad * XXX Avoid this -- just resend our response -- if the 1770 1.94 riastrad * INIT message is identical to the previous one. 1771 1.94 riastrad */ 1772 1.94 riastrad wg_put_session_index(wg, wgs); 1773 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 1774 1.94 riastrad wgs->wgs_state); 1775 1.49 riastrad break; 1776 1.49 riastrad case WGS_STATE_ESTABLISHED: /* can't happen */ 1777 1.49 riastrad panic("unstable session can't be established"); 1778 1.49 riastrad case WGS_STATE_DESTROYING: /* rekey initiated by peer */ 1779 1.49 riastrad WG_TRACE("Session destroying, but force to clear"); 1780 1.94 riastrad wg_put_session_index(wg, wgs); 1781 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 1782 1.94 riastrad wgs->wgs_state); 1783 1.49 riastrad break; 1784 1.49 riastrad default: 1785 1.49 riastrad panic("invalid session state: %d", wgs->wgs_state); 1786 1.49 riastrad } 1787 1.94 riastrad 1788 1.94 riastrad /* 1789 1.94 riastrad * Assign a fresh session index. 1790 1.94 riastrad */ 1791 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 1792 1.94 riastrad wgs->wgs_state); 1793 1.94 riastrad wg_get_session_index(wg, wgs); 1794 1.49 riastrad 1795 1.1 riastrad memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash)); 1796 1.1 riastrad memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey)); 1797 1.1 riastrad memcpy(wgs->wgs_ephemeral_key_peer, wgmi->wgmi_ephemeral, 1798 1.1 riastrad sizeof(wgmi->wgmi_ephemeral)); 1799 1.1 riastrad 1800 1.122 riastrad /* 1801 1.122 riastrad * The packet is genuine. Update the peer's endpoint if the 1802 1.122 riastrad * source address changed. 1803 1.122 riastrad * 1804 1.122 riastrad * XXX How to prevent DoS by replaying genuine packets from the 1805 1.122 riastrad * wrong source address? 1806 1.122 riastrad */ 1807 1.1 riastrad wg_update_endpoint_if_necessary(wgp, src); 1808 1.1 riastrad 1809 1.94 riastrad /* 1810 1.117 riastrad * Even though we don't transition from INIT_PASSIVE to 1811 1.117 riastrad * ESTABLISHED until we receive the first data packet from the 1812 1.117 riastrad * initiator, we count the time of the INIT message as the time 1813 1.117 riastrad * of establishment -- this is used to decide when to erase 1814 1.117 riastrad * keys, and we want to start counting as soon as we have 1815 1.117 riastrad * generated keys. 1816 1.100 riastrad */ 1817 1.104 riastrad wgs->wgs_time_established = time_uptime32; 1818 1.100 riastrad wg_schedule_session_dtor_timer(wgp); 1819 1.100 riastrad 1820 1.100 riastrad /* 1821 1.94 riastrad * Respond to the initiator with our ephemeral public key. 1822 1.94 riastrad */ 1823 1.108 riastrad wg_send_handshake_msg_resp(wg, wgp, wgs, wgmi); 1824 1.1 riastrad 1825 1.94 riastrad WG_DLOG("session[L=%"PRIx32" R=%"PRIx32"]:" 1826 1.94 riastrad " calculate keys as responder\n", 1827 1.94 riastrad wgs->wgs_local_index, wgs->wgs_remote_index); 1828 1.1 riastrad wg_calculate_keys(wgs, false); 1829 1.1 riastrad wg_clear_states(wgs); 1830 1.1 riastrad 1831 1.94 riastrad /* 1832 1.94 riastrad * Session is ready to receive data now that we have received 1833 1.94 riastrad * the peer initiator's ephemeral key pair, generated our 1834 1.94 riastrad * responder's ephemeral key pair, and derived a session key. 1835 1.94 riastrad * 1836 1.94 riastrad * Transition from UNKNOWN to INIT_PASSIVE to publish it to the 1837 1.94 riastrad * data rx path, wg_handle_msg_data, where the 1838 1.94 riastrad * atomic_load_acquire matching this atomic_store_release 1839 1.94 riastrad * happens. 1840 1.94 riastrad * 1841 1.94 riastrad * (Session is not, however, ready to send data until the peer 1842 1.94 riastrad * has acknowledged our response by sending its first data 1843 1.94 riastrad * packet. So don't swap the sessions yet.) 1844 1.94 riastrad */ 1845 1.94 riastrad WG_DLOG("session[L=%"PRIx32" R=%"PRIx32"] -> WGS_STATE_INIT_PASSIVE\n", 1846 1.94 riastrad wgs->wgs_local_index, wgs->wgs_remote_index); 1847 1.94 riastrad atomic_store_release(&wgs->wgs_state, WGS_STATE_INIT_PASSIVE); 1848 1.94 riastrad WG_TRACE("WGS_STATE_INIT_PASSIVE"); 1849 1.94 riastrad 1850 1.1 riastrad out: 1851 1.49 riastrad mutex_exit(wgp->wgp_lock); 1852 1.1 riastrad wg_put_peer(wgp, &psref_peer); 1853 1.1 riastrad } 1854 1.1 riastrad 1855 1.1 riastrad static struct socket * 1856 1.55 riastrad wg_get_so_by_af(struct wg_softc *wg, const int af) 1857 1.1 riastrad { 1858 1.1 riastrad 1859 1.62 riastrad switch (af) { 1860 1.62 riastrad #ifdef INET 1861 1.62 riastrad case AF_INET: 1862 1.62 riastrad return wg->wg_so4; 1863 1.62 riastrad #endif 1864 1.62 riastrad #ifdef INET6 1865 1.62 riastrad case AF_INET6: 1866 1.62 riastrad return wg->wg_so6; 1867 1.62 riastrad #endif 1868 1.62 riastrad default: 1869 1.62 riastrad panic("wg: no such af: %d", af); 1870 1.62 riastrad } 1871 1.1 riastrad } 1872 1.1 riastrad 1873 1.1 riastrad static struct socket * 1874 1.47 riastrad wg_get_so_by_peer(struct wg_peer *wgp, struct wg_sockaddr *wgsa) 1875 1.1 riastrad { 1876 1.1 riastrad 1877 1.55 riastrad return wg_get_so_by_af(wgp->wgp_sc, wgsa_family(wgsa)); 1878 1.1 riastrad } 1879 1.1 riastrad 1880 1.1 riastrad static struct wg_sockaddr * 1881 1.1 riastrad wg_get_endpoint_sa(struct wg_peer *wgp, struct psref *psref) 1882 1.1 riastrad { 1883 1.1 riastrad struct wg_sockaddr *wgsa; 1884 1.1 riastrad int s; 1885 1.1 riastrad 1886 1.1 riastrad s = pserialize_read_enter(); 1887 1.47 riastrad wgsa = atomic_load_consume(&wgp->wgp_endpoint); 1888 1.1 riastrad psref_acquire(psref, &wgsa->wgsa_psref, wg_psref_class); 1889 1.1 riastrad pserialize_read_exit(s); 1890 1.1 riastrad 1891 1.1 riastrad return wgsa; 1892 1.1 riastrad } 1893 1.1 riastrad 1894 1.1 riastrad static void 1895 1.1 riastrad wg_put_sa(struct wg_peer *wgp, struct wg_sockaddr *wgsa, struct psref *psref) 1896 1.1 riastrad { 1897 1.1 riastrad 1898 1.1 riastrad psref_release(psref, &wgsa->wgsa_psref, wg_psref_class); 1899 1.1 riastrad } 1900 1.1 riastrad 1901 1.1 riastrad static int 1902 1.134 riastrad wg_send_hs(struct wg_peer *wgp, struct mbuf *m) 1903 1.1 riastrad { 1904 1.1 riastrad int error; 1905 1.1 riastrad struct socket *so; 1906 1.1 riastrad struct psref psref; 1907 1.1 riastrad struct wg_sockaddr *wgsa; 1908 1.1 riastrad 1909 1.1 riastrad wgsa = wg_get_endpoint_sa(wgp, &psref); 1910 1.134 riastrad #ifdef WG_DEBUG_LOG 1911 1.134 riastrad char addr[128]; 1912 1.134 riastrad sockaddr_format(wgsatosa(wgsa), addr, sizeof(addr)); 1913 1.134 riastrad WG_DLOG("send handshake msg to %s\n", addr); 1914 1.134 riastrad #endif 1915 1.47 riastrad so = wg_get_so_by_peer(wgp, wgsa); 1916 1.1 riastrad error = sosend(so, wgsatosa(wgsa), NULL, m, NULL, 0, curlwp); 1917 1.1 riastrad wg_put_sa(wgp, wgsa, &psref); 1918 1.1 riastrad 1919 1.1 riastrad return error; 1920 1.1 riastrad } 1921 1.1 riastrad 1922 1.108 riastrad static void 1923 1.1 riastrad wg_send_handshake_msg_init(struct wg_softc *wg, struct wg_peer *wgp) 1924 1.1 riastrad { 1925 1.1 riastrad int error; 1926 1.1 riastrad struct mbuf *m; 1927 1.1 riastrad struct wg_msg_init *wgmi; 1928 1.1 riastrad struct wg_session *wgs; 1929 1.1 riastrad 1930 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 1931 1.49 riastrad 1932 1.49 riastrad wgs = wgp->wgp_session_unstable; 1933 1.49 riastrad /* XXX pull dispatch out into wg_task_send_init_message */ 1934 1.49 riastrad switch (wgs->wgs_state) { 1935 1.49 riastrad case WGS_STATE_UNKNOWN: /* new session initiated by us */ 1936 1.49 riastrad break; 1937 1.49 riastrad case WGS_STATE_INIT_ACTIVE: /* we're already initiating, stop */ 1938 1.49 riastrad WG_TRACE("Session already initializing, skip starting new one"); 1939 1.108 riastrad return; 1940 1.49 riastrad case WGS_STATE_INIT_PASSIVE: /* peer was trying -- XXX what now? */ 1941 1.94 riastrad WG_TRACE("Session already initializing, waiting for peer"); 1942 1.108 riastrad return; 1943 1.49 riastrad case WGS_STATE_ESTABLISHED: /* can't happen */ 1944 1.49 riastrad panic("unstable session can't be established"); 1945 1.49 riastrad case WGS_STATE_DESTROYING: /* rekey initiated by us too early */ 1946 1.1 riastrad WG_TRACE("Session destroying"); 1947 1.94 riastrad wg_put_session_index(wg, wgs); 1948 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 1949 1.94 riastrad wgs->wgs_state); 1950 1.94 riastrad break; 1951 1.1 riastrad } 1952 1.94 riastrad 1953 1.94 riastrad /* 1954 1.94 riastrad * Assign a fresh session index. 1955 1.94 riastrad */ 1956 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 1957 1.94 riastrad wgs->wgs_state); 1958 1.94 riastrad wg_get_session_index(wg, wgs); 1959 1.94 riastrad 1960 1.94 riastrad /* 1961 1.94 riastrad * We have initiated a session. Transition to INIT_ACTIVE. 1962 1.94 riastrad * This doesn't publish it for use in the data rx path, 1963 1.94 riastrad * wg_handle_msg_data, or in the data tx path, wg_output -- we 1964 1.94 riastrad * have to wait for the peer to respond with their ephemeral 1965 1.94 riastrad * public key before we can derive a session key for tx/rx. 1966 1.94 riastrad * Hence only atomic_store_relaxed. 1967 1.94 riastrad */ 1968 1.94 riastrad WG_DLOG("session[L=%"PRIx32" R=(unknown)] -> WGS_STATE_INIT_ACTIVE\n", 1969 1.94 riastrad wgs->wgs_local_index); 1970 1.94 riastrad atomic_store_relaxed(&wgs->wgs_state, WGS_STATE_INIT_ACTIVE); 1971 1.1 riastrad 1972 1.1 riastrad m = m_gethdr(M_WAIT, MT_DATA); 1973 1.69 hannken if (sizeof(*wgmi) > MHLEN) { 1974 1.69 hannken m_clget(m, M_WAIT); 1975 1.69 hannken CTASSERT(sizeof(*wgmi) <= MCLBYTES); 1976 1.69 hannken } 1977 1.1 riastrad m->m_pkthdr.len = m->m_len = sizeof(*wgmi); 1978 1.1 riastrad wgmi = mtod(m, struct wg_msg_init *); 1979 1.1 riastrad wg_fill_msg_init(wg, wgp, wgs, wgmi); 1980 1.1 riastrad 1981 1.108 riastrad error = wg->wg_ops->send_hs_msg(wgp, m); /* consumes m */ 1982 1.108 riastrad if (error) { 1983 1.108 riastrad /* 1984 1.108 riastrad * Sending out an initiation packet failed; give up on 1985 1.108 riastrad * this session and toss packet waiting for it if any. 1986 1.108 riastrad * 1987 1.108 riastrad * XXX Why don't we just let the periodic handshake 1988 1.108 riastrad * retry logic work in this case? 1989 1.108 riastrad */ 1990 1.108 riastrad WG_DLOG("send_hs_msg failed, error=%d\n", error); 1991 1.49 riastrad wg_put_session_index(wg, wgs); 1992 1.79 rin m = atomic_swap_ptr(&wgp->wgp_pending, NULL); 1993 1.126 riastrad membar_acquire(); /* matches membar_release in wgintr */ 1994 1.79 rin m_freem(m); 1995 1.108 riastrad return; 1996 1.1 riastrad } 1997 1.1 riastrad 1998 1.108 riastrad WG_TRACE("init msg sent"); 1999 1.108 riastrad if (wgp->wgp_handshake_start_time == 0) 2000 1.108 riastrad wgp->wgp_handshake_start_time = time_uptime; 2001 1.108 riastrad callout_schedule(&wgp->wgp_handshake_timeout_timer, 2002 1.108 riastrad MIN(wg_rekey_timeout, (unsigned)(INT_MAX / hz)) * hz); 2003 1.1 riastrad } 2004 1.1 riastrad 2005 1.1 riastrad static void 2006 1.1 riastrad wg_fill_msg_resp(struct wg_softc *wg, struct wg_peer *wgp, 2007 1.49 riastrad struct wg_session *wgs, struct wg_msg_resp *wgmr, 2008 1.49 riastrad const struct wg_msg_init *wgmi) 2009 1.1 riastrad { 2010 1.1 riastrad uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */ 2011 1.1 riastrad uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Hr */ 2012 1.1 riastrad uint8_t cipher_key[WG_KDF_OUTPUT_LEN]; 2013 1.1 riastrad uint8_t pubkey[WG_EPHEMERAL_KEY_LEN]; 2014 1.1 riastrad uint8_t privkey[WG_EPHEMERAL_KEY_LEN]; 2015 1.1 riastrad 2016 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 2017 1.49 riastrad KASSERT(wgs == wgp->wgp_session_unstable); 2018 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 2019 1.94 riastrad wgs->wgs_state); 2020 1.49 riastrad 2021 1.1 riastrad memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash)); 2022 1.1 riastrad memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey)); 2023 1.1 riastrad 2024 1.39 riastrad wgmr->wgmr_type = htole32(WG_MSG_TYPE_RESP); 2025 1.49 riastrad wgmr->wgmr_sender = wgs->wgs_local_index; 2026 1.1 riastrad wgmr->wgmr_receiver = wgmi->wgmi_sender; 2027 1.1 riastrad 2028 1.1 riastrad /* [W] 5.4.3 Second Message: Responder to Initiator */ 2029 1.1 riastrad 2030 1.1 riastrad /* [N] 2.2: "e" */ 2031 1.1 riastrad /* Er^priv, Er^pub := DH-GENERATE() */ 2032 1.1 riastrad wg_algo_generate_keypair(pubkey, privkey); 2033 1.1 riastrad /* Cr := KDF1(Cr, Er^pub) */ 2034 1.1 riastrad wg_algo_kdf(ckey, NULL, NULL, ckey, pubkey, sizeof(pubkey)); 2035 1.1 riastrad /* msg.ephemeral := Er^pub */ 2036 1.1 riastrad memcpy(wgmr->wgmr_ephemeral, pubkey, sizeof(wgmr->wgmr_ephemeral)); 2037 1.1 riastrad /* Hr := HASH(Hr || msg.ephemeral) */ 2038 1.1 riastrad wg_algo_hash(hash, pubkey, sizeof(pubkey)); 2039 1.1 riastrad 2040 1.1 riastrad WG_DUMP_HASH("ckey", ckey); 2041 1.1 riastrad WG_DUMP_HASH("hash", hash); 2042 1.1 riastrad 2043 1.1 riastrad /* [N] 2.2: "ee" */ 2044 1.1 riastrad /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */ 2045 1.1 riastrad wg_algo_dh_kdf(ckey, NULL, privkey, wgs->wgs_ephemeral_key_peer); 2046 1.1 riastrad 2047 1.1 riastrad /* [N] 2.2: "se" */ 2048 1.1 riastrad /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */ 2049 1.1 riastrad wg_algo_dh_kdf(ckey, NULL, privkey, wgp->wgp_pubkey); 2050 1.1 riastrad 2051 1.1 riastrad /* [N] 9.2: "psk" */ 2052 1.1 riastrad { 2053 1.1 riastrad uint8_t kdfout[WG_KDF_OUTPUT_LEN]; 2054 1.1 riastrad /* Cr, r, k := KDF3(Cr, Q) */ 2055 1.1 riastrad wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk, 2056 1.1 riastrad sizeof(wgp->wgp_psk)); 2057 1.1 riastrad /* Hr := HASH(Hr || r) */ 2058 1.1 riastrad wg_algo_hash(hash, kdfout, sizeof(kdfout)); 2059 1.1 riastrad } 2060 1.1 riastrad 2061 1.1 riastrad /* msg.empty := AEAD(k, 0, e, Hr) */ 2062 1.14 riastrad wg_algo_aead_enc(wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty), 2063 1.14 riastrad cipher_key, 0, NULL, 0, hash, sizeof(hash)); 2064 1.1 riastrad /* Hr := HASH(Hr || msg.empty) */ 2065 1.1 riastrad wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty)); 2066 1.1 riastrad 2067 1.1 riastrad WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty); 2068 1.1 riastrad 2069 1.1 riastrad /* [W] 5.4.4: Cookie MACs */ 2070 1.1 riastrad /* msg.mac1 := MAC(HASH(LABEL-MAC1 || Sm'^pub), msg_a) */ 2071 1.1 riastrad wg_algo_mac_mac1(wgmr->wgmr_mac1, sizeof(wgmi->wgmi_mac1), 2072 1.1 riastrad wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey), 2073 1.17 riastrad (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1)); 2074 1.1 riastrad /* Need mac1 to decrypt a cookie from a cookie message */ 2075 1.1 riastrad memcpy(wgp->wgp_last_sent_mac1, wgmr->wgmr_mac1, 2076 1.1 riastrad sizeof(wgp->wgp_last_sent_mac1)); 2077 1.1 riastrad wgp->wgp_last_sent_mac1_valid = true; 2078 1.1 riastrad 2079 1.1 riastrad if (wgp->wgp_latest_cookie_time == 0 || 2080 1.1 riastrad (time_uptime - wgp->wgp_latest_cookie_time) >= WG_COOKIE_TIME) 2081 1.1 riastrad /* msg.mac2 := 0^16 */ 2082 1.1 riastrad memset(wgmr->wgmr_mac2, 0, sizeof(wgmr->wgmr_mac2)); 2083 1.1 riastrad else { 2084 1.1 riastrad /* msg.mac2 := MAC(Lm, msg_b) */ 2085 1.1 riastrad wg_algo_mac(wgmr->wgmr_mac2, sizeof(wgmi->wgmi_mac2), 2086 1.1 riastrad wgp->wgp_latest_cookie, WG_COOKIE_LEN, 2087 1.17 riastrad (const uint8_t *)wgmr, 2088 1.17 riastrad offsetof(struct wg_msg_resp, wgmr_mac2), 2089 1.1 riastrad NULL, 0); 2090 1.1 riastrad } 2091 1.1 riastrad 2092 1.1 riastrad memcpy(wgs->wgs_handshake_hash, hash, sizeof(hash)); 2093 1.1 riastrad memcpy(wgs->wgs_chaining_key, ckey, sizeof(ckey)); 2094 1.1 riastrad memcpy(wgs->wgs_ephemeral_key_pub, pubkey, sizeof(pubkey)); 2095 1.1 riastrad memcpy(wgs->wgs_ephemeral_key_priv, privkey, sizeof(privkey)); 2096 1.49 riastrad wgs->wgs_remote_index = wgmi->wgmi_sender; 2097 1.49 riastrad WG_DLOG("sender=%x\n", wgs->wgs_local_index); 2098 1.49 riastrad WG_DLOG("receiver=%x\n", wgs->wgs_remote_index); 2099 1.1 riastrad } 2100 1.1 riastrad 2101 1.122 riastrad /* 2102 1.122 riastrad * wg_swap_sessions(wg, wgp) 2103 1.122 riastrad * 2104 1.122 riastrad * Caller has just finished establishing the unstable session in 2105 1.122 riastrad * wg for peer wgp. Publish it as the stable session, send queued 2106 1.122 riastrad * packets or keepalives as necessary to kick off the session, 2107 1.122 riastrad * move the previously stable session to unstable, and begin 2108 1.122 riastrad * destroying it. 2109 1.122 riastrad */ 2110 1.1 riastrad static void 2111 1.122 riastrad wg_swap_sessions(struct wg_softc *wg, struct wg_peer *wgp) 2112 1.1 riastrad { 2113 1.49 riastrad struct wg_session *wgs, *wgs_prev; 2114 1.122 riastrad struct mbuf *m; 2115 1.1 riastrad 2116 1.1 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 2117 1.1 riastrad 2118 1.116 riastrad /* 2119 1.116 riastrad * Get the newly established session, to become the new 2120 1.116 riastrad * session. Caller must have transitioned from INIT_ACTIVE to 2121 1.119 riastrad * INIT_PASSIVE or to ESTABLISHED already. This will become 2122 1.119 riastrad * the stable session. 2123 1.116 riastrad */ 2124 1.49 riastrad wgs = wgp->wgp_session_unstable; 2125 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_ESTABLISHED, "state=%d", 2126 1.94 riastrad wgs->wgs_state); 2127 1.49 riastrad 2128 1.116 riastrad /* 2129 1.116 riastrad * Get the stable session, which is either the previously 2130 1.116 riastrad * established session in the ESTABLISHED state, or has not 2131 1.116 riastrad * been established at all and is UNKNOWN. This will become 2132 1.116 riastrad * the unstable session. 2133 1.116 riastrad */ 2134 1.49 riastrad wgs_prev = wgp->wgp_session_stable; 2135 1.94 riastrad KASSERTMSG((wgs_prev->wgs_state == WGS_STATE_ESTABLISHED || 2136 1.94 riastrad wgs_prev->wgs_state == WGS_STATE_UNKNOWN), 2137 1.94 riastrad "state=%d", wgs_prev->wgs_state); 2138 1.116 riastrad 2139 1.116 riastrad /* 2140 1.116 riastrad * Publish the newly established session for the tx path to use 2141 1.116 riastrad * and make the other one the unstable session to handle 2142 1.116 riastrad * stragglers in the rx path and later be used for the next 2143 1.116 riastrad * session's handshake. 2144 1.116 riastrad */ 2145 1.49 riastrad atomic_store_release(&wgp->wgp_session_stable, wgs); 2146 1.49 riastrad wgp->wgp_session_unstable = wgs_prev; 2147 1.122 riastrad 2148 1.122 riastrad /* 2149 1.122 riastrad * Record the handshake time and reset the handshake state. 2150 1.122 riastrad */ 2151 1.122 riastrad getnanotime(&wgp->wgp_last_handshake_time); 2152 1.122 riastrad wgp->wgp_handshake_start_time = 0; 2153 1.122 riastrad wgp->wgp_last_sent_mac1_valid = false; 2154 1.122 riastrad wgp->wgp_last_sent_cookie_valid = false; 2155 1.122 riastrad 2156 1.122 riastrad /* 2157 1.122 riastrad * If we had a data packet queued up, send it. 2158 1.122 riastrad * 2159 1.122 riastrad * If not, but we're the initiator, send a keepalive message -- 2160 1.122 riastrad * if we're the initiator we have to send something immediately 2161 1.122 riastrad * or else the responder will never answer. 2162 1.122 riastrad */ 2163 1.122 riastrad if ((m = atomic_swap_ptr(&wgp->wgp_pending, NULL)) != NULL) { 2164 1.126 riastrad membar_acquire(); /* matches membar_release in wgintr */ 2165 1.128 riastrad wg_send_data_msg(wgp, wgs, m); /* consumes m */ 2166 1.128 riastrad m = NULL; 2167 1.122 riastrad } else if (wgs->wgs_is_initiator) { 2168 1.122 riastrad wg_send_keepalive_msg(wgp, wgs); 2169 1.122 riastrad } 2170 1.122 riastrad 2171 1.122 riastrad /* 2172 1.122 riastrad * If the previous stable session was established, begin to 2173 1.122 riastrad * destroy it. 2174 1.122 riastrad */ 2175 1.122 riastrad if (wgs_prev->wgs_state == WGS_STATE_ESTABLISHED) { 2176 1.122 riastrad /* 2177 1.122 riastrad * Transition ESTABLISHED->DESTROYING. The session 2178 1.122 riastrad * will remain usable for the data rx path to process 2179 1.122 riastrad * packets still in flight to us, but we won't use it 2180 1.122 riastrad * for data tx. 2181 1.122 riastrad */ 2182 1.122 riastrad WG_DLOG("session[L=%"PRIx32" R=%"PRIx32"]" 2183 1.122 riastrad " -> WGS_STATE_DESTROYING\n", 2184 1.122 riastrad wgs_prev->wgs_local_index, wgs_prev->wgs_remote_index); 2185 1.122 riastrad atomic_store_relaxed(&wgs_prev->wgs_state, 2186 1.122 riastrad WGS_STATE_DESTROYING); 2187 1.122 riastrad } else { 2188 1.122 riastrad KASSERTMSG(wgs_prev->wgs_state == WGS_STATE_UNKNOWN, 2189 1.122 riastrad "state=%d", wgs_prev->wgs_state); 2190 1.122 riastrad wgs_prev->wgs_local_index = 0; /* paranoia */ 2191 1.122 riastrad wgs_prev->wgs_remote_index = 0; /* paranoia */ 2192 1.122 riastrad wg_clear_states(wgs_prev); /* paranoia */ 2193 1.122 riastrad wgs_prev->wgs_state = WGS_STATE_UNKNOWN; 2194 1.122 riastrad } 2195 1.1 riastrad } 2196 1.1 riastrad 2197 1.63 riastrad static void __noinline 2198 1.1 riastrad wg_handle_msg_resp(struct wg_softc *wg, const struct wg_msg_resp *wgmr, 2199 1.1 riastrad const struct sockaddr *src) 2200 1.1 riastrad { 2201 1.1 riastrad uint8_t ckey[WG_CHAINING_KEY_LEN]; /* [W] 5.4.3: Cr */ 2202 1.1 riastrad uint8_t hash[WG_HASH_LEN]; /* [W] 5.4.3: Kr */ 2203 1.1 riastrad uint8_t cipher_key[WG_KDF_OUTPUT_LEN]; 2204 1.1 riastrad struct wg_peer *wgp; 2205 1.1 riastrad struct wg_session *wgs; 2206 1.1 riastrad struct psref psref; 2207 1.1 riastrad int error; 2208 1.1 riastrad uint8_t mac1[WG_MAC_LEN]; 2209 1.1 riastrad 2210 1.1 riastrad wg_algo_mac_mac1(mac1, sizeof(mac1), 2211 1.1 riastrad wg->wg_pubkey, sizeof(wg->wg_pubkey), 2212 1.1 riastrad (const uint8_t *)wgmr, offsetof(struct wg_msg_resp, wgmr_mac1)); 2213 1.1 riastrad 2214 1.1 riastrad /* 2215 1.1 riastrad * [W] 5.3: Denial of Service Mitigation & Cookies 2216 1.1 riastrad * "the responder, ..., must always reject messages with an invalid 2217 1.1 riastrad * msg.mac1" 2218 1.1 riastrad */ 2219 1.13 riastrad if (!consttime_memequal(mac1, wgmr->wgmr_mac1, sizeof(mac1))) { 2220 1.1 riastrad WG_DLOG("mac1 is invalid\n"); 2221 1.44 riastrad return; 2222 1.44 riastrad } 2223 1.44 riastrad 2224 1.44 riastrad WG_TRACE("resp msg received"); 2225 1.44 riastrad wgs = wg_lookup_session_by_index(wg, wgmr->wgmr_receiver, &psref); 2226 1.44 riastrad if (wgs == NULL) { 2227 1.44 riastrad WG_TRACE("No session found"); 2228 1.44 riastrad return; 2229 1.1 riastrad } 2230 1.1 riastrad 2231 1.44 riastrad wgp = wgs->wgs_peer; 2232 1.44 riastrad 2233 1.49 riastrad mutex_enter(wgp->wgp_lock); 2234 1.49 riastrad 2235 1.49 riastrad /* If we weren't waiting for a handshake response, drop it. */ 2236 1.49 riastrad if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE) { 2237 1.49 riastrad WG_TRACE("peer sent spurious handshake response, ignoring"); 2238 1.49 riastrad goto out; 2239 1.49 riastrad } 2240 1.49 riastrad 2241 1.1 riastrad if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_RESP))) { 2242 1.1 riastrad WG_TRACE("under load"); 2243 1.1 riastrad /* 2244 1.1 riastrad * [W] 5.3: Denial of Service Mitigation & Cookies 2245 1.1 riastrad * "the responder, ..., and when under load may reject messages 2246 1.1 riastrad * with an invalid msg.mac2. If the responder receives a 2247 1.1 riastrad * message with a valid msg.mac1 yet with an invalid msg.mac2, 2248 1.1 riastrad * and is under load, it may respond with a cookie reply 2249 1.1 riastrad * message" 2250 1.1 riastrad */ 2251 1.1 riastrad uint8_t zero[WG_MAC_LEN] = {0}; 2252 1.13 riastrad if (consttime_memequal(wgmr->wgmr_mac2, zero, sizeof(zero))) { 2253 1.1 riastrad WG_TRACE("sending a cookie message: no cookie included"); 2254 1.108 riastrad wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender, 2255 1.1 riastrad wgmr->wgmr_mac1, src); 2256 1.1 riastrad goto out; 2257 1.1 riastrad } 2258 1.1 riastrad if (!wgp->wgp_last_sent_cookie_valid) { 2259 1.1 riastrad WG_TRACE("sending a cookie message: no cookie sent ever"); 2260 1.108 riastrad wg_send_cookie_msg(wg, wgp, wgmr->wgmr_sender, 2261 1.1 riastrad wgmr->wgmr_mac1, src); 2262 1.1 riastrad goto out; 2263 1.1 riastrad } 2264 1.1 riastrad uint8_t mac2[WG_MAC_LEN]; 2265 1.1 riastrad wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie, 2266 1.1 riastrad WG_COOKIE_LEN, (const uint8_t *)wgmr, 2267 1.1 riastrad offsetof(struct wg_msg_resp, wgmr_mac2), NULL, 0); 2268 1.13 riastrad if (!consttime_memequal(mac2, wgmr->wgmr_mac2, sizeof(mac2))) { 2269 1.1 riastrad WG_DLOG("mac2 is invalid\n"); 2270 1.1 riastrad goto out; 2271 1.1 riastrad } 2272 1.1 riastrad WG_TRACE("under load, but continue to sending"); 2273 1.1 riastrad } 2274 1.1 riastrad 2275 1.1 riastrad memcpy(hash, wgs->wgs_handshake_hash, sizeof(hash)); 2276 1.1 riastrad memcpy(ckey, wgs->wgs_chaining_key, sizeof(ckey)); 2277 1.1 riastrad 2278 1.1 riastrad /* 2279 1.1 riastrad * [W] 5.4.3 Second Message: Responder to Initiator 2280 1.1 riastrad * "When the initiator receives this message, it does the same 2281 1.1 riastrad * operations so that its final state variables are identical, 2282 1.1 riastrad * replacing the operands of the DH function to produce equivalent 2283 1.1 riastrad * values." 2284 1.1 riastrad * Note that the following comments of operations are just copies of 2285 1.1 riastrad * the initiator's ones. 2286 1.1 riastrad */ 2287 1.1 riastrad 2288 1.1 riastrad /* [N] 2.2: "e" */ 2289 1.1 riastrad /* Cr := KDF1(Cr, Er^pub) */ 2290 1.1 riastrad wg_algo_kdf(ckey, NULL, NULL, ckey, wgmr->wgmr_ephemeral, 2291 1.1 riastrad sizeof(wgmr->wgmr_ephemeral)); 2292 1.1 riastrad /* Hr := HASH(Hr || msg.ephemeral) */ 2293 1.1 riastrad wg_algo_hash(hash, wgmr->wgmr_ephemeral, sizeof(wgmr->wgmr_ephemeral)); 2294 1.1 riastrad 2295 1.1 riastrad WG_DUMP_HASH("ckey", ckey); 2296 1.1 riastrad WG_DUMP_HASH("hash", hash); 2297 1.1 riastrad 2298 1.1 riastrad /* [N] 2.2: "ee" */ 2299 1.1 riastrad /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */ 2300 1.1 riastrad wg_algo_dh_kdf(ckey, NULL, wgs->wgs_ephemeral_key_priv, 2301 1.1 riastrad wgmr->wgmr_ephemeral); 2302 1.1 riastrad 2303 1.1 riastrad /* [N] 2.2: "se" */ 2304 1.1 riastrad /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */ 2305 1.1 riastrad wg_algo_dh_kdf(ckey, NULL, wg->wg_privkey, wgmr->wgmr_ephemeral); 2306 1.1 riastrad 2307 1.1 riastrad /* [N] 9.2: "psk" */ 2308 1.1 riastrad { 2309 1.1 riastrad uint8_t kdfout[WG_KDF_OUTPUT_LEN]; 2310 1.1 riastrad /* Cr, r, k := KDF3(Cr, Q) */ 2311 1.1 riastrad wg_algo_kdf(ckey, kdfout, cipher_key, ckey, wgp->wgp_psk, 2312 1.1 riastrad sizeof(wgp->wgp_psk)); 2313 1.1 riastrad /* Hr := HASH(Hr || r) */ 2314 1.1 riastrad wg_algo_hash(hash, kdfout, sizeof(kdfout)); 2315 1.1 riastrad } 2316 1.1 riastrad 2317 1.1 riastrad { 2318 1.1 riastrad uint8_t out[sizeof(wgmr->wgmr_empty)]; /* for safety */ 2319 1.1 riastrad /* msg.empty := AEAD(k, 0, e, Hr) */ 2320 1.1 riastrad error = wg_algo_aead_dec(out, 0, cipher_key, 0, wgmr->wgmr_empty, 2321 1.1 riastrad sizeof(wgmr->wgmr_empty), hash, sizeof(hash)); 2322 1.1 riastrad WG_DUMP_HASH("wgmr_empty", wgmr->wgmr_empty); 2323 1.1 riastrad if (error != 0) { 2324 1.1 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2325 1.76 jakllsch "%s: peer %s: wg_algo_aead_dec for empty message failed\n", 2326 1.76 jakllsch if_name(&wg->wg_if), wgp->wgp_name); 2327 1.1 riastrad goto out; 2328 1.1 riastrad } 2329 1.1 riastrad /* Hr := HASH(Hr || msg.empty) */ 2330 1.1 riastrad wg_algo_hash(hash, wgmr->wgmr_empty, sizeof(wgmr->wgmr_empty)); 2331 1.1 riastrad } 2332 1.1 riastrad 2333 1.1 riastrad memcpy(wgs->wgs_handshake_hash, hash, sizeof(wgs->wgs_handshake_hash)); 2334 1.1 riastrad memcpy(wgs->wgs_chaining_key, ckey, sizeof(wgs->wgs_chaining_key)); 2335 1.49 riastrad wgs->wgs_remote_index = wgmr->wgmr_sender; 2336 1.49 riastrad WG_DLOG("receiver=%x\n", wgs->wgs_remote_index); 2337 1.1 riastrad 2338 1.122 riastrad /* 2339 1.122 riastrad * The packet is genuine. Update the peer's endpoint if the 2340 1.122 riastrad * source address changed. 2341 1.122 riastrad * 2342 1.122 riastrad * XXX How to prevent DoS by replaying genuine packets from the 2343 1.122 riastrad * wrong source address? 2344 1.122 riastrad */ 2345 1.122 riastrad wg_update_endpoint_if_necessary(wgp, src); 2346 1.122 riastrad 2347 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_INIT_ACTIVE, "state=%d", 2348 1.94 riastrad wgs->wgs_state); 2349 1.104 riastrad wgs->wgs_time_established = time_uptime32; 2350 1.100 riastrad wg_schedule_session_dtor_timer(wgp); 2351 1.1 riastrad wgs->wgs_time_last_data_sent = 0; 2352 1.1 riastrad wgs->wgs_is_initiator = true; 2353 1.94 riastrad WG_DLOG("session[L=%"PRIx32" R=%"PRIx32"]:" 2354 1.94 riastrad " calculate keys as initiator\n", 2355 1.94 riastrad wgs->wgs_local_index, wgs->wgs_remote_index); 2356 1.1 riastrad wg_calculate_keys(wgs, true); 2357 1.1 riastrad wg_clear_states(wgs); 2358 1.94 riastrad 2359 1.94 riastrad /* 2360 1.94 riastrad * Session is ready to receive data now that we have received 2361 1.94 riastrad * the responder's response. 2362 1.94 riastrad * 2363 1.94 riastrad * Transition from INIT_ACTIVE to ESTABLISHED to publish it to 2364 1.94 riastrad * the data rx path, wg_handle_msg_data. 2365 1.94 riastrad */ 2366 1.94 riastrad WG_DLOG("session[L=%"PRIx32" R=%"PRIx32" -> WGS_STATE_ESTABLISHED\n", 2367 1.94 riastrad wgs->wgs_local_index, wgs->wgs_remote_index); 2368 1.94 riastrad atomic_store_release(&wgs->wgs_state, WGS_STATE_ESTABLISHED); 2369 1.1 riastrad WG_TRACE("WGS_STATE_ESTABLISHED"); 2370 1.1 riastrad 2371 1.96 riastrad callout_halt(&wgp->wgp_handshake_timeout_timer, NULL); 2372 1.18 riastrad 2373 1.94 riastrad /* 2374 1.94 riastrad * Session is ready to send data now that we have received the 2375 1.94 riastrad * responder's response. 2376 1.94 riastrad * 2377 1.94 riastrad * Swap the sessions to publish the new one as the stable 2378 1.94 riastrad * session for the data tx path, wg_output. 2379 1.94 riastrad */ 2380 1.122 riastrad wg_swap_sessions(wg, wgp); 2381 1.49 riastrad KASSERT(wgs == wgp->wgp_session_stable); 2382 1.1 riastrad 2383 1.1 riastrad out: 2384 1.49 riastrad mutex_exit(wgp->wgp_lock); 2385 1.1 riastrad wg_put_session(wgs, &psref); 2386 1.1 riastrad } 2387 1.1 riastrad 2388 1.108 riastrad static void 2389 1.1 riastrad wg_send_handshake_msg_resp(struct wg_softc *wg, struct wg_peer *wgp, 2390 1.49 riastrad struct wg_session *wgs, const struct wg_msg_init *wgmi) 2391 1.1 riastrad { 2392 1.1 riastrad int error; 2393 1.1 riastrad struct mbuf *m; 2394 1.1 riastrad struct wg_msg_resp *wgmr; 2395 1.1 riastrad 2396 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 2397 1.49 riastrad KASSERT(wgs == wgp->wgp_session_unstable); 2398 1.94 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 2399 1.94 riastrad wgs->wgs_state); 2400 1.49 riastrad 2401 1.1 riastrad m = m_gethdr(M_WAIT, MT_DATA); 2402 1.69 hannken if (sizeof(*wgmr) > MHLEN) { 2403 1.69 hannken m_clget(m, M_WAIT); 2404 1.69 hannken CTASSERT(sizeof(*wgmr) <= MCLBYTES); 2405 1.69 hannken } 2406 1.1 riastrad m->m_pkthdr.len = m->m_len = sizeof(*wgmr); 2407 1.1 riastrad wgmr = mtod(m, struct wg_msg_resp *); 2408 1.49 riastrad wg_fill_msg_resp(wg, wgp, wgs, wgmr, wgmi); 2409 1.1 riastrad 2410 1.108 riastrad error = wg->wg_ops->send_hs_msg(wgp, m); /* consumes m */ 2411 1.108 riastrad if (error) { 2412 1.108 riastrad WG_DLOG("send_hs_msg failed, error=%d\n", error); 2413 1.108 riastrad return; 2414 1.108 riastrad } 2415 1.108 riastrad 2416 1.108 riastrad WG_TRACE("resp msg sent"); 2417 1.1 riastrad } 2418 1.1 riastrad 2419 1.1 riastrad static struct wg_peer * 2420 1.1 riastrad wg_lookup_peer_by_pubkey(struct wg_softc *wg, 2421 1.114 riastrad const uint8_t pubkey[static WG_STATIC_KEY_LEN], struct psref *psref) 2422 1.1 riastrad { 2423 1.1 riastrad struct wg_peer *wgp; 2424 1.1 riastrad 2425 1.1 riastrad int s = pserialize_read_enter(); 2426 1.37 riastrad wgp = thmap_get(wg->wg_peers_bypubkey, pubkey, WG_STATIC_KEY_LEN); 2427 1.1 riastrad if (wgp != NULL) 2428 1.1 riastrad wg_get_peer(wgp, psref); 2429 1.1 riastrad pserialize_read_exit(s); 2430 1.1 riastrad 2431 1.1 riastrad return wgp; 2432 1.1 riastrad } 2433 1.1 riastrad 2434 1.1 riastrad static void 2435 1.1 riastrad wg_fill_msg_cookie(struct wg_softc *wg, struct wg_peer *wgp, 2436 1.1 riastrad struct wg_msg_cookie *wgmc, const uint32_t sender, 2437 1.114 riastrad const uint8_t mac1[static WG_MAC_LEN], const struct sockaddr *src) 2438 1.1 riastrad { 2439 1.1 riastrad uint8_t cookie[WG_COOKIE_LEN]; 2440 1.1 riastrad uint8_t key[WG_HASH_LEN]; 2441 1.1 riastrad uint8_t addr[sizeof(struct in6_addr)]; 2442 1.1 riastrad size_t addrlen; 2443 1.1 riastrad uint16_t uh_sport; /* be */ 2444 1.1 riastrad 2445 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 2446 1.49 riastrad 2447 1.39 riastrad wgmc->wgmc_type = htole32(WG_MSG_TYPE_COOKIE); 2448 1.1 riastrad wgmc->wgmc_receiver = sender; 2449 1.1 riastrad cprng_fast(wgmc->wgmc_salt, sizeof(wgmc->wgmc_salt)); 2450 1.1 riastrad 2451 1.1 riastrad /* 2452 1.1 riastrad * [W] 5.4.7: Under Load: Cookie Reply Message 2453 1.14 riastrad * "The secret variable, Rm, changes every two minutes to a 2454 1.14 riastrad * random value" 2455 1.1 riastrad */ 2456 1.98 riastrad if ((time_uptime - wgp->wgp_last_cookiesecret_time) > 2457 1.98 riastrad WG_COOKIESECRET_TIME) { 2458 1.98 riastrad cprng_strong(kern_cprng, wgp->wgp_cookiesecret, 2459 1.98 riastrad sizeof(wgp->wgp_cookiesecret), 0); 2460 1.98 riastrad wgp->wgp_last_cookiesecret_time = time_uptime; 2461 1.1 riastrad } 2462 1.1 riastrad 2463 1.1 riastrad switch (src->sa_family) { 2464 1.109 riastrad #ifdef INET 2465 1.1 riastrad case AF_INET: { 2466 1.1 riastrad const struct sockaddr_in *sin = satocsin(src); 2467 1.1 riastrad addrlen = sizeof(sin->sin_addr); 2468 1.1 riastrad memcpy(addr, &sin->sin_addr, addrlen); 2469 1.1 riastrad uh_sport = sin->sin_port; 2470 1.1 riastrad break; 2471 1.1 riastrad } 2472 1.109 riastrad #endif 2473 1.1 riastrad #ifdef INET6 2474 1.1 riastrad case AF_INET6: { 2475 1.1 riastrad const struct sockaddr_in6 *sin6 = satocsin6(src); 2476 1.1 riastrad addrlen = sizeof(sin6->sin6_addr); 2477 1.1 riastrad memcpy(addr, &sin6->sin6_addr, addrlen); 2478 1.1 riastrad uh_sport = sin6->sin6_port; 2479 1.1 riastrad break; 2480 1.1 riastrad } 2481 1.1 riastrad #endif 2482 1.1 riastrad default: 2483 1.47 riastrad panic("invalid af=%d", src->sa_family); 2484 1.1 riastrad } 2485 1.1 riastrad 2486 1.1 riastrad wg_algo_mac(cookie, sizeof(cookie), 2487 1.98 riastrad wgp->wgp_cookiesecret, sizeof(wgp->wgp_cookiesecret), 2488 1.17 riastrad addr, addrlen, (const uint8_t *)&uh_sport, sizeof(uh_sport)); 2489 1.1 riastrad wg_algo_mac_cookie(key, sizeof(key), wg->wg_pubkey, 2490 1.1 riastrad sizeof(wg->wg_pubkey)); 2491 1.1 riastrad wg_algo_xaead_enc(wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), key, 2492 1.1 riastrad cookie, sizeof(cookie), mac1, WG_MAC_LEN, wgmc->wgmc_salt); 2493 1.1 riastrad 2494 1.1 riastrad /* Need to store to calculate mac2 */ 2495 1.1 riastrad memcpy(wgp->wgp_last_sent_cookie, cookie, sizeof(cookie)); 2496 1.1 riastrad wgp->wgp_last_sent_cookie_valid = true; 2497 1.1 riastrad } 2498 1.1 riastrad 2499 1.108 riastrad static void 2500 1.1 riastrad wg_send_cookie_msg(struct wg_softc *wg, struct wg_peer *wgp, 2501 1.114 riastrad const uint32_t sender, const uint8_t mac1[static WG_MAC_LEN], 2502 1.1 riastrad const struct sockaddr *src) 2503 1.1 riastrad { 2504 1.1 riastrad int error; 2505 1.1 riastrad struct mbuf *m; 2506 1.1 riastrad struct wg_msg_cookie *wgmc; 2507 1.1 riastrad 2508 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 2509 1.49 riastrad 2510 1.1 riastrad m = m_gethdr(M_WAIT, MT_DATA); 2511 1.69 hannken if (sizeof(*wgmc) > MHLEN) { 2512 1.69 hannken m_clget(m, M_WAIT); 2513 1.69 hannken CTASSERT(sizeof(*wgmc) <= MCLBYTES); 2514 1.69 hannken } 2515 1.1 riastrad m->m_pkthdr.len = m->m_len = sizeof(*wgmc); 2516 1.1 riastrad wgmc = mtod(m, struct wg_msg_cookie *); 2517 1.1 riastrad wg_fill_msg_cookie(wg, wgp, wgmc, sender, mac1, src); 2518 1.1 riastrad 2519 1.108 riastrad error = wg->wg_ops->send_hs_msg(wgp, m); /* consumes m */ 2520 1.108 riastrad if (error) { 2521 1.108 riastrad WG_DLOG("send_hs_msg failed, error=%d\n", error); 2522 1.108 riastrad return; 2523 1.108 riastrad } 2524 1.108 riastrad 2525 1.108 riastrad WG_TRACE("cookie msg sent"); 2526 1.1 riastrad } 2527 1.1 riastrad 2528 1.1 riastrad static bool 2529 1.1 riastrad wg_is_underload(struct wg_softc *wg, struct wg_peer *wgp, int msgtype) 2530 1.1 riastrad { 2531 1.1 riastrad #ifdef WG_DEBUG_PARAMS 2532 1.1 riastrad if (wg_force_underload) 2533 1.1 riastrad return true; 2534 1.1 riastrad #endif 2535 1.1 riastrad 2536 1.1 riastrad /* 2537 1.1 riastrad * XXX we don't have a means of a load estimation. The purpose of 2538 1.1 riastrad * the mechanism is a DoS mitigation, so we consider frequent handshake 2539 1.1 riastrad * messages as (a kind of) load; if a message of the same type comes 2540 1.1 riastrad * to a peer within 1 second, we consider we are under load. 2541 1.1 riastrad */ 2542 1.1 riastrad time_t last = wgp->wgp_last_msg_received_time[msgtype]; 2543 1.1 riastrad wgp->wgp_last_msg_received_time[msgtype] = time_uptime; 2544 1.1 riastrad return (time_uptime - last) == 0; 2545 1.1 riastrad } 2546 1.1 riastrad 2547 1.1 riastrad static void 2548 1.1 riastrad wg_calculate_keys(struct wg_session *wgs, const bool initiator) 2549 1.1 riastrad { 2550 1.1 riastrad 2551 1.49 riastrad KASSERT(mutex_owned(wgs->wgs_peer->wgp_lock)); 2552 1.49 riastrad 2553 1.14 riastrad /* 2554 1.14 riastrad * [W] 5.4.5: Ti^send = Tr^recv, Ti^recv = Tr^send := KDF2(Ci = Cr, e) 2555 1.14 riastrad */ 2556 1.1 riastrad if (initiator) { 2557 1.1 riastrad wg_algo_kdf(wgs->wgs_tkey_send, wgs->wgs_tkey_recv, NULL, 2558 1.1 riastrad wgs->wgs_chaining_key, NULL, 0); 2559 1.1 riastrad } else { 2560 1.1 riastrad wg_algo_kdf(wgs->wgs_tkey_recv, wgs->wgs_tkey_send, NULL, 2561 1.1 riastrad wgs->wgs_chaining_key, NULL, 0); 2562 1.1 riastrad } 2563 1.1 riastrad WG_DUMP_HASH("wgs_tkey_send", wgs->wgs_tkey_send); 2564 1.1 riastrad WG_DUMP_HASH("wgs_tkey_recv", wgs->wgs_tkey_recv); 2565 1.1 riastrad } 2566 1.1 riastrad 2567 1.22 riastrad static uint64_t 2568 1.22 riastrad wg_session_get_send_counter(struct wg_session *wgs) 2569 1.22 riastrad { 2570 1.22 riastrad #ifdef __HAVE_ATOMIC64_LOADSTORE 2571 1.22 riastrad return atomic_load_relaxed(&wgs->wgs_send_counter); 2572 1.22 riastrad #else 2573 1.22 riastrad uint64_t send_counter; 2574 1.22 riastrad 2575 1.22 riastrad mutex_enter(&wgs->wgs_send_counter_lock); 2576 1.22 riastrad send_counter = wgs->wgs_send_counter; 2577 1.22 riastrad mutex_exit(&wgs->wgs_send_counter_lock); 2578 1.22 riastrad 2579 1.22 riastrad return send_counter; 2580 1.22 riastrad #endif 2581 1.22 riastrad } 2582 1.22 riastrad 2583 1.22 riastrad static uint64_t 2584 1.22 riastrad wg_session_inc_send_counter(struct wg_session *wgs) 2585 1.22 riastrad { 2586 1.22 riastrad #ifdef __HAVE_ATOMIC64_LOADSTORE 2587 1.22 riastrad return atomic_inc_64_nv(&wgs->wgs_send_counter) - 1; 2588 1.22 riastrad #else 2589 1.22 riastrad uint64_t send_counter; 2590 1.22 riastrad 2591 1.22 riastrad mutex_enter(&wgs->wgs_send_counter_lock); 2592 1.22 riastrad send_counter = wgs->wgs_send_counter++; 2593 1.22 riastrad mutex_exit(&wgs->wgs_send_counter_lock); 2594 1.22 riastrad 2595 1.22 riastrad return send_counter; 2596 1.22 riastrad #endif 2597 1.22 riastrad } 2598 1.22 riastrad 2599 1.1 riastrad static void 2600 1.1 riastrad wg_clear_states(struct wg_session *wgs) 2601 1.1 riastrad { 2602 1.1 riastrad 2603 1.49 riastrad KASSERT(mutex_owned(wgs->wgs_peer->wgp_lock)); 2604 1.49 riastrad 2605 1.1 riastrad wgs->wgs_send_counter = 0; 2606 1.6 riastrad sliwin_reset(&wgs->wgs_recvwin->window); 2607 1.1 riastrad 2608 1.1 riastrad #define wgs_clear(v) explicit_memset(wgs->wgs_##v, 0, sizeof(wgs->wgs_##v)) 2609 1.1 riastrad wgs_clear(handshake_hash); 2610 1.1 riastrad wgs_clear(chaining_key); 2611 1.1 riastrad wgs_clear(ephemeral_key_pub); 2612 1.1 riastrad wgs_clear(ephemeral_key_priv); 2613 1.1 riastrad wgs_clear(ephemeral_key_peer); 2614 1.1 riastrad #undef wgs_clear 2615 1.1 riastrad } 2616 1.1 riastrad 2617 1.1 riastrad static struct wg_session * 2618 1.1 riastrad wg_lookup_session_by_index(struct wg_softc *wg, const uint32_t index, 2619 1.1 riastrad struct psref *psref) 2620 1.1 riastrad { 2621 1.1 riastrad struct wg_session *wgs; 2622 1.1 riastrad 2623 1.1 riastrad int s = pserialize_read_enter(); 2624 1.37 riastrad wgs = thmap_get(wg->wg_sessions_byindex, &index, sizeof index); 2625 1.49 riastrad if (wgs != NULL) { 2626 1.120 riastrad KASSERTMSG(index == wgs->wgs_local_index, 2627 1.94 riastrad "index=%"PRIx32" wgs->wgs_local_index=%"PRIx32, 2628 1.120 riastrad index, wgs->wgs_local_index); 2629 1.1 riastrad psref_acquire(psref, &wgs->wgs_psref, wg_psref_class); 2630 1.49 riastrad } 2631 1.1 riastrad pserialize_read_exit(s); 2632 1.1 riastrad 2633 1.1 riastrad return wgs; 2634 1.1 riastrad } 2635 1.1 riastrad 2636 1.1 riastrad static void 2637 1.1 riastrad wg_send_keepalive_msg(struct wg_peer *wgp, struct wg_session *wgs) 2638 1.1 riastrad { 2639 1.1 riastrad struct mbuf *m; 2640 1.1 riastrad 2641 1.1 riastrad /* 2642 1.1 riastrad * [W] 6.5 Passive Keepalive 2643 1.1 riastrad * "A keepalive message is simply a transport data message with 2644 1.1 riastrad * a zero-length encapsulated encrypted inner-packet." 2645 1.1 riastrad */ 2646 1.80 christos WG_TRACE(""); 2647 1.1 riastrad m = m_gethdr(M_WAIT, MT_DATA); 2648 1.1 riastrad wg_send_data_msg(wgp, wgs, m); 2649 1.1 riastrad } 2650 1.1 riastrad 2651 1.1 riastrad static bool 2652 1.1 riastrad wg_need_to_send_init_message(struct wg_session *wgs) 2653 1.1 riastrad { 2654 1.1 riastrad /* 2655 1.1 riastrad * [W] 6.2 Transport Message Limits 2656 1.1 riastrad * "if a peer is the initiator of a current secure session, 2657 1.1 riastrad * WireGuard will send a handshake initiation message to begin 2658 1.1 riastrad * a new secure session ... if after receiving a transport data 2659 1.1 riastrad * message, the current secure session is (REJECT-AFTER-TIME 2660 1.1 riastrad * KEEPALIVE-TIMEOUT REKEY-TIMEOUT) seconds old and it has 2661 1.1 riastrad * not yet acted upon this event." 2662 1.1 riastrad */ 2663 1.104 riastrad return wgs->wgs_is_initiator && 2664 1.104 riastrad atomic_load_relaxed(&wgs->wgs_time_last_data_sent) == 0 && 2665 1.117 riastrad (time_uptime32 - wgs->wgs_time_established >= 2666 1.104 riastrad (wg_reject_after_time - wg_keepalive_timeout - 2667 1.104 riastrad wg_rekey_timeout)); 2668 1.1 riastrad } 2669 1.1 riastrad 2670 1.1 riastrad static void 2671 1.65 christos wg_schedule_peer_task(struct wg_peer *wgp, unsigned int task) 2672 1.1 riastrad { 2673 1.1 riastrad 2674 1.55 riastrad mutex_enter(wgp->wgp_intr_lock); 2675 1.1 riastrad WG_DLOG("tasks=%d, task=%d\n", wgp->wgp_tasks, task); 2676 1.55 riastrad if (wgp->wgp_tasks == 0) 2677 1.55 riastrad /* 2678 1.55 riastrad * XXX If the current CPU is already loaded -- e.g., if 2679 1.55 riastrad * there's already a bunch of handshakes queued up -- 2680 1.55 riastrad * consider tossing this over to another CPU to 2681 1.55 riastrad * distribute the load. 2682 1.55 riastrad */ 2683 1.55 riastrad workqueue_enqueue(wg_wq, &wgp->wgp_work, NULL); 2684 1.55 riastrad wgp->wgp_tasks |= task; 2685 1.55 riastrad mutex_exit(wgp->wgp_intr_lock); 2686 1.1 riastrad } 2687 1.1 riastrad 2688 1.1 riastrad static void 2689 1.1 riastrad wg_change_endpoint(struct wg_peer *wgp, const struct sockaddr *new) 2690 1.1 riastrad { 2691 1.49 riastrad struct wg_sockaddr *wgsa_prev; 2692 1.1 riastrad 2693 1.1 riastrad WG_TRACE("Changing endpoint"); 2694 1.1 riastrad 2695 1.1 riastrad memcpy(wgp->wgp_endpoint0, new, new->sa_len); 2696 1.49 riastrad wgsa_prev = wgp->wgp_endpoint; 2697 1.49 riastrad atomic_store_release(&wgp->wgp_endpoint, wgp->wgp_endpoint0); 2698 1.49 riastrad wgp->wgp_endpoint0 = wgsa_prev; 2699 1.49 riastrad atomic_store_release(&wgp->wgp_endpoint_available, true); 2700 1.49 riastrad 2701 1.1 riastrad wg_schedule_peer_task(wgp, WGP_TASK_ENDPOINT_CHANGED); 2702 1.1 riastrad } 2703 1.1 riastrad 2704 1.2 riastrad static bool 2705 1.17 riastrad wg_validate_inner_packet(const char *packet, size_t decrypted_len, int *af) 2706 1.1 riastrad { 2707 1.2 riastrad uint16_t packet_len; 2708 1.17 riastrad const struct ip *ip; 2709 1.2 riastrad 2710 1.81 christos if (__predict_false(decrypted_len < sizeof(*ip))) { 2711 1.81 christos WG_DLOG("decrypted_len=%zu < %zu\n", decrypted_len, 2712 1.81 christos sizeof(*ip)); 2713 1.2 riastrad return false; 2714 1.81 christos } 2715 1.1 riastrad 2716 1.17 riastrad ip = (const struct ip *)packet; 2717 1.2 riastrad if (ip->ip_v == 4) 2718 1.2 riastrad *af = AF_INET; 2719 1.2 riastrad else if (ip->ip_v == 6) 2720 1.2 riastrad *af = AF_INET6; 2721 1.81 christos else { 2722 1.81 christos WG_DLOG("ip_v=%d\n", ip->ip_v); 2723 1.2 riastrad return false; 2724 1.81 christos } 2725 1.2 riastrad 2726 1.2 riastrad WG_DLOG("af=%d\n", *af); 2727 1.1 riastrad 2728 1.62 riastrad switch (*af) { 2729 1.62 riastrad #ifdef INET 2730 1.62 riastrad case AF_INET: 2731 1.2 riastrad packet_len = ntohs(ip->ip_len); 2732 1.62 riastrad break; 2733 1.62 riastrad #endif 2734 1.62 riastrad #ifdef INET6 2735 1.62 riastrad case AF_INET6: { 2736 1.17 riastrad const struct ip6_hdr *ip6; 2737 1.1 riastrad 2738 1.81 christos if (__predict_false(decrypted_len < sizeof(*ip6))) { 2739 1.81 christos WG_DLOG("decrypted_len=%zu < %zu\n", decrypted_len, 2740 1.81 christos sizeof(*ip6)); 2741 1.2 riastrad return false; 2742 1.81 christos } 2743 1.1 riastrad 2744 1.17 riastrad ip6 = (const struct ip6_hdr *)packet; 2745 1.81 christos packet_len = sizeof(*ip6) + ntohs(ip6->ip6_plen); 2746 1.62 riastrad break; 2747 1.62 riastrad } 2748 1.62 riastrad #endif 2749 1.62 riastrad default: 2750 1.62 riastrad return false; 2751 1.1 riastrad } 2752 1.2 riastrad 2753 1.81 christos if (packet_len > decrypted_len) { 2754 1.81 christos WG_DLOG("packet_len %u > decrypted_len %zu\n", packet_len, 2755 1.81 christos decrypted_len); 2756 1.1 riastrad return false; 2757 1.81 christos } 2758 1.1 riastrad 2759 1.1 riastrad return true; 2760 1.1 riastrad } 2761 1.1 riastrad 2762 1.1 riastrad static bool 2763 1.1 riastrad wg_validate_route(struct wg_softc *wg, struct wg_peer *wgp_expected, 2764 1.1 riastrad int af, char *packet) 2765 1.1 riastrad { 2766 1.1 riastrad struct sockaddr_storage ss; 2767 1.1 riastrad struct sockaddr *sa; 2768 1.1 riastrad struct psref psref; 2769 1.1 riastrad struct wg_peer *wgp; 2770 1.1 riastrad bool ok; 2771 1.1 riastrad 2772 1.1 riastrad /* 2773 1.1 riastrad * II CRYPTOKEY ROUTING 2774 1.14 riastrad * "it will only accept it if its source IP resolves in the 2775 1.14 riastrad * table to the public key used in the secure session for 2776 1.14 riastrad * decrypting it." 2777 1.1 riastrad */ 2778 1.1 riastrad 2779 1.109 riastrad switch (af) { 2780 1.109 riastrad #ifdef INET 2781 1.109 riastrad case AF_INET: { 2782 1.17 riastrad const struct ip *ip = (const struct ip *)packet; 2783 1.1 riastrad struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 2784 1.1 riastrad sockaddr_in_init(sin, &ip->ip_src, 0); 2785 1.1 riastrad sa = sintosa(sin); 2786 1.109 riastrad break; 2787 1.109 riastrad } 2788 1.109 riastrad #endif 2789 1.1 riastrad #ifdef INET6 2790 1.109 riastrad case AF_INET6: { 2791 1.17 riastrad const struct ip6_hdr *ip6 = (const struct ip6_hdr *)packet; 2792 1.1 riastrad struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 2793 1.1 riastrad sockaddr_in6_init(sin6, &ip6->ip6_src, 0, 0, 0); 2794 1.1 riastrad sa = sin6tosa(sin6); 2795 1.109 riastrad break; 2796 1.109 riastrad } 2797 1.1 riastrad #endif 2798 1.109 riastrad default: 2799 1.109 riastrad __USE(ss); 2800 1.109 riastrad return false; 2801 1.1 riastrad } 2802 1.1 riastrad 2803 1.1 riastrad wgp = wg_pick_peer_by_sa(wg, sa, &psref); 2804 1.1 riastrad ok = (wgp == wgp_expected); 2805 1.1 riastrad if (wgp != NULL) 2806 1.1 riastrad wg_put_peer(wgp, &psref); 2807 1.1 riastrad 2808 1.1 riastrad return ok; 2809 1.1 riastrad } 2810 1.1 riastrad 2811 1.1 riastrad static void 2812 1.1 riastrad wg_session_dtor_timer(void *arg) 2813 1.1 riastrad { 2814 1.1 riastrad struct wg_peer *wgp = arg; 2815 1.1 riastrad 2816 1.1 riastrad WG_TRACE("enter"); 2817 1.1 riastrad 2818 1.100 riastrad wg_schedule_session_dtor_timer(wgp); 2819 1.1 riastrad wg_schedule_peer_task(wgp, WGP_TASK_DESTROY_PREV_SESSION); 2820 1.1 riastrad } 2821 1.1 riastrad 2822 1.1 riastrad static void 2823 1.1 riastrad wg_schedule_session_dtor_timer(struct wg_peer *wgp) 2824 1.1 riastrad { 2825 1.1 riastrad 2826 1.100 riastrad /* 2827 1.100 riastrad * If the periodic session destructor is already pending to 2828 1.100 riastrad * handle the previous session, that's fine -- leave it in 2829 1.100 riastrad * place; it will be scheduled again. 2830 1.100 riastrad */ 2831 1.100 riastrad if (callout_pending(&wgp->wgp_session_dtor_timer)) { 2832 1.100 riastrad WG_DLOG("session dtor already pending\n"); 2833 1.100 riastrad return; 2834 1.100 riastrad } 2835 1.100 riastrad 2836 1.100 riastrad WG_DLOG("scheduling session dtor in %u secs\n", wg_reject_after_time); 2837 1.100 riastrad callout_schedule(&wgp->wgp_session_dtor_timer, 2838 1.100 riastrad wg_reject_after_time*hz); 2839 1.1 riastrad } 2840 1.1 riastrad 2841 1.1 riastrad static bool 2842 1.1 riastrad sockaddr_port_match(const struct sockaddr *sa1, const struct sockaddr *sa2) 2843 1.1 riastrad { 2844 1.1 riastrad if (sa1->sa_family != sa2->sa_family) 2845 1.1 riastrad return false; 2846 1.1 riastrad 2847 1.1 riastrad switch (sa1->sa_family) { 2848 1.62 riastrad #ifdef INET 2849 1.1 riastrad case AF_INET: 2850 1.1 riastrad return satocsin(sa1)->sin_port == satocsin(sa2)->sin_port; 2851 1.62 riastrad #endif 2852 1.62 riastrad #ifdef INET6 2853 1.1 riastrad case AF_INET6: 2854 1.1 riastrad return satocsin6(sa1)->sin6_port == satocsin6(sa2)->sin6_port; 2855 1.62 riastrad #endif 2856 1.1 riastrad default: 2857 1.62 riastrad return false; 2858 1.1 riastrad } 2859 1.1 riastrad } 2860 1.1 riastrad 2861 1.1 riastrad static void 2862 1.1 riastrad wg_update_endpoint_if_necessary(struct wg_peer *wgp, 2863 1.1 riastrad const struct sockaddr *src) 2864 1.1 riastrad { 2865 1.47 riastrad struct wg_sockaddr *wgsa; 2866 1.47 riastrad struct psref psref; 2867 1.47 riastrad 2868 1.47 riastrad wgsa = wg_get_endpoint_sa(wgp, &psref); 2869 1.1 riastrad 2870 1.1 riastrad #ifdef WG_DEBUG_LOG 2871 1.1 riastrad char oldaddr[128], newaddr[128]; 2872 1.47 riastrad sockaddr_format(wgsatosa(wgsa), oldaddr, sizeof(oldaddr)); 2873 1.1 riastrad sockaddr_format(src, newaddr, sizeof(newaddr)); 2874 1.1 riastrad WG_DLOG("old=%s, new=%s\n", oldaddr, newaddr); 2875 1.1 riastrad #endif 2876 1.1 riastrad 2877 1.1 riastrad /* 2878 1.1 riastrad * III: "Since the packet has authenticated correctly, the source IP of 2879 1.1 riastrad * the outer UDP/IP packet is used to update the endpoint for peer..." 2880 1.1 riastrad */ 2881 1.47 riastrad if (__predict_false(sockaddr_cmp(src, wgsatosa(wgsa)) != 0 || 2882 1.47 riastrad !sockaddr_port_match(src, wgsatosa(wgsa)))) { 2883 1.1 riastrad /* XXX We can't change the endpoint twice in a short period */ 2884 1.49 riastrad if (atomic_swap_uint(&wgp->wgp_endpoint_changing, 1) == 0) { 2885 1.1 riastrad wg_change_endpoint(wgp, src); 2886 1.1 riastrad } 2887 1.1 riastrad } 2888 1.47 riastrad 2889 1.47 riastrad wg_put_sa(wgp, wgsa, &psref); 2890 1.1 riastrad } 2891 1.1 riastrad 2892 1.63 riastrad static void __noinline 2893 1.1 riastrad wg_handle_msg_data(struct wg_softc *wg, struct mbuf *m, 2894 1.1 riastrad const struct sockaddr *src) 2895 1.1 riastrad { 2896 1.2 riastrad struct wg_msg_data *wgmd; 2897 1.1 riastrad char *encrypted_buf = NULL, *decrypted_buf; 2898 1.1 riastrad size_t encrypted_len, decrypted_len; 2899 1.1 riastrad struct wg_session *wgs; 2900 1.1 riastrad struct wg_peer *wgp; 2901 1.49 riastrad int state; 2902 1.104 riastrad uint32_t age; 2903 1.1 riastrad size_t mlen; 2904 1.1 riastrad struct psref psref; 2905 1.1 riastrad int error, af; 2906 1.1 riastrad bool success, free_encrypted_buf = false, ok; 2907 1.1 riastrad struct mbuf *n; 2908 1.1 riastrad 2909 1.26 riastrad KASSERT(m->m_len >= sizeof(struct wg_msg_data)); 2910 1.2 riastrad wgmd = mtod(m, struct wg_msg_data *); 2911 1.2 riastrad 2912 1.39 riastrad KASSERT(wgmd->wgmd_type == htole32(WG_MSG_TYPE_DATA)); 2913 1.1 riastrad WG_TRACE("data"); 2914 1.1 riastrad 2915 1.49 riastrad /* Find the putative session, or drop. */ 2916 1.1 riastrad wgs = wg_lookup_session_by_index(wg, wgmd->wgmd_receiver, &psref); 2917 1.1 riastrad if (wgs == NULL) { 2918 1.1 riastrad WG_TRACE("No session found"); 2919 1.1 riastrad m_freem(m); 2920 1.1 riastrad return; 2921 1.1 riastrad } 2922 1.49 riastrad 2923 1.49 riastrad /* 2924 1.49 riastrad * We are only ready to handle data when in INIT_PASSIVE, 2925 1.49 riastrad * ESTABLISHED, or DESTROYING. All transitions out of that 2926 1.49 riastrad * state dissociate the session index and drain psrefs. 2927 1.94 riastrad * 2928 1.94 riastrad * atomic_load_acquire matches atomic_store_release in either 2929 1.94 riastrad * wg_handle_msg_init or wg_handle_msg_resp. (The transition 2930 1.94 riastrad * INIT_PASSIVE to ESTABLISHED in wg_task_establish_session 2931 1.94 riastrad * doesn't make a difference for this rx path.) 2932 1.49 riastrad */ 2933 1.94 riastrad state = atomic_load_acquire(&wgs->wgs_state); 2934 1.49 riastrad switch (state) { 2935 1.49 riastrad case WGS_STATE_UNKNOWN: 2936 1.49 riastrad case WGS_STATE_INIT_ACTIVE: 2937 1.49 riastrad WG_TRACE("not yet ready for data"); 2938 1.49 riastrad goto out; 2939 1.49 riastrad case WGS_STATE_INIT_PASSIVE: 2940 1.49 riastrad case WGS_STATE_ESTABLISHED: 2941 1.49 riastrad case WGS_STATE_DESTROYING: 2942 1.49 riastrad break; 2943 1.49 riastrad } 2944 1.49 riastrad 2945 1.49 riastrad /* 2946 1.101 riastrad * Reject if the session is too old. 2947 1.101 riastrad */ 2948 1.117 riastrad age = time_uptime32 - wgs->wgs_time_established; 2949 1.101 riastrad if (__predict_false(age >= wg_reject_after_time)) { 2950 1.104 riastrad WG_DLOG("session %"PRIx32" too old, %"PRIu32" sec\n", 2951 1.104 riastrad wgmd->wgmd_receiver, age); 2952 1.101 riastrad goto out; 2953 1.101 riastrad } 2954 1.101 riastrad 2955 1.101 riastrad /* 2956 1.49 riastrad * Get the peer, for rate-limited logs (XXX MPSAFE, dtrace) and 2957 1.49 riastrad * to update the endpoint if authentication succeeds. 2958 1.49 riastrad */ 2959 1.1 riastrad wgp = wgs->wgs_peer; 2960 1.1 riastrad 2961 1.49 riastrad /* 2962 1.49 riastrad * Reject outrageously wrong sequence numbers before doing any 2963 1.49 riastrad * crypto work or taking any locks. 2964 1.49 riastrad */ 2965 1.6 riastrad error = sliwin_check_fast(&wgs->wgs_recvwin->window, 2966 1.39 riastrad le64toh(wgmd->wgmd_counter)); 2967 1.6 riastrad if (error) { 2968 1.6 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 2969 1.76 jakllsch "%s: peer %s: out-of-window packet: %"PRIu64"\n", 2970 1.76 jakllsch if_name(&wg->wg_if), wgp->wgp_name, 2971 1.39 riastrad le64toh(wgmd->wgmd_counter)); 2972 1.6 riastrad goto out; 2973 1.6 riastrad } 2974 1.6 riastrad 2975 1.49 riastrad /* Ensure the payload and authenticator are contiguous. */ 2976 1.1 riastrad mlen = m_length(m); 2977 1.1 riastrad encrypted_len = mlen - sizeof(*wgmd); 2978 1.2 riastrad if (encrypted_len < WG_AUTHTAG_LEN) { 2979 1.87 kre WG_DLOG("Short encrypted_len: %zu\n", encrypted_len); 2980 1.2 riastrad goto out; 2981 1.2 riastrad } 2982 1.1 riastrad success = m_ensure_contig(&m, sizeof(*wgmd) + encrypted_len); 2983 1.1 riastrad if (success) { 2984 1.1 riastrad encrypted_buf = mtod(m, char *) + sizeof(*wgmd); 2985 1.1 riastrad } else { 2986 1.1 riastrad encrypted_buf = kmem_intr_alloc(encrypted_len, KM_NOSLEEP); 2987 1.1 riastrad if (encrypted_buf == NULL) { 2988 1.1 riastrad WG_DLOG("failed to allocate encrypted_buf\n"); 2989 1.1 riastrad goto out; 2990 1.1 riastrad } 2991 1.2 riastrad m_copydata(m, sizeof(*wgmd), encrypted_len, encrypted_buf); 2992 1.1 riastrad free_encrypted_buf = true; 2993 1.1 riastrad } 2994 1.1 riastrad /* m_ensure_contig may change m regardless of its result */ 2995 1.27 riastrad KASSERT(m->m_len >= sizeof(*wgmd)); 2996 1.1 riastrad wgmd = mtod(m, struct wg_msg_data *); 2997 1.1 riastrad 2998 1.49 riastrad /* 2999 1.49 riastrad * Get a buffer for the plaintext. Add WG_AUTHTAG_LEN to avoid 3000 1.49 riastrad * a zero-length buffer (XXX). Drop if plaintext is longer 3001 1.49 riastrad * than MCLBYTES (XXX). 3002 1.49 riastrad */ 3003 1.2 riastrad decrypted_len = encrypted_len - WG_AUTHTAG_LEN; 3004 1.2 riastrad if (decrypted_len > MCLBYTES) { 3005 1.2 riastrad /* FIXME handle larger data than MCLBYTES */ 3006 1.2 riastrad WG_DLOG("couldn't handle larger data than MCLBYTES\n"); 3007 1.2 riastrad goto out; 3008 1.2 riastrad } 3009 1.14 riastrad n = wg_get_mbuf(0, decrypted_len + WG_AUTHTAG_LEN); 3010 1.1 riastrad if (n == NULL) { 3011 1.1 riastrad WG_DLOG("wg_get_mbuf failed\n"); 3012 1.1 riastrad goto out; 3013 1.1 riastrad } 3014 1.1 riastrad decrypted_buf = mtod(n, char *); 3015 1.1 riastrad 3016 1.49 riastrad /* Decrypt and verify the packet. */ 3017 1.87 kre WG_DLOG("mlen=%zu, encrypted_len=%zu\n", mlen, encrypted_len); 3018 1.1 riastrad error = wg_algo_aead_dec(decrypted_buf, 3019 1.1 riastrad encrypted_len - WG_AUTHTAG_LEN /* can be 0 */, 3020 1.39 riastrad wgs->wgs_tkey_recv, le64toh(wgmd->wgmd_counter), encrypted_buf, 3021 1.1 riastrad encrypted_len, NULL, 0); 3022 1.1 riastrad if (error != 0) { 3023 1.1 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 3024 1.76 jakllsch "%s: peer %s: failed to wg_algo_aead_dec\n", 3025 1.76 jakllsch if_name(&wg->wg_if), wgp->wgp_name); 3026 1.1 riastrad m_freem(n); 3027 1.1 riastrad goto out; 3028 1.1 riastrad } 3029 1.1 riastrad WG_DLOG("outsize=%u\n", (u_int)decrypted_len); 3030 1.1 riastrad 3031 1.49 riastrad /* Packet is genuine. Reject it if a replay or just too old. */ 3032 1.6 riastrad mutex_enter(&wgs->wgs_recvwin->lock); 3033 1.6 riastrad error = sliwin_update(&wgs->wgs_recvwin->window, 3034 1.39 riastrad le64toh(wgmd->wgmd_counter)); 3035 1.6 riastrad mutex_exit(&wgs->wgs_recvwin->lock); 3036 1.6 riastrad if (error) { 3037 1.1 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 3038 1.76 jakllsch "%s: peer %s: replay or out-of-window packet: %"PRIu64"\n", 3039 1.76 jakllsch if_name(&wg->wg_if), wgp->wgp_name, 3040 1.39 riastrad le64toh(wgmd->wgmd_counter)); 3041 1.1 riastrad m_freem(n); 3042 1.1 riastrad goto out; 3043 1.1 riastrad } 3044 1.1 riastrad 3045 1.49 riastrad /* We're done with m now; free it and chuck the pointers. */ 3046 1.1 riastrad m_freem(m); 3047 1.1 riastrad m = NULL; 3048 1.1 riastrad wgmd = NULL; 3049 1.1 riastrad 3050 1.49 riastrad /* 3051 1.103 riastrad * The packet is genuine. Update the peer's endpoint if the 3052 1.103 riastrad * source address changed. 3053 1.103 riastrad * 3054 1.103 riastrad * XXX How to prevent DoS by replaying genuine packets from the 3055 1.103 riastrad * wrong source address? 3056 1.103 riastrad */ 3057 1.103 riastrad wg_update_endpoint_if_necessary(wgp, src); 3058 1.103 riastrad 3059 1.103 riastrad /* 3060 1.49 riastrad * Validate the encapsulated packet header and get the address 3061 1.49 riastrad * family, or drop. 3062 1.49 riastrad */ 3063 1.2 riastrad ok = wg_validate_inner_packet(decrypted_buf, decrypted_len, &af); 3064 1.1 riastrad if (!ok) { 3065 1.1 riastrad m_freem(n); 3066 1.102 riastrad goto update_state; 3067 1.1 riastrad } 3068 1.1 riastrad 3069 1.49 riastrad /* Submit it into our network stack if routable. */ 3070 1.1 riastrad ok = wg_validate_route(wg, wgp, af, decrypted_buf); 3071 1.1 riastrad if (ok) { 3072 1.1 riastrad wg->wg_ops->input(&wg->wg_if, n, af); 3073 1.1 riastrad } else { 3074 1.76 jakllsch char addrstr[INET6_ADDRSTRLEN]; 3075 1.76 jakllsch memset(addrstr, 0, sizeof(addrstr)); 3076 1.109 riastrad switch (af) { 3077 1.109 riastrad #ifdef INET 3078 1.109 riastrad case AF_INET: { 3079 1.76 jakllsch const struct ip *ip = (const struct ip *)decrypted_buf; 3080 1.76 jakllsch IN_PRINT(addrstr, &ip->ip_src); 3081 1.109 riastrad break; 3082 1.109 riastrad } 3083 1.109 riastrad #endif 3084 1.76 jakllsch #ifdef INET6 3085 1.109 riastrad case AF_INET6: { 3086 1.76 jakllsch const struct ip6_hdr *ip6 = 3087 1.76 jakllsch (const struct ip6_hdr *)decrypted_buf; 3088 1.76 jakllsch IN6_PRINT(addrstr, &ip6->ip6_src); 3089 1.109 riastrad break; 3090 1.109 riastrad } 3091 1.76 jakllsch #endif 3092 1.109 riastrad default: 3093 1.109 riastrad panic("invalid af=%d", af); 3094 1.76 jakllsch } 3095 1.1 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 3096 1.76 jakllsch "%s: peer %s: invalid source address (%s)\n", 3097 1.76 jakllsch if_name(&wg->wg_if), wgp->wgp_name, addrstr); 3098 1.1 riastrad m_freem(n); 3099 1.1 riastrad /* 3100 1.1 riastrad * The inner address is invalid however the session is valid 3101 1.1 riastrad * so continue the session processing below. 3102 1.1 riastrad */ 3103 1.1 riastrad } 3104 1.1 riastrad n = NULL; 3105 1.1 riastrad 3106 1.102 riastrad update_state: 3107 1.49 riastrad /* Update the state machine if necessary. */ 3108 1.49 riastrad if (__predict_false(state == WGS_STATE_INIT_PASSIVE)) { 3109 1.49 riastrad /* 3110 1.49 riastrad * We were waiting for the initiator to send their 3111 1.49 riastrad * first data transport message, and that has happened. 3112 1.49 riastrad * Schedule a task to establish this session. 3113 1.49 riastrad */ 3114 1.49 riastrad wg_schedule_peer_task(wgp, WGP_TASK_ESTABLISH_SESSION); 3115 1.1 riastrad } else { 3116 1.1 riastrad if (__predict_false(wg_need_to_send_init_message(wgs))) { 3117 1.1 riastrad wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 3118 1.1 riastrad } 3119 1.1 riastrad /* 3120 1.1 riastrad * [W] 6.5 Passive Keepalive 3121 1.1 riastrad * "If a peer has received a validly-authenticated transport 3122 1.1 riastrad * data message (section 5.4.6), but does not have any packets 3123 1.1 riastrad * itself to send back for KEEPALIVE-TIMEOUT seconds, it sends 3124 1.1 riastrad * a keepalive message." 3125 1.1 riastrad */ 3126 1.104 riastrad const uint32_t now = time_uptime32; 3127 1.104 riastrad const uint32_t time_last_data_sent = 3128 1.104 riastrad atomic_load_relaxed(&wgs->wgs_time_last_data_sent); 3129 1.104 riastrad WG_DLOG("time_uptime32=%"PRIu32 3130 1.104 riastrad " wgs_time_last_data_sent=%"PRIu32"\n", 3131 1.104 riastrad now, time_last_data_sent); 3132 1.104 riastrad if ((now - time_last_data_sent) >= wg_keepalive_timeout) { 3133 1.1 riastrad WG_TRACE("Schedule sending keepalive message"); 3134 1.1 riastrad /* 3135 1.1 riastrad * We can't send a keepalive message here to avoid 3136 1.1 riastrad * a deadlock; we already hold the solock of a socket 3137 1.1 riastrad * that is used to send the message. 3138 1.1 riastrad */ 3139 1.14 riastrad wg_schedule_peer_task(wgp, 3140 1.14 riastrad WGP_TASK_SEND_KEEPALIVE_MESSAGE); 3141 1.1 riastrad } 3142 1.1 riastrad } 3143 1.1 riastrad out: 3144 1.1 riastrad wg_put_session(wgs, &psref); 3145 1.79 rin m_freem(m); 3146 1.1 riastrad if (free_encrypted_buf) 3147 1.1 riastrad kmem_intr_free(encrypted_buf, encrypted_len); 3148 1.1 riastrad } 3149 1.1 riastrad 3150 1.63 riastrad static void __noinline 3151 1.1 riastrad wg_handle_msg_cookie(struct wg_softc *wg, const struct wg_msg_cookie *wgmc) 3152 1.1 riastrad { 3153 1.1 riastrad struct wg_session *wgs; 3154 1.1 riastrad struct wg_peer *wgp; 3155 1.1 riastrad struct psref psref; 3156 1.1 riastrad int error; 3157 1.1 riastrad uint8_t key[WG_HASH_LEN]; 3158 1.1 riastrad uint8_t cookie[WG_COOKIE_LEN]; 3159 1.1 riastrad 3160 1.1 riastrad WG_TRACE("cookie msg received"); 3161 1.49 riastrad 3162 1.49 riastrad /* Find the putative session. */ 3163 1.1 riastrad wgs = wg_lookup_session_by_index(wg, wgmc->wgmc_receiver, &psref); 3164 1.1 riastrad if (wgs == NULL) { 3165 1.1 riastrad WG_TRACE("No session found"); 3166 1.1 riastrad return; 3167 1.1 riastrad } 3168 1.49 riastrad 3169 1.49 riastrad /* Lock the peer so we can update the cookie state. */ 3170 1.1 riastrad wgp = wgs->wgs_peer; 3171 1.49 riastrad mutex_enter(wgp->wgp_lock); 3172 1.1 riastrad 3173 1.1 riastrad if (!wgp->wgp_last_sent_mac1_valid) { 3174 1.1 riastrad WG_TRACE("No valid mac1 sent (or expired)"); 3175 1.1 riastrad goto out; 3176 1.1 riastrad } 3177 1.1 riastrad 3178 1.94 riastrad /* 3179 1.94 riastrad * wgp_last_sent_mac1_valid is only set to true when we are 3180 1.94 riastrad * transitioning to INIT_ACTIVE or INIT_PASSIVE, and always 3181 1.94 riastrad * cleared on transition out of them. 3182 1.94 riastrad */ 3183 1.94 riastrad KASSERTMSG((wgs->wgs_state == WGS_STATE_INIT_ACTIVE || 3184 1.94 riastrad wgs->wgs_state == WGS_STATE_INIT_PASSIVE), 3185 1.94 riastrad "state=%d", wgs->wgs_state); 3186 1.94 riastrad 3187 1.49 riastrad /* Decrypt the cookie and store it for later handshake retry. */ 3188 1.1 riastrad wg_algo_mac_cookie(key, sizeof(key), wgp->wgp_pubkey, 3189 1.1 riastrad sizeof(wgp->wgp_pubkey)); 3190 1.36 riastrad error = wg_algo_xaead_dec(cookie, sizeof(cookie), key, 3191 1.1 riastrad wgmc->wgmc_cookie, sizeof(wgmc->wgmc_cookie), 3192 1.1 riastrad wgp->wgp_last_sent_mac1, sizeof(wgp->wgp_last_sent_mac1), 3193 1.1 riastrad wgmc->wgmc_salt); 3194 1.1 riastrad if (error != 0) { 3195 1.1 riastrad WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, 3196 1.76 jakllsch "%s: peer %s: wg_algo_aead_dec for cookie failed: " 3197 1.76 jakllsch "error=%d\n", if_name(&wg->wg_if), wgp->wgp_name, error); 3198 1.1 riastrad goto out; 3199 1.1 riastrad } 3200 1.1 riastrad /* 3201 1.1 riastrad * [W] 6.6: Interaction with Cookie Reply System 3202 1.1 riastrad * "it should simply store the decrypted cookie value from the cookie 3203 1.1 riastrad * reply message, and wait for the expiration of the REKEY-TIMEOUT 3204 1.1 riastrad * timer for retrying a handshake initiation message." 3205 1.1 riastrad */ 3206 1.1 riastrad wgp->wgp_latest_cookie_time = time_uptime; 3207 1.1 riastrad memcpy(wgp->wgp_latest_cookie, cookie, sizeof(wgp->wgp_latest_cookie)); 3208 1.1 riastrad out: 3209 1.49 riastrad mutex_exit(wgp->wgp_lock); 3210 1.1 riastrad wg_put_session(wgs, &psref); 3211 1.1 riastrad } 3212 1.1 riastrad 3213 1.26 riastrad static struct mbuf * 3214 1.26 riastrad wg_validate_msg_header(struct wg_softc *wg, struct mbuf *m) 3215 1.2 riastrad { 3216 1.26 riastrad struct wg_msg wgm; 3217 1.26 riastrad size_t mbuflen; 3218 1.26 riastrad size_t msglen; 3219 1.2 riastrad 3220 1.26 riastrad /* 3221 1.26 riastrad * Get the mbuf chain length. It is already guaranteed, by 3222 1.26 riastrad * wg_overudp_cb, to be large enough for a struct wg_msg. 3223 1.26 riastrad */ 3224 1.26 riastrad mbuflen = m_length(m); 3225 1.26 riastrad KASSERT(mbuflen >= sizeof(struct wg_msg)); 3226 1.2 riastrad 3227 1.26 riastrad /* 3228 1.26 riastrad * Copy the message header (32-bit message type) out -- we'll 3229 1.26 riastrad * worry about contiguity and alignment later. 3230 1.26 riastrad */ 3231 1.26 riastrad m_copydata(m, 0, sizeof(wgm), &wgm); 3232 1.39 riastrad switch (le32toh(wgm.wgm_type)) { 3233 1.2 riastrad case WG_MSG_TYPE_INIT: 3234 1.26 riastrad msglen = sizeof(struct wg_msg_init); 3235 1.2 riastrad break; 3236 1.2 riastrad case WG_MSG_TYPE_RESP: 3237 1.26 riastrad msglen = sizeof(struct wg_msg_resp); 3238 1.2 riastrad break; 3239 1.2 riastrad case WG_MSG_TYPE_COOKIE: 3240 1.26 riastrad msglen = sizeof(struct wg_msg_cookie); 3241 1.2 riastrad break; 3242 1.2 riastrad case WG_MSG_TYPE_DATA: 3243 1.26 riastrad msglen = sizeof(struct wg_msg_data); 3244 1.2 riastrad break; 3245 1.2 riastrad default: 3246 1.2 riastrad WG_LOG_RATECHECK(&wg->wg_ppsratecheck, LOG_DEBUG, 3247 1.76 jakllsch "%s: Unexpected msg type: %u\n", if_name(&wg->wg_if), 3248 1.76 jakllsch le32toh(wgm.wgm_type)); 3249 1.26 riastrad goto error; 3250 1.26 riastrad } 3251 1.26 riastrad 3252 1.26 riastrad /* Verify the mbuf chain is long enough for this type of message. */ 3253 1.26 riastrad if (__predict_false(mbuflen < msglen)) { 3254 1.87 kre WG_DLOG("Invalid msg size: mbuflen=%zu type=%u\n", mbuflen, 3255 1.39 riastrad le32toh(wgm.wgm_type)); 3256 1.26 riastrad goto error; 3257 1.26 riastrad } 3258 1.26 riastrad 3259 1.26 riastrad /* Make the message header contiguous if necessary. */ 3260 1.26 riastrad if (__predict_false(m->m_len < msglen)) { 3261 1.26 riastrad m = m_pullup(m, msglen); 3262 1.26 riastrad if (m == NULL) 3263 1.26 riastrad return NULL; 3264 1.2 riastrad } 3265 1.2 riastrad 3266 1.26 riastrad return m; 3267 1.26 riastrad 3268 1.26 riastrad error: 3269 1.26 riastrad m_freem(m); 3270 1.26 riastrad return NULL; 3271 1.2 riastrad } 3272 1.2 riastrad 3273 1.1 riastrad static void 3274 1.14 riastrad wg_handle_packet(struct wg_softc *wg, struct mbuf *m, 3275 1.14 riastrad const struct sockaddr *src) 3276 1.1 riastrad { 3277 1.1 riastrad struct wg_msg *wgm; 3278 1.2 riastrad 3279 1.78 riastrad KASSERT(curlwp->l_pflag & LP_BOUND); 3280 1.78 riastrad 3281 1.26 riastrad m = wg_validate_msg_header(wg, m); 3282 1.26 riastrad if (__predict_false(m == NULL)) 3283 1.2 riastrad return; 3284 1.1 riastrad 3285 1.26 riastrad KASSERT(m->m_len >= sizeof(struct wg_msg)); 3286 1.1 riastrad wgm = mtod(m, struct wg_msg *); 3287 1.39 riastrad switch (le32toh(wgm->wgm_type)) { 3288 1.1 riastrad case WG_MSG_TYPE_INIT: 3289 1.1 riastrad wg_handle_msg_init(wg, (struct wg_msg_init *)wgm, src); 3290 1.1 riastrad break; 3291 1.1 riastrad case WG_MSG_TYPE_RESP: 3292 1.1 riastrad wg_handle_msg_resp(wg, (struct wg_msg_resp *)wgm, src); 3293 1.1 riastrad break; 3294 1.1 riastrad case WG_MSG_TYPE_COOKIE: 3295 1.1 riastrad wg_handle_msg_cookie(wg, (struct wg_msg_cookie *)wgm); 3296 1.1 riastrad break; 3297 1.1 riastrad case WG_MSG_TYPE_DATA: 3298 1.1 riastrad wg_handle_msg_data(wg, m, src); 3299 1.38 riastrad /* wg_handle_msg_data frees m for us */ 3300 1.38 riastrad return; 3301 1.1 riastrad default: 3302 1.39 riastrad panic("invalid message type: %d", le32toh(wgm->wgm_type)); 3303 1.1 riastrad } 3304 1.38 riastrad 3305 1.38 riastrad m_freem(m); 3306 1.1 riastrad } 3307 1.1 riastrad 3308 1.1 riastrad static void 3309 1.1 riastrad wg_receive_packets(struct wg_softc *wg, const int af) 3310 1.1 riastrad { 3311 1.1 riastrad 3312 1.14 riastrad for (;;) { 3313 1.1 riastrad int error, flags; 3314 1.1 riastrad struct socket *so; 3315 1.1 riastrad struct mbuf *m = NULL; 3316 1.1 riastrad struct uio dummy_uio; 3317 1.1 riastrad struct mbuf *paddr = NULL; 3318 1.1 riastrad struct sockaddr *src; 3319 1.1 riastrad 3320 1.55 riastrad so = wg_get_so_by_af(wg, af); 3321 1.1 riastrad flags = MSG_DONTWAIT; 3322 1.1 riastrad dummy_uio.uio_resid = 1000000000; 3323 1.1 riastrad 3324 1.14 riastrad error = so->so_receive(so, &paddr, &dummy_uio, &m, NULL, 3325 1.14 riastrad &flags); 3326 1.1 riastrad if (error || m == NULL) { 3327 1.1 riastrad //if (error == EWOULDBLOCK) 3328 1.1 riastrad return; 3329 1.1 riastrad } 3330 1.1 riastrad 3331 1.1 riastrad KASSERT(paddr != NULL); 3332 1.27 riastrad KASSERT(paddr->m_len >= sizeof(struct sockaddr)); 3333 1.1 riastrad src = mtod(paddr, struct sockaddr *); 3334 1.1 riastrad 3335 1.1 riastrad wg_handle_packet(wg, m, src); 3336 1.1 riastrad } 3337 1.1 riastrad } 3338 1.1 riastrad 3339 1.1 riastrad static void 3340 1.1 riastrad wg_get_peer(struct wg_peer *wgp, struct psref *psref) 3341 1.1 riastrad { 3342 1.1 riastrad 3343 1.1 riastrad psref_acquire(psref, &wgp->wgp_psref, wg_psref_class); 3344 1.1 riastrad } 3345 1.1 riastrad 3346 1.1 riastrad static void 3347 1.1 riastrad wg_put_peer(struct wg_peer *wgp, struct psref *psref) 3348 1.1 riastrad { 3349 1.1 riastrad 3350 1.1 riastrad psref_release(psref, &wgp->wgp_psref, wg_psref_class); 3351 1.1 riastrad } 3352 1.1 riastrad 3353 1.1 riastrad static void 3354 1.11 riastrad wg_task_send_init_message(struct wg_softc *wg, struct wg_peer *wgp) 3355 1.11 riastrad { 3356 1.11 riastrad struct wg_session *wgs; 3357 1.11 riastrad 3358 1.11 riastrad WG_TRACE("WGP_TASK_SEND_INIT_MESSAGE"); 3359 1.11 riastrad 3360 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 3361 1.49 riastrad 3362 1.49 riastrad if (!atomic_load_acquire(&wgp->wgp_endpoint_available)) { 3363 1.76 jakllsch WGLOG(LOG_DEBUG, "%s: No endpoint available\n", 3364 1.76 jakllsch if_name(&wg->wg_if)); 3365 1.11 riastrad /* XXX should do something? */ 3366 1.11 riastrad return; 3367 1.11 riastrad } 3368 1.11 riastrad 3369 1.95 riastrad /* 3370 1.95 riastrad * If we already have an established session, there's no need 3371 1.95 riastrad * to initiate a new one -- unless the rekey-after-time or 3372 1.95 riastrad * rekey-after-messages limits have passed. 3373 1.95 riastrad */ 3374 1.49 riastrad wgs = wgp->wgp_session_stable; 3375 1.95 riastrad if (wgs->wgs_state == WGS_STATE_ESTABLISHED && 3376 1.113 riastrad !atomic_load_relaxed(&wgs->wgs_force_rekey)) 3377 1.95 riastrad return; 3378 1.95 riastrad 3379 1.95 riastrad /* 3380 1.95 riastrad * Ensure we're initiating a new session. If the unstable 3381 1.95 riastrad * session is already INIT_ACTIVE or INIT_PASSIVE, this does 3382 1.95 riastrad * nothing. 3383 1.95 riastrad */ 3384 1.95 riastrad wg_send_handshake_msg_init(wg, wgp); 3385 1.11 riastrad } 3386 1.11 riastrad 3387 1.11 riastrad static void 3388 1.49 riastrad wg_task_retry_handshake(struct wg_softc *wg, struct wg_peer *wgp) 3389 1.49 riastrad { 3390 1.49 riastrad struct wg_session *wgs; 3391 1.49 riastrad 3392 1.49 riastrad WG_TRACE("WGP_TASK_RETRY_HANDSHAKE"); 3393 1.49 riastrad 3394 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 3395 1.49 riastrad 3396 1.49 riastrad wgs = wgp->wgp_session_unstable; 3397 1.49 riastrad if (wgs->wgs_state != WGS_STATE_INIT_ACTIVE) 3398 1.49 riastrad return; 3399 1.49 riastrad 3400 1.133 riastrad KASSERT(wgp->wgp_handshake_start_time != 0); 3401 1.133 riastrad 3402 1.49 riastrad /* 3403 1.49 riastrad * XXX no real need to assign a new index here, but we do need 3404 1.49 riastrad * to transition to UNKNOWN temporarily 3405 1.49 riastrad */ 3406 1.49 riastrad wg_put_session_index(wg, wgs); 3407 1.49 riastrad 3408 1.49 riastrad /* [W] 6.4 Handshake Initiation Retransmission */ 3409 1.49 riastrad if ((time_uptime - wgp->wgp_handshake_start_time) > 3410 1.49 riastrad wg_rekey_attempt_time) { 3411 1.49 riastrad /* Give up handshaking */ 3412 1.49 riastrad wgp->wgp_handshake_start_time = 0; 3413 1.49 riastrad WG_TRACE("give up"); 3414 1.49 riastrad 3415 1.49 riastrad /* 3416 1.49 riastrad * If a new data packet comes, handshaking will be retried 3417 1.49 riastrad * and a new session would be established at that time, 3418 1.49 riastrad * however we don't want to send pending packets then. 3419 1.49 riastrad */ 3420 1.49 riastrad wg_purge_pending_packets(wgp); 3421 1.49 riastrad return; 3422 1.49 riastrad } 3423 1.49 riastrad 3424 1.49 riastrad wg_task_send_init_message(wg, wgp); 3425 1.49 riastrad } 3426 1.49 riastrad 3427 1.49 riastrad static void 3428 1.49 riastrad wg_task_establish_session(struct wg_softc *wg, struct wg_peer *wgp) 3429 1.49 riastrad { 3430 1.122 riastrad struct wg_session *wgs; 3431 1.49 riastrad 3432 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 3433 1.49 riastrad 3434 1.49 riastrad wgs = wgp->wgp_session_unstable; 3435 1.49 riastrad if (wgs->wgs_state != WGS_STATE_INIT_PASSIVE) 3436 1.49 riastrad /* XXX Can this happen? */ 3437 1.49 riastrad return; 3438 1.49 riastrad 3439 1.49 riastrad wgs->wgs_time_last_data_sent = 0; 3440 1.49 riastrad wgs->wgs_is_initiator = false; 3441 1.94 riastrad 3442 1.94 riastrad /* 3443 1.94 riastrad * Session was already ready to receive data. Transition from 3444 1.94 riastrad * INIT_PASSIVE to ESTABLISHED just so we can swap the 3445 1.94 riastrad * sessions. 3446 1.94 riastrad * 3447 1.94 riastrad * atomic_store_relaxed because this doesn't affect the data rx 3448 1.94 riastrad * path, wg_handle_msg_data -- changing from INIT_PASSIVE to 3449 1.94 riastrad * ESTABLISHED makes no difference to the data rx path, and the 3450 1.94 riastrad * transition to INIT_PASSIVE with store-release already 3451 1.94 riastrad * published the state needed by the data rx path. 3452 1.94 riastrad */ 3453 1.94 riastrad WG_DLOG("session[L=%"PRIx32" R=%"PRIx32"] -> WGS_STATE_ESTABLISHED\n", 3454 1.94 riastrad wgs->wgs_local_index, wgs->wgs_remote_index); 3455 1.94 riastrad atomic_store_relaxed(&wgs->wgs_state, WGS_STATE_ESTABLISHED); 3456 1.49 riastrad WG_TRACE("WGS_STATE_ESTABLISHED"); 3457 1.49 riastrad 3458 1.94 riastrad /* 3459 1.94 riastrad * Session is ready to send data too now that we have received 3460 1.94 riastrad * the peer initiator's first data packet. 3461 1.94 riastrad * 3462 1.94 riastrad * Swap the sessions to publish the new one as the stable 3463 1.94 riastrad * session for the data tx path, wg_output. 3464 1.94 riastrad */ 3465 1.122 riastrad wg_swap_sessions(wg, wgp); 3466 1.49 riastrad KASSERT(wgs == wgp->wgp_session_stable); 3467 1.49 riastrad } 3468 1.49 riastrad 3469 1.49 riastrad static void 3470 1.11 riastrad wg_task_endpoint_changed(struct wg_softc *wg, struct wg_peer *wgp) 3471 1.11 riastrad { 3472 1.11 riastrad 3473 1.11 riastrad WG_TRACE("WGP_TASK_ENDPOINT_CHANGED"); 3474 1.11 riastrad 3475 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 3476 1.49 riastrad 3477 1.49 riastrad if (atomic_load_relaxed(&wgp->wgp_endpoint_changing)) { 3478 1.11 riastrad pserialize_perform(wgp->wgp_psz); 3479 1.56 riastrad mutex_exit(wgp->wgp_lock); 3480 1.11 riastrad psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, 3481 1.11 riastrad wg_psref_class); 3482 1.11 riastrad psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, 3483 1.11 riastrad wg_psref_class); 3484 1.56 riastrad mutex_enter(wgp->wgp_lock); 3485 1.49 riastrad atomic_store_release(&wgp->wgp_endpoint_changing, 0); 3486 1.11 riastrad } 3487 1.11 riastrad } 3488 1.11 riastrad 3489 1.11 riastrad static void 3490 1.11 riastrad wg_task_send_keepalive_message(struct wg_softc *wg, struct wg_peer *wgp) 3491 1.11 riastrad { 3492 1.11 riastrad struct wg_session *wgs; 3493 1.11 riastrad 3494 1.11 riastrad WG_TRACE("WGP_TASK_SEND_KEEPALIVE_MESSAGE"); 3495 1.11 riastrad 3496 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 3497 1.49 riastrad 3498 1.49 riastrad wgs = wgp->wgp_session_stable; 3499 1.49 riastrad if (wgs->wgs_state != WGS_STATE_ESTABLISHED) 3500 1.49 riastrad return; 3501 1.49 riastrad 3502 1.11 riastrad wg_send_keepalive_msg(wgp, wgs); 3503 1.11 riastrad } 3504 1.11 riastrad 3505 1.11 riastrad static void 3506 1.11 riastrad wg_task_destroy_prev_session(struct wg_softc *wg, struct wg_peer *wgp) 3507 1.11 riastrad { 3508 1.11 riastrad struct wg_session *wgs; 3509 1.104 riastrad uint32_t age; 3510 1.11 riastrad 3511 1.11 riastrad WG_TRACE("WGP_TASK_DESTROY_PREV_SESSION"); 3512 1.11 riastrad 3513 1.49 riastrad KASSERT(mutex_owned(wgp->wgp_lock)); 3514 1.49 riastrad 3515 1.100 riastrad /* 3516 1.100 riastrad * If theres's any previous unstable session, i.e., one that 3517 1.100 riastrad * was ESTABLISHED and is now DESTROYING, older than 3518 1.100 riastrad * reject-after-time, destroy it. Upcoming sessions are still 3519 1.100 riastrad * in INIT_ACTIVE or INIT_PASSIVE -- we don't touch those here. 3520 1.100 riastrad */ 3521 1.11 riastrad wgs = wgp->wgp_session_unstable; 3522 1.100 riastrad KASSERT(wgs->wgs_state != WGS_STATE_ESTABLISHED); 3523 1.100 riastrad if (wgs->wgs_state == WGS_STATE_DESTROYING && 3524 1.104 riastrad ((age = (time_uptime32 - wgs->wgs_time_established)) >= 3525 1.100 riastrad wg_reject_after_time)) { 3526 1.104 riastrad WG_DLOG("destroying past session %"PRIu32" sec old\n", age); 3527 1.49 riastrad wg_put_session_index(wg, wgs); 3528 1.100 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 3529 1.100 riastrad wgs->wgs_state); 3530 1.100 riastrad } 3531 1.100 riastrad 3532 1.100 riastrad /* 3533 1.100 riastrad * If theres's any ESTABLISHED stable session older than 3534 1.100 riastrad * reject-after-time, destroy it. (The stable session can also 3535 1.100 riastrad * be in UNKNOWN state -- nothing to do in that case) 3536 1.100 riastrad */ 3537 1.100 riastrad wgs = wgp->wgp_session_stable; 3538 1.100 riastrad KASSERT(wgs->wgs_state != WGS_STATE_INIT_ACTIVE); 3539 1.100 riastrad KASSERT(wgs->wgs_state != WGS_STATE_INIT_PASSIVE); 3540 1.100 riastrad KASSERT(wgs->wgs_state != WGS_STATE_DESTROYING); 3541 1.100 riastrad if (wgs->wgs_state == WGS_STATE_ESTABLISHED && 3542 1.104 riastrad ((age = (time_uptime32 - wgs->wgs_time_established)) >= 3543 1.100 riastrad wg_reject_after_time)) { 3544 1.104 riastrad WG_DLOG("destroying current session %"PRIu32" sec old\n", age); 3545 1.100 riastrad atomic_store_relaxed(&wgs->wgs_state, WGS_STATE_DESTROYING); 3546 1.100 riastrad wg_put_session_index(wg, wgs); 3547 1.100 riastrad KASSERTMSG(wgs->wgs_state == WGS_STATE_UNKNOWN, "state=%d", 3548 1.100 riastrad wgs->wgs_state); 3549 1.11 riastrad } 3550 1.100 riastrad 3551 1.100 riastrad /* 3552 1.100 riastrad * If there's no sessions left, no need to have the timer run 3553 1.100 riastrad * until the next time around -- halt it. 3554 1.100 riastrad * 3555 1.100 riastrad * It is only ever scheduled with wgp_lock held or in the 3556 1.100 riastrad * callout itself, and callout_halt prevents rescheudling 3557 1.100 riastrad * itself, so this never races with rescheduling. 3558 1.100 riastrad */ 3559 1.100 riastrad if (wgp->wgp_session_unstable->wgs_state == WGS_STATE_UNKNOWN && 3560 1.100 riastrad wgp->wgp_session_stable->wgs_state == WGS_STATE_UNKNOWN) 3561 1.100 riastrad callout_halt(&wgp->wgp_session_dtor_timer, NULL); 3562 1.11 riastrad } 3563 1.11 riastrad 3564 1.11 riastrad static void 3565 1.55 riastrad wg_peer_work(struct work *wk, void *cookie) 3566 1.1 riastrad { 3567 1.55 riastrad struct wg_peer *wgp = container_of(wk, struct wg_peer, wgp_work); 3568 1.55 riastrad struct wg_softc *wg = wgp->wgp_sc; 3569 1.65 christos unsigned int tasks; 3570 1.1 riastrad 3571 1.55 riastrad mutex_enter(wgp->wgp_intr_lock); 3572 1.55 riastrad while ((tasks = wgp->wgp_tasks) != 0) { 3573 1.55 riastrad wgp->wgp_tasks = 0; 3574 1.55 riastrad mutex_exit(wgp->wgp_intr_lock); 3575 1.1 riastrad 3576 1.49 riastrad mutex_enter(wgp->wgp_lock); 3577 1.11 riastrad if (ISSET(tasks, WGP_TASK_SEND_INIT_MESSAGE)) 3578 1.11 riastrad wg_task_send_init_message(wg, wgp); 3579 1.49 riastrad if (ISSET(tasks, WGP_TASK_RETRY_HANDSHAKE)) 3580 1.49 riastrad wg_task_retry_handshake(wg, wgp); 3581 1.49 riastrad if (ISSET(tasks, WGP_TASK_ESTABLISH_SESSION)) 3582 1.49 riastrad wg_task_establish_session(wg, wgp); 3583 1.11 riastrad if (ISSET(tasks, WGP_TASK_ENDPOINT_CHANGED)) 3584 1.11 riastrad wg_task_endpoint_changed(wg, wgp); 3585 1.11 riastrad if (ISSET(tasks, WGP_TASK_SEND_KEEPALIVE_MESSAGE)) 3586 1.11 riastrad wg_task_send_keepalive_message(wg, wgp); 3587 1.11 riastrad if (ISSET(tasks, WGP_TASK_DESTROY_PREV_SESSION)) 3588 1.11 riastrad wg_task_destroy_prev_session(wg, wgp); 3589 1.49 riastrad mutex_exit(wgp->wgp_lock); 3590 1.1 riastrad 3591 1.55 riastrad mutex_enter(wgp->wgp_intr_lock); 3592 1.1 riastrad } 3593 1.55 riastrad mutex_exit(wgp->wgp_intr_lock); 3594 1.1 riastrad } 3595 1.1 riastrad 3596 1.1 riastrad static void 3597 1.55 riastrad wg_job(struct threadpool_job *job) 3598 1.1 riastrad { 3599 1.55 riastrad struct wg_softc *wg = container_of(job, struct wg_softc, wg_job); 3600 1.55 riastrad int bound, upcalls; 3601 1.1 riastrad 3602 1.55 riastrad mutex_enter(wg->wg_intr_lock); 3603 1.55 riastrad while ((upcalls = wg->wg_upcalls) != 0) { 3604 1.55 riastrad wg->wg_upcalls = 0; 3605 1.55 riastrad mutex_exit(wg->wg_intr_lock); 3606 1.10 riastrad bound = curlwp_bind(); 3607 1.55 riastrad if (ISSET(upcalls, WG_UPCALL_INET)) 3608 1.1 riastrad wg_receive_packets(wg, AF_INET); 3609 1.55 riastrad if (ISSET(upcalls, WG_UPCALL_INET6)) 3610 1.1 riastrad wg_receive_packets(wg, AF_INET6); 3611 1.10 riastrad curlwp_bindx(bound); 3612 1.55 riastrad mutex_enter(wg->wg_intr_lock); 3613 1.1 riastrad } 3614 1.55 riastrad threadpool_job_done(job); 3615 1.55 riastrad mutex_exit(wg->wg_intr_lock); 3616 1.1 riastrad } 3617 1.1 riastrad 3618 1.1 riastrad static int 3619 1.1 riastrad wg_bind_port(struct wg_softc *wg, const uint16_t port) 3620 1.1 riastrad { 3621 1.109 riastrad int error = 0; 3622 1.1 riastrad uint16_t old_port = wg->wg_listen_port; 3623 1.1 riastrad 3624 1.1 riastrad if (port != 0 && old_port == port) 3625 1.1 riastrad return 0; 3626 1.1 riastrad 3627 1.109 riastrad #ifdef INET 3628 1.1 riastrad struct sockaddr_in _sin, *sin = &_sin; 3629 1.1 riastrad sin->sin_len = sizeof(*sin); 3630 1.1 riastrad sin->sin_family = AF_INET; 3631 1.1 riastrad sin->sin_addr.s_addr = INADDR_ANY; 3632 1.1 riastrad sin->sin_port = htons(port); 3633 1.1 riastrad 3634 1.55 riastrad error = sobind(wg->wg_so4, sintosa(sin), curlwp); 3635 1.109 riastrad if (error) 3636 1.1 riastrad return error; 3637 1.109 riastrad #endif 3638 1.1 riastrad 3639 1.1 riastrad #ifdef INET6 3640 1.1 riastrad struct sockaddr_in6 _sin6, *sin6 = &_sin6; 3641 1.1 riastrad sin6->sin6_len = sizeof(*sin6); 3642 1.1 riastrad sin6->sin6_family = AF_INET6; 3643 1.1 riastrad sin6->sin6_addr = in6addr_any; 3644 1.1 riastrad sin6->sin6_port = htons(port); 3645 1.1 riastrad 3646 1.55 riastrad error = sobind(wg->wg_so6, sin6tosa(sin6), curlwp); 3647 1.109 riastrad if (error) 3648 1.1 riastrad return error; 3649 1.1 riastrad #endif 3650 1.1 riastrad 3651 1.1 riastrad wg->wg_listen_port = port; 3652 1.1 riastrad 3653 1.109 riastrad return error; 3654 1.1 riastrad } 3655 1.1 riastrad 3656 1.1 riastrad static void 3657 1.55 riastrad wg_so_upcall(struct socket *so, void *cookie, int events, int waitflag) 3658 1.1 riastrad { 3659 1.55 riastrad struct wg_softc *wg = cookie; 3660 1.1 riastrad int reason; 3661 1.1 riastrad 3662 1.1 riastrad reason = (so->so_proto->pr_domain->dom_family == AF_INET) ? 3663 1.55 riastrad WG_UPCALL_INET : 3664 1.55 riastrad WG_UPCALL_INET6; 3665 1.55 riastrad 3666 1.55 riastrad mutex_enter(wg->wg_intr_lock); 3667 1.55 riastrad wg->wg_upcalls |= reason; 3668 1.55 riastrad threadpool_schedule_job(wg->wg_threadpool, &wg->wg_job); 3669 1.55 riastrad mutex_exit(wg->wg_intr_lock); 3670 1.1 riastrad } 3671 1.1 riastrad 3672 1.132 riastrad /* 3673 1.132 riastrad * wg_overudp_cb(&m, offset, so, src, arg) 3674 1.132 riastrad * 3675 1.132 riastrad * Callback for incoming UDP packets in high-priority 3676 1.132 riastrad * packet-processing path. 3677 1.132 riastrad * 3678 1.132 riastrad * Three cases: 3679 1.132 riastrad * 3680 1.132 riastrad * - Data packet. Consumed here for high-priority handling. 3681 1.132 riastrad * => Returns 1 and takes ownership of m. 3682 1.132 riastrad * 3683 1.132 riastrad * - Handshake packet. Defer to thread context via so_receive in 3684 1.132 riastrad * wg_receive_packets. 3685 1.132 riastrad * => Returns 0 and leaves caller with ownership of m. 3686 1.132 riastrad * 3687 1.132 riastrad * - Invalid. Dropped on the floor and freed. 3688 1.132 riastrad * => Returns -1 and takes ownership of m (frees m). 3689 1.132 riastrad */ 3690 1.1 riastrad static int 3691 1.1 riastrad wg_overudp_cb(struct mbuf **mp, int offset, struct socket *so, 3692 1.1 riastrad struct sockaddr *src, void *arg) 3693 1.1 riastrad { 3694 1.1 riastrad struct wg_softc *wg = arg; 3695 1.2 riastrad struct wg_msg wgm; 3696 1.1 riastrad struct mbuf *m = *mp; 3697 1.1 riastrad 3698 1.1 riastrad WG_TRACE("enter"); 3699 1.1 riastrad 3700 1.25 riastrad /* Verify the mbuf chain is long enough to have a wg msg header. */ 3701 1.25 riastrad KASSERT(offset <= m_length(m)); 3702 1.25 riastrad if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) { 3703 1.28 riastrad /* drop on the floor */ 3704 1.25 riastrad m_freem(m); 3705 1.132 riastrad *mp = NULL; 3706 1.132 riastrad return -1; /* dropped */ 3707 1.25 riastrad } 3708 1.25 riastrad 3709 1.25 riastrad /* 3710 1.25 riastrad * Copy the message header (32-bit message type) out -- we'll 3711 1.25 riastrad * worry about contiguity and alignment later. 3712 1.25 riastrad */ 3713 1.2 riastrad m_copydata(m, offset, sizeof(struct wg_msg), &wgm); 3714 1.39 riastrad WG_DLOG("type=%d\n", le32toh(wgm.wgm_type)); 3715 1.2 riastrad 3716 1.25 riastrad /* 3717 1.94 riastrad * Handle DATA packets promptly as they arrive, if they are in 3718 1.94 riastrad * an active session. Other packets may require expensive 3719 1.94 riastrad * public-key crypto and are not as sensitive to latency, so 3720 1.94 riastrad * defer them to the worker thread. 3721 1.25 riastrad */ 3722 1.39 riastrad switch (le32toh(wgm.wgm_type)) { 3723 1.1 riastrad case WG_MSG_TYPE_DATA: 3724 1.28 riastrad /* handle immediately */ 3725 1.1 riastrad m_adj(m, offset); 3726 1.29 riastrad if (__predict_false(m->m_len < sizeof(struct wg_msg_data))) { 3727 1.29 riastrad m = m_pullup(m, sizeof(struct wg_msg_data)); 3728 1.132 riastrad if (m == NULL) { 3729 1.132 riastrad *mp = NULL; 3730 1.132 riastrad return -1; /* dropped */ 3731 1.132 riastrad } 3732 1.29 riastrad } 3733 1.1 riastrad wg_handle_msg_data(wg, m, src); 3734 1.1 riastrad *mp = NULL; 3735 1.132 riastrad return 1; /* consumed */ 3736 1.28 riastrad case WG_MSG_TYPE_INIT: 3737 1.28 riastrad case WG_MSG_TYPE_RESP: 3738 1.28 riastrad case WG_MSG_TYPE_COOKIE: 3739 1.28 riastrad /* pass through to so_receive in wg_receive_packets */ 3740 1.132 riastrad return 0; /* passthrough */ 3741 1.1 riastrad default: 3742 1.28 riastrad /* drop on the floor */ 3743 1.28 riastrad m_freem(m); 3744 1.132 riastrad *mp = NULL; 3745 1.132 riastrad return -1; /* dropped */ 3746 1.1 riastrad } 3747 1.1 riastrad } 3748 1.1 riastrad 3749 1.1 riastrad static int 3750 1.55 riastrad wg_socreate(struct wg_softc *wg, int af, struct socket **sop) 3751 1.1 riastrad { 3752 1.1 riastrad int error; 3753 1.1 riastrad struct socket *so; 3754 1.1 riastrad 3755 1.1 riastrad error = socreate(af, &so, SOCK_DGRAM, 0, curlwp, NULL); 3756 1.1 riastrad if (error != 0) 3757 1.1 riastrad return error; 3758 1.1 riastrad 3759 1.1 riastrad solock(so); 3760 1.55 riastrad so->so_upcallarg = wg; 3761 1.1 riastrad so->so_upcall = wg_so_upcall; 3762 1.1 riastrad so->so_rcv.sb_flags |= SB_UPCALL; 3763 1.71 ozaki inpcb_register_overudp_cb(sotoinpcb(so), wg_overudp_cb, wg); 3764 1.1 riastrad sounlock(so); 3765 1.1 riastrad 3766 1.1 riastrad *sop = so; 3767 1.1 riastrad 3768 1.1 riastrad return 0; 3769 1.1 riastrad } 3770 1.1 riastrad 3771 1.1 riastrad static bool 3772 1.1 riastrad wg_session_hit_limits(struct wg_session *wgs) 3773 1.1 riastrad { 3774 1.1 riastrad 3775 1.1 riastrad /* 3776 1.1 riastrad * [W] 6.2: Transport Message Limits 3777 1.1 riastrad * "After REJECT-AFTER-MESSAGES transport data messages or after the 3778 1.1 riastrad * current secure session is REJECT-AFTER-TIME seconds old, whichever 3779 1.106 riastrad * comes first, WireGuard will refuse to send or receive any more 3780 1.106 riastrad * transport data messages using the current secure session, ..." 3781 1.1 riastrad */ 3782 1.117 riastrad KASSERT(wgs->wgs_time_established != 0 || time_uptime > UINT32_MAX); 3783 1.117 riastrad if (time_uptime32 - wgs->wgs_time_established > wg_reject_after_time) { 3784 1.1 riastrad WG_DLOG("The session hits REJECT_AFTER_TIME\n"); 3785 1.1 riastrad return true; 3786 1.22 riastrad } else if (wg_session_get_send_counter(wgs) > 3787 1.22 riastrad wg_reject_after_messages) { 3788 1.1 riastrad WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n"); 3789 1.1 riastrad return true; 3790 1.1 riastrad } 3791 1.1 riastrad 3792 1.1 riastrad return false; 3793 1.1 riastrad } 3794 1.1 riastrad 3795 1.1 riastrad static void 3796 1.54 riastrad wgintr(void *cookie) 3797 1.1 riastrad { 3798 1.54 riastrad struct wg_peer *wgp; 3799 1.1 riastrad struct wg_session *wgs; 3800 1.1 riastrad struct mbuf *m; 3801 1.1 riastrad struct psref psref; 3802 1.1 riastrad 3803 1.54 riastrad while ((m = pktq_dequeue(wg_pktq)) != NULL) { 3804 1.54 riastrad wgp = M_GETCTX(m, struct wg_peer *); 3805 1.54 riastrad if ((wgs = wg_get_stable_session(wgp, &psref)) == NULL) { 3806 1.126 riastrad /* 3807 1.126 riastrad * No established session. If we're the first 3808 1.126 riastrad * to try sending data, schedule a handshake 3809 1.126 riastrad * and queue the packet for when the handshake 3810 1.126 riastrad * is done; otherwise just drop the packet and 3811 1.126 riastrad * let the ongoing handshake attempt continue. 3812 1.126 riastrad * We could queue more data packets but it's 3813 1.126 riastrad * not clear that's worthwhile. 3814 1.126 riastrad */ 3815 1.54 riastrad WG_TRACE("no stable session"); 3816 1.126 riastrad membar_release(); 3817 1.126 riastrad if ((m = atomic_swap_ptr(&wgp->wgp_pending, m)) == 3818 1.126 riastrad NULL) { 3819 1.126 riastrad WG_TRACE("queued first packet;" 3820 1.126 riastrad " init handshake"); 3821 1.126 riastrad wg_schedule_peer_task(wgp, 3822 1.126 riastrad WGP_TASK_SEND_INIT_MESSAGE); 3823 1.126 riastrad } else { 3824 1.126 riastrad membar_acquire(); 3825 1.126 riastrad WG_TRACE("first packet already queued," 3826 1.126 riastrad " dropping"); 3827 1.126 riastrad } 3828 1.54 riastrad goto next0; 3829 1.54 riastrad } 3830 1.54 riastrad if (__predict_false(wg_session_hit_limits(wgs))) { 3831 1.54 riastrad WG_TRACE("stable session hit limits"); 3832 1.127 riastrad membar_release(); 3833 1.127 riastrad if ((m = atomic_swap_ptr(&wgp->wgp_pending, m)) == 3834 1.127 riastrad NULL) { 3835 1.127 riastrad WG_TRACE("queued first packet in a while;" 3836 1.127 riastrad " reinit handshake"); 3837 1.127 riastrad atomic_store_relaxed(&wgs->wgs_force_rekey, 3838 1.127 riastrad true); 3839 1.127 riastrad wg_schedule_peer_task(wgp, 3840 1.127 riastrad WGP_TASK_SEND_INIT_MESSAGE); 3841 1.127 riastrad } else { 3842 1.127 riastrad membar_acquire(); 3843 1.127 riastrad WG_TRACE("first packet in already queued," 3844 1.127 riastrad " dropping"); 3845 1.127 riastrad } 3846 1.54 riastrad goto next1; 3847 1.54 riastrad } 3848 1.1 riastrad wg_send_data_msg(wgp, wgs, m); 3849 1.54 riastrad m = NULL; /* consumed */ 3850 1.54 riastrad next1: wg_put_session(wgs, &psref); 3851 1.79 rin next0: m_freem(m); 3852 1.54 riastrad /* XXX Yield to avoid userland starvation? */ 3853 1.1 riastrad } 3854 1.1 riastrad } 3855 1.1 riastrad 3856 1.1 riastrad static void 3857 1.1 riastrad wg_purge_pending_packets(struct wg_peer *wgp) 3858 1.1 riastrad { 3859 1.1 riastrad struct mbuf *m; 3860 1.1 riastrad 3861 1.79 rin m = atomic_swap_ptr(&wgp->wgp_pending, NULL); 3862 1.126 riastrad membar_acquire(); /* matches membar_release in wgintr */ 3863 1.79 rin m_freem(m); 3864 1.107 riastrad #ifdef ALTQ 3865 1.107 riastrad wg_start(&wgp->wgp_sc->wg_if); 3866 1.107 riastrad #endif 3867 1.54 riastrad pktq_barrier(wg_pktq); 3868 1.1 riastrad } 3869 1.1 riastrad 3870 1.1 riastrad static void 3871 1.1 riastrad wg_handshake_timeout_timer(void *arg) 3872 1.1 riastrad { 3873 1.1 riastrad struct wg_peer *wgp = arg; 3874 1.1 riastrad 3875 1.1 riastrad WG_TRACE("enter"); 3876 1.1 riastrad 3877 1.49 riastrad wg_schedule_peer_task(wgp, WGP_TASK_RETRY_HANDSHAKE); 3878 1.1 riastrad } 3879 1.1 riastrad 3880 1.1 riastrad static struct wg_peer * 3881 1.1 riastrad wg_alloc_peer(struct wg_softc *wg) 3882 1.1 riastrad { 3883 1.1 riastrad struct wg_peer *wgp; 3884 1.1 riastrad 3885 1.1 riastrad wgp = kmem_zalloc(sizeof(*wgp), KM_SLEEP); 3886 1.1 riastrad 3887 1.1 riastrad wgp->wgp_sc = wg; 3888 1.1 riastrad callout_init(&wgp->wgp_handshake_timeout_timer, CALLOUT_MPSAFE); 3889 1.1 riastrad callout_setfunc(&wgp->wgp_handshake_timeout_timer, 3890 1.1 riastrad wg_handshake_timeout_timer, wgp); 3891 1.1 riastrad callout_init(&wgp->wgp_session_dtor_timer, CALLOUT_MPSAFE); 3892 1.1 riastrad callout_setfunc(&wgp->wgp_session_dtor_timer, 3893 1.1 riastrad wg_session_dtor_timer, wgp); 3894 1.1 riastrad PSLIST_ENTRY_INIT(wgp, wgp_peerlist_entry); 3895 1.1 riastrad wgp->wgp_endpoint_changing = false; 3896 1.1 riastrad wgp->wgp_endpoint_available = false; 3897 1.1 riastrad wgp->wgp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 3898 1.55 riastrad wgp->wgp_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); 3899 1.1 riastrad wgp->wgp_psz = pserialize_create(); 3900 1.1 riastrad psref_target_init(&wgp->wgp_psref, wg_psref_class); 3901 1.1 riastrad 3902 1.1 riastrad wgp->wgp_endpoint = kmem_zalloc(sizeof(*wgp->wgp_endpoint), KM_SLEEP); 3903 1.1 riastrad wgp->wgp_endpoint0 = kmem_zalloc(sizeof(*wgp->wgp_endpoint0), KM_SLEEP); 3904 1.1 riastrad psref_target_init(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3905 1.1 riastrad psref_target_init(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3906 1.1 riastrad 3907 1.1 riastrad struct wg_session *wgs; 3908 1.14 riastrad wgp->wgp_session_stable = 3909 1.14 riastrad kmem_zalloc(sizeof(*wgp->wgp_session_stable), KM_SLEEP); 3910 1.14 riastrad wgp->wgp_session_unstable = 3911 1.14 riastrad kmem_zalloc(sizeof(*wgp->wgp_session_unstable), KM_SLEEP); 3912 1.1 riastrad wgs = wgp->wgp_session_stable; 3913 1.1 riastrad wgs->wgs_peer = wgp; 3914 1.1 riastrad wgs->wgs_state = WGS_STATE_UNKNOWN; 3915 1.1 riastrad psref_target_init(&wgs->wgs_psref, wg_psref_class); 3916 1.22 riastrad #ifndef __HAVE_ATOMIC64_LOADSTORE 3917 1.22 riastrad mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3918 1.22 riastrad #endif 3919 1.6 riastrad wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3920 1.49 riastrad mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_SOFTNET); 3921 1.6 riastrad 3922 1.1 riastrad wgs = wgp->wgp_session_unstable; 3923 1.1 riastrad wgs->wgs_peer = wgp; 3924 1.1 riastrad wgs->wgs_state = WGS_STATE_UNKNOWN; 3925 1.1 riastrad psref_target_init(&wgs->wgs_psref, wg_psref_class); 3926 1.22 riastrad #ifndef __HAVE_ATOMIC64_LOADSTORE 3927 1.22 riastrad mutex_init(&wgs->wgs_send_counter_lock, MUTEX_DEFAULT, IPL_SOFTNET); 3928 1.22 riastrad #endif 3929 1.6 riastrad wgs->wgs_recvwin = kmem_zalloc(sizeof(*wgs->wgs_recvwin), KM_SLEEP); 3930 1.49 riastrad mutex_init(&wgs->wgs_recvwin->lock, MUTEX_DEFAULT, IPL_SOFTNET); 3931 1.1 riastrad 3932 1.1 riastrad return wgp; 3933 1.1 riastrad } 3934 1.1 riastrad 3935 1.1 riastrad static void 3936 1.1 riastrad wg_destroy_peer(struct wg_peer *wgp) 3937 1.1 riastrad { 3938 1.1 riastrad struct wg_session *wgs; 3939 1.1 riastrad struct wg_softc *wg = wgp->wgp_sc; 3940 1.1 riastrad 3941 1.37 riastrad /* Prevent new packets from this peer on any source address. */ 3942 1.1 riastrad rw_enter(wg->wg_rwlock, RW_WRITER); 3943 1.1 riastrad for (int i = 0; i < wgp->wgp_n_allowedips; i++) { 3944 1.1 riastrad struct wg_allowedip *wga = &wgp->wgp_allowedips[i]; 3945 1.1 riastrad struct radix_node_head *rnh = wg_rnh(wg, wga->wga_family); 3946 1.1 riastrad struct radix_node *rn; 3947 1.1 riastrad 3948 1.1 riastrad KASSERT(rnh != NULL); 3949 1.1 riastrad rn = rnh->rnh_deladdr(&wga->wga_sa_addr, 3950 1.1 riastrad &wga->wga_sa_mask, rnh); 3951 1.1 riastrad if (rn == NULL) { 3952 1.1 riastrad char addrstr[128]; 3953 1.1 riastrad sockaddr_format(&wga->wga_sa_addr, addrstr, 3954 1.1 riastrad sizeof(addrstr)); 3955 1.76 jakllsch WGLOG(LOG_WARNING, "%s: Couldn't delete %s", 3956 1.76 jakllsch if_name(&wg->wg_if), addrstr); 3957 1.1 riastrad } 3958 1.1 riastrad } 3959 1.1 riastrad rw_exit(wg->wg_rwlock); 3960 1.1 riastrad 3961 1.38 riastrad /* Purge pending packets. */ 3962 1.38 riastrad wg_purge_pending_packets(wgp); 3963 1.38 riastrad 3964 1.37 riastrad /* Halt all packet processing and timeouts. */ 3965 1.1 riastrad callout_halt(&wgp->wgp_handshake_timeout_timer, NULL); 3966 1.1 riastrad callout_halt(&wgp->wgp_session_dtor_timer, NULL); 3967 1.1 riastrad 3968 1.55 riastrad /* Wait for any queued work to complete. */ 3969 1.55 riastrad workqueue_wait(wg_wq, &wgp->wgp_work); 3970 1.55 riastrad 3971 1.49 riastrad wgs = wgp->wgp_session_unstable; 3972 1.49 riastrad if (wgs->wgs_state != WGS_STATE_UNKNOWN) { 3973 1.49 riastrad mutex_enter(wgp->wgp_lock); 3974 1.49 riastrad wg_destroy_session(wg, wgs); 3975 1.49 riastrad mutex_exit(wgp->wgp_lock); 3976 1.37 riastrad } 3977 1.6 riastrad mutex_destroy(&wgs->wgs_recvwin->lock); 3978 1.6 riastrad kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3979 1.22 riastrad #ifndef __HAVE_ATOMIC64_LOADSTORE 3980 1.22 riastrad mutex_destroy(&wgs->wgs_send_counter_lock); 3981 1.22 riastrad #endif 3982 1.1 riastrad kmem_free(wgs, sizeof(*wgs)); 3983 1.37 riastrad 3984 1.1 riastrad wgs = wgp->wgp_session_stable; 3985 1.49 riastrad if (wgs->wgs_state != WGS_STATE_UNKNOWN) { 3986 1.49 riastrad mutex_enter(wgp->wgp_lock); 3987 1.49 riastrad wg_destroy_session(wg, wgs); 3988 1.49 riastrad mutex_exit(wgp->wgp_lock); 3989 1.49 riastrad } 3990 1.6 riastrad mutex_destroy(&wgs->wgs_recvwin->lock); 3991 1.6 riastrad kmem_free(wgs->wgs_recvwin, sizeof(*wgs->wgs_recvwin)); 3992 1.22 riastrad #ifndef __HAVE_ATOMIC64_LOADSTORE 3993 1.22 riastrad mutex_destroy(&wgs->wgs_send_counter_lock); 3994 1.22 riastrad #endif 3995 1.1 riastrad kmem_free(wgs, sizeof(*wgs)); 3996 1.1 riastrad 3997 1.1 riastrad psref_target_destroy(&wgp->wgp_endpoint->wgsa_psref, wg_psref_class); 3998 1.1 riastrad psref_target_destroy(&wgp->wgp_endpoint0->wgsa_psref, wg_psref_class); 3999 1.1 riastrad kmem_free(wgp->wgp_endpoint, sizeof(*wgp->wgp_endpoint)); 4000 1.1 riastrad kmem_free(wgp->wgp_endpoint0, sizeof(*wgp->wgp_endpoint0)); 4001 1.1 riastrad 4002 1.1 riastrad pserialize_destroy(wgp->wgp_psz); 4003 1.55 riastrad mutex_obj_free(wgp->wgp_intr_lock); 4004 1.1 riastrad mutex_obj_free(wgp->wgp_lock); 4005 1.1 riastrad 4006 1.1 riastrad kmem_free(wgp, sizeof(*wgp)); 4007 1.1 riastrad } 4008 1.1 riastrad 4009 1.1 riastrad static void 4010 1.1 riastrad wg_destroy_all_peers(struct wg_softc *wg) 4011 1.1 riastrad { 4012 1.37 riastrad struct wg_peer *wgp, *wgp0 __diagused; 4013 1.37 riastrad void *garbage_byname, *garbage_bypubkey; 4014 1.1 riastrad 4015 1.1 riastrad restart: 4016 1.37 riastrad garbage_byname = garbage_bypubkey = NULL; 4017 1.1 riastrad mutex_enter(wg->wg_lock); 4018 1.1 riastrad WG_PEER_WRITER_FOREACH(wgp, wg) { 4019 1.37 riastrad if (wgp->wgp_name[0]) { 4020 1.37 riastrad wgp0 = thmap_del(wg->wg_peers_byname, wgp->wgp_name, 4021 1.37 riastrad strlen(wgp->wgp_name)); 4022 1.37 riastrad KASSERT(wgp0 == wgp); 4023 1.37 riastrad garbage_byname = thmap_stage_gc(wg->wg_peers_byname); 4024 1.37 riastrad } 4025 1.37 riastrad wgp0 = thmap_del(wg->wg_peers_bypubkey, wgp->wgp_pubkey, 4026 1.37 riastrad sizeof(wgp->wgp_pubkey)); 4027 1.37 riastrad KASSERT(wgp0 == wgp); 4028 1.37 riastrad garbage_bypubkey = thmap_stage_gc(wg->wg_peers_bypubkey); 4029 1.1 riastrad WG_PEER_WRITER_REMOVE(wgp); 4030 1.35 riastrad wg->wg_npeers--; 4031 1.1 riastrad mutex_enter(wgp->wgp_lock); 4032 1.1 riastrad pserialize_perform(wgp->wgp_psz); 4033 1.1 riastrad mutex_exit(wgp->wgp_lock); 4034 1.1 riastrad PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 4035 1.1 riastrad break; 4036 1.1 riastrad } 4037 1.1 riastrad mutex_exit(wg->wg_lock); 4038 1.1 riastrad 4039 1.1 riastrad if (wgp == NULL) 4040 1.1 riastrad return; 4041 1.1 riastrad 4042 1.1 riastrad psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 4043 1.1 riastrad 4044 1.1 riastrad wg_destroy_peer(wgp); 4045 1.37 riastrad thmap_gc(wg->wg_peers_byname, garbage_byname); 4046 1.37 riastrad thmap_gc(wg->wg_peers_bypubkey, garbage_bypubkey); 4047 1.1 riastrad 4048 1.1 riastrad goto restart; 4049 1.1 riastrad } 4050 1.1 riastrad 4051 1.1 riastrad static int 4052 1.1 riastrad wg_destroy_peer_name(struct wg_softc *wg, const char *name) 4053 1.1 riastrad { 4054 1.37 riastrad struct wg_peer *wgp, *wgp0 __diagused; 4055 1.37 riastrad void *garbage_byname, *garbage_bypubkey; 4056 1.1 riastrad 4057 1.1 riastrad mutex_enter(wg->wg_lock); 4058 1.37 riastrad wgp = thmap_del(wg->wg_peers_byname, name, strlen(name)); 4059 1.1 riastrad if (wgp != NULL) { 4060 1.37 riastrad wgp0 = thmap_del(wg->wg_peers_bypubkey, wgp->wgp_pubkey, 4061 1.37 riastrad sizeof(wgp->wgp_pubkey)); 4062 1.37 riastrad KASSERT(wgp0 == wgp); 4063 1.37 riastrad garbage_byname = thmap_stage_gc(wg->wg_peers_byname); 4064 1.37 riastrad garbage_bypubkey = thmap_stage_gc(wg->wg_peers_bypubkey); 4065 1.1 riastrad WG_PEER_WRITER_REMOVE(wgp); 4066 1.1 riastrad wg->wg_npeers--; 4067 1.61 roy if (wg->wg_npeers == 0) 4068 1.61 roy if_link_state_change(&wg->wg_if, LINK_STATE_DOWN); 4069 1.1 riastrad mutex_enter(wgp->wgp_lock); 4070 1.1 riastrad pserialize_perform(wgp->wgp_psz); 4071 1.1 riastrad mutex_exit(wgp->wgp_lock); 4072 1.1 riastrad PSLIST_ENTRY_DESTROY(wgp, wgp_peerlist_entry); 4073 1.1 riastrad } 4074 1.1 riastrad mutex_exit(wg->wg_lock); 4075 1.1 riastrad 4076 1.1 riastrad if (wgp == NULL) 4077 1.1 riastrad return ENOENT; 4078 1.1 riastrad 4079 1.1 riastrad psref_target_destroy(&wgp->wgp_psref, wg_psref_class); 4080 1.1 riastrad 4081 1.1 riastrad wg_destroy_peer(wgp); 4082 1.37 riastrad thmap_gc(wg->wg_peers_byname, garbage_byname); 4083 1.37 riastrad thmap_gc(wg->wg_peers_bypubkey, garbage_bypubkey); 4084 1.1 riastrad 4085 1.1 riastrad return 0; 4086 1.1 riastrad } 4087 1.1 riastrad 4088 1.1 riastrad static int 4089 1.1 riastrad wg_if_attach(struct wg_softc *wg) 4090 1.1 riastrad { 4091 1.1 riastrad 4092 1.1 riastrad wg->wg_if.if_addrlen = 0; 4093 1.1 riastrad wg->wg_if.if_mtu = WG_MTU; 4094 1.33 riastrad wg->wg_if.if_flags = IFF_MULTICAST; 4095 1.61 roy wg->wg_if.if_extflags = IFEF_MPSAFE; 4096 1.1 riastrad wg->wg_if.if_ioctl = wg_ioctl; 4097 1.1 riastrad wg->wg_if.if_output = wg_output; 4098 1.1 riastrad wg->wg_if.if_init = wg_init; 4099 1.60 riastrad #ifdef ALTQ 4100 1.60 riastrad wg->wg_if.if_start = wg_start; 4101 1.60 riastrad #endif 4102 1.1 riastrad wg->wg_if.if_stop = wg_stop; 4103 1.24 riastrad wg->wg_if.if_type = IFT_OTHER; 4104 1.1 riastrad wg->wg_if.if_dlt = DLT_NULL; 4105 1.1 riastrad wg->wg_if.if_softc = wg; 4106 1.60 riastrad #ifdef ALTQ 4107 1.1 riastrad IFQ_SET_READY(&wg->wg_if.if_snd); 4108 1.60 riastrad #endif 4109 1.64 riastrad if_initialize(&wg->wg_if); 4110 1.1 riastrad 4111 1.61 roy wg->wg_if.if_link_state = LINK_STATE_DOWN; 4112 1.1 riastrad if_alloc_sadl(&wg->wg_if); 4113 1.1 riastrad if_register(&wg->wg_if); 4114 1.1 riastrad 4115 1.1 riastrad bpf_attach(&wg->wg_if, DLT_NULL, sizeof(uint32_t)); 4116 1.1 riastrad 4117 1.1 riastrad return 0; 4118 1.1 riastrad } 4119 1.1 riastrad 4120 1.54 riastrad static void 4121 1.54 riastrad wg_if_detach(struct wg_softc *wg) 4122 1.54 riastrad { 4123 1.54 riastrad struct ifnet *ifp = &wg->wg_if; 4124 1.54 riastrad 4125 1.54 riastrad bpf_detach(ifp); 4126 1.54 riastrad if_detach(ifp); 4127 1.54 riastrad } 4128 1.54 riastrad 4129 1.1 riastrad static int 4130 1.1 riastrad wg_clone_create(struct if_clone *ifc, int unit) 4131 1.1 riastrad { 4132 1.1 riastrad struct wg_softc *wg; 4133 1.1 riastrad int error; 4134 1.1 riastrad 4135 1.58 riastrad wg_guarantee_initialized(); 4136 1.58 riastrad 4137 1.59 riastrad error = wg_count_inc(); 4138 1.59 riastrad if (error) 4139 1.59 riastrad return error; 4140 1.59 riastrad 4141 1.54 riastrad wg = kmem_zalloc(sizeof(*wg), KM_SLEEP); 4142 1.1 riastrad 4143 1.1 riastrad if_initname(&wg->wg_if, ifc->ifc_name, unit); 4144 1.1 riastrad 4145 1.55 riastrad PSLIST_INIT(&wg->wg_peers); 4146 1.55 riastrad wg->wg_peers_bypubkey = thmap_create(0, NULL, THMAP_NOCOPY); 4147 1.55 riastrad wg->wg_peers_byname = thmap_create(0, NULL, THMAP_NOCOPY); 4148 1.55 riastrad wg->wg_sessions_byindex = thmap_create(0, NULL, THMAP_NOCOPY); 4149 1.55 riastrad wg->wg_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 4150 1.55 riastrad wg->wg_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); 4151 1.55 riastrad wg->wg_rwlock = rw_obj_alloc(); 4152 1.55 riastrad threadpool_job_init(&wg->wg_job, wg_job, wg->wg_intr_lock, 4153 1.55 riastrad "%s", if_name(&wg->wg_if)); 4154 1.55 riastrad wg->wg_ops = &wg_ops_rumpkernel; 4155 1.55 riastrad 4156 1.55 riastrad error = threadpool_get(&wg->wg_threadpool, PRI_NONE); 4157 1.54 riastrad if (error) 4158 1.54 riastrad goto fail0; 4159 1.1 riastrad 4160 1.55 riastrad #ifdef INET 4161 1.55 riastrad error = wg_socreate(wg, AF_INET, &wg->wg_so4); 4162 1.55 riastrad if (error) 4163 1.55 riastrad goto fail1; 4164 1.1 riastrad rn_inithead((void **)&wg->wg_rtable_ipv4, 4165 1.1 riastrad offsetof(struct sockaddr_in, sin_addr) * NBBY); 4166 1.55 riastrad #endif 4167 1.1 riastrad #ifdef INET6 4168 1.55 riastrad error = wg_socreate(wg, AF_INET6, &wg->wg_so6); 4169 1.55 riastrad if (error) 4170 1.55 riastrad goto fail2; 4171 1.1 riastrad rn_inithead((void **)&wg->wg_rtable_ipv6, 4172 1.1 riastrad offsetof(struct sockaddr_in6, sin6_addr) * NBBY); 4173 1.1 riastrad #endif 4174 1.1 riastrad 4175 1.1 riastrad error = wg_if_attach(wg); 4176 1.54 riastrad if (error) 4177 1.55 riastrad goto fail3; 4178 1.1 riastrad 4179 1.1 riastrad return 0; 4180 1.54 riastrad 4181 1.55 riastrad fail4: __unused 4182 1.107 riastrad wg_destroy_all_peers(wg); 4183 1.54 riastrad wg_if_detach(wg); 4184 1.107 riastrad fail3: 4185 1.55 riastrad #ifdef INET6 4186 1.55 riastrad solock(wg->wg_so6); 4187 1.55 riastrad wg->wg_so6->so_rcv.sb_flags &= ~SB_UPCALL; 4188 1.55 riastrad sounlock(wg->wg_so6); 4189 1.55 riastrad #endif 4190 1.55 riastrad #ifdef INET 4191 1.55 riastrad solock(wg->wg_so4); 4192 1.55 riastrad wg->wg_so4->so_rcv.sb_flags &= ~SB_UPCALL; 4193 1.55 riastrad sounlock(wg->wg_so4); 4194 1.55 riastrad #endif 4195 1.55 riastrad mutex_enter(wg->wg_intr_lock); 4196 1.55 riastrad threadpool_cancel_job(wg->wg_threadpool, &wg->wg_job); 4197 1.55 riastrad mutex_exit(wg->wg_intr_lock); 4198 1.55 riastrad #ifdef INET6 4199 1.55 riastrad if (wg->wg_rtable_ipv6 != NULL) 4200 1.55 riastrad free(wg->wg_rtable_ipv6, M_RTABLE); 4201 1.55 riastrad soclose(wg->wg_so6); 4202 1.55 riastrad fail2: 4203 1.55 riastrad #endif 4204 1.55 riastrad #ifdef INET 4205 1.55 riastrad if (wg->wg_rtable_ipv4 != NULL) 4206 1.55 riastrad free(wg->wg_rtable_ipv4, M_RTABLE); 4207 1.55 riastrad soclose(wg->wg_so4); 4208 1.55 riastrad fail1: 4209 1.55 riastrad #endif 4210 1.55 riastrad threadpool_put(wg->wg_threadpool, PRI_NONE); 4211 1.55 riastrad fail0: threadpool_job_destroy(&wg->wg_job); 4212 1.54 riastrad rw_obj_free(wg->wg_rwlock); 4213 1.55 riastrad mutex_obj_free(wg->wg_intr_lock); 4214 1.54 riastrad mutex_obj_free(wg->wg_lock); 4215 1.54 riastrad thmap_destroy(wg->wg_sessions_byindex); 4216 1.54 riastrad thmap_destroy(wg->wg_peers_byname); 4217 1.54 riastrad thmap_destroy(wg->wg_peers_bypubkey); 4218 1.54 riastrad PSLIST_DESTROY(&wg->wg_peers); 4219 1.55 riastrad kmem_free(wg, sizeof(*wg)); 4220 1.59 riastrad wg_count_dec(); 4221 1.54 riastrad return error; 4222 1.1 riastrad } 4223 1.1 riastrad 4224 1.1 riastrad static int 4225 1.1 riastrad wg_clone_destroy(struct ifnet *ifp) 4226 1.1 riastrad { 4227 1.16 riastrad struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if); 4228 1.1 riastrad 4229 1.1 riastrad #ifdef WG_RUMPKERNEL 4230 1.1 riastrad if (wg_user_mode(wg)) { 4231 1.1 riastrad rumpuser_wg_destroy(wg->wg_user); 4232 1.1 riastrad wg->wg_user = NULL; 4233 1.1 riastrad } 4234 1.1 riastrad #endif 4235 1.1 riastrad 4236 1.107 riastrad wg_destroy_all_peers(wg); 4237 1.54 riastrad wg_if_detach(wg); 4238 1.55 riastrad #ifdef INET6 4239 1.55 riastrad solock(wg->wg_so6); 4240 1.55 riastrad wg->wg_so6->so_rcv.sb_flags &= ~SB_UPCALL; 4241 1.55 riastrad sounlock(wg->wg_so6); 4242 1.55 riastrad #endif 4243 1.55 riastrad #ifdef INET 4244 1.55 riastrad solock(wg->wg_so4); 4245 1.55 riastrad wg->wg_so4->so_rcv.sb_flags &= ~SB_UPCALL; 4246 1.55 riastrad sounlock(wg->wg_so4); 4247 1.55 riastrad #endif 4248 1.55 riastrad mutex_enter(wg->wg_intr_lock); 4249 1.55 riastrad threadpool_cancel_job(wg->wg_threadpool, &wg->wg_job); 4250 1.55 riastrad mutex_exit(wg->wg_intr_lock); 4251 1.55 riastrad #ifdef INET6 4252 1.55 riastrad if (wg->wg_rtable_ipv6 != NULL) 4253 1.55 riastrad free(wg->wg_rtable_ipv6, M_RTABLE); 4254 1.55 riastrad soclose(wg->wg_so6); 4255 1.55 riastrad #endif 4256 1.55 riastrad #ifdef INET 4257 1.55 riastrad if (wg->wg_rtable_ipv4 != NULL) 4258 1.55 riastrad free(wg->wg_rtable_ipv4, M_RTABLE); 4259 1.55 riastrad soclose(wg->wg_so4); 4260 1.55 riastrad #endif 4261 1.55 riastrad threadpool_put(wg->wg_threadpool, PRI_NONE); 4262 1.55 riastrad threadpool_job_destroy(&wg->wg_job); 4263 1.54 riastrad rw_obj_free(wg->wg_rwlock); 4264 1.55 riastrad mutex_obj_free(wg->wg_intr_lock); 4265 1.54 riastrad mutex_obj_free(wg->wg_lock); 4266 1.54 riastrad thmap_destroy(wg->wg_sessions_byindex); 4267 1.54 riastrad thmap_destroy(wg->wg_peers_byname); 4268 1.54 riastrad thmap_destroy(wg->wg_peers_bypubkey); 4269 1.54 riastrad PSLIST_DESTROY(&wg->wg_peers); 4270 1.54 riastrad kmem_free(wg, sizeof(*wg)); 4271 1.59 riastrad wg_count_dec(); 4272 1.1 riastrad 4273 1.1 riastrad return 0; 4274 1.1 riastrad } 4275 1.1 riastrad 4276 1.1 riastrad static struct wg_peer * 4277 1.1 riastrad wg_pick_peer_by_sa(struct wg_softc *wg, const struct sockaddr *sa, 4278 1.1 riastrad struct psref *psref) 4279 1.1 riastrad { 4280 1.1 riastrad struct radix_node_head *rnh; 4281 1.1 riastrad struct radix_node *rn; 4282 1.1 riastrad struct wg_peer *wgp = NULL; 4283 1.1 riastrad struct wg_allowedip *wga; 4284 1.1 riastrad 4285 1.1 riastrad #ifdef WG_DEBUG_LOG 4286 1.1 riastrad char addrstr[128]; 4287 1.1 riastrad sockaddr_format(sa, addrstr, sizeof(addrstr)); 4288 1.1 riastrad WG_DLOG("sa=%s\n", addrstr); 4289 1.1 riastrad #endif 4290 1.1 riastrad 4291 1.1 riastrad rw_enter(wg->wg_rwlock, RW_READER); 4292 1.1 riastrad 4293 1.1 riastrad rnh = wg_rnh(wg, sa->sa_family); 4294 1.1 riastrad if (rnh == NULL) 4295 1.1 riastrad goto out; 4296 1.1 riastrad 4297 1.1 riastrad rn = rnh->rnh_matchaddr(sa, rnh); 4298 1.1 riastrad if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) 4299 1.1 riastrad goto out; 4300 1.1 riastrad 4301 1.1 riastrad WG_TRACE("success"); 4302 1.1 riastrad 4303 1.16 riastrad wga = container_of(rn, struct wg_allowedip, wga_nodes[0]); 4304 1.1 riastrad wgp = wga->wga_peer; 4305 1.1 riastrad wg_get_peer(wgp, psref); 4306 1.1 riastrad 4307 1.1 riastrad out: 4308 1.1 riastrad rw_exit(wg->wg_rwlock); 4309 1.1 riastrad return wgp; 4310 1.1 riastrad } 4311 1.1 riastrad 4312 1.1 riastrad static void 4313 1.1 riastrad wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp, 4314 1.1 riastrad struct wg_session *wgs, struct wg_msg_data *wgmd) 4315 1.1 riastrad { 4316 1.1 riastrad 4317 1.1 riastrad memset(wgmd, 0, sizeof(*wgmd)); 4318 1.39 riastrad wgmd->wgmd_type = htole32(WG_MSG_TYPE_DATA); 4319 1.49 riastrad wgmd->wgmd_receiver = wgs->wgs_remote_index; 4320 1.1 riastrad /* [W] 5.4.6: msg.counter := Nm^send */ 4321 1.1 riastrad /* [W] 5.4.6: Nm^send := Nm^send + 1 */ 4322 1.39 riastrad wgmd->wgmd_counter = htole64(wg_session_inc_send_counter(wgs)); 4323 1.39 riastrad WG_DLOG("counter=%"PRIu64"\n", le64toh(wgmd->wgmd_counter)); 4324 1.1 riastrad } 4325 1.1 riastrad 4326 1.1 riastrad static int 4327 1.1 riastrad wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 4328 1.1 riastrad const struct rtentry *rt) 4329 1.1 riastrad { 4330 1.1 riastrad struct wg_softc *wg = ifp->if_softc; 4331 1.49 riastrad struct wg_peer *wgp = NULL; 4332 1.126 riastrad struct psref wgp_psref; 4333 1.1 riastrad int bound; 4334 1.49 riastrad int error; 4335 1.49 riastrad 4336 1.49 riastrad bound = curlwp_bind(); 4337 1.1 riastrad 4338 1.1 riastrad /* TODO make the nest limit configurable via sysctl */ 4339 1.1 riastrad error = if_tunnel_check_nesting(ifp, m, 1); 4340 1.49 riastrad if (error) { 4341 1.76 jakllsch WGLOG(LOG_ERR, 4342 1.76 jakllsch "%s: tunneling loop detected and packet dropped\n", 4343 1.76 jakllsch if_name(&wg->wg_if)); 4344 1.54 riastrad goto out0; 4345 1.1 riastrad } 4346 1.1 riastrad 4347 1.60 riastrad #ifdef ALTQ 4348 1.60 riastrad bool altq = atomic_load_relaxed(&ifp->if_snd.altq_flags) 4349 1.60 riastrad & ALTQF_ENABLED; 4350 1.60 riastrad if (altq) 4351 1.60 riastrad IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 4352 1.60 riastrad #endif 4353 1.1 riastrad 4354 1.1 riastrad bpf_mtap_af(ifp, dst->sa_family, m, BPF_D_OUT); 4355 1.1 riastrad 4356 1.1 riastrad m->m_flags &= ~(M_BCAST|M_MCAST); 4357 1.1 riastrad 4358 1.49 riastrad wgp = wg_pick_peer_by_sa(wg, dst, &wgp_psref); 4359 1.1 riastrad if (wgp == NULL) { 4360 1.1 riastrad WG_TRACE("peer not found"); 4361 1.1 riastrad error = EHOSTUNREACH; 4362 1.54 riastrad goto out0; 4363 1.1 riastrad } 4364 1.1 riastrad 4365 1.1 riastrad /* Clear checksum-offload flags. */ 4366 1.1 riastrad m->m_pkthdr.csum_flags = 0; 4367 1.1 riastrad m->m_pkthdr.csum_data = 0; 4368 1.1 riastrad 4369 1.126 riastrad /* Toss it in the queue. */ 4370 1.60 riastrad #ifdef ALTQ 4371 1.60 riastrad if (altq) { 4372 1.60 riastrad mutex_enter(ifp->if_snd.ifq_lock); 4373 1.60 riastrad if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 4374 1.60 riastrad M_SETCTX(m, wgp); 4375 1.60 riastrad ALTQ_ENQUEUE(&ifp->if_snd, m, error); 4376 1.60 riastrad m = NULL; /* consume */ 4377 1.60 riastrad } 4378 1.60 riastrad mutex_exit(ifp->if_snd.ifq_lock); 4379 1.60 riastrad if (m == NULL) { 4380 1.60 riastrad wg_start(ifp); 4381 1.126 riastrad goto out1; 4382 1.60 riastrad } 4383 1.60 riastrad } 4384 1.60 riastrad #endif 4385 1.54 riastrad kpreempt_disable(); 4386 1.54 riastrad const uint32_t h = curcpu()->ci_index; // pktq_rps_hash(m) 4387 1.54 riastrad M_SETCTX(m, wgp); 4388 1.54 riastrad if (__predict_false(!pktq_enqueue(wg_pktq, m, h))) { 4389 1.76 jakllsch WGLOG(LOG_ERR, "%s: pktq full, dropping\n", 4390 1.76 jakllsch if_name(&wg->wg_if)); 4391 1.1 riastrad error = ENOBUFS; 4392 1.126 riastrad goto out2; 4393 1.1 riastrad } 4394 1.49 riastrad m = NULL; /* consumed */ 4395 1.49 riastrad error = 0; 4396 1.126 riastrad out2: kpreempt_enable(); 4397 1.1 riastrad 4398 1.60 riastrad #ifdef ALTQ 4399 1.126 riastrad out1: 4400 1.60 riastrad #endif 4401 1.126 riastrad wg_put_peer(wgp, &wgp_psref); 4402 1.79 rin out0: m_freem(m); 4403 1.1 riastrad curlwp_bindx(bound); 4404 1.1 riastrad return error; 4405 1.1 riastrad } 4406 1.1 riastrad 4407 1.1 riastrad static int 4408 1.134 riastrad wg_send_data(struct wg_peer *wgp, struct mbuf *m) 4409 1.1 riastrad { 4410 1.1 riastrad struct psref psref; 4411 1.1 riastrad struct wg_sockaddr *wgsa; 4412 1.1 riastrad int error; 4413 1.47 riastrad struct socket *so; 4414 1.1 riastrad 4415 1.47 riastrad wgsa = wg_get_endpoint_sa(wgp, &psref); 4416 1.47 riastrad so = wg_get_so_by_peer(wgp, wgsa); 4417 1.1 riastrad solock(so); 4418 1.109 riastrad switch (wgsatosa(wgsa)->sa_family) { 4419 1.109 riastrad #ifdef INET 4420 1.109 riastrad case AF_INET: 4421 1.1 riastrad error = udp_send(so, m, wgsatosa(wgsa), NULL, curlwp); 4422 1.109 riastrad break; 4423 1.109 riastrad #endif 4424 1.1 riastrad #ifdef INET6 4425 1.109 riastrad case AF_INET6: 4426 1.70 ozaki error = udp6_output(sotoinpcb(so), m, wgsatosin6(wgsa), 4427 1.1 riastrad NULL, curlwp); 4428 1.109 riastrad break; 4429 1.109 riastrad #endif 4430 1.109 riastrad default: 4431 1.38 riastrad m_freem(m); 4432 1.47 riastrad error = EPFNOSUPPORT; 4433 1.1 riastrad } 4434 1.47 riastrad sounlock(so); 4435 1.1 riastrad wg_put_sa(wgp, wgsa, &psref); 4436 1.1 riastrad 4437 1.1 riastrad return error; 4438 1.1 riastrad } 4439 1.1 riastrad 4440 1.1 riastrad /* Inspired by pppoe_get_mbuf */ 4441 1.1 riastrad static struct mbuf * 4442 1.1 riastrad wg_get_mbuf(size_t leading_len, size_t len) 4443 1.1 riastrad { 4444 1.1 riastrad struct mbuf *m; 4445 1.1 riastrad 4446 1.30 riastrad KASSERT(leading_len <= MCLBYTES); 4447 1.30 riastrad KASSERT(len <= MCLBYTES - leading_len); 4448 1.30 riastrad 4449 1.1 riastrad m = m_gethdr(M_DONTWAIT, MT_DATA); 4450 1.1 riastrad if (m == NULL) 4451 1.1 riastrad return NULL; 4452 1.1 riastrad if (len + leading_len > MHLEN) { 4453 1.1 riastrad m_clget(m, M_DONTWAIT); 4454 1.1 riastrad if ((m->m_flags & M_EXT) == 0) { 4455 1.1 riastrad m_free(m); 4456 1.1 riastrad return NULL; 4457 1.1 riastrad } 4458 1.1 riastrad } 4459 1.1 riastrad m->m_data += leading_len; 4460 1.1 riastrad m->m_pkthdr.len = m->m_len = len; 4461 1.1 riastrad 4462 1.1 riastrad return m; 4463 1.1 riastrad } 4464 1.1 riastrad 4465 1.108 riastrad static void 4466 1.108 riastrad wg_send_data_msg(struct wg_peer *wgp, struct wg_session *wgs, struct mbuf *m) 4467 1.1 riastrad { 4468 1.1 riastrad struct wg_softc *wg = wgp->wgp_sc; 4469 1.1 riastrad int error; 4470 1.1 riastrad size_t inner_len, padded_len, encrypted_len; 4471 1.1 riastrad char *padded_buf = NULL; 4472 1.1 riastrad size_t mlen; 4473 1.1 riastrad struct wg_msg_data *wgmd; 4474 1.1 riastrad bool free_padded_buf = false; 4475 1.1 riastrad struct mbuf *n; 4476 1.62 riastrad size_t leading_len = max_hdr + sizeof(struct udphdr); 4477 1.1 riastrad 4478 1.1 riastrad mlen = m_length(m); 4479 1.1 riastrad inner_len = mlen; 4480 1.2 riastrad padded_len = roundup(mlen, 16); 4481 1.2 riastrad encrypted_len = padded_len + WG_AUTHTAG_LEN; 4482 1.87 kre WG_DLOG("inner=%zu, padded=%zu, encrypted_len=%zu\n", 4483 1.1 riastrad inner_len, padded_len, encrypted_len); 4484 1.1 riastrad if (mlen != 0) { 4485 1.1 riastrad bool success; 4486 1.1 riastrad success = m_ensure_contig(&m, padded_len); 4487 1.1 riastrad if (success) { 4488 1.1 riastrad padded_buf = mtod(m, char *); 4489 1.1 riastrad } else { 4490 1.1 riastrad padded_buf = kmem_intr_alloc(padded_len, KM_NOSLEEP); 4491 1.1 riastrad if (padded_buf == NULL) { 4492 1.1 riastrad error = ENOBUFS; 4493 1.108 riastrad goto out; 4494 1.1 riastrad } 4495 1.1 riastrad free_padded_buf = true; 4496 1.1 riastrad m_copydata(m, 0, mlen, padded_buf); 4497 1.1 riastrad } 4498 1.1 riastrad memset(padded_buf + mlen, 0, padded_len - inner_len); 4499 1.1 riastrad } 4500 1.1 riastrad 4501 1.1 riastrad n = wg_get_mbuf(leading_len, sizeof(*wgmd) + encrypted_len); 4502 1.1 riastrad if (n == NULL) { 4503 1.1 riastrad error = ENOBUFS; 4504 1.108 riastrad goto out; 4505 1.1 riastrad } 4506 1.27 riastrad KASSERT(n->m_len >= sizeof(*wgmd)); 4507 1.1 riastrad wgmd = mtod(n, struct wg_msg_data *); 4508 1.1 riastrad wg_fill_msg_data(wg, wgp, wgs, wgmd); 4509 1.111 riastrad 4510 1.1 riastrad /* [W] 5.4.6: AEAD(Tm^send, Nm^send, P, e) */ 4511 1.1 riastrad wg_algo_aead_enc((char *)wgmd + sizeof(*wgmd), encrypted_len, 4512 1.39 riastrad wgs->wgs_tkey_send, le64toh(wgmd->wgmd_counter), 4513 1.39 riastrad padded_buf, padded_len, 4514 1.1 riastrad NULL, 0); 4515 1.1 riastrad 4516 1.108 riastrad error = wg->wg_ops->send_data_msg(wgp, n); /* consumes n */ 4517 1.108 riastrad if (error) { 4518 1.108 riastrad WG_DLOG("send_data_msg failed, error=%d\n", error); 4519 1.108 riastrad goto out; 4520 1.108 riastrad } 4521 1.108 riastrad 4522 1.108 riastrad /* 4523 1.108 riastrad * Packet was sent out -- count it in the interface statistics. 4524 1.108 riastrad */ 4525 1.108 riastrad if_statadd(&wg->wg_if, if_obytes, mlen); 4526 1.108 riastrad if_statinc(&wg->wg_if, if_opackets); 4527 1.108 riastrad 4528 1.108 riastrad /* 4529 1.108 riastrad * Record when we last sent data, for determining when we need 4530 1.108 riastrad * to send a passive keepalive. 4531 1.108 riastrad * 4532 1.108 riastrad * Other logic assumes that wgs_time_last_data_sent is zero iff 4533 1.108 riastrad * we have never sent data on this session. Early at boot, if 4534 1.108 riastrad * wg(4) starts operating within <1sec, or after 136 years of 4535 1.108 riastrad * uptime, we may observe time_uptime32 = 0. In that case, 4536 1.108 riastrad * pretend we observed 1 instead. That way, we correctly 4537 1.108 riastrad * indicate we have sent data on this session; the only logic 4538 1.108 riastrad * this might adversely affect is the keepalive timeout 4539 1.108 riastrad * detection, which might spuriously send a keepalive during 4540 1.108 riastrad * one second every 136 years. All of this is very silly, of 4541 1.108 riastrad * course, but the cost to guaranteeing wgs_time_last_data_sent 4542 1.108 riastrad * is nonzero is negligible here. 4543 1.108 riastrad */ 4544 1.108 riastrad const uint32_t now = time_uptime32; 4545 1.108 riastrad atomic_store_relaxed(&wgs->wgs_time_last_data_sent, MAX(now, 1)); 4546 1.108 riastrad 4547 1.108 riastrad /* 4548 1.108 riastrad * Check rekey-after-time. 4549 1.108 riastrad */ 4550 1.108 riastrad if (wgs->wgs_is_initiator && 4551 1.117 riastrad now - wgs->wgs_time_established >= wg_rekey_after_time) { 4552 1.108 riastrad /* 4553 1.108 riastrad * [W] 6.2 Transport Message Limits 4554 1.108 riastrad * "if a peer is the initiator of a current secure 4555 1.108 riastrad * session, WireGuard will send a handshake initiation 4556 1.108 riastrad * message to begin a new secure session if, after 4557 1.108 riastrad * transmitting a transport data message, the current 4558 1.108 riastrad * secure session is REKEY-AFTER-TIME seconds old," 4559 1.108 riastrad */ 4560 1.108 riastrad WG_TRACE("rekey after time"); 4561 1.113 riastrad atomic_store_relaxed(&wgs->wgs_force_rekey, true); 4562 1.108 riastrad wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 4563 1.108 riastrad } 4564 1.108 riastrad 4565 1.108 riastrad /* 4566 1.108 riastrad * Check rekey-after-messages. 4567 1.108 riastrad */ 4568 1.108 riastrad if (wg_session_get_send_counter(wgs) >= wg_rekey_after_messages) { 4569 1.108 riastrad /* 4570 1.108 riastrad * [W] 6.2 Transport Message Limits 4571 1.108 riastrad * "WireGuard will try to create a new session, by 4572 1.108 riastrad * sending a handshake initiation message (section 4573 1.108 riastrad * 5.4.2), after it has sent REKEY-AFTER-MESSAGES 4574 1.108 riastrad * transport data messages..." 4575 1.108 riastrad */ 4576 1.108 riastrad WG_TRACE("rekey after messages"); 4577 1.113 riastrad atomic_store_relaxed(&wgs->wgs_force_rekey, true); 4578 1.108 riastrad wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); 4579 1.1 riastrad } 4580 1.108 riastrad 4581 1.108 riastrad out: m_freem(m); 4582 1.1 riastrad if (free_padded_buf) 4583 1.1 riastrad kmem_intr_free(padded_buf, padded_len); 4584 1.1 riastrad } 4585 1.1 riastrad 4586 1.1 riastrad static void 4587 1.1 riastrad wg_input(struct ifnet *ifp, struct mbuf *m, const int af) 4588 1.1 riastrad { 4589 1.1 riastrad pktqueue_t *pktq; 4590 1.1 riastrad size_t pktlen; 4591 1.1 riastrad 4592 1.1 riastrad KASSERT(af == AF_INET || af == AF_INET6); 4593 1.1 riastrad 4594 1.1 riastrad WG_TRACE(""); 4595 1.1 riastrad 4596 1.1 riastrad m_set_rcvif(m, ifp); 4597 1.1 riastrad pktlen = m->m_pkthdr.len; 4598 1.1 riastrad 4599 1.1 riastrad bpf_mtap_af(ifp, af, m, BPF_D_IN); 4600 1.1 riastrad 4601 1.1 riastrad switch (af) { 4602 1.109 riastrad #ifdef INET 4603 1.1 riastrad case AF_INET: 4604 1.1 riastrad pktq = ip_pktq; 4605 1.1 riastrad break; 4606 1.109 riastrad #endif 4607 1.1 riastrad #ifdef INET6 4608 1.1 riastrad case AF_INET6: 4609 1.1 riastrad pktq = ip6_pktq; 4610 1.1 riastrad break; 4611 1.1 riastrad #endif 4612 1.1 riastrad default: 4613 1.1 riastrad panic("invalid af=%d", af); 4614 1.1 riastrad } 4615 1.1 riastrad 4616 1.57 riastrad kpreempt_disable(); 4617 1.1 riastrad const u_int h = curcpu()->ci_index; 4618 1.1 riastrad if (__predict_true(pktq_enqueue(pktq, m, h))) { 4619 1.4 riastrad if_statadd(ifp, if_ibytes, pktlen); 4620 1.4 riastrad if_statinc(ifp, if_ipackets); 4621 1.1 riastrad } else { 4622 1.1 riastrad m_freem(m); 4623 1.1 riastrad } 4624 1.57 riastrad kpreempt_enable(); 4625 1.1 riastrad } 4626 1.1 riastrad 4627 1.1 riastrad static void 4628 1.114 riastrad wg_calc_pubkey(uint8_t pubkey[static WG_STATIC_KEY_LEN], 4629 1.114 riastrad const uint8_t privkey[static WG_STATIC_KEY_LEN]) 4630 1.1 riastrad { 4631 1.1 riastrad 4632 1.1 riastrad crypto_scalarmult_base(pubkey, privkey); 4633 1.1 riastrad } 4634 1.1 riastrad 4635 1.1 riastrad static int 4636 1.1 riastrad wg_rtable_add_route(struct wg_softc *wg, struct wg_allowedip *wga) 4637 1.1 riastrad { 4638 1.1 riastrad struct radix_node_head *rnh; 4639 1.1 riastrad struct radix_node *rn; 4640 1.1 riastrad int error = 0; 4641 1.1 riastrad 4642 1.1 riastrad rw_enter(wg->wg_rwlock, RW_WRITER); 4643 1.1 riastrad rnh = wg_rnh(wg, wga->wga_family); 4644 1.1 riastrad KASSERT(rnh != NULL); 4645 1.1 riastrad rn = rnh->rnh_addaddr(&wga->wga_sa_addr, &wga->wga_sa_mask, rnh, 4646 1.1 riastrad wga->wga_nodes); 4647 1.1 riastrad rw_exit(wg->wg_rwlock); 4648 1.1 riastrad 4649 1.1 riastrad if (rn == NULL) 4650 1.1 riastrad error = EEXIST; 4651 1.1 riastrad 4652 1.1 riastrad return error; 4653 1.1 riastrad } 4654 1.1 riastrad 4655 1.1 riastrad static int 4656 1.1 riastrad wg_handle_prop_peer(struct wg_softc *wg, prop_dictionary_t peer, 4657 1.1 riastrad struct wg_peer **wgpp) 4658 1.1 riastrad { 4659 1.1 riastrad int error = 0; 4660 1.12 riastrad const void *pubkey; 4661 1.1 riastrad size_t pubkey_len; 4662 1.12 riastrad const void *psk; 4663 1.12 riastrad size_t psk_len; 4664 1.1 riastrad const char *name = NULL; 4665 1.1 riastrad 4666 1.12 riastrad if (prop_dictionary_get_string(peer, "name", &name)) { 4667 1.1 riastrad if (strlen(name) > WG_PEER_NAME_MAXLEN) { 4668 1.1 riastrad error = EINVAL; 4669 1.1 riastrad goto out; 4670 1.1 riastrad } 4671 1.1 riastrad } 4672 1.1 riastrad 4673 1.12 riastrad if (!prop_dictionary_get_data(peer, "public_key", 4674 1.12 riastrad &pubkey, &pubkey_len)) { 4675 1.1 riastrad error = EINVAL; 4676 1.1 riastrad goto out; 4677 1.1 riastrad } 4678 1.1 riastrad #ifdef WG_DEBUG_DUMP 4679 1.80 christos if (wg_debug & WG_DEBUG_FLAGS_DUMP) { 4680 1.80 christos char *hex = gethexdump(pubkey, pubkey_len); 4681 1.87 kre log(LOG_DEBUG, "pubkey=%p, pubkey_len=%zu\n%s\n", 4682 1.80 christos pubkey, pubkey_len, hex); 4683 1.80 christos puthexdump(hex, pubkey, pubkey_len); 4684 1.80 christos } 4685 1.1 riastrad #endif 4686 1.1 riastrad 4687 1.1 riastrad struct wg_peer *wgp = wg_alloc_peer(wg); 4688 1.1 riastrad memcpy(wgp->wgp_pubkey, pubkey, sizeof(wgp->wgp_pubkey)); 4689 1.1 riastrad if (name != NULL) 4690 1.1 riastrad strncpy(wgp->wgp_name, name, sizeof(wgp->wgp_name)); 4691 1.1 riastrad 4692 1.12 riastrad if (prop_dictionary_get_data(peer, "preshared_key", &psk, &psk_len)) { 4693 1.1 riastrad if (psk_len != sizeof(wgp->wgp_psk)) { 4694 1.1 riastrad error = EINVAL; 4695 1.1 riastrad goto out; 4696 1.1 riastrad } 4697 1.1 riastrad memcpy(wgp->wgp_psk, psk, sizeof(wgp->wgp_psk)); 4698 1.1 riastrad } 4699 1.1 riastrad 4700 1.12 riastrad const void *addr; 4701 1.1 riastrad size_t addr_len; 4702 1.47 riastrad struct wg_sockaddr *wgsa = wgp->wgp_endpoint; 4703 1.1 riastrad 4704 1.12 riastrad if (!prop_dictionary_get_data(peer, "endpoint", &addr, &addr_len)) 4705 1.1 riastrad goto skip_endpoint; 4706 1.47 riastrad if (addr_len < sizeof(*wgsatosa(wgsa)) || 4707 1.47 riastrad addr_len > sizeof(*wgsatoss(wgsa))) { 4708 1.47 riastrad error = EINVAL; 4709 1.47 riastrad goto out; 4710 1.47 riastrad } 4711 1.47 riastrad memcpy(wgsatoss(wgsa), addr, addr_len); 4712 1.47 riastrad switch (wgsa_family(wgsa)) { 4713 1.109 riastrad #ifdef INET 4714 1.47 riastrad case AF_INET: 4715 1.109 riastrad break; 4716 1.109 riastrad #endif 4717 1.1 riastrad #ifdef INET6 4718 1.47 riastrad case AF_INET6: 4719 1.109 riastrad break; 4720 1.47 riastrad #endif 4721 1.1 riastrad default: 4722 1.47 riastrad error = EPFNOSUPPORT; 4723 1.47 riastrad goto out; 4724 1.47 riastrad } 4725 1.47 riastrad if (addr_len != sockaddr_getsize_by_family(wgsa_family(wgsa))) { 4726 1.47 riastrad error = EINVAL; 4727 1.47 riastrad goto out; 4728 1.1 riastrad } 4729 1.47 riastrad { 4730 1.47 riastrad char addrstr[128]; 4731 1.47 riastrad sockaddr_format(wgsatosa(wgsa), addrstr, sizeof(addrstr)); 4732 1.47 riastrad WG_DLOG("addr=%s\n", addrstr); 4733 1.47 riastrad } 4734 1.1 riastrad wgp->wgp_endpoint_available = true; 4735 1.1 riastrad 4736 1.1 riastrad prop_array_t allowedips; 4737 1.1 riastrad skip_endpoint: 4738 1.1 riastrad allowedips = prop_dictionary_get(peer, "allowedips"); 4739 1.1 riastrad if (allowedips == NULL) 4740 1.1 riastrad goto skip; 4741 1.1 riastrad 4742 1.1 riastrad prop_object_iterator_t _it = prop_array_iterator(allowedips); 4743 1.1 riastrad prop_dictionary_t prop_allowedip; 4744 1.1 riastrad int j = 0; 4745 1.1 riastrad while ((prop_allowedip = prop_object_iterator_next(_it)) != NULL) { 4746 1.1 riastrad struct wg_allowedip *wga = &wgp->wgp_allowedips[j]; 4747 1.1 riastrad 4748 1.12 riastrad if (!prop_dictionary_get_int(prop_allowedip, "family", 4749 1.12 riastrad &wga->wga_family)) 4750 1.1 riastrad continue; 4751 1.12 riastrad if (!prop_dictionary_get_data(prop_allowedip, "ip", 4752 1.12 riastrad &addr, &addr_len)) 4753 1.1 riastrad continue; 4754 1.12 riastrad if (!prop_dictionary_get_uint8(prop_allowedip, "cidr", 4755 1.12 riastrad &wga->wga_cidr)) 4756 1.1 riastrad continue; 4757 1.1 riastrad 4758 1.1 riastrad switch (wga->wga_family) { 4759 1.109 riastrad #ifdef INET 4760 1.1 riastrad case AF_INET: { 4761 1.1 riastrad struct sockaddr_in sin; 4762 1.1 riastrad char addrstr[128]; 4763 1.1 riastrad struct in_addr mask; 4764 1.1 riastrad struct sockaddr_in sin_mask; 4765 1.1 riastrad 4766 1.1 riastrad if (addr_len != sizeof(struct in_addr)) 4767 1.1 riastrad return EINVAL; 4768 1.1 riastrad memcpy(&wga->wga_addr4, addr, addr_len); 4769 1.1 riastrad 4770 1.9 riastrad sockaddr_in_init(&sin, (const struct in_addr *)addr, 4771 1.9 riastrad 0); 4772 1.1 riastrad sockaddr_copy(&wga->wga_sa_addr, 4773 1.1 riastrad sizeof(sin), sintosa(&sin)); 4774 1.1 riastrad 4775 1.9 riastrad sockaddr_format(sintosa(&sin), 4776 1.9 riastrad addrstr, sizeof(addrstr)); 4777 1.1 riastrad WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr); 4778 1.1 riastrad 4779 1.1 riastrad in_len2mask(&mask, wga->wga_cidr); 4780 1.1 riastrad sockaddr_in_init(&sin_mask, &mask, 0); 4781 1.1 riastrad sockaddr_copy(&wga->wga_sa_mask, 4782 1.1 riastrad sizeof(sin_mask), sintosa(&sin_mask)); 4783 1.1 riastrad 4784 1.1 riastrad break; 4785 1.1 riastrad } 4786 1.109 riastrad #endif 4787 1.1 riastrad #ifdef INET6 4788 1.1 riastrad case AF_INET6: { 4789 1.1 riastrad struct sockaddr_in6 sin6; 4790 1.1 riastrad char addrstr[128]; 4791 1.1 riastrad struct in6_addr mask; 4792 1.1 riastrad struct sockaddr_in6 sin6_mask; 4793 1.1 riastrad 4794 1.1 riastrad if (addr_len != sizeof(struct in6_addr)) 4795 1.1 riastrad return EINVAL; 4796 1.1 riastrad memcpy(&wga->wga_addr6, addr, addr_len); 4797 1.1 riastrad 4798 1.9 riastrad sockaddr_in6_init(&sin6, (const struct in6_addr *)addr, 4799 1.9 riastrad 0, 0, 0); 4800 1.1 riastrad sockaddr_copy(&wga->wga_sa_addr, 4801 1.1 riastrad sizeof(sin6), sin6tosa(&sin6)); 4802 1.1 riastrad 4803 1.9 riastrad sockaddr_format(sin6tosa(&sin6), 4804 1.9 riastrad addrstr, sizeof(addrstr)); 4805 1.1 riastrad WG_DLOG("addr=%s/%d\n", addrstr, wga->wga_cidr); 4806 1.1 riastrad 4807 1.1 riastrad in6_prefixlen2mask(&mask, wga->wga_cidr); 4808 1.1 riastrad sockaddr_in6_init(&sin6_mask, &mask, 0, 0, 0); 4809 1.1 riastrad sockaddr_copy(&wga->wga_sa_mask, 4810 1.1 riastrad sizeof(sin6_mask), sin6tosa(&sin6_mask)); 4811 1.1 riastrad 4812 1.1 riastrad break; 4813 1.1 riastrad } 4814 1.1 riastrad #endif 4815 1.1 riastrad default: 4816 1.1 riastrad error = EINVAL; 4817 1.1 riastrad goto out; 4818 1.1 riastrad } 4819 1.1 riastrad wga->wga_peer = wgp; 4820 1.1 riastrad 4821 1.1 riastrad error = wg_rtable_add_route(wg, wga); 4822 1.1 riastrad if (error != 0) 4823 1.1 riastrad goto out; 4824 1.1 riastrad 4825 1.1 riastrad j++; 4826 1.1 riastrad } 4827 1.1 riastrad wgp->wgp_n_allowedips = j; 4828 1.1 riastrad skip: 4829 1.1 riastrad *wgpp = wgp; 4830 1.1 riastrad out: 4831 1.1 riastrad return error; 4832 1.1 riastrad } 4833 1.1 riastrad 4834 1.1 riastrad static int 4835 1.1 riastrad wg_alloc_prop_buf(char **_buf, struct ifdrv *ifd) 4836 1.1 riastrad { 4837 1.1 riastrad int error; 4838 1.1 riastrad char *buf; 4839 1.1 riastrad 4840 1.87 kre WG_DLOG("buf=%p, len=%zu\n", ifd->ifd_data, ifd->ifd_len); 4841 1.68 riastrad if (ifd->ifd_len >= WG_MAX_PROPLEN) 4842 1.68 riastrad return E2BIG; 4843 1.1 riastrad buf = kmem_alloc(ifd->ifd_len + 1, KM_SLEEP); 4844 1.1 riastrad error = copyin(ifd->ifd_data, buf, ifd->ifd_len); 4845 1.1 riastrad if (error != 0) 4846 1.1 riastrad return error; 4847 1.1 riastrad buf[ifd->ifd_len] = '\0'; 4848 1.1 riastrad #ifdef WG_DEBUG_DUMP 4849 1.80 christos if (wg_debug & WG_DEBUG_FLAGS_DUMP) { 4850 1.80 christos log(LOG_DEBUG, "%.*s\n", (int)MIN(INT_MAX, ifd->ifd_len), 4851 1.80 christos (const char *)buf); 4852 1.80 christos } 4853 1.1 riastrad #endif 4854 1.1 riastrad *_buf = buf; 4855 1.1 riastrad return 0; 4856 1.1 riastrad } 4857 1.1 riastrad 4858 1.1 riastrad static int 4859 1.1 riastrad wg_ioctl_set_private_key(struct wg_softc *wg, struct ifdrv *ifd) 4860 1.1 riastrad { 4861 1.1 riastrad int error; 4862 1.1 riastrad prop_dictionary_t prop_dict; 4863 1.1 riastrad char *buf = NULL; 4864 1.12 riastrad const void *privkey; 4865 1.1 riastrad size_t privkey_len; 4866 1.1 riastrad 4867 1.1 riastrad error = wg_alloc_prop_buf(&buf, ifd); 4868 1.1 riastrad if (error != 0) 4869 1.1 riastrad return error; 4870 1.1 riastrad error = EINVAL; 4871 1.1 riastrad prop_dict = prop_dictionary_internalize(buf); 4872 1.1 riastrad if (prop_dict == NULL) 4873 1.1 riastrad goto out; 4874 1.12 riastrad if (!prop_dictionary_get_data(prop_dict, "private_key", 4875 1.12 riastrad &privkey, &privkey_len)) 4876 1.1 riastrad goto out; 4877 1.1 riastrad #ifdef WG_DEBUG_DUMP 4878 1.80 christos if (wg_debug & WG_DEBUG_FLAGS_DUMP) { 4879 1.80 christos char *hex = gethexdump(privkey, privkey_len); 4880 1.87 kre log(LOG_DEBUG, "privkey=%p, privkey_len=%zu\n%s\n", 4881 1.80 christos privkey, privkey_len, hex); 4882 1.80 christos puthexdump(hex, privkey, privkey_len); 4883 1.80 christos } 4884 1.1 riastrad #endif 4885 1.1 riastrad if (privkey_len != WG_STATIC_KEY_LEN) 4886 1.1 riastrad goto out; 4887 1.1 riastrad memcpy(wg->wg_privkey, privkey, WG_STATIC_KEY_LEN); 4888 1.1 riastrad wg_calc_pubkey(wg->wg_pubkey, wg->wg_privkey); 4889 1.1 riastrad error = 0; 4890 1.1 riastrad 4891 1.1 riastrad out: 4892 1.1 riastrad kmem_free(buf, ifd->ifd_len + 1); 4893 1.1 riastrad return error; 4894 1.1 riastrad } 4895 1.1 riastrad 4896 1.1 riastrad static int 4897 1.1 riastrad wg_ioctl_set_listen_port(struct wg_softc *wg, struct ifdrv *ifd) 4898 1.1 riastrad { 4899 1.1 riastrad int error; 4900 1.1 riastrad prop_dictionary_t prop_dict; 4901 1.1 riastrad char *buf = NULL; 4902 1.12 riastrad uint16_t port; 4903 1.1 riastrad 4904 1.1 riastrad error = wg_alloc_prop_buf(&buf, ifd); 4905 1.1 riastrad if (error != 0) 4906 1.1 riastrad return error; 4907 1.1 riastrad error = EINVAL; 4908 1.1 riastrad prop_dict = prop_dictionary_internalize(buf); 4909 1.1 riastrad if (prop_dict == NULL) 4910 1.1 riastrad goto out; 4911 1.12 riastrad if (!prop_dictionary_get_uint16(prop_dict, "listen_port", &port)) 4912 1.1 riastrad goto out; 4913 1.1 riastrad 4914 1.1 riastrad error = wg->wg_ops->bind_port(wg, (uint16_t)port); 4915 1.1 riastrad 4916 1.1 riastrad out: 4917 1.1 riastrad kmem_free(buf, ifd->ifd_len + 1); 4918 1.1 riastrad return error; 4919 1.1 riastrad } 4920 1.1 riastrad 4921 1.1 riastrad static int 4922 1.1 riastrad wg_ioctl_add_peer(struct wg_softc *wg, struct ifdrv *ifd) 4923 1.1 riastrad { 4924 1.1 riastrad int error; 4925 1.1 riastrad prop_dictionary_t prop_dict; 4926 1.1 riastrad char *buf = NULL; 4927 1.37 riastrad struct wg_peer *wgp = NULL, *wgp0 __diagused; 4928 1.1 riastrad 4929 1.1 riastrad error = wg_alloc_prop_buf(&buf, ifd); 4930 1.1 riastrad if (error != 0) 4931 1.1 riastrad return error; 4932 1.1 riastrad error = EINVAL; 4933 1.1 riastrad prop_dict = prop_dictionary_internalize(buf); 4934 1.1 riastrad if (prop_dict == NULL) 4935 1.1 riastrad goto out; 4936 1.1 riastrad 4937 1.1 riastrad error = wg_handle_prop_peer(wg, prop_dict, &wgp); 4938 1.1 riastrad if (error != 0) 4939 1.1 riastrad goto out; 4940 1.1 riastrad 4941 1.1 riastrad mutex_enter(wg->wg_lock); 4942 1.37 riastrad if (thmap_get(wg->wg_peers_bypubkey, wgp->wgp_pubkey, 4943 1.37 riastrad sizeof(wgp->wgp_pubkey)) != NULL || 4944 1.37 riastrad (wgp->wgp_name[0] && 4945 1.37 riastrad thmap_get(wg->wg_peers_byname, wgp->wgp_name, 4946 1.37 riastrad strlen(wgp->wgp_name)) != NULL)) { 4947 1.37 riastrad mutex_exit(wg->wg_lock); 4948 1.37 riastrad wg_destroy_peer(wgp); 4949 1.37 riastrad error = EEXIST; 4950 1.37 riastrad goto out; 4951 1.37 riastrad } 4952 1.37 riastrad wgp0 = thmap_put(wg->wg_peers_bypubkey, wgp->wgp_pubkey, 4953 1.37 riastrad sizeof(wgp->wgp_pubkey), wgp); 4954 1.37 riastrad KASSERT(wgp0 == wgp); 4955 1.37 riastrad if (wgp->wgp_name[0]) { 4956 1.37 riastrad wgp0 = thmap_put(wg->wg_peers_byname, wgp->wgp_name, 4957 1.37 riastrad strlen(wgp->wgp_name), wgp); 4958 1.37 riastrad KASSERT(wgp0 == wgp); 4959 1.37 riastrad } 4960 1.1 riastrad WG_PEER_WRITER_INSERT_HEAD(wgp, wg); 4961 1.1 riastrad wg->wg_npeers++; 4962 1.1 riastrad mutex_exit(wg->wg_lock); 4963 1.1 riastrad 4964 1.61 roy if_link_state_change(&wg->wg_if, LINK_STATE_UP); 4965 1.61 roy 4966 1.1 riastrad out: 4967 1.1 riastrad kmem_free(buf, ifd->ifd_len + 1); 4968 1.1 riastrad return error; 4969 1.1 riastrad } 4970 1.1 riastrad 4971 1.1 riastrad static int 4972 1.1 riastrad wg_ioctl_delete_peer(struct wg_softc *wg, struct ifdrv *ifd) 4973 1.1 riastrad { 4974 1.1 riastrad int error; 4975 1.1 riastrad prop_dictionary_t prop_dict; 4976 1.1 riastrad char *buf = NULL; 4977 1.1 riastrad const char *name; 4978 1.1 riastrad 4979 1.1 riastrad error = wg_alloc_prop_buf(&buf, ifd); 4980 1.1 riastrad if (error != 0) 4981 1.1 riastrad return error; 4982 1.1 riastrad error = EINVAL; 4983 1.1 riastrad prop_dict = prop_dictionary_internalize(buf); 4984 1.1 riastrad if (prop_dict == NULL) 4985 1.1 riastrad goto out; 4986 1.1 riastrad 4987 1.12 riastrad if (!prop_dictionary_get_string(prop_dict, "name", &name)) 4988 1.1 riastrad goto out; 4989 1.1 riastrad if (strlen(name) > WG_PEER_NAME_MAXLEN) 4990 1.1 riastrad goto out; 4991 1.1 riastrad 4992 1.1 riastrad error = wg_destroy_peer_name(wg, name); 4993 1.1 riastrad out: 4994 1.1 riastrad kmem_free(buf, ifd->ifd_len + 1); 4995 1.1 riastrad return error; 4996 1.1 riastrad } 4997 1.1 riastrad 4998 1.74 christos static bool 4999 1.74 christos wg_is_authorized(struct wg_softc *wg, u_long cmd) 5000 1.74 christos { 5001 1.74 christos int au = cmd == SIOCGDRVSPEC ? 5002 1.74 christos KAUTH_REQ_NETWORK_INTERFACE_WG_GETPRIV : 5003 1.74 christos KAUTH_REQ_NETWORK_INTERFACE_WG_SETPRIV; 5004 1.74 christos return kauth_authorize_network(kauth_cred_get(), 5005 1.74 christos KAUTH_NETWORK_INTERFACE_WG, au, &wg->wg_if, 5006 1.74 christos (void *)cmd, NULL) == 0; 5007 1.74 christos } 5008 1.74 christos 5009 1.1 riastrad static int 5010 1.1 riastrad wg_ioctl_get(struct wg_softc *wg, struct ifdrv *ifd) 5011 1.1 riastrad { 5012 1.1 riastrad int error = ENOMEM; 5013 1.1 riastrad prop_dictionary_t prop_dict; 5014 1.23 riastrad prop_array_t peers = NULL; 5015 1.1 riastrad char *buf; 5016 1.1 riastrad struct wg_peer *wgp; 5017 1.1 riastrad int s, i; 5018 1.1 riastrad 5019 1.1 riastrad prop_dict = prop_dictionary_create(); 5020 1.1 riastrad if (prop_dict == NULL) 5021 1.1 riastrad goto error; 5022 1.1 riastrad 5023 1.74 christos if (wg_is_authorized(wg, SIOCGDRVSPEC)) { 5024 1.73 jakllsch if (!prop_dictionary_set_data(prop_dict, "private_key", 5025 1.73 jakllsch wg->wg_privkey, WG_STATIC_KEY_LEN)) 5026 1.73 jakllsch goto error; 5027 1.73 jakllsch } 5028 1.1 riastrad 5029 1.1 riastrad if (wg->wg_listen_port != 0) { 5030 1.12 riastrad if (!prop_dictionary_set_uint16(prop_dict, "listen_port", 5031 1.12 riastrad wg->wg_listen_port)) 5032 1.1 riastrad goto error; 5033 1.1 riastrad } 5034 1.1 riastrad 5035 1.1 riastrad if (wg->wg_npeers == 0) 5036 1.1 riastrad goto skip_peers; 5037 1.1 riastrad 5038 1.1 riastrad peers = prop_array_create(); 5039 1.12 riastrad if (peers == NULL) 5040 1.12 riastrad goto error; 5041 1.12 riastrad 5042 1.1 riastrad s = pserialize_read_enter(); 5043 1.1 riastrad i = 0; 5044 1.1 riastrad WG_PEER_READER_FOREACH(wgp, wg) { 5045 1.47 riastrad struct wg_sockaddr *wgsa; 5046 1.47 riastrad struct psref wgp_psref, wgsa_psref; 5047 1.1 riastrad prop_dictionary_t prop_peer; 5048 1.1 riastrad 5049 1.47 riastrad wg_get_peer(wgp, &wgp_psref); 5050 1.1 riastrad pserialize_read_exit(s); 5051 1.1 riastrad 5052 1.1 riastrad prop_peer = prop_dictionary_create(); 5053 1.12 riastrad if (prop_peer == NULL) 5054 1.12 riastrad goto next; 5055 1.1 riastrad 5056 1.1 riastrad if (strlen(wgp->wgp_name) > 0) { 5057 1.12 riastrad if (!prop_dictionary_set_string(prop_peer, "name", 5058 1.12 riastrad wgp->wgp_name)) 5059 1.12 riastrad goto next; 5060 1.1 riastrad } 5061 1.1 riastrad 5062 1.12 riastrad if (!prop_dictionary_set_data(prop_peer, "public_key", 5063 1.12 riastrad wgp->wgp_pubkey, sizeof(wgp->wgp_pubkey))) 5064 1.1 riastrad goto next; 5065 1.1 riastrad 5066 1.1 riastrad uint8_t psk_zero[WG_PRESHARED_KEY_LEN] = {0}; 5067 1.13 riastrad if (!consttime_memequal(wgp->wgp_psk, psk_zero, 5068 1.13 riastrad sizeof(wgp->wgp_psk))) { 5069 1.74 christos if (wg_is_authorized(wg, SIOCGDRVSPEC)) { 5070 1.73 jakllsch if (!prop_dictionary_set_data(prop_peer, 5071 1.73 jakllsch "preshared_key", 5072 1.73 jakllsch wgp->wgp_psk, sizeof(wgp->wgp_psk))) 5073 1.73 jakllsch goto next; 5074 1.73 jakllsch } 5075 1.1 riastrad } 5076 1.1 riastrad 5077 1.47 riastrad wgsa = wg_get_endpoint_sa(wgp, &wgsa_psref); 5078 1.47 riastrad CTASSERT(AF_UNSPEC == 0); 5079 1.47 riastrad if (wgsa_family(wgsa) != 0 /*AF_UNSPEC*/ && 5080 1.47 riastrad !prop_dictionary_set_data(prop_peer, "endpoint", 5081 1.47 riastrad wgsatoss(wgsa), 5082 1.47 riastrad sockaddr_getsize_by_family(wgsa_family(wgsa)))) { 5083 1.47 riastrad wg_put_sa(wgp, wgsa, &wgsa_psref); 5084 1.47 riastrad goto next; 5085 1.1 riastrad } 5086 1.47 riastrad wg_put_sa(wgp, wgsa, &wgsa_psref); 5087 1.1 riastrad 5088 1.9 riastrad const struct timespec *t = &wgp->wgp_last_handshake_time; 5089 1.9 riastrad 5090 1.12 riastrad if (!prop_dictionary_set_uint64(prop_peer, 5091 1.65 christos "last_handshake_time_sec", (uint64_t)t->tv_sec)) 5092 1.1 riastrad goto next; 5093 1.12 riastrad if (!prop_dictionary_set_uint32(prop_peer, 5094 1.65 christos "last_handshake_time_nsec", (uint32_t)t->tv_nsec)) 5095 1.1 riastrad goto next; 5096 1.1 riastrad 5097 1.1 riastrad if (wgp->wgp_n_allowedips == 0) 5098 1.1 riastrad goto skip_allowedips; 5099 1.1 riastrad 5100 1.1 riastrad prop_array_t allowedips = prop_array_create(); 5101 1.12 riastrad if (allowedips == NULL) 5102 1.12 riastrad goto next; 5103 1.1 riastrad for (int j = 0; j < wgp->wgp_n_allowedips; j++) { 5104 1.1 riastrad struct wg_allowedip *wga = &wgp->wgp_allowedips[j]; 5105 1.1 riastrad prop_dictionary_t prop_allowedip; 5106 1.1 riastrad 5107 1.1 riastrad prop_allowedip = prop_dictionary_create(); 5108 1.1 riastrad if (prop_allowedip == NULL) 5109 1.1 riastrad break; 5110 1.1 riastrad 5111 1.12 riastrad if (!prop_dictionary_set_int(prop_allowedip, "family", 5112 1.12 riastrad wga->wga_family)) 5113 1.1 riastrad goto _next; 5114 1.12 riastrad if (!prop_dictionary_set_uint8(prop_allowedip, "cidr", 5115 1.12 riastrad wga->wga_cidr)) 5116 1.1 riastrad goto _next; 5117 1.1 riastrad 5118 1.1 riastrad switch (wga->wga_family) { 5119 1.109 riastrad #ifdef INET 5120 1.1 riastrad case AF_INET: 5121 1.12 riastrad if (!prop_dictionary_set_data(prop_allowedip, 5122 1.12 riastrad "ip", &wga->wga_addr4, 5123 1.12 riastrad sizeof(wga->wga_addr4))) 5124 1.1 riastrad goto _next; 5125 1.1 riastrad break; 5126 1.109 riastrad #endif 5127 1.1 riastrad #ifdef INET6 5128 1.1 riastrad case AF_INET6: 5129 1.12 riastrad if (!prop_dictionary_set_data(prop_allowedip, 5130 1.12 riastrad "ip", &wga->wga_addr6, 5131 1.12 riastrad sizeof(wga->wga_addr6))) 5132 1.1 riastrad goto _next; 5133 1.1 riastrad break; 5134 1.1 riastrad #endif 5135 1.1 riastrad default: 5136 1.109 riastrad panic("invalid af=%d", wga->wga_family); 5137 1.1 riastrad } 5138 1.1 riastrad prop_array_set(allowedips, j, prop_allowedip); 5139 1.1 riastrad _next: 5140 1.1 riastrad prop_object_release(prop_allowedip); 5141 1.1 riastrad } 5142 1.1 riastrad prop_dictionary_set(prop_peer, "allowedips", allowedips); 5143 1.1 riastrad prop_object_release(allowedips); 5144 1.1 riastrad 5145 1.1 riastrad skip_allowedips: 5146 1.1 riastrad 5147 1.1 riastrad prop_array_set(peers, i, prop_peer); 5148 1.1 riastrad next: 5149 1.12 riastrad if (prop_peer) 5150 1.12 riastrad prop_object_release(prop_peer); 5151 1.1 riastrad i++; 5152 1.1 riastrad 5153 1.1 riastrad s = pserialize_read_enter(); 5154 1.47 riastrad wg_put_peer(wgp, &wgp_psref); 5155 1.1 riastrad } 5156 1.1 riastrad pserialize_read_exit(s); 5157 1.1 riastrad 5158 1.1 riastrad prop_dictionary_set(prop_dict, "peers", peers); 5159 1.1 riastrad prop_object_release(peers); 5160 1.1 riastrad peers = NULL; 5161 1.1 riastrad 5162 1.1 riastrad skip_peers: 5163 1.1 riastrad buf = prop_dictionary_externalize(prop_dict); 5164 1.1 riastrad if (buf == NULL) 5165 1.1 riastrad goto error; 5166 1.1 riastrad if (ifd->ifd_len < (strlen(buf) + 1)) { 5167 1.1 riastrad error = EINVAL; 5168 1.1 riastrad goto error; 5169 1.1 riastrad } 5170 1.1 riastrad error = copyout(buf, ifd->ifd_data, strlen(buf) + 1); 5171 1.1 riastrad 5172 1.1 riastrad free(buf, 0); 5173 1.1 riastrad error: 5174 1.1 riastrad if (peers != NULL) 5175 1.1 riastrad prop_object_release(peers); 5176 1.1 riastrad if (prop_dict != NULL) 5177 1.1 riastrad prop_object_release(prop_dict); 5178 1.1 riastrad 5179 1.1 riastrad return error; 5180 1.1 riastrad } 5181 1.1 riastrad 5182 1.1 riastrad static int 5183 1.1 riastrad wg_ioctl(struct ifnet *ifp, u_long cmd, void *data) 5184 1.1 riastrad { 5185 1.1 riastrad struct wg_softc *wg = ifp->if_softc; 5186 1.1 riastrad struct ifreq *ifr = data; 5187 1.1 riastrad struct ifaddr *ifa = data; 5188 1.1 riastrad struct ifdrv *ifd = data; 5189 1.1 riastrad int error = 0; 5190 1.1 riastrad 5191 1.1 riastrad switch (cmd) { 5192 1.1 riastrad case SIOCINITIFADDR: 5193 1.1 riastrad if (ifa->ifa_addr->sa_family != AF_LINK && 5194 1.1 riastrad (ifp->if_flags & (IFF_UP | IFF_RUNNING)) != 5195 1.1 riastrad (IFF_UP | IFF_RUNNING)) { 5196 1.1 riastrad ifp->if_flags |= IFF_UP; 5197 1.67 riastrad error = if_init(ifp); 5198 1.1 riastrad } 5199 1.14 riastrad return error; 5200 1.1 riastrad case SIOCADDMULTI: 5201 1.1 riastrad case SIOCDELMULTI: 5202 1.1 riastrad switch (ifr->ifr_addr.sa_family) { 5203 1.109 riastrad #ifdef INET 5204 1.1 riastrad case AF_INET: /* IP supports Multicast */ 5205 1.1 riastrad break; 5206 1.109 riastrad #endif 5207 1.1 riastrad #ifdef INET6 5208 1.1 riastrad case AF_INET6: /* IP6 supports Multicast */ 5209 1.1 riastrad break; 5210 1.1 riastrad #endif 5211 1.1 riastrad default: /* Other protocols doesn't support Multicast */ 5212 1.1 riastrad error = EAFNOSUPPORT; 5213 1.1 riastrad break; 5214 1.1 riastrad } 5215 1.14 riastrad return error; 5216 1.1 riastrad case SIOCSDRVSPEC: 5217 1.74 christos if (!wg_is_authorized(wg, cmd)) { 5218 1.72 jakllsch return EPERM; 5219 1.72 jakllsch } 5220 1.1 riastrad switch (ifd->ifd_cmd) { 5221 1.1 riastrad case WG_IOCTL_SET_PRIVATE_KEY: 5222 1.1 riastrad error = wg_ioctl_set_private_key(wg, ifd); 5223 1.1 riastrad break; 5224 1.1 riastrad case WG_IOCTL_SET_LISTEN_PORT: 5225 1.1 riastrad error = wg_ioctl_set_listen_port(wg, ifd); 5226 1.1 riastrad break; 5227 1.1 riastrad case WG_IOCTL_ADD_PEER: 5228 1.1 riastrad error = wg_ioctl_add_peer(wg, ifd); 5229 1.1 riastrad break; 5230 1.1 riastrad case WG_IOCTL_DELETE_PEER: 5231 1.1 riastrad error = wg_ioctl_delete_peer(wg, ifd); 5232 1.1 riastrad break; 5233 1.1 riastrad default: 5234 1.1 riastrad error = EINVAL; 5235 1.1 riastrad break; 5236 1.1 riastrad } 5237 1.14 riastrad return error; 5238 1.1 riastrad case SIOCGDRVSPEC: 5239 1.14 riastrad return wg_ioctl_get(wg, ifd); 5240 1.1 riastrad case SIOCSIFFLAGS: 5241 1.1 riastrad if ((error = ifioctl_common(ifp, cmd, data)) != 0) 5242 1.1 riastrad break; 5243 1.1 riastrad switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 5244 1.1 riastrad case IFF_RUNNING: 5245 1.1 riastrad /* 5246 1.1 riastrad * If interface is marked down and it is running, 5247 1.1 riastrad * then stop and disable it. 5248 1.1 riastrad */ 5249 1.66 riastrad if_stop(ifp, 1); 5250 1.1 riastrad break; 5251 1.1 riastrad case IFF_UP: 5252 1.1 riastrad /* 5253 1.1 riastrad * If interface is marked up and it is stopped, then 5254 1.1 riastrad * start it. 5255 1.1 riastrad */ 5256 1.67 riastrad error = if_init(ifp); 5257 1.1 riastrad break; 5258 1.1 riastrad default: 5259 1.1 riastrad break; 5260 1.1 riastrad } 5261 1.14 riastrad return error; 5262 1.1 riastrad #ifdef WG_RUMPKERNEL 5263 1.1 riastrad case SIOCSLINKSTR: 5264 1.1 riastrad error = wg_ioctl_linkstr(wg, ifd); 5265 1.108 riastrad if (error) 5266 1.108 riastrad return error; 5267 1.108 riastrad wg->wg_ops = &wg_ops_rumpuser; 5268 1.108 riastrad return 0; 5269 1.14 riastrad #endif 5270 1.14 riastrad default: 5271 1.1 riastrad break; 5272 1.14 riastrad } 5273 1.1 riastrad 5274 1.14 riastrad error = ifioctl_common(ifp, cmd, data); 5275 1.1 riastrad 5276 1.1 riastrad #ifdef WG_RUMPKERNEL 5277 1.14 riastrad if (!wg_user_mode(wg)) 5278 1.14 riastrad return error; 5279 1.14 riastrad 5280 1.14 riastrad /* Do the same to the corresponding tun device on the host */ 5281 1.14 riastrad /* 5282 1.14 riastrad * XXX Actually the command has not been handled yet. It 5283 1.14 riastrad * will be handled via pr_ioctl form doifioctl later. 5284 1.14 riastrad */ 5285 1.14 riastrad switch (cmd) { 5286 1.109 riastrad #ifdef INET 5287 1.14 riastrad case SIOCAIFADDR: 5288 1.14 riastrad case SIOCDIFADDR: { 5289 1.17 riastrad struct in_aliasreq _ifra = *(const struct in_aliasreq *)data; 5290 1.14 riastrad struct in_aliasreq *ifra = &_ifra; 5291 1.14 riastrad KASSERT(error == ENOTTY); 5292 1.14 riastrad strncpy(ifra->ifra_name, rumpuser_wg_get_tunname(wg->wg_user), 5293 1.14 riastrad IFNAMSIZ); 5294 1.14 riastrad error = rumpuser_wg_ioctl(wg->wg_user, cmd, ifra, AF_INET); 5295 1.14 riastrad if (error == 0) 5296 1.14 riastrad error = ENOTTY; 5297 1.14 riastrad break; 5298 1.14 riastrad } 5299 1.109 riastrad #endif 5300 1.1 riastrad #ifdef INET6 5301 1.14 riastrad case SIOCAIFADDR_IN6: 5302 1.14 riastrad case SIOCDIFADDR_IN6: { 5303 1.17 riastrad struct in6_aliasreq _ifra = *(const struct in6_aliasreq *)data; 5304 1.14 riastrad struct in6_aliasreq *ifra = &_ifra; 5305 1.14 riastrad KASSERT(error == ENOTTY); 5306 1.14 riastrad strncpy(ifra->ifra_name, rumpuser_wg_get_tunname(wg->wg_user), 5307 1.14 riastrad IFNAMSIZ); 5308 1.14 riastrad error = rumpuser_wg_ioctl(wg->wg_user, cmd, ifra, AF_INET6); 5309 1.14 riastrad if (error == 0) 5310 1.14 riastrad error = ENOTTY; 5311 1.14 riastrad break; 5312 1.14 riastrad } 5313 1.1 riastrad #endif 5314 1.109 riastrad default: 5315 1.109 riastrad break; 5316 1.14 riastrad } 5317 1.1 riastrad #endif /* WG_RUMPKERNEL */ 5318 1.1 riastrad 5319 1.1 riastrad return error; 5320 1.1 riastrad } 5321 1.1 riastrad 5322 1.1 riastrad static int 5323 1.1 riastrad wg_init(struct ifnet *ifp) 5324 1.1 riastrad { 5325 1.1 riastrad 5326 1.1 riastrad ifp->if_flags |= IFF_RUNNING; 5327 1.1 riastrad 5328 1.1 riastrad /* TODO flush pending packets. */ 5329 1.1 riastrad return 0; 5330 1.1 riastrad } 5331 1.1 riastrad 5332 1.60 riastrad #ifdef ALTQ 5333 1.60 riastrad static void 5334 1.60 riastrad wg_start(struct ifnet *ifp) 5335 1.60 riastrad { 5336 1.60 riastrad struct mbuf *m; 5337 1.60 riastrad 5338 1.60 riastrad for (;;) { 5339 1.60 riastrad IFQ_DEQUEUE(&ifp->if_snd, m); 5340 1.60 riastrad if (m == NULL) 5341 1.60 riastrad break; 5342 1.60 riastrad 5343 1.60 riastrad kpreempt_disable(); 5344 1.60 riastrad const uint32_t h = curcpu()->ci_index; // pktq_rps_hash(m) 5345 1.60 riastrad if (__predict_false(!pktq_enqueue(wg_pktq, m, h))) { 5346 1.76 jakllsch WGLOG(LOG_ERR, "%s: pktq full, dropping\n", 5347 1.76 jakllsch if_name(ifp)); 5348 1.60 riastrad m_freem(m); 5349 1.60 riastrad } 5350 1.60 riastrad kpreempt_enable(); 5351 1.60 riastrad } 5352 1.60 riastrad } 5353 1.60 riastrad #endif 5354 1.60 riastrad 5355 1.1 riastrad static void 5356 1.1 riastrad wg_stop(struct ifnet *ifp, int disable) 5357 1.1 riastrad { 5358 1.1 riastrad 5359 1.1 riastrad KASSERT((ifp->if_flags & IFF_RUNNING) != 0); 5360 1.1 riastrad ifp->if_flags &= ~IFF_RUNNING; 5361 1.1 riastrad 5362 1.1 riastrad /* Need to do something? */ 5363 1.1 riastrad } 5364 1.1 riastrad 5365 1.8 riastrad #ifdef WG_DEBUG_PARAMS 5366 1.24 riastrad SYSCTL_SETUP(sysctl_net_wg_setup, "sysctl net.wg setup") 5367 1.1 riastrad { 5368 1.1 riastrad const struct sysctlnode *node = NULL; 5369 1.1 riastrad 5370 1.8 riastrad sysctl_createv(clog, 0, NULL, &node, 5371 1.8 riastrad CTLFLAG_PERMANENT, 5372 1.24 riastrad CTLTYPE_NODE, "wg", 5373 1.24 riastrad SYSCTL_DESCR("wg(4)"), 5374 1.8 riastrad NULL, 0, NULL, 0, 5375 1.8 riastrad CTL_NET, CTL_CREATE, CTL_EOL); 5376 1.8 riastrad sysctl_createv(clog, 0, &node, NULL, 5377 1.8 riastrad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 5378 1.21 riastrad CTLTYPE_QUAD, "rekey_after_messages", 5379 1.8 riastrad SYSCTL_DESCR("session liftime by messages"), 5380 1.8 riastrad NULL, 0, &wg_rekey_after_messages, 0, CTL_CREATE, CTL_EOL); 5381 1.8 riastrad sysctl_createv(clog, 0, &node, NULL, 5382 1.8 riastrad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 5383 1.21 riastrad CTLTYPE_INT, "rekey_after_time", 5384 1.8 riastrad SYSCTL_DESCR("session liftime"), 5385 1.8 riastrad NULL, 0, &wg_rekey_after_time, 0, CTL_CREATE, CTL_EOL); 5386 1.8 riastrad sysctl_createv(clog, 0, &node, NULL, 5387 1.8 riastrad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 5388 1.21 riastrad CTLTYPE_INT, "rekey_timeout", 5389 1.8 riastrad SYSCTL_DESCR("session handshake retry time"), 5390 1.8 riastrad NULL, 0, &wg_rekey_timeout, 0, CTL_CREATE, CTL_EOL); 5391 1.8 riastrad sysctl_createv(clog, 0, &node, NULL, 5392 1.8 riastrad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 5393 1.21 riastrad CTLTYPE_INT, "rekey_attempt_time", 5394 1.8 riastrad SYSCTL_DESCR("session handshake timeout"), 5395 1.8 riastrad NULL, 0, &wg_rekey_attempt_time, 0, CTL_CREATE, CTL_EOL); 5396 1.8 riastrad sysctl_createv(clog, 0, &node, NULL, 5397 1.8 riastrad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 5398 1.21 riastrad CTLTYPE_INT, "keepalive_timeout", 5399 1.8 riastrad SYSCTL_DESCR("keepalive timeout"), 5400 1.8 riastrad NULL, 0, &wg_keepalive_timeout, 0, CTL_CREATE, CTL_EOL); 5401 1.8 riastrad sysctl_createv(clog, 0, &node, NULL, 5402 1.8 riastrad CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 5403 1.8 riastrad CTLTYPE_BOOL, "force_underload", 5404 1.8 riastrad SYSCTL_DESCR("force to detemine under load"), 5405 1.8 riastrad NULL, 0, &wg_force_underload, 0, CTL_CREATE, CTL_EOL); 5406 1.80 christos sysctl_createv(clog, 0, &node, NULL, 5407 1.80 christos CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 5408 1.80 christos CTLTYPE_INT, "debug", 5409 1.84 christos SYSCTL_DESCR("set debug flags 1=log 2=trace 4=dump 8=packet"), 5410 1.80 christos NULL, 0, &wg_debug, 0, CTL_CREATE, CTL_EOL); 5411 1.8 riastrad } 5412 1.1 riastrad #endif 5413 1.1 riastrad 5414 1.1 riastrad #ifdef WG_RUMPKERNEL 5415 1.1 riastrad static bool 5416 1.1 riastrad wg_user_mode(struct wg_softc *wg) 5417 1.1 riastrad { 5418 1.1 riastrad 5419 1.1 riastrad return wg->wg_user != NULL; 5420 1.1 riastrad } 5421 1.1 riastrad 5422 1.1 riastrad static int 5423 1.1 riastrad wg_ioctl_linkstr(struct wg_softc *wg, struct ifdrv *ifd) 5424 1.1 riastrad { 5425 1.1 riastrad struct ifnet *ifp = &wg->wg_if; 5426 1.1 riastrad int error; 5427 1.1 riastrad 5428 1.1 riastrad if (ifp->if_flags & IFF_UP) 5429 1.1 riastrad return EBUSY; 5430 1.1 riastrad 5431 1.1 riastrad if (ifd->ifd_cmd == IFLINKSTR_UNSET) { 5432 1.1 riastrad /* XXX do nothing */ 5433 1.1 riastrad return 0; 5434 1.1 riastrad } else if (ifd->ifd_cmd != 0) { 5435 1.1 riastrad return EINVAL; 5436 1.1 riastrad } else if (wg->wg_user != NULL) { 5437 1.1 riastrad return EBUSY; 5438 1.1 riastrad } 5439 1.1 riastrad 5440 1.1 riastrad /* Assume \0 included */ 5441 1.1 riastrad if (ifd->ifd_len > IFNAMSIZ) { 5442 1.1 riastrad return E2BIG; 5443 1.1 riastrad } else if (ifd->ifd_len < 1) { 5444 1.1 riastrad return EINVAL; 5445 1.1 riastrad } 5446 1.1 riastrad 5447 1.1 riastrad char tun_name[IFNAMSIZ]; 5448 1.1 riastrad error = copyinstr(ifd->ifd_data, tun_name, ifd->ifd_len, NULL); 5449 1.1 riastrad if (error != 0) 5450 1.1 riastrad return error; 5451 1.1 riastrad 5452 1.1 riastrad if (strncmp(tun_name, "tun", 3) != 0) 5453 1.1 riastrad return EINVAL; 5454 1.1 riastrad 5455 1.1 riastrad error = rumpuser_wg_create(tun_name, wg, &wg->wg_user); 5456 1.1 riastrad 5457 1.1 riastrad return error; 5458 1.1 riastrad } 5459 1.1 riastrad 5460 1.1 riastrad static int 5461 1.134 riastrad wg_send_user(struct wg_peer *wgp, struct mbuf *m, bool handshake) 5462 1.1 riastrad { 5463 1.1 riastrad int error; 5464 1.1 riastrad struct psref psref; 5465 1.1 riastrad struct wg_sockaddr *wgsa; 5466 1.1 riastrad struct wg_softc *wg = wgp->wgp_sc; 5467 1.1 riastrad struct iovec iov[1]; 5468 1.1 riastrad 5469 1.1 riastrad wgsa = wg_get_endpoint_sa(wgp, &psref); 5470 1.1 riastrad 5471 1.134 riastrad #ifdef WG_DEBUG_LOG 5472 1.134 riastrad if (handshake) { 5473 1.134 riastrad char addr[128]; 5474 1.134 riastrad sockaddr_format(wgsatosa(wgsa), addr, sizeof(addr)); 5475 1.134 riastrad WG_DLOG("send handshake msg to %s\n", addr); 5476 1.134 riastrad } 5477 1.134 riastrad #endif 5478 1.134 riastrad 5479 1.1 riastrad iov[0].iov_base = mtod(m, void *); 5480 1.1 riastrad iov[0].iov_len = m->m_len; 5481 1.1 riastrad 5482 1.1 riastrad /* Send messages to a peer via an ordinary socket. */ 5483 1.1 riastrad error = rumpuser_wg_send_peer(wg->wg_user, wgsatosa(wgsa), iov, 1); 5484 1.1 riastrad 5485 1.1 riastrad wg_put_sa(wgp, wgsa, &psref); 5486 1.1 riastrad 5487 1.38 riastrad m_freem(m); 5488 1.38 riastrad 5489 1.1 riastrad return error; 5490 1.1 riastrad } 5491 1.1 riastrad 5492 1.134 riastrad static int 5493 1.134 riastrad wg_send_hs_user(struct wg_peer *wgp, struct mbuf *m) 5494 1.134 riastrad { 5495 1.134 riastrad 5496 1.134 riastrad return wg_send_user(wgp, m, /*handshake*/true); 5497 1.134 riastrad } 5498 1.134 riastrad 5499 1.134 riastrad static int 5500 1.135 riastrad wg_send_data_user(struct wg_peer *wgp, struct mbuf *m) 5501 1.134 riastrad { 5502 1.134 riastrad 5503 1.134 riastrad return wg_send_user(wgp, m, /*handshake*/false); 5504 1.134 riastrad } 5505 1.134 riastrad 5506 1.1 riastrad static void 5507 1.1 riastrad wg_input_user(struct ifnet *ifp, struct mbuf *m, const int af) 5508 1.1 riastrad { 5509 1.1 riastrad struct wg_softc *wg = ifp->if_softc; 5510 1.1 riastrad struct iovec iov[2]; 5511 1.1 riastrad struct sockaddr_storage ss; 5512 1.1 riastrad 5513 1.1 riastrad KASSERT(af == AF_INET || af == AF_INET6); 5514 1.1 riastrad 5515 1.1 riastrad WG_TRACE(""); 5516 1.1 riastrad 5517 1.109 riastrad switch (af) { 5518 1.109 riastrad #ifdef INET 5519 1.109 riastrad case AF_INET: { 5520 1.1 riastrad struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 5521 1.1 riastrad struct ip *ip; 5522 1.27 riastrad 5523 1.27 riastrad KASSERT(m->m_len >= sizeof(struct ip)); 5524 1.1 riastrad ip = mtod(m, struct ip *); 5525 1.1 riastrad sockaddr_in_init(sin, &ip->ip_dst, 0); 5526 1.109 riastrad break; 5527 1.109 riastrad } 5528 1.109 riastrad #endif 5529 1.109 riastrad #ifdef INET6 5530 1.109 riastrad case AF_INET6: { 5531 1.1 riastrad struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 5532 1.1 riastrad struct ip6_hdr *ip6; 5533 1.27 riastrad 5534 1.27 riastrad KASSERT(m->m_len >= sizeof(struct ip6_hdr)); 5535 1.1 riastrad ip6 = mtod(m, struct ip6_hdr *); 5536 1.1 riastrad sockaddr_in6_init(sin6, &ip6->ip6_dst, 0, 0, 0); 5537 1.109 riastrad break; 5538 1.109 riastrad } 5539 1.109 riastrad #endif 5540 1.109 riastrad default: 5541 1.109 riastrad goto out; 5542 1.1 riastrad } 5543 1.1 riastrad 5544 1.1 riastrad iov[0].iov_base = &ss; 5545 1.1 riastrad iov[0].iov_len = ss.ss_len; 5546 1.1 riastrad iov[1].iov_base = mtod(m, void *); 5547 1.1 riastrad iov[1].iov_len = m->m_len; 5548 1.1 riastrad 5549 1.1 riastrad WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len); 5550 1.1 riastrad 5551 1.1 riastrad /* Send decrypted packets to users via a tun. */ 5552 1.1 riastrad rumpuser_wg_send_user(wg->wg_user, iov, 2); 5553 1.38 riastrad 5554 1.109 riastrad out: m_freem(m); 5555 1.1 riastrad } 5556 1.1 riastrad 5557 1.1 riastrad static int 5558 1.1 riastrad wg_bind_port_user(struct wg_softc *wg, const uint16_t port) 5559 1.1 riastrad { 5560 1.1 riastrad int error; 5561 1.1 riastrad uint16_t old_port = wg->wg_listen_port; 5562 1.1 riastrad 5563 1.1 riastrad if (port != 0 && old_port == port) 5564 1.1 riastrad return 0; 5565 1.1 riastrad 5566 1.1 riastrad error = rumpuser_wg_sock_bind(wg->wg_user, port); 5567 1.108 riastrad if (error) 5568 1.108 riastrad return error; 5569 1.108 riastrad 5570 1.108 riastrad wg->wg_listen_port = port; 5571 1.108 riastrad return 0; 5572 1.1 riastrad } 5573 1.1 riastrad 5574 1.1 riastrad /* 5575 1.1 riastrad * Receive user packets. 5576 1.1 riastrad */ 5577 1.1 riastrad void 5578 1.1 riastrad rumpkern_wg_recv_user(struct wg_softc *wg, struct iovec *iov, size_t iovlen) 5579 1.1 riastrad { 5580 1.1 riastrad struct ifnet *ifp = &wg->wg_if; 5581 1.1 riastrad struct mbuf *m; 5582 1.1 riastrad const struct sockaddr *dst; 5583 1.108 riastrad int error; 5584 1.1 riastrad 5585 1.1 riastrad WG_TRACE(""); 5586 1.1 riastrad 5587 1.1 riastrad dst = iov[0].iov_base; 5588 1.1 riastrad 5589 1.48 riastrad m = m_gethdr(M_DONTWAIT, MT_DATA); 5590 1.1 riastrad if (m == NULL) 5591 1.1 riastrad return; 5592 1.1 riastrad m->m_len = m->m_pkthdr.len = 0; 5593 1.1 riastrad m_copyback(m, 0, iov[1].iov_len, iov[1].iov_base); 5594 1.1 riastrad 5595 1.87 kre WG_DLOG("iov_len=%zu\n", iov[1].iov_len); 5596 1.1 riastrad WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len); 5597 1.1 riastrad 5598 1.108 riastrad error = wg_output(ifp, m, dst, NULL); /* consumes m */ 5599 1.108 riastrad if (error) 5600 1.108 riastrad WG_DLOG("wg_output failed, error=%d\n", error); 5601 1.1 riastrad } 5602 1.1 riastrad 5603 1.1 riastrad /* 5604 1.1 riastrad * Receive packets from a peer. 5605 1.1 riastrad */ 5606 1.1 riastrad void 5607 1.1 riastrad rumpkern_wg_recv_peer(struct wg_softc *wg, struct iovec *iov, size_t iovlen) 5608 1.1 riastrad { 5609 1.1 riastrad struct mbuf *m; 5610 1.1 riastrad const struct sockaddr *src; 5611 1.78 riastrad int bound; 5612 1.1 riastrad 5613 1.1 riastrad WG_TRACE(""); 5614 1.1 riastrad 5615 1.1 riastrad src = iov[0].iov_base; 5616 1.1 riastrad 5617 1.48 riastrad m = m_gethdr(M_DONTWAIT, MT_DATA); 5618 1.1 riastrad if (m == NULL) 5619 1.1 riastrad return; 5620 1.1 riastrad m->m_len = m->m_pkthdr.len = 0; 5621 1.1 riastrad m_copyback(m, 0, iov[1].iov_len, iov[1].iov_base); 5622 1.1 riastrad 5623 1.87 kre WG_DLOG("iov_len=%zu\n", iov[1].iov_len); 5624 1.1 riastrad WG_DUMP_BUF(iov[1].iov_base, iov[1].iov_len); 5625 1.1 riastrad 5626 1.78 riastrad bound = curlwp_bind(); 5627 1.1 riastrad wg_handle_packet(wg, m, src); 5628 1.78 riastrad curlwp_bindx(bound); 5629 1.1 riastrad } 5630 1.1 riastrad #endif /* WG_RUMPKERNEL */ 5631 1.1 riastrad 5632 1.1 riastrad /* 5633 1.1 riastrad * Module infrastructure 5634 1.1 riastrad */ 5635 1.1 riastrad #include "if_module.h" 5636 1.1 riastrad 5637 1.65 christos IF_MODULE(MODULE_CLASS_DRIVER, wg, "sodium,blake2s") 5638