Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Jul 2018 14:37:32 +0000 (UTC)
From:      Cy Schubert <cy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r336486 - in vendor/wpa/dist/src: common rsn_supp
Message-ID:  <201807191437.w6JEbWn2064722@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cy
Date: Thu Jul 19 14:37:32 2018
New Revision: 336486
URL: https://svnweb.freebsd.org/changeset/base/336486

Log:
  Import upline security patch to prevent an alreadi in use group ke.
  
  Obtained from:	https://w1.fi/security/2017-1/\
  		rebased-v2.6-0002-Prevent-reinstallation-\
  		of-an-already-in-use-group-ke.patch

Modified:
  vendor/wpa/dist/src/common/wpa_common.h
  vendor/wpa/dist/src/rsn_supp/wpa.c
  vendor/wpa/dist/src/rsn_supp/wpa_i.h

Modified: vendor/wpa/dist/src/common/wpa_common.h
==============================================================================
--- vendor/wpa/dist/src/common/wpa_common.h	Thu Jul 19 14:35:27 2018	(r336485)
+++ vendor/wpa/dist/src/common/wpa_common.h	Thu Jul 19 14:37:32 2018	(r336486)
@@ -217,6 +217,17 @@ struct wpa_ptk {
 	size_t tk_len;
 };
 
+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)

Modified: vendor/wpa/dist/src/rsn_supp/wpa.c
==============================================================================
--- vendor/wpa/dist/src/rsn_supp/wpa.c	Thu Jul 19 14:35:27 2018	(r336485)
+++ vendor/wpa/dist/src/rsn_supp/wpa.c	Thu Jul 19 14:37:32 2018	(r336486)
@@ -714,6 +714,15 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *s
 	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) {
+		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)",
@@ -748,6 +757,9 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *s
 	}
 	os_memset(gtk_buf, 0, sizeof(gtk_buf));
 
+	sm->gtk.gtk_len = gd->gtk_len;
+	os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
+
 	return 0;
 }
 
@@ -854,6 +866,48 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *
 }
 
 
+#ifdef CONFIG_IEEE80211W
+static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
+				       const struct wpa_igtk_kde *igtk)
+{
+	size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
+	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) {
+		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_cipher_to_alg(sm->mgmt_group_cipher),
+			   broadcast_ether_addr,
+			   keyidx, 0, igtk->pn, sizeof(igtk->pn),
+			   igtk->igtk, len) < 0) {
+		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+			"WPA: Failed to configure IGTK to the driver");
+		return -1;
+	}
+
+	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)
 {
@@ -864,30 +918,14 @@ static int ieee80211w_set_keys(struct wpa_sm *sm,
 	if (ie->igtk) {
 		size_t len;
 		const struct wpa_igtk_kde *igtk;
-		u16 keyidx;
+
 		len = wpa_cipher_key_len(sm->mgmt_group_cipher);
 		if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
 			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, 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)
 			return -1;
-		}
-		if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
-				   broadcast_ether_addr,
-				   keyidx, 0, igtk->pn, sizeof(igtk->pn),
-				   igtk->igtk, len) < 0) {
-			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
-				"WPA: Failed to configure IGTK to the driver");
-			return -1;
-		}
 	}
 
 	return 0;
@@ -2307,7 +2345,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
  */
 void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
 {
-	int clear_ptk = 1;
+	int clear_keys = 1;
 
 	if (sm == NULL)
 		return;
@@ -2333,11 +2371,11 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *
 		/* 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.
@@ -2347,6 +2385,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *
 		os_memset(&sm->ptk, 0, sizeof(sm->ptk));
 		sm->tptk_set = 0;
 		os_memset(&sm->tptk, 0, sizeof(sm->tptk));
+		os_memset(&sm->gtk, 0, sizeof(sm->gtk));
+#ifdef CONFIG_IEEE80211W
+		os_memset(&sm->igtk, 0, sizeof(sm->igtk));
+#endif /* CONFIG_IEEE80211W */
 	}
 
 #ifdef CONFIG_TDLS
@@ -2877,6 +2919,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
 	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));
+#ifdef CONFIG_IEEE80211W
+	os_memset(&sm->igtk, 0, sizeof(sm->igtk));
+#endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_IEEE80211R
 	os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
 	os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
@@ -2949,29 +2995,11 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 sub
 		os_memset(&gd, 0, sizeof(gd));
 #ifdef CONFIG_IEEE80211W
 	} else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
-		struct wpa_igtk_kde igd;
-		u16 keyidx;
+		const struct wpa_igtk_kde *igtk;
 
-		os_memset(&igd, 0, sizeof(igd));
-		keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
-		os_memcpy(igd.keyid, buf + 2, 2);
-		os_memcpy(igd.pn, buf + 4, 6);
-
-		keyidx = WPA_GET_LE16(igd.keyid);
-		os_memcpy(igd.igtk, buf + 10, keylen);
-
-		wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
-				igd.igtk, keylen);
-		if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
-				   broadcast_ether_addr,
-				   keyidx, 0, igd.pn, sizeof(igd.pn),
-				   igd.igtk, keylen) < 0) {
-			wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
-				   "WNM mode");
-			os_memset(&igd, 0, sizeof(igd));
+		igtk = (const struct wpa_igtk_kde *) (buf + 2);
+		if (wpa_supplicant_install_igtk(sm, igtk) < 0)
 			return -1;
-		}
-		os_memset(&igd, 0, sizeof(igd));
 #endif /* CONFIG_IEEE80211W */
 	} else {
 		wpa_printf(MSG_DEBUG, "Unknown element id");

Modified: vendor/wpa/dist/src/rsn_supp/wpa_i.h
==============================================================================
--- vendor/wpa/dist/src/rsn_supp/wpa_i.h	Thu Jul 19 14:35:27 2018	(r336485)
+++ vendor/wpa/dist/src/rsn_supp/wpa_i.h	Thu Jul 19 14:37:32 2018	(r336486)
@@ -31,6 +31,10 @@ struct wpa_sm {
 	u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN];
 	int rx_replay_counter_set;
 	u8 request_counter[WPA_REPLAY_COUNTER_LEN];
+	struct wpa_gtk gtk;
+#ifdef CONFIG_IEEE80211W
+	struct wpa_igtk igtk;
+#endif /* CONFIG_IEEE80211W */
 
 	struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807191437.w6JEbWn2064722>