Index: head/share/security/advisories/FreeBSD-SA-17:07.wpa.asc =================================================================== --- head/share/security/advisories/FreeBSD-SA-17:07.wpa.asc (revision 51135) +++ head/share/security/advisories/FreeBSD-SA-17:07.wpa.asc (revision 51136) @@ -1,159 +1,171 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 ============================================================================= FreeBSD-SA-17:07.wpa Security Advisory The FreeBSD Project Topic: WPA2 protocol vulnerability Category: contrib Module: wpa Announced: 2017-10-16 Credits: Mathy Vanhoef Affects: All supported versions of FreeBSD. Corrected: 2017-10-17 17:30:18 UTC (stable/11, 11.1-STABLE) 2017-10-17 17:57:18 UTC (releng/11.1, 11.1-RELEASE-p2) 2017-10-17 17:56:03 UTC (releng/11.0, 11.0-RELEASE-p13) + 2017-10-19 03:18:22 UTC (stable/10, 10.4-STABLE) + 2017-10-19 03:20:17 UTC (releng/10.4, 10.4-RELEASE-p1) + 2017-10-19 03:19:42 UTC (releng/10.3, 10.3-RELEASE-p22) CVE Name: CVE-2017-13077, CVE-2017-13078, CVE-2017-13079, CVE-2017-13080, CVE-2017-13081, CVE-2017-13082, CVE-2017-13086, CVE-2017-13087, CVE-2017-13088 For general information regarding FreeBSD Security Advisories, including descriptions of the fields above, security branches, and the following sections, please visit . +0. Revision history + +v1.0 2017-10-17 Initial release. +v1.1 2017-10-19 Add patches for 10.x releases. + I. Background Wi-Fi Protected Access II (WPA2) is a security protocol developed by the Wi-Fi Alliance to secure wireless computer networks. hostapd and wpa_supplicant are implementations of user space daemon for access points and wireless client that implements the WPA2 protocol. II. Problem Description A vulnerability was found in how a number of implementations can be triggered to reconfigure WPA/WPA2/RSN keys (TK, GTK, or IGTK) by replaying a specific frame that is used to manage the keys. III. Impact Such reinstallation of the encryption key can result in two different types of vulnerabilities: disabling replay protection and significantly reducing the security of encryption to the point of allowing frames to be decrypted or some parts of the keys to be determined by an attacker depending on which cipher is used. IV. Workaround An updated version of wpa_supplicant is available in the FreeBSD Ports Collection. Install version 2.6_2 or later of the security/wpa_supplicant port/pkg. Once installed, update /etc/rc.conf to use the new binary: wpa_supplicant_program="/usr/local/sbin/wpa_supplicant" and restart networking. An updated version of hostapd is available in the FreeBSD Ports Collection. Install version 2.6_1 or later of the net/hostapd port/pkg. Once installed, update /etc/rc.conf to use the new binary: hostapd_program="/usr/local/sbin/hostapd" and restart hostapd. V. Solution -Patches are currently available for stable/11, releng/11.0, and -releng/11.1. Patches for stable/10, releng/10.3, and releng/10.4 are -still being evaluated. - Perform one of the following: 1) Upgrade your vulnerable system to a supported FreeBSD stable or release / security branch (releng) dated after the correction date. Restart the Wi-Fi network interfaces/hostapd or reboot the system. 2) To update your vulnerable system via a binary patch: Systems running a RELEASE version of FreeBSD on the i386 or amd64 platforms can be updated via the freebsd-update(8) utility: # freebsd-update fetch # freebsd-update install Restart the Wi-Fi network interfaces/hostapd or reboot the system. 3) To update your vulnerable system via a source code patch: The following patches have been verified to apply to the applicable FreeBSD release branches. a) Download the relevant patch from the location below, and verify the detached PGP signature using your PGP utility. [FreeBSD 11.0-RELEASE, 11.1-RELEASE, and 11-STABLE] # fetch https://security.FreeBSD.org/patches/SA-17:07/wpa-11.patch # fetch https://security.FreeBSD.org/patches/SA-17:07/wpa-11.patch.asc # gpg --verify wpa-11.patch.asc +[FreeBSD 10.3-RELEASE, 10.4-RELEASE, and 10-STABLE] +# fetch https://security.FreeBSD.org/patches/SA-17:07/wpa-10.patch +# fetch https://security.FreeBSD.org/patches/SA-17:07/wpa-10.patch.asc +# gpg --verify wpa-10.patch.asc + b) Apply the patch. Execute the following commands as root: # cd /usr/src # patch < /path/to/patch c) Recompile the operating system using buildworld and installworld as described in . Restart the applicable daemons, or reboot the system. VI. Correction details The following list contains the correction revision numbers for each affected branch. Branch/path Revision - ------------------------------------------------------------------------- stable/11/ r324697 releng/11.0/ r324698 releng/11.1/ r324699 +stable/10/ r324739 +releng/10.3/ r324740 +releng/10.4/ r324741 - ------------------------------------------------------------------------- To see which files were modified by a particular revision, run the following command, replacing NNNNNN with the revision number, on a machine with Subversion installed: # svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base Or visit the following URL, replacing NNNNNN with the revision number: VII. References The latest revision of this advisory is available at -----BEGIN PGP SIGNATURE----- -iQKTBAEBCgB9FiEEHPf/b631yp++G4yy7Wfs1l3PaucFAlnmRUZfFIAAAAAALgAo +iQKTBAEBCgB9FiEEHPf/b631yp++G4yy7Wfs1l3PaucFAlnoGpNfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDFD RjdGRjZGQURGNUNBOUZCRTFCOENCMkVENjdFQ0Q2NURDRjZBRTcACgkQ7Wfs1l3P -aueKcxAAwObogcEZAgGioU4uZvk9kKIpmG/NwvUjcZ0viFhePowKnh6/UoFDd+13 -NsjriznPNKbXPch2Gp3Zwgd/hff10vlvr69QOFXnI3/Y8b+thxkl1kCAxC0xkfEl -eQBzjllMrjtrSgfKtoWInxnZLIrghuJAg4Jvvz+uWd3VTggM0pQgLUuhR/a8lWHd -3HBj5//sOhmVW2OFYC5dskYAn6TqyHtlMP9AT32h6QEyEzJeNWMlToELxy6OK59j -MYaS0vclz7QT+4SATvcl8RCmxmYfyWxEtFhDmPNz4mfQ915AxTjGFv7KbjTZtunl -k3niR3O8F450xduw5Yj9Mz3YdZ4ZYmvHbDgQLsMNwAmtQvXSteXUUBVNVAg9PsjR -4kxlEFsStWh6CtJVKYUvKDThnHrWYLiVUh6o/FtRm5fx2ws/gcj7H9csr8mQ0pkO -zm9jVOgMe7pqI7gygOfb61Rjz6PnLgVQcnP2LoC9pB21O5Q/Q2rv9d6XN3mQ6CQ2 -+mUEZ5M7TWyd6gFrP2Eu6srec1nT1NjVjzyyupgusiQve3xV0wacG0jwgy7+VXE8 -Ls2a/SObVDZkvFhOYMrLVui33l7f/vgT0KImyO2fkaWjbDcEyVcm1f+A7K+hqwp8 -2O/Eh+NVSG0GIbt9pro0BxsZhMb/V4WmWV+4WnLKPwCQZ9fimKA= -=aNWn +auc7WBAAm27w+fujv5sJsRxauUMopTVtRh5utwbDuoHTP+L+RCWmQfVBmueNQ0gf +uJzMNxBIkbtY9LvyukpRsH3iD7mh26c0pd9rxxkkr4F96C9B5+W0amxJF1gdm54/ +F/50FpY+lo7cNs5tiBjypPrg8UOBBI/1G4XR7130XC0HjaTwt1ngZ0oQUWUMSsIp +gN5ZfPul81WPWd1NqF+vyObcJhwq/Y1uoexoO27o7GQCFZoL3enZy8c4f1xqMlVM +4HHkTgNGac6E0aW+ArH4J0DFFAOJXPqF8rdt+9XINfoBbtliIyOixJ4oh1n6eAR0 +VpBWZKFNyXSlUKIvDGa+LDhxgL1jJXV0ABSyKlUOijdmr3bbbiQE9MW/MNv2AFTd +OAFQ0QQtm9KCWp5JLh+FPIb/kR2l7MOUP+yz4zFcJpdGtl9tDLyPN8vRTq60bY8O +y7tBcf/SMqkd/AIFdchL4zrOguKnRARydIlwTarp8wtAQI3MKSsa1B0wgsDtlL6K +xfdjnwWMKvKKlNOW16e1WXXO0n/ucHV4njBE+bGPro3jLgXP2/WFZpIGAR3I4xrr +SdD4AxSNiR9f3bL7LRfMIbugJAylWNSlTLWUOVUv0/ONh85LqbcCj13NI230B64K +ETx2QOZgKnCs2oDNiw4aQHb7kvi2w94Iw/R1sAPkkxYJWO3reyE= +=h/5q -----END PGP SIGNATURE----- Index: head/share/security/patches/SA-17:07/wpa-10.patch =================================================================== --- head/share/security/patches/SA-17:07/wpa-10.patch (nonexistent) +++ head/share/security/patches/SA-17:07/wpa-10.patch (revision 51136) @@ -0,0 +1,606 @@ +--- contrib/wpa/src/ap/wpa_auth.h.orig ++++ contrib/wpa/src/ap/wpa_auth.h +@@ -247,6 +247,7 @@ + int wpa_auth_get_pairwise(struct wpa_state_machine *sm); + int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm); + int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm); ++int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm); + int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, + struct rsn_pmksa_cache_entry *entry); + struct rsn_pmksa_cache_entry * +--- contrib/wpa/src/ap/wpa_auth.c.orig ++++ contrib/wpa/src/ap/wpa_auth.c +@@ -1623,6 +1623,21 @@ + } + + ++static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm) ++{ ++ if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { ++ wpa_printf(MSG_ERROR, ++ "WPA: Failed to get random data for ANonce"); ++ sm->Disconnect = TRUE; ++ return -1; ++ } ++ wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce, ++ WPA_NONCE_LEN); ++ sm->TimeoutCtr = 0; ++ return 0; ++} ++ ++ + SM_STATE(WPA_PTK, INITPMK) + { + u8 msk[2 * PMK_LEN]; +@@ -2111,9 +2126,12 @@ + SM_ENTER(WPA_PTK, AUTHENTICATION); + else if (sm->ReAuthenticationRequest) + SM_ENTER(WPA_PTK, AUTHENTICATION2); +- else if (sm->PTKRequest) +- SM_ENTER(WPA_PTK, PTKSTART); +- else switch (sm->wpa_ptk_state) { ++ else if (sm->PTKRequest) { ++ if (wpa_auth_sm_ptk_update(sm) < 0) ++ SM_ENTER(WPA_PTK, DISCONNECTED); ++ else ++ SM_ENTER(WPA_PTK, PTKSTART); ++ } else switch (sm->wpa_ptk_state) { + case WPA_PTK_INITIALIZE: + break; + case WPA_PTK_DISCONNECT: +@@ -2866,6 +2884,14 @@ + } + + ++int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm) ++{ ++ if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt)) ++ return 0; ++ return sm->tk_already_set; ++} ++ ++ + int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, + struct rsn_pmksa_cache_entry *entry) + { +--- contrib/wpa/src/ap/wpa_auth_ft.c.orig ++++ contrib/wpa/src/ap/wpa_auth_ft.c +@@ -762,6 +762,14 @@ + return; + } + ++ if (sm->tk_already_set) { ++ /* Must avoid TK reconfiguration to prevent clearing of TX/RX ++ * PN in the driver */ ++ wpa_printf(MSG_DEBUG, ++ "FT: Do not re-install same PTK to the driver"); ++ return; ++ } ++ + /* FIX: add STA entry to kernel/driver here? The set_key will fail + * most likely without this.. At the moment, STA entry is added only + * after association has been completed. This function will be called +@@ -774,6 +782,7 @@ + + /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ + sm->pairwise_set = TRUE; ++ sm->tk_already_set = TRUE; + } + + +@@ -887,6 +896,7 @@ + wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN); + + sm->pairwise = pairwise; ++ sm->tk_already_set = FALSE; + wpa_ft_install_ptk(sm); + + buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + +--- contrib/wpa/src/ap/wpa_auth_i.h.orig ++++ contrib/wpa/src/ap/wpa_auth_i.h +@@ -61,6 +61,7 @@ + struct wpa_ptk PTK; + Boolean PTK_valid; + Boolean pairwise_set; ++ Boolean tk_already_set; + int keycount; + Boolean Pair; + struct wpa_key_replay_counter { +--- contrib/wpa/src/common/wpa_common.h.orig ++++ contrib/wpa/src/common/wpa_common.h +@@ -187,6 +187,17 @@ + } u; + } STRUCT_PACKED; + ++struct wpa_gtk { ++ u8 gtk[WPA_GTK_MAX_LEN]; ++ size_t gtk_len; ++}; ++ ++#ifdef CONFIG_IEEE80211W ++struct wpa_igtk { ++ u8 igtk[WPA_IGTK_MAX_LEN]; ++ size_t igtk_len; ++}; ++#endif /* CONFIG_IEEE80211W */ + + /* WPA IE version 1 + * 00-50-f2:1 (OUI:OUI type) +--- contrib/wpa/src/rsn_supp/tdls.c.orig ++++ contrib/wpa/src/rsn_supp/tdls.c +@@ -103,6 +103,7 @@ + u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */ + } tpk; + int tpk_set; ++ int tk_set; /* TPK-TK configured to the driver */ + int tpk_success; + + struct tpk_timer { +@@ -160,6 +161,20 @@ + u8 rsc[6]; + enum wpa_alg alg; + ++ if (peer->tk_set) { ++ /* ++ * This same TPK-TK has already been configured to the driver ++ * and this new configuration attempt (likely due to an ++ * unexpected retransmitted frame) would result in clearing ++ * the TX/RX sequence number which can break security, so must ++ * not allow that to happen. ++ */ ++ wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR ++ " has already been configured to the driver - do not reconfigure", ++ MAC2STR(peer->addr)); ++ return -1; ++ } ++ + os_memset(rsc, 0, 6); + + switch (peer->cipher) { +@@ -177,12 +192,15 @@ + return -1; + } + ++ wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR, ++ MAC2STR(peer->addr)); + if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, + rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) { + wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the " + "driver"); + return -1; + } ++ peer->tk_set = 1; + return 0; + } + +@@ -613,7 +631,7 @@ + peer->sm_tmr.buf = NULL; + peer->rsnie_i_len = peer->rsnie_p_len = 0; + peer->cipher = 0; +- peer->tpk_set = peer->tpk_success = 0; ++ peer->tk_set = peer->tpk_set = peer->tpk_success = 0; + os_memset(&peer->tpk, 0, sizeof(peer->tpk)); + os_memset(peer->inonce, 0, WPA_NONCE_LEN); + os_memset(peer->rnonce, 0, WPA_NONCE_LEN); +@@ -1002,6 +1020,7 @@ + wpa_tdls_peer_free(sm, peer); + return -1; + } ++ peer->tk_set = 0; /* A new nonce results in a new TK */ + wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake", + peer->inonce, WPA_NONCE_LEN); + os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); +@@ -1583,6 +1602,7 @@ + wpa_tdls_peer_free(sm, peer); + goto error; + } ++ peer->tk_set = 0; /* A new nonce results in a new TK */ + + #if 0 + /* get version info from RSNIE received from Peer */ +@@ -1710,6 +1730,14 @@ + "TPK M2: " MACSTR, MAC2STR(src_addr)); + return -1; + } ++ ++ if (peer->tpk_success) { ++ wpa_printf(MSG_INFO, "TDLS: Ignore incoming TPK M2 retry, from " ++ MACSTR " as TPK M3 was already sent", ++ MAC2STR(src_addr)); ++ return 0; ++ } ++ + wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST); + + if (len < 3 + 2 + 1) +--- contrib/wpa/src/rsn_supp/wpa.c.orig ++++ contrib/wpa/src/rsn_supp/wpa.c +@@ -517,6 +517,12 @@ + const u8 *key_rsc; + u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + ++ if (sm->ptk_installed) { ++ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, ++ "WPA: Do not re-install same PTK to the driver"); ++ return 0; ++ } ++ + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Installing PTK to the driver"); + +@@ -553,6 +559,8 @@ + return -1; + } + ++ sm->ptk_installed = 1; ++ + if (sm->wpa_ptk_rekey) { + eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); + eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk, +@@ -601,11 +609,23 @@ + + static int wpa_supplicant_install_gtk(struct wpa_sm *sm, + const struct wpa_gtk_data *gd, +- const u8 *key_rsc) ++ const u8 *key_rsc, int wnm_sleep) + { + const u8 *_gtk = gd->gtk; + u8 gtk_buf[32]; + ++ /* Detect possible key reinstallation */ ++ if ((sm->gtk.gtk_len == (size_t) gd->gtk_len && ++ os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) || ++ (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len && ++ os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk, ++ sm->gtk_wnm_sleep.gtk_len) == 0)) { ++ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, ++ "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", ++ gd->keyidx, gd->tx, gd->gtk_len); ++ return 0; ++ } ++ + wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)", +@@ -637,6 +657,15 @@ + return -1; + } + ++ if (wnm_sleep) { ++ sm->gtk_wnm_sleep.gtk_len = gd->gtk_len; ++ os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk, ++ sm->gtk_wnm_sleep.gtk_len); ++ } else { ++ sm->gtk.gtk_len = gd->gtk_len; ++ os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); ++ } ++ + return 0; + } + +@@ -694,7 +723,7 @@ + if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, + gtk_len, gtk_len, + &gd.key_rsc_len, &gd.alg) || +- wpa_supplicant_install_gtk(sm, &gd, key->key_rsc)) { ++ wpa_supplicant_install_gtk(sm, &gd, key->key_rsc, 0)) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "RSN: Failed to install GTK"); + return -1; +@@ -709,6 +738,57 @@ + } + + ++#ifdef CONFIG_IEEE80211W ++static int wpa_supplicant_install_igtk(struct wpa_sm *sm, ++ const struct wpa_igtk_kde *igtk, ++ int wnm_sleep) ++{ ++ size_t len = WPA_IGTK_LEN; ++ u16 keyidx = WPA_GET_LE16(igtk->keyid); ++ ++ /* Detect possible key reinstallation */ ++ if ((sm->igtk.igtk_len == len && ++ os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) || ++ (sm->igtk_wnm_sleep.igtk_len == len && ++ os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk, ++ sm->igtk_wnm_sleep.igtk_len) == 0)) { ++ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, ++ "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", ++ keyidx); ++ return 0; ++ } ++ ++ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, ++ "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x", ++ keyidx, MAC2STR(igtk->pn)); ++ wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); ++ if (keyidx > 4095) { ++ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, ++ "WPA: Invalid IGTK KeyID %d", keyidx); ++ return -1; ++ } ++ if (wpa_sm_set_key(sm, WPA_ALG_IGTK, broadcast_ether_addr, ++ keyidx, 0, igtk->pn, sizeof(igtk->pn), ++ igtk->igtk, WPA_IGTK_LEN) < 0) { ++ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, ++ "WPA: Failed to configure IGTK to the driver"); ++ return -1; ++ } ++ ++ if (wnm_sleep) { ++ sm->igtk_wnm_sleep.igtk_len = len; ++ os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk, ++ sm->igtk_wnm_sleep.igtk_len); ++ } else { ++ sm->igtk.igtk_len = len; ++ os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); ++ } ++ ++ return 0; ++} ++#endif /* CONFIG_IEEE80211W */ ++ ++ + static int ieee80211w_set_keys(struct wpa_sm *sm, + struct wpa_eapol_ie_parse *ie) + { +@@ -718,28 +798,12 @@ + + if (ie->igtk) { + const struct wpa_igtk_kde *igtk; +- u16 keyidx; + if (ie->igtk_len != sizeof(*igtk)) + return -1; ++ + igtk = (const struct wpa_igtk_kde *) ie->igtk; +- keyidx = WPA_GET_LE16(igtk->keyid); +- wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d " +- "pn %02x%02x%02x%02x%02x%02x", +- keyidx, MAC2STR(igtk->pn)); +- wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", +- igtk->igtk, WPA_IGTK_LEN); +- if (keyidx > 4095) { +- wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, +- "WPA: Invalid IGTK KeyID %d", keyidx); ++ if (wpa_supplicant_install_igtk(sm, igtk, 0) < 0) + return -1; +- } +- if (wpa_sm_set_key(sm, WPA_ALG_IGTK, broadcast_ether_addr, +- keyidx, 0, igtk->pn, sizeof(igtk->pn), +- igtk->igtk, WPA_IGTK_LEN) < 0) { +- wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, +- "WPA: Failed to configure IGTK to the driver"); +- return -1; +- } + } + + return 0; +@@ -1343,7 +1407,7 @@ + if (ret) + goto failed; + +- if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) || ++ if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc, 0) || + wpa_supplicant_send_2_of_2(sm, key, ver, key_info)) + goto failed; + +@@ -2043,7 +2107,7 @@ + */ + void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) + { +- int clear_ptk = 1; ++ int clear_keys = 1; + + if (sm == NULL) + return; +@@ -2069,18 +2133,24 @@ + /* Prepare for the next transition */ + wpa_ft_prepare_auth_request(sm, NULL); + +- clear_ptk = 0; ++ clear_keys = 0; + } + #endif /* CONFIG_IEEE80211R */ + +- if (clear_ptk) { ++ if (clear_keys) { + /* + * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if + * this is not part of a Fast BSS Transition. + */ + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK"); + sm->ptk_set = 0; + sm->tptk_set = 0; ++ os_memset(&sm->gtk, 0, sizeof(sm->gtk)); ++ os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); ++#ifdef CONFIG_IEEE80211W ++ os_memset(&sm->igtk, 0, sizeof(sm->igtk)); ++ os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); ++#endif /* CONFIG_IEEE80211W */ + } + + #ifdef CONFIG_TDLS +@@ -2105,6 +2175,9 @@ + #ifdef CONFIG_TDLS + wpa_tdls_disassoc(sm); + #endif /* CONFIG_TDLS */ ++#ifdef CONFIG_IEEE80211R ++ sm->ft_reassoc_completed = 0; ++#endif /* CONFIG_IEEE80211R */ + } + + +@@ -2602,6 +2675,12 @@ + os_memset(sm->pmk, 0, sizeof(sm->pmk)); + os_memset(&sm->ptk, 0, sizeof(sm->ptk)); + os_memset(&sm->tptk, 0, sizeof(sm->tptk)); ++ os_memset(&sm->gtk, 0, sizeof(sm->gtk)); ++ os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); ++#ifdef CONFIG_IEEE80211W ++ os_memset(&sm->igtk, 0, sizeof(sm->igtk)); ++ os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); ++#endif /* CONFIG_IEEE80211W */ + } + + +@@ -2669,28 +2748,18 @@ + + wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)", + gd.gtk, gd.gtk_len); +- if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) { ++ if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) { + wpa_printf(MSG_DEBUG, "Failed to install the GTK in " + "WNM mode"); + return -1; + } + #ifdef CONFIG_IEEE80211W + } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) { +- os_memcpy(igd.keyid, buf + 2, 2); +- os_memcpy(igd.pn, buf + 4, 6); ++ const struct wpa_igtk_kde *igtk; + +- keyidx = WPA_GET_LE16(igd.keyid); +- os_memcpy(igd.igtk, buf + 10, WPA_IGTK_LEN); +- +- wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)", +- igd.igtk, WPA_IGTK_LEN); +- if (wpa_sm_set_key(sm, WPA_ALG_IGTK, broadcast_ether_addr, +- keyidx, 0, igd.pn, sizeof(igd.pn), +- igd.igtk, WPA_IGTK_LEN) < 0) { +- wpa_printf(MSG_DEBUG, "Failed to install the IGTK in " +- "WNM mode"); ++ igtk = (const struct wpa_igtk_kde *) (buf + 2); ++ if (wpa_supplicant_install_igtk(sm, igtk, 1) < 0) + return -1; +- } + #endif /* CONFIG_IEEE80211W */ + } else { + wpa_printf(MSG_DEBUG, "Unknown element id"); +--- contrib/wpa/src/rsn_supp/wpa_ft.c.orig ++++ contrib/wpa/src/rsn_supp/wpa_ft.c +@@ -156,6 +156,7 @@ + u16 capab; + + sm->ft_completed = 0; ++ sm->ft_reassoc_completed = 0; + + buf_len = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + + 2 + sm->r0kh_id_len + ric_ies_len + 100; +@@ -671,6 +672,11 @@ + return -1; + } + ++ if (sm->ft_reassoc_completed) { ++ wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission"); ++ return 0; ++ } ++ + if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) { + wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs"); + return -1; +@@ -769,6 +775,8 @@ + return -1; + } + ++ sm->ft_reassoc_completed = 1; ++ + if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0) + return -1; + +--- contrib/wpa/src/rsn_supp/wpa_i.h.orig ++++ contrib/wpa/src/rsn_supp/wpa_i.h +@@ -23,12 +23,19 @@ + size_t pmk_len; + struct wpa_ptk ptk, tptk; + int ptk_set, tptk_set; ++ int ptk_installed; + u8 snonce[WPA_NONCE_LEN]; + u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ + int renew_snonce; + u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; + int rx_replay_counter_set; + u8 request_counter[WPA_REPLAY_COUNTER_LEN]; ++ struct wpa_gtk gtk; ++ struct wpa_gtk gtk_wnm_sleep; ++#ifdef CONFIG_IEEE80211W ++ struct wpa_igtk igtk; ++ struct wpa_igtk igtk_wnm_sleep; ++#endif /* CONFIG_IEEE80211W */ + + struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ + +@@ -115,6 +122,7 @@ + size_t r0kh_id_len; + u8 r1kh_id[FT_R1KH_ID_LEN]; + int ft_completed; ++ int ft_reassoc_completed; + int over_the_ds_in_progress; + u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ + int set_ptk_after_assoc; +--- contrib/wpa/wpa_supplicant/events.c.orig ++++ contrib/wpa/wpa_supplicant/events.c +@@ -181,6 +181,7 @@ + wpa_s->ap_ies_from_associnfo = 0; + wpa_s->current_ssid = NULL; + wpa_s->key_mgmt = 0; ++ wpa_s->wnmsleep_used = 0; + } + + +--- contrib/wpa/wpa_supplicant/wnm_sta.c.orig ++++ contrib/wpa/wpa_supplicant/wnm_sta.c +@@ -130,6 +130,8 @@ + if (res < 0) + wpa_printf(MSG_DEBUG, "Failed to send WNM-Sleep Request " + "(action=%d, intval=%d)", action, intval); ++ else ++ wpa_s->wnmsleep_used = 1; + + os_free(wnmsleep_ie); + os_free(wnmtfs_ie); +@@ -180,6 +182,12 @@ + end = ptr + key_len_total; + wpa_hexdump_key(MSG_DEBUG, "WNM: Key Data", ptr, key_len_total); + ++ if (key_len_total && !wpa_sm_pmf_enabled(wpa_s->wpa)) { ++ wpa_msg(wpa_s, MSG_INFO, ++ "WNM: Ignore Key Data in WNM-Sleep Mode Response - PMF not enabled"); ++ return; ++ } ++ + while (ptr + 1 < end) { + if (ptr + 2 + ptr[1] > end) { + wpa_printf(MSG_DEBUG, "WNM: Invalid Key Data element " +@@ -239,6 +247,12 @@ + u8 *tfsresp_ie_start = NULL; + u8 *tfsresp_ie_end = NULL; + ++ if (!wpa_s->wnmsleep_used) { ++ wpa_printf(MSG_DEBUG, ++ "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode operation has not been requested"); ++ return; ++ } ++ + wpa_printf(MSG_DEBUG, "action=%d token = %d key_len_total = %d", + frm[0], frm[1], key_len_total); + pos += 4 + key_len_total; +@@ -269,6 +283,8 @@ + return; + } + ++ wpa_s->wnmsleep_used = 0; ++ + if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT || + wnmsleep_ie->status == WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE) { + wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response " +--- contrib/wpa/wpa_supplicant/wpa_supplicant_i.h.orig ++++ contrib/wpa/wpa_supplicant/wpa_supplicant_i.h +@@ -478,6 +478,7 @@ + struct os_time pending_eapol_rx_time; + u8 pending_eapol_rx_src[ETH_ALEN]; + unsigned int last_eapol_matches_bssid:1; ++ unsigned int wnmsleep_used:1; + + struct ibss_rsn *ibss_rsn; + Property changes on: head/share/security/patches/SA-17:07/wpa-10.patch ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/share/security/patches/SA-17:07/wpa-10.patch.asc =================================================================== --- head/share/security/patches/SA-17:07/wpa-10.patch.asc (nonexistent) +++ head/share/security/patches/SA-17:07/wpa-10.patch.asc (revision 51136) @@ -0,0 +1,18 @@ +-----BEGIN PGP SIGNATURE----- + +iQKTBAABCgB9FiEEHPf/b631yp++G4yy7Wfs1l3PaucFAlnoGtRfFIAAAAAALgAo +aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDFD +RjdGRjZGQURGNUNBOUZCRTFCOENCMkVENjdFQ0Q2NURDRjZBRTcACgkQ7Wfs1l3P +aucCEQ/8DaxuDr39Gr9kzRvIxSlC2/zDcY8voV87+usheH4g7bnvUtgCzaBg1fB6 +XePSOPyga9GmZ/DOci+5gof2uVlV4h52BxHTyc5fv6T4fPH+deCe+lSOwnyWIT3C +fVBTiCsiveV14iwTylAPssc2ZP+SSG3IV2bPWUmShRMbt3xHWAZcN+o56M3KuHed +8wtR2hqwaQ4sYXnPjrrO032UbQjy3Mb8NXthgezkJPXd5bL1y2Zl2n/mr6CAtYZz +HsjBf/Qzna9IFOPCtDiiqWPubtxH0CCZsCjeKOIVSFrdLTvyTafRA6IoUVPKtIdn +5ftJqp4V/9NCo2lYVNW2P9zMcv8gl8lyYStGz1Az3tgAa0aCs/VZdoyouxRBVHAY +HQJIQ9/0YXJ2KUSmwcek2i5oy1Knb9uTMawgBQoJsEjMuzxxUw/yzmrW1rAsR8se +smlcZTtkbUd//062icsYu8Qve4pOPuMCnmALjXDCvlWA7juQ7zZWxPgaEXqarPcK +VROxDn18LgIS05TSRdNyju6nghpnlEYAYmVbLxfehMFq5Dvh0qivwRdIvJaPeVfj +rOGG8GhCoS30CSZxFpk9aTOApuAEL34we88pMANDbUa/K/9ymF1+g83Zd0sPgsas +RvP6Zabw51dyJoPzNW4ctKZJ3AK1cDYDrm3w0X7crnMTKLL+XPQ= +=RB18 +-----END PGP SIGNATURE----- Property changes on: head/share/security/patches/SA-17:07/wpa-10.patch.asc ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property