FT: Fix FTIE generation for 4-way handshake after FT protocol run
wpa_insert_pmkid() did not support cases where the original RSN IE included any PMKIDs. That case can happen when PTK rekeying through 4-way handshake is used after FT protocol run. Such a 4-way handshake used to fail with wpa_supplicant being unable to build the EAPOL-Key msg 2/4. Fix this by extending wpa_insert_pmkid() to support removal of the old PMKIDs, if needed. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
		
							parent
							
								
									cc02fd3eff
								
							
						
					
					
						commit
						59e78c2408
					
				
					 4 changed files with 36 additions and 12 deletions
				
			
		|  | @ -2298,14 +2298,19 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | |||
| 	pos += wpa_ie_len; | ||||
| #ifdef CONFIG_IEEE80211R | ||||
| 	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { | ||||
| 		int res = wpa_insert_pmkid(kde, pos - kde, sm->pmk_r1_name); | ||||
| 		int res; | ||||
| 		size_t elen; | ||||
| 
 | ||||
| 		elen = pos - kde; | ||||
| 		res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name); | ||||
| 		if (res < 0) { | ||||
| 			wpa_printf(MSG_ERROR, "FT: Failed to insert " | ||||
| 				   "PMKR1Name into RSN IE in EAPOL-Key data"); | ||||
| 			os_free(kde); | ||||
| 			return; | ||||
| 		} | ||||
| 		pos += res; | ||||
| 		pos -= wpa_ie_len; | ||||
| 		pos += elen; | ||||
| 	} | ||||
| #endif /* CONFIG_IEEE80211R */ | ||||
| 	if (gtk) { | ||||
|  |  | |||
|  | @ -1280,13 +1280,13 @@ int wpa_compare_rsn_ie(int ft_initial_assoc, | |||
| 
 | ||||
| 
 | ||||
| #ifdef CONFIG_IEEE80211R | ||||
| int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid) | ||||
| int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid) | ||||
| { | ||||
| 	u8 *start, *end, *rpos, *rend; | ||||
| 	int added = 0; | ||||
| 
 | ||||
| 	start = ies; | ||||
| 	end = ies + ies_len; | ||||
| 	end = ies + *ies_len; | ||||
| 
 | ||||
| 	while (start < end) { | ||||
| 		if (*start == WLAN_EID_RSN) | ||||
|  | @ -1339,11 +1339,29 @@ int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid) | |||
| 		added += 2 + PMKID_LEN; | ||||
| 		start[1] += 2 + PMKID_LEN; | ||||
| 	} else { | ||||
| 		/* PMKID-Count was included; use it */ | ||||
| 		if (WPA_GET_LE16(rpos) != 0) { | ||||
| 			wpa_printf(MSG_ERROR, "FT: Unexpected PMKID " | ||||
| 				   "in RSN IE in EAPOL-Key data"); | ||||
| 		u16 num_pmkid; | ||||
| 
 | ||||
| 		if (rend - rpos < 2) | ||||
| 			return -1; | ||||
| 		num_pmkid = WPA_GET_LE16(rpos); | ||||
| 		/* PMKID-Count was included; use it */ | ||||
| 		if (num_pmkid != 0) { | ||||
| 			u8 *after; | ||||
| 
 | ||||
| 			if (num_pmkid * PMKID_LEN > rend - rpos - 2) | ||||
| 				return -1; | ||||
| 			/*
 | ||||
| 			 * PMKID may have been included in RSN IE in | ||||
| 			 * (Re)Association Request frame, so remove the old | ||||
| 			 * PMKID(s) first before adding the new one. | ||||
| 			 */ | ||||
| 			wpa_printf(MSG_DEBUG, | ||||
| 				   "FT: Remove %u old PMKID(s) from RSN IE", | ||||
| 				   num_pmkid); | ||||
| 			after = rpos + 2 + num_pmkid * PMKID_LEN; | ||||
| 			os_memmove(rpos + 2, after, rend - after); | ||||
| 			start[1] -= num_pmkid * PMKID_LEN; | ||||
| 			added -= num_pmkid * PMKID_LEN; | ||||
| 		} | ||||
| 		WPA_PUT_LE16(rpos, 1); | ||||
| 		rpos += 2; | ||||
|  | @ -1356,7 +1374,9 @@ int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid) | |||
| 	wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification " | ||||
| 		    "(PMKID inserted)", start, 2 + start[1]); | ||||
| 
 | ||||
| 	return added; | ||||
| 	*ies_len += added; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| #endif /* CONFIG_IEEE80211R */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -409,7 +409,7 @@ u32 wpa_akm_to_suite(int akm); | |||
| int wpa_compare_rsn_ie(int ft_initial_assoc, | ||||
| 		       const u8 *ie1, size_t ie1len, | ||||
| 		       const u8 *ie2, size_t ie2len); | ||||
| int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid); | ||||
| int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid); | ||||
| 
 | ||||
| struct wpa_ft_ies { | ||||
| 	const u8 *mdie; | ||||
|  |  | |||
|  | @ -364,13 +364,12 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, | |||
| 		if (rsn_ie_buf == NULL) | ||||
| 			return -1; | ||||
| 		os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len); | ||||
| 		res = wpa_insert_pmkid(rsn_ie_buf, wpa_ie_len, | ||||
| 		res = wpa_insert_pmkid(rsn_ie_buf, &wpa_ie_len, | ||||
| 				       sm->pmk_r1_name); | ||||
| 		if (res < 0) { | ||||
| 			os_free(rsn_ie_buf); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		wpa_ie_len += res; | ||||
| 
 | ||||
| 		if (sm->assoc_resp_ies) { | ||||
| 			os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen