Module Name: src Committed By: riastradh Date: Mon Aug 31 20:29:14 UTC 2020
Modified Files: src/sys/net: if_wg.c Log Message: wg: Verify or send cookie challenge before looking up session. This step doesn't depend on the session, so let's avoid touching the session state until we've passed it. To generate a diff of this commit: cvs rdiff -u -r1.44 -r1.45 src/sys/net/if_wg.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_wg.c diff -u src/sys/net/if_wg.c:1.44 src/sys/net/if_wg.c:1.45 --- src/sys/net/if_wg.c:1.44 Mon Aug 31 20:27:06 2020 +++ src/sys/net/if_wg.c Mon Aug 31 20:29:14 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wg.c,v 1.44 2020/08/31 20:27:06 riastradh Exp $ */ +/* $NetBSD: if_wg.c,v 1.45 2020/08/31 20:29:14 riastradh Exp $ */ /* * Copyright (C) Ryota Ozaki <ozaki.ry...@gmail.com> @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.44 2020/08/31 20:27:06 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.45 2020/08/31 20:29:14 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1399,32 +1399,6 @@ wg_handle_msg_init(struct wg_softc *wg, return; } - wgs = wg_lock_unstable_session(wgp); - if (wgs->wgs_state == WGS_STATE_DESTROYING) { - /* - * We can assume that the peer doesn't have an - * established session, so clear it now. If the timer - * fired, tough -- it won't have any effect unless we - * manage to transition back to WGS_STATE_DESTROYING. - */ - WG_TRACE("Session destroying, but force to clear"); - callout_stop(&wgp->wgp_session_dtor_timer); - wg_clear_states(wgs); - wgs->wgs_state = WGS_STATE_UNKNOWN; - } - if (wgs->wgs_state == WGS_STATE_INIT_ACTIVE) { - WG_TRACE("Sesssion already initializing, ignoring the message"); - mutex_exit(wgs->wgs_lock); - goto out_wgp; - } - if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) { - WG_TRACE("Sesssion already initializing, destroying old states"); - wg_clear_states(wgs); - } - wgs->wgs_state = WGS_STATE_INIT_PASSIVE; - wg_get_session(wgs, &psref_session); - mutex_exit(wgs->wgs_lock); - if (__predict_false(wg_is_underload(wg, wgp, WG_MSG_TYPE_INIT))) { WG_TRACE("under load"); /* @@ -1440,13 +1414,13 @@ wg_handle_msg_init(struct wg_softc *wg, WG_TRACE("sending a cookie message: no cookie included"); (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender, wgmi->wgmi_mac1, src); - goto out; + goto out_wgp; } if (!wgp->wgp_last_sent_cookie_valid) { WG_TRACE("sending a cookie message: no cookie sent ever"); (void)wg_send_cookie_msg(wg, wgp, wgmi->wgmi_sender, wgmi->wgmi_mac1, src); - goto out; + goto out_wgp; } uint8_t mac2[WG_MAC_LEN]; wg_algo_mac(mac2, sizeof(mac2), wgp->wgp_last_sent_cookie, @@ -1454,11 +1428,37 @@ wg_handle_msg_init(struct wg_softc *wg, offsetof(struct wg_msg_init, wgmi_mac2), NULL, 0); if (!consttime_memequal(mac2, wgmi->wgmi_mac2, sizeof(mac2))) { WG_DLOG("mac2 is invalid\n"); - goto out; + goto out_wgp; } WG_TRACE("under load, but continue to sending"); } + wgs = wg_lock_unstable_session(wgp); + if (wgs->wgs_state == WGS_STATE_DESTROYING) { + /* + * We can assume that the peer doesn't have an + * established session, so clear it now. If the timer + * fired, tough -- it won't have any effect unless we + * manage to transition back to WGS_STATE_DESTROYING. + */ + WG_TRACE("Session destroying, but force to clear"); + callout_stop(&wgp->wgp_session_dtor_timer); + wg_clear_states(wgs); + wgs->wgs_state = WGS_STATE_UNKNOWN; + } + if (wgs->wgs_state == WGS_STATE_INIT_ACTIVE) { + WG_TRACE("Sesssion already initializing, ignoring the message"); + mutex_exit(wgs->wgs_lock); + goto out_wgp; + } + if (wgs->wgs_state == WGS_STATE_INIT_PASSIVE) { + WG_TRACE("Sesssion already initializing, destroying old states"); + wg_clear_states(wgs); + } + wgs->wgs_state = WGS_STATE_INIT_PASSIVE; + wg_get_session(wgs, &psref_session); + mutex_exit(wgs->wgs_lock); + /* [N] 2.2: "ss" */ /* Ci, k := KDF2(Ci, DH(Si^priv, Sr^pub)) */ wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey);