Index: if_wg.c =================================================================== RCS file: /cvsroot/src/sys/net/if_wg.c,v retrieving revision 1.135 diff -u -p -u -r1.135 if_wg.c --- if_wg.c 27 Dec 2024 16:42:28 -0000 1.135 +++ if_wg.c 9 Apr 2026 16:32:35 -0000 @@ -1086,7 +1086,7 @@ wg_algo_generate_keypair(uint8_t pubkey[ crypto_scalarmult_base(pubkey, privkey); } -static void +static bool wg_algo_dh(uint8_t out[static WG_DH_OUTPUT_LEN], const uint8_t privkey[static WG_STATIC_KEY_LEN], const uint8_t pubkey[static WG_STATIC_KEY_LEN]) @@ -1094,8 +1094,7 @@ wg_algo_dh(uint8_t out[static WG_DH_OUTP CTASSERT(WG_STATIC_KEY_LEN == crypto_scalarmult_curve25519_BYTES); - int ret __diagused = crypto_scalarmult(out, privkey, pubkey); - KASSERT(ret == 0); + return crypto_scalarmult(out, privkey, pubkey) == 0; } static void @@ -1176,7 +1175,7 @@ wg_algo_kdf(uint8_t out1[static WG_KDF_O WG_DUMP_HASH("out3", out3); } -static void __noinline +static bool __noinline wg_algo_dh_kdf(uint8_t ckey[static WG_CHAINING_KEY_LEN], uint8_t cipher_key[WG_CIPHER_KEY_LEN], const uint8_t local_key[static WG_STATIC_KEY_LEN], @@ -1184,13 +1183,14 @@ wg_algo_dh_kdf(uint8_t ckey[static WG_CH { uint8_t dhout[WG_DH_OUTPUT_LEN]; - wg_algo_dh(dhout, local_key, remote_key); + bool rv = wg_algo_dh(dhout, local_key, remote_key); wg_algo_kdf(ckey, cipher_key, NULL, ckey, dhout, sizeof(dhout)); WG_DUMP_HASH("dhout", dhout); WG_DUMP_HASH("ckey", ckey); if (cipher_key != NULL) WG_DUMP_HASH("cipher_key", cipher_key); + return rv; } static void @@ -1474,7 +1474,7 @@ wg_fill_msg_init(struct wg_softc *wg, st /* [N] 2.2: "es" */ /* Ci, k := KDF2(Ci, DH(Ei^priv, Sr^pub)) */ - wg_algo_dh_kdf(ckey, cipher_key, privkey, wgp->wgp_pubkey); + (void)wg_algo_dh_kdf(ckey, cipher_key, privkey, wgp->wgp_pubkey); /* [N] 2.2: "s" */ /* msg.static := AEAD(k, 0, Si^pub, Hi) */ @@ -1488,7 +1488,7 @@ wg_fill_msg_init(struct wg_softc *wg, st /* [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); + (void)wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgp->wgp_pubkey); /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */ wg_timestamp_t timestamp; @@ -1646,7 +1646,12 @@ wg_handle_msg_init(struct wg_softc *wg, /* [N] 2.2: "es" */ /* Ci, k := KDF2(Ci, DH(Ei^priv, Sr^pub)) */ - wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, wgmi->wgmi_ephemeral); + if (!wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, + wgmi->wgmi_ephemeral)) { + WG_DLOG("public key is invalid (es)\n"); + return; + } + WG_DUMP_HASH48("wgmi_static", wgmi->wgmi_static); @@ -1713,7 +1718,13 @@ wg_handle_msg_init(struct wg_softc *wg, /* [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); + if (!wg_algo_dh_kdf(ckey, cipher_key, wg->wg_privkey, + wgp->wgp_pubkey)) { + WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, + "%s: peer %s: invalid key (ss)\n", + if_name(&wg->wg_if), wgp->wgp_name); + goto out; + } /* msg.timestamp := AEAD(k, TIMESTAMP(), Hi) */ wg_timestamp_t timestamp; @@ -2042,11 +2053,11 @@ wg_fill_msg_resp(struct wg_softc *wg, st /* [N] 2.2: "ee" */ /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */ - wg_algo_dh_kdf(ckey, NULL, privkey, wgs->wgs_ephemeral_key_peer); + (void)wg_algo_dh_kdf(ckey, NULL, privkey, wgs->wgs_ephemeral_key_peer); /* [N] 2.2: "se" */ /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */ - wg_algo_dh_kdf(ckey, NULL, privkey, wgp->wgp_pubkey); + (void)wg_algo_dh_kdf(ckey, NULL, privkey, wgp->wgp_pubkey); /* [N] 9.2: "psk" */ { @@ -2297,12 +2308,22 @@ wg_handle_msg_resp(struct wg_softc *wg, /* [N] 2.2: "ee" */ /* Cr := KDF1(Cr, DH(Er^priv, Ei^pub)) */ - wg_algo_dh_kdf(ckey, NULL, wgs->wgs_ephemeral_key_priv, - wgmr->wgmr_ephemeral); + if (!wg_algo_dh_kdf(ckey, NULL, wgs->wgs_ephemeral_key_priv, + wgmr->wgmr_ephemeral)) { + WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, + "%s: peer %s: invalid key (ee)\n", + if_name(&wg->wg_if), wgp->wgp_name); + goto out; + } /* [N] 2.2: "se" */ /* Cr := KDF1(Cr, DH(Er^priv, Si^pub)) */ - wg_algo_dh_kdf(ckey, NULL, wg->wg_privkey, wgmr->wgmr_ephemeral); + if (!wg_algo_dh_kdf(ckey, NULL, wg->wg_privkey, wgmr->wgmr_ephemeral)) { + WG_LOG_RATECHECK(&wgp->wgp_ppsratecheck, LOG_DEBUG, + "%s: peer %s: invalid key (se)\n", + if_name(&wg->wg_if), wgp->wgp_name); + goto out; + } /* [N] 9.2: "psk" */ {