HS 2.0: Add mechanism for disabling DGAF

disable_dgaf=1 in hostapd.conf can now be used to disable downstream
group-addressed forwarding (DGAF). In this configuration, a unique
GTK (and IGTK) is provided to each STA in the BSS to make sure the
keys do not match and no STA can forge group-addressed frames.

An additional mechanism in the AP needs to be provided to handle some
group-addressed frames, e.g., by converting DHCP packets to unicast
IEEE 802.11 frames regardless of their destination IP address and by
providing Proxy ARP functionality.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2011-10-18 12:38:32 +03:00 committed by Jouni Malinen
parent 19a8ad9944
commit 8342185012
9 changed files with 55 additions and 4 deletions

View file

@ -2442,6 +2442,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
} else if (os_strcmp(buf, "hs20") == 0) { } else if (os_strcmp(buf, "hs20") == 0) {
bss->hs20 = atoi(pos); bss->hs20 = atoi(pos);
} else if (os_strcmp(buf, "disable_dgaf") == 0) {
bss->disable_dgaf = atoi(pos);
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
} else { } else {
wpa_printf(MSG_ERROR, "Line %d: unknown configuration " wpa_printf(MSG_ERROR, "Line %d: unknown configuration "

View file

@ -1330,6 +1330,13 @@ own_ip_addr=127.0.0.1
# Enable Hotspot 2.0 support # Enable Hotspot 2.0 support
#hs20=1 #hs20=1
# Disable Downstream Group-Addressed Forwarding (DGAF)
# This can be used to configure a network where no group-addressed frames are
# allowed. The AP will not forward any group-address frames to the stations and
# random GTKs are issued for each station to prevent associated stations from
# forging such frames to other stations in the BSS.
#disable_dgaf=1
##### Multiple BSSID support ################################################## ##### Multiple BSSID support ##################################################
# #
# Above configuration is using the default interface (wlan#, or multi-SSID VLAN # Above configuration is using the default interface (wlan#, or multi-SSID VLAN

View file

@ -396,6 +396,7 @@ struct hostapd_bss_config {
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
int hs20; int hs20;
int disable_dgaf;
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */ u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */

View file

@ -703,6 +703,9 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
params.hessid = hapd->conf->hessid; params.hessid = hapd->conf->hessid;
params.access_network_type = hapd->conf->access_network_type; params.access_network_type = hapd->conf->access_network_type;
params.ap_max_inactivity = hapd->conf->ap_max_inactivity; params.ap_max_inactivity = hapd->conf->ap_max_inactivity;
#ifdef CONFIG_HS20
params.disable_dgaf = hapd->conf->disable_dgaf;
#endif /* CONFIG_HS20 */
if (hostapd_drv_set_ap(hapd, &params)) if (hostapd_drv_set_ap(hapd, &params))
wpa_printf(MSG_ERROR, "Failed to set beacon parameters"); wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp); hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);

View file

@ -25,6 +25,7 @@ u8 * hostapd_eid_hs20_indication(struct hostapd_data *hapd, u8 *eid)
WPA_PUT_BE24(eid, OUI_WFA); WPA_PUT_BE24(eid, OUI_WFA);
eid += 3; eid += 3;
*eid++ = HS20_INDICATION_OUI_TYPE; *eid++ = HS20_INDICATION_OUI_TYPE;
*eid++ = 0x00; /* Hotspot Configuration: DGAF Enabled */ /* Hotspot Configuration: DGAF Enabled */
*eid++ = hapd->conf->disable_dgaf ? 0x01 : 0x00;
return eid; return eid;
} }

View file

@ -1898,6 +1898,14 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, igtk.pn) < 0) wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, igtk.pn) < 0)
os_memset(igtk.pn, 0, sizeof(igtk.pn)); os_memset(igtk.pn, 0, sizeof(igtk.pn));
os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN); os_memcpy(igtk.igtk, gsm->IGTK[gsm->GN_igtk - 4], WPA_IGTK_LEN);
if (sm->wpa_auth->conf.disable_gtk) {
/*
* Provide unique random IGTK to each STA to prevent use of
* IGTK in the BSS.
*/
if (random_get_bytes(igtk.igtk, WPA_IGTK_LEN) < 0)
return pos;
}
pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK, pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK,
(const u8 *) &igtk, sizeof(igtk), NULL, 0); (const u8 *) &igtk, sizeof(igtk), NULL, 0);
@ -1922,7 +1930,7 @@ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
SM_STATE(WPA_PTK, PTKINITNEGOTIATING) SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
{ {
u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos; u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *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;
@ -1960,6 +1968,15 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
secure = 1; secure = 1;
gtk = gsm->GTK[gsm->GN - 1]; gtk = gsm->GTK[gsm->GN - 1];
gtk_len = gsm->GTK_len; gtk_len = gsm->GTK_len;
if (sm->wpa_auth->conf.disable_gtk) {
/*
* Provide unique random GTK to each STA to prevent use
* of GTK in the BSS.
*/
if (random_get_bytes(dummy_gtk, gtk_len) < 0)
return;
gtk = dummy_gtk;
}
keyidx = gsm->GN; keyidx = gsm->GN;
_rsc = rsc; _rsc = rsc;
encr = 1; encr = 1;
@ -2256,6 +2273,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
struct wpa_group *gsm = sm->group; struct wpa_group *gsm = sm->group;
u8 *kde, *pos, hdr[2]; u8 *kde, *pos, hdr[2];
size_t kde_len; size_t kde_len;
u8 *gtk, dummy_gtk[32];
SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group); SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
@ -2276,6 +2294,16 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG, wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
"sending 1/2 msg of Group Key Handshake"); "sending 1/2 msg of Group Key Handshake");
gtk = gsm->GTK[gsm->GN - 1];
if (sm->wpa_auth->conf.disable_gtk) {
/*
* Provide unique random GTK to each STA to prevent use
* of GTK in the BSS.
*/
if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0)
return;
gtk = dummy_gtk;
}
if (sm->wpa == WPA_VERSION_WPA2) { if (sm->wpa == WPA_VERSION_WPA2) {
kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len + kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
ieee80211w_kde_len(sm); ieee80211w_kde_len(sm);
@ -2287,10 +2315,10 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
hdr[0] = gsm->GN & 0x03; hdr[0] = gsm->GN & 0x03;
hdr[1] = 0; hdr[1] = 0;
pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2, pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
gsm->GTK[gsm->GN - 1], gsm->GTK_len); gtk, gsm->GTK_len);
pos = ieee80211w_kde_add(sm, pos); pos = ieee80211w_kde_add(sm, pos);
} else { } else {
kde = gsm->GTK[gsm->GN - 1]; kde = gtk;
pos = kde + gsm->GTK_len; pos = kde + gsm->GTK_len;
} }

View file

@ -158,6 +158,7 @@ struct wpa_auth_config {
int pmk_r1_push; int pmk_r1_push;
int ft_over_ds; int ft_over_ds;
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
int disable_gtk;
}; };
typedef enum { typedef enum {

View file

@ -70,6 +70,9 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
wconf->pmk_r1_push = conf->pmk_r1_push; wconf->pmk_r1_push = conf->pmk_r1_push;
wconf->ft_over_ds = conf->ft_over_ds; wconf->ft_over_ds = conf->ft_over_ds;
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_HS20
wconf->disable_gtk = conf->disable_dgaf;
#endif /* CONFIG_HS20 */
} }

View file

@ -740,6 +740,11 @@ struct wpa_driver_ap_params {
* This is used by driver which advertises this capability. * This is used by driver which advertises this capability.
*/ */
int ap_max_inactivity; int ap_max_inactivity;
/**
* disable_dgaf - Whether group-addressed frames are disabled
*/
int disable_dgaf;
}; };
/** /**