AP-side workaround for WNM-Sleep Mode GTK/IGTK reinstallation issues
Normally, WNM-Sleep Mode exit with management frame protection negotiated would result in the current GTK/IGTK getting added into the WNM-Sleep Mode Response frame. Some station implementations may have a vulnerability that results in GTK/IGTK reinstallation based on this frame being replayed. Add a new hostapd configuration parameter that can be used to disable that behavior and use EAPOL-Key frames for GTK/IGTK update instead. This would likely be only used with wpa_disable_eapol_key_retries=1 that enables a workaround for similar issues with EAPOL-Key. This is related to station side vulnerabilities CVE-2017-13087 and CVE-2017-13088. To enable this AP-side workaround, set wnm_sleep_mode_no_keys=1. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
		
							parent
							
								
									3f5a1860a8
								
							
						
					
					
						commit
						348c93847a
					
				
					 4 changed files with 18 additions and 1 deletions
				
			
		|  | @ -3293,6 +3293,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, | ||||||
| #ifdef CONFIG_WNM_AP | #ifdef CONFIG_WNM_AP | ||||||
| 	} else if (os_strcmp(buf, "wnm_sleep_mode") == 0) { | 	} else if (os_strcmp(buf, "wnm_sleep_mode") == 0) { | ||||||
| 		bss->wnm_sleep_mode = atoi(pos); | 		bss->wnm_sleep_mode = atoi(pos); | ||||||
|  | 	} else if (os_strcmp(buf, "wnm_sleep_mode_no_keys") == 0) { | ||||||
|  | 		bss->wnm_sleep_mode_no_keys = atoi(pos); | ||||||
| 	} else if (os_strcmp(buf, "bss_transition") == 0) { | 	} else if (os_strcmp(buf, "bss_transition") == 0) { | ||||||
| 		bss->bss_transition = atoi(pos); | 		bss->bss_transition = atoi(pos); | ||||||
| #endif /* CONFIG_WNM_AP */ | #endif /* CONFIG_WNM_AP */ | ||||||
|  |  | ||||||
|  | @ -1841,6 +1841,18 @@ own_ip_addr=127.0.0.1 | ||||||
| # 1 = enabled (allow stations to use WNM-Sleep Mode) | # 1 = enabled (allow stations to use WNM-Sleep Mode) | ||||||
| #wnm_sleep_mode=1 | #wnm_sleep_mode=1 | ||||||
| 
 | 
 | ||||||
|  | # WNM-Sleep Mode GTK/IGTK workaround | ||||||
|  | # Normally, WNM-Sleep Mode exit with management frame protection negotiated | ||||||
|  | # would result in the current GTK/IGTK getting added into the WNM-Sleep Mode | ||||||
|  | # Response frame. Some station implementations may have a vulnerability that | ||||||
|  | # results in GTK/IGTK reinstallation based on this frame being replayed. This | ||||||
|  | # configuration parameter can be used to disable that behavior and use EAPOL-Key | ||||||
|  | # frames for GTK/IGTK update instead. This would likely be only used with | ||||||
|  | # wpa_disable_eapol_key_retries=1 that enables a workaround for similar issues | ||||||
|  | # with EAPOL-Key. This is related to station side vulnerabilities CVE-2017-13087 | ||||||
|  | # and CVE-2017-13088. To enable this AP-side workaround, set the parameter to 1. | ||||||
|  | #wnm_sleep_mode_no_keys=0 | ||||||
|  | 
 | ||||||
| # BSS Transition Management | # BSS Transition Management | ||||||
| # 0 = disabled (default) | # 0 = disabled (default) | ||||||
| # 1 = enabled | # 1 = enabled | ||||||
|  |  | ||||||
|  | @ -479,6 +479,7 @@ struct hostapd_bss_config { | ||||||
| 	int time_advertisement; | 	int time_advertisement; | ||||||
| 	char *time_zone; | 	char *time_zone; | ||||||
| 	int wnm_sleep_mode; | 	int wnm_sleep_mode; | ||||||
|  | 	int wnm_sleep_mode_no_keys; | ||||||
| 	int bss_transition; | 	int bss_transition; | ||||||
| 
 | 
 | ||||||
| 	/* IEEE 802.11u - Interworking */ | 	/* IEEE 802.11u - Interworking */ | ||||||
|  |  | ||||||
|  | @ -109,6 +109,7 @@ static int ieee802_11_send_wnmsleep_resp(struct hostapd_data *hapd, | ||||||
| 	pos = (u8 *)mgmt->u.action.u.wnm_sleep_resp.variable; | 	pos = (u8 *)mgmt->u.action.u.wnm_sleep_resp.variable; | ||||||
| 	/* add key data if MFP is enabled */ | 	/* add key data if MFP is enabled */ | ||||||
| 	if (!wpa_auth_uses_mfp(sta->wpa_sm) || | 	if (!wpa_auth_uses_mfp(sta->wpa_sm) || | ||||||
|  | 	    hapd->conf->wnm_sleep_mode_no_keys || | ||||||
| 	    action_type != WNM_SLEEP_MODE_EXIT) { | 	    action_type != WNM_SLEEP_MODE_EXIT) { | ||||||
| 		mgmt->u.action.u.wnm_sleep_resp.keydata_len = 0; | 		mgmt->u.action.u.wnm_sleep_resp.keydata_len = 0; | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -173,7 +174,8 @@ static int ieee802_11_send_wnmsleep_resp(struct hostapd_data *hapd, | ||||||
| 			wpa_set_wnmsleep(sta->wpa_sm, 0); | 			wpa_set_wnmsleep(sta->wpa_sm, 0); | ||||||
| 			hostapd_drv_wnm_oper(hapd, WNM_SLEEP_EXIT_CONFIRM, | 			hostapd_drv_wnm_oper(hapd, WNM_SLEEP_EXIT_CONFIRM, | ||||||
| 					     addr, NULL, NULL); | 					     addr, NULL, NULL); | ||||||
| 			if (!wpa_auth_uses_mfp(sta->wpa_sm)) | 			if (!wpa_auth_uses_mfp(sta->wpa_sm) || | ||||||
|  | 			    hapd->conf->wnm_sleep_mode_no_keys) | ||||||
| 				wpa_wnmsleep_rekey_gtk(sta->wpa_sm); | 				wpa_wnmsleep_rekey_gtk(sta->wpa_sm); | ||||||
| 		} | 		} | ||||||
| 	} else | 	} else | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen