HS 2.0: Add mechanism for disabling DGAF
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 18 Oct 2011 09:38:32 +0000 (12:38 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 30 Jul 2012 15:23:52 +0000 (18:23 +0300)
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>

hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/beacon.c
src/ap/hs20.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c
src/drivers/driver.h

index 9edc80d..117f56b 100644 (file)
@@ -2442,6 +2442,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 #ifdef CONFIG_HS20
                } else if (os_strcmp(buf, "hs20") == 0) {
                        bss->hs20 = atoi(pos);
+               } else if (os_strcmp(buf, "disable_dgaf") == 0) {
+                       bss->disable_dgaf = atoi(pos);
 #endif /* CONFIG_HS20 */
                } else {
                        wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
index 48aae53..6ab3f12 100644 (file)
@@ -1330,6 +1330,13 @@ own_ip_addr=127.0.0.1
 # Enable Hotspot 2.0 support
 #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 ##################################################
 #
 # Above configuration is using the default interface (wlan#, or multi-SSID VLAN
index e3834ad..caf0153 100644 (file)
@@ -396,6 +396,7 @@ struct hostapd_bss_config {
 
 #ifdef CONFIG_HS20
        int hs20;
+       int disable_dgaf;
 #endif /* CONFIG_HS20 */
 
        u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */
index 31dbcff..ef97c6e 100644 (file)
@@ -703,6 +703,9 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
                params.hessid = hapd->conf->hessid;
        params.access_network_type = hapd->conf->access_network_type;
        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))
                wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
        hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
index c99db58..45d518b 100644 (file)
@@ -25,6 +25,7 @@ u8 * hostapd_eid_hs20_indication(struct hostapd_data *hapd, u8 *eid)
        WPA_PUT_BE24(eid, OUI_WFA);
        eid += 3;
        *eid++ = HS20_INDICATION_OUI_TYPE;
-       *eid++ = 0x00; /* Hotspot Configuration: DGAF Enabled */
+       /* Hotspot Configuration: DGAF Enabled */
+       *eid++ = hapd->conf->disable_dgaf ? 0x01 : 0x00;
        return eid;
 }
index 1d942a4..ef49837 100644 (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)
                os_memset(igtk.pn, 0, sizeof(igtk.pn));
        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,
                          (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)
 {
-       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;
        struct wpa_group *gsm = sm->group;
        u8 *wpa_ie;
@@ -1960,6 +1968,15 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
                secure = 1;
                gtk = gsm->GTK[gsm->GN - 1];
                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;
                _rsc = rsc;
                encr = 1;
@@ -2256,6 +2273,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
        struct wpa_group *gsm = sm->group;
        u8 *kde, *pos, hdr[2];
        size_t kde_len;
+       u8 *gtk, dummy_gtk[32];
 
        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,
                        "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) {
                kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
                        ieee80211w_kde_len(sm);
@@ -2287,10 +2315,10 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
                hdr[0] = gsm->GN & 0x03;
                hdr[1] = 0;
                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);
        } else {
-               kde = gsm->GTK[gsm->GN - 1];
+               kde = gtk;
                pos = kde + gsm->GTK_len;
        }
 
index a07779f..1464ca9 100644 (file)
@@ -158,6 +158,7 @@ struct wpa_auth_config {
        int pmk_r1_push;
        int ft_over_ds;
 #endif /* CONFIG_IEEE80211R */
+       int disable_gtk;
 };
 
 typedef enum {
index 3e5ac1d..d6b1ca3 100644 (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->ft_over_ds = conf->ft_over_ds;
 #endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_HS20
+       wconf->disable_gtk = conf->disable_dgaf;
+#endif /* CONFIG_HS20 */
 }
 
 
index 99da31c..4a8604d 100644 (file)
@@ -740,6 +740,11 @@ struct wpa_driver_ap_params {
         * This is used by driver which advertises this capability.
         */
        int ap_max_inactivity;
+
+       /**
+        * disable_dgaf - Whether group-addressed frames are disabled
+        */
+       int disable_dgaf;
 };
 
 /**