SAE H2E: RSNXE override in EAPOL-Key msg 3/4
This new hostapd configuration parameter rsnxe_override_eapol=<hexdump> can be used to override RSNXE value in EAPOL-Key msg 3/4 for testing purposes. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
		
							parent
							
								
									49ac2466c3
								
							
						
					
					
						commit
						f2c4b44b40
					
				
					 6 changed files with 54 additions and 11 deletions
				
			
		|  | @ -4156,6 +4156,9 @@ static int hostapd_config_fill(struct hostapd_config *conf, | ||||||
| 	} else if (os_strcmp(buf, "sae_commit_override") == 0) { | 	} else if (os_strcmp(buf, "sae_commit_override") == 0) { | ||||||
| 		wpabuf_free(bss->sae_commit_override); | 		wpabuf_free(bss->sae_commit_override); | ||||||
| 		bss->sae_commit_override = wpabuf_parse_bin(pos); | 		bss->sae_commit_override = wpabuf_parse_bin(pos); | ||||||
|  | 	} else if (os_strcmp(buf, "rsnxe_override_eapol") == 0) { | ||||||
|  | 		wpabuf_free(bss->rsnxe_override_eapol); | ||||||
|  | 		bss->rsnxe_override_eapol = wpabuf_parse_bin(pos); | ||||||
| #endif /* CONFIG_TESTING_OPTIONS */ | #endif /* CONFIG_TESTING_OPTIONS */ | ||||||
| #ifdef CONFIG_SAE | #ifdef CONFIG_SAE | ||||||
| 	} else if (os_strcmp(buf, "sae_password") == 0) { | 	} else if (os_strcmp(buf, "sae_password") == 0) { | ||||||
|  |  | ||||||
|  | @ -880,6 +880,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) | ||||||
| #ifdef CONFIG_TESTING_OPTIONS | #ifdef CONFIG_TESTING_OPTIONS | ||||||
| 	wpabuf_free(conf->own_ie_override); | 	wpabuf_free(conf->own_ie_override); | ||||||
| 	wpabuf_free(conf->sae_commit_override); | 	wpabuf_free(conf->sae_commit_override); | ||||||
|  | 	wpabuf_free(conf->rsnxe_override_eapol); | ||||||
| #endif /* CONFIG_TESTING_OPTIONS */ | #endif /* CONFIG_TESTING_OPTIONS */ | ||||||
| 
 | 
 | ||||||
| 	os_free(conf->no_probe_resp_if_seen_on); | 	os_free(conf->no_probe_resp_if_seen_on); | ||||||
|  |  | ||||||
|  | @ -664,6 +664,7 @@ struct hostapd_bss_config { | ||||||
| 	struct wpabuf *own_ie_override; | 	struct wpabuf *own_ie_override; | ||||||
| 	int sae_reflection_attack; | 	int sae_reflection_attack; | ||||||
| 	struct wpabuf *sae_commit_override; | 	struct wpabuf *sae_commit_override; | ||||||
|  | 	struct wpabuf *rsnxe_override_eapol; | ||||||
| #endif /* CONFIG_TESTING_OPTIONS */ | #endif /* CONFIG_TESTING_OPTIONS */ | ||||||
| 
 | 
 | ||||||
| #define MESH_ENABLED BIT(0) | #define MESH_ENABLED BIT(0) | ||||||
|  |  | ||||||
|  | @ -3139,11 +3139,12 @@ static int ocv_oci_add(struct wpa_state_machine *sm, u8 **argpos) | ||||||
| 
 | 
 | ||||||
| SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| { | { | ||||||
| 	u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos, dummy_gtk[32]; | 	u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, dummy_gtk[32]; | ||||||
| 	size_t gtk_len, kde_len; | 	size_t gtk_len, kde_len; | ||||||
| 	struct wpa_group *gsm = sm->group; | 	struct wpa_group *gsm = sm->group; | ||||||
| 	u8 *wpa_ie; | 	u8 *wpa_ie; | ||||||
| 	int wpa_ie_len, secure, gtkidx, encr = 0; | 	int wpa_ie_len, secure, gtkidx, encr = 0; | ||||||
|  | 	u8 *wpa_ie_buf = NULL; | ||||||
| 
 | 
 | ||||||
| 	SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); | 	SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk); | ||||||
| 	sm->TimeoutEvt = FALSE; | 	sm->TimeoutEvt = FALSE; | ||||||
|  | @ -3177,6 +3178,35 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| 			wpa_ie = wpa_ie + wpa_ie[1] + 2; | 			wpa_ie = wpa_ie + wpa_ie[1] + 2; | ||||||
| 		wpa_ie_len = wpa_ie[1] + 2; | 		wpa_ie_len = wpa_ie[1] + 2; | ||||||
| 	} | 	} | ||||||
|  | #ifdef CONFIG_TESTING_OPTIONS | ||||||
|  | 	if (sm->wpa_auth->conf.rsnxe_override_eapol_len) { | ||||||
|  | 		u8 *obuf = sm->wpa_auth->conf.rsnxe_override_eapol; | ||||||
|  | 		size_t olen = sm->wpa_auth->conf.rsnxe_override_eapol_len; | ||||||
|  | 		const u8 *rsnxe; | ||||||
|  | 
 | ||||||
|  | 		wpa_hexdump(MSG_DEBUG, | ||||||
|  | 			    "TESTING: wpa_ie before RSNXE EAPOL override", | ||||||
|  | 			    wpa_ie, wpa_ie_len); | ||||||
|  | 		wpa_ie_buf = os_malloc(wpa_ie_len + olen); | ||||||
|  | 		if (!wpa_ie_buf) | ||||||
|  | 			return; | ||||||
|  | 		os_memcpy(wpa_ie_buf, wpa_ie, wpa_ie_len); | ||||||
|  | 		wpa_ie = wpa_ie_buf; | ||||||
|  | 		rsnxe = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_RSNX); | ||||||
|  | 		if (rsnxe) { | ||||||
|  | 			u8 rsnxe_len = 2 + rsnxe[1]; | ||||||
|  | 
 | ||||||
|  | 			os_memmove((void *) rsnxe, rsnxe + rsnxe_len, | ||||||
|  | 				   wpa_ie_len - (rsnxe - wpa_ie) - rsnxe_len); | ||||||
|  | 			wpa_ie_len -= rsnxe_len; | ||||||
|  | 		} | ||||||
|  | 		os_memcpy(wpa_ie + wpa_ie_len, obuf, olen); | ||||||
|  | 		wpa_ie_len += olen; | ||||||
|  | 		wpa_hexdump(MSG_DEBUG, | ||||||
|  | 			    "TESTING: wpa_ie after RSNXE EAPOL override", | ||||||
|  | 			    wpa_ie, wpa_ie_len); | ||||||
|  | 	} | ||||||
|  | #endif /* CONFIG_TESTING_OPTIONS */ | ||||||
| 	wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, | 	wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, | ||||||
| 			"sending 3/4 msg of 4-Way Handshake"); | 			"sending 3/4 msg of 4-Way Handshake"); | ||||||
| 	if (sm->wpa == WPA_VERSION_WPA2) { | 	if (sm->wpa == WPA_VERSION_WPA2) { | ||||||
|  | @ -3191,7 +3221,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| 			 * of GTK in the BSS. | 			 * of GTK in the BSS. | ||||||
| 			 */ | 			 */ | ||||||
| 			if (random_get_bytes(dummy_gtk, gtk_len) < 0) | 			if (random_get_bytes(dummy_gtk, gtk_len) < 0) | ||||||
| 				return; | 				goto done; | ||||||
| 			gtk = dummy_gtk; | 			gtk = dummy_gtk; | ||||||
| 		} | 		} | ||||||
| 		gtkidx = gsm->GN; | 		gtkidx = gsm->GN; | ||||||
|  | @ -3234,7 +3264,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| #endif /* CONFIG_P2P */ | #endif /* CONFIG_P2P */ | ||||||
| 	kde = os_malloc(kde_len); | 	kde = os_malloc(kde_len); | ||||||
| 	if (kde == NULL) | 	if (kde == NULL) | ||||||
| 		return; | 		goto done; | ||||||
| 
 | 
 | ||||||
| 	pos = kde; | 	pos = kde; | ||||||
| 	os_memcpy(pos, wpa_ie, wpa_ie_len); | 	os_memcpy(pos, wpa_ie, wpa_ie_len); | ||||||
|  | @ -3249,8 +3279,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| 		if (res < 0) { | 		if (res < 0) { | ||||||
| 			wpa_printf(MSG_ERROR, "FT: Failed to insert " | 			wpa_printf(MSG_ERROR, "FT: Failed to insert " | ||||||
| 				   "PMKR1Name into RSN IE in EAPOL-Key data"); | 				   "PMKR1Name into RSN IE in EAPOL-Key data"); | ||||||
| 			os_free(kde); | 			goto done; | ||||||
| 			return; |  | ||||||
| 		} | 		} | ||||||
| 		pos -= wpa_ie_len; | 		pos -= wpa_ie_len; | ||||||
| 		pos += elen; | 		pos += elen; | ||||||
|  | @ -3264,10 +3293,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| 				  gtk, gtk_len); | 				  gtk, gtk_len); | ||||||
| 	} | 	} | ||||||
| 	pos = ieee80211w_kde_add(sm, pos); | 	pos = ieee80211w_kde_add(sm, pos); | ||||||
| 	if (ocv_oci_add(sm, &pos) < 0) { | 	if (ocv_oci_add(sm, &pos) < 0) | ||||||
| 		os_free(kde); | 		goto done; | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_IEEE80211R_AP | #ifdef CONFIG_IEEE80211R_AP | ||||||
| 	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { | 	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { | ||||||
|  | @ -3293,8 +3320,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| 		if (res < 0) { | 		if (res < 0) { | ||||||
| 			wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " | 			wpa_printf(MSG_ERROR, "FT: Failed to insert FTIE " | ||||||
| 				   "into EAPOL-Key Key Data"); | 				   "into EAPOL-Key Key Data"); | ||||||
| 			os_free(kde); | 			goto done; | ||||||
| 			return; |  | ||||||
| 		} | 		} | ||||||
| 		pos += res; | 		pos += res; | ||||||
| 
 | 
 | ||||||
|  | @ -3331,7 +3357,9 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING) | ||||||
| 		       WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL | | 		       WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL | | ||||||
| 		       WPA_KEY_INFO_KEY_TYPE, | 		       WPA_KEY_INFO_KEY_TYPE, | ||||||
| 		       _rsc, sm->ANonce, kde, pos - kde, 0, encr); | 		       _rsc, sm->ANonce, kde, pos - kde, 0, encr); | ||||||
|  | done: | ||||||
| 	os_free(kde); | 	os_free(kde); | ||||||
|  | 	os_free(wpa_ie_buf); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -219,6 +219,8 @@ struct wpa_auth_config { | ||||||
| 	double corrupt_gtk_rekey_mic_probability; | 	double corrupt_gtk_rekey_mic_probability; | ||||||
| 	u8 own_ie_override[MAX_OWN_IE_OVERRIDE]; | 	u8 own_ie_override[MAX_OWN_IE_OVERRIDE]; | ||||||
| 	size_t own_ie_override_len; | 	size_t own_ie_override_len; | ||||||
|  | 	u8 rsnxe_override_eapol[MAX_OWN_IE_OVERRIDE]; | ||||||
|  | 	size_t rsnxe_override_eapol_len; | ||||||
| #endif /* CONFIG_TESTING_OPTIONS */ | #endif /* CONFIG_TESTING_OPTIONS */ | ||||||
| #ifdef CONFIG_P2P | #ifdef CONFIG_P2P | ||||||
| 	u8 ip_addr_go[4]; | 	u8 ip_addr_go[4]; | ||||||
|  |  | ||||||
|  | @ -118,6 +118,14 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, | ||||||
| 			  wpabuf_head(conf->own_ie_override), | 			  wpabuf_head(conf->own_ie_override), | ||||||
| 			  wconf->own_ie_override_len); | 			  wconf->own_ie_override_len); | ||||||
| 	} | 	} | ||||||
|  | 	if (conf->rsnxe_override_eapol && | ||||||
|  | 	    wpabuf_len(conf->rsnxe_override_eapol) <= MAX_OWN_IE_OVERRIDE) { | ||||||
|  | 		wconf->rsnxe_override_eapol_len = | ||||||
|  | 			wpabuf_len(conf->rsnxe_override_eapol); | ||||||
|  | 		os_memcpy(wconf->rsnxe_override_eapol, | ||||||
|  | 			  wpabuf_head(conf->rsnxe_override_eapol), | ||||||
|  | 			  wconf->rsnxe_override_eapol_len); | ||||||
|  | 	} | ||||||
| #endif /* CONFIG_TESTING_OPTIONS */ | #endif /* CONFIG_TESTING_OPTIONS */ | ||||||
| #ifdef CONFIG_P2P | #ifdef CONFIG_P2P | ||||||
| 	os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4); | 	os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen