Browse Source

FT: Add FTIE, TIE[ReassocDeadline], TIE[KeyLifetime] to EAPOL-Key 3/4

These are mandatory IEs to be included in the FT 4-Way Handshake
Message 3.
Jouni Malinen 15 years ago
parent
commit
86dfabb809
3 changed files with 51 additions and 8 deletions
  1. 41 3
      src/ap/wpa_auth.c
  2. 5 5
      src/ap/wpa_auth_ft.c
  3. 5 0
      src/ap/wpa_auth_i.h

+ 41 - 3
src/ap/wpa_auth.c

@@ -1633,10 +1633,12 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 		return;
 	}
 
-	/* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, GTK[GN])
+	/* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, [MDIE],
+	   GTK[GN], IGTK, [FTIE], [TIE * 2])
 	 */
 	os_memset(rsc, 0, WPA_KEY_RSC_LEN);
 	wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc);
+	/* If FT is used, wpa_auth->wpa_ie includes both RSNIE and MDIE */
 	wpa_ie = sm->wpa_auth->wpa_ie;
 	wpa_ie_len = sm->wpa_auth->wpa_ie_len;
 	if (sm->wpa == WPA_VERSION_WPA &&
@@ -1669,8 +1671,10 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 	if (gtk)
 		kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len;
 #ifdef CONFIG_IEEE80211R
-	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
-		kde_len += 2 + PMKID_LEN;
+	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
+		kde_len += 2 + PMKID_LEN; /* PMKR1Name into RSN IE */
+		kde_len += 300; /* FTIE + 2 * TIE */
+	}
 #endif /* CONFIG_IEEE80211R */
 	kde = os_malloc(kde_len);
 	if (kde == NULL)
@@ -1700,6 +1704,40 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 	}
 	pos = ieee80211w_kde_add(sm, pos);
 
+#ifdef CONFIG_IEEE80211R
+	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
+		int res;
+		struct wpa_auth_config *conf;
+
+		conf = &sm->wpa_auth->conf;
+		res = wpa_write_ftie(conf, conf->r0_key_holder,
+				     conf->r0_key_holder_len,
+				     NULL, NULL, pos, kde + kde_len - pos,
+				     NULL, 0);
+		if (res < 0) {
+			wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE "
+				   "into EAPOL-Key Key Data");
+			os_free(kde);
+			return;
+		}
+		pos += res;
+
+		/* TIE[ReassociationDeadline] (TU) */
+		*pos++ = WLAN_EID_TIMEOUT_INTERVAL;
+		*pos++ = 5;
+		*pos++ = WLAN_TIMEOUT_REASSOC_DEADLINE;
+		WPA_PUT_LE32(pos, conf->reassociation_deadline);
+		pos += 4;
+
+		/* TIE[KeyLifetime] (seconds) */
+		*pos++ = WLAN_EID_TIMEOUT_INTERVAL;
+		*pos++ = 5;
+		*pos++ = WLAN_TIMEOUT_KEY_LIFETIME;
+		WPA_PUT_LE32(pos, conf->r0_key_lifetime * 60);
+		pos += 4;
+	}
+#endif /* CONFIG_IEEE80211R */
+
 	wpa_send_eapol(sm->wpa_auth, sm,
 		       (secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC |
 		       WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL |

+ 5 - 5
src/ap/wpa_auth_ft.c

@@ -97,11 +97,11 @@ int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len)
 }
 
 
-static int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
-			  size_t r0kh_id_len,
-			  const u8 *anonce, const u8 *snonce,
-			  u8 *buf, size_t len, const u8 *subelem,
-			  size_t subelem_len)
+int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
+		   size_t r0kh_id_len,
+		   const u8 *anonce, const u8 *snonce,
+		   u8 *buf, size_t len, const u8 *subelem,
+		   size_t subelem_len)
 {
 	u8 *pos = buf, *ielen;
 	struct rsn_ftie *hdr;

+ 5 - 0
src/ap/wpa_auth_i.h

@@ -214,6 +214,11 @@ void wpa_smk_m3(struct wpa_authenticator *wpa_auth,
 
 #ifdef CONFIG_IEEE80211R
 int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len);
+int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
+		   size_t r0kh_id_len,
+		   const u8 *anonce, const u8 *snonce,
+		   u8 *buf, size_t len, const u8 *subelem,
+		   size_t subelem_len);
 int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
 			   struct wpa_ptk *ptk, size_t ptk_len);
 struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);