]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow per-device PSK to be assigned
authorJouni Malinen <j@w1.fi>
Sun, 1 Sep 2013 07:08:30 +0000 (10:08 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 1 Sep 2013 07:14:29 +0000 (10:14 +0300)
"wpa_cli p2p_set per_sta_psk <0/1>" can now be used to disable/enable
use of per-device PSKs in P2P groups. This is disabled by default.
When enabled, a default passphrase is still generated by the GO for
legacy stations, but all P2P and non-P2P devices using WPS will get
a unique PSK.

This gives more protection for the P2P group by preventing clients from
being able to derive the unicast keys used by other clients. This is
also a step towards allowing specific clients to be removed from a group
reliably without having to tear down the full group to do so.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/ap/ap_config.h
src/ap/wps_hostapd.c
src/wps/wps.h
src/wps/wps_registrar.c
wpa_supplicant/ap.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c
wpa_supplicant/wpa_supplicant_i.h

index d5bfabceb9fe004fc205234e0d4b466337d0cc3f..e2836456e8e566e2417640dc7b653a970c8da01e 100644 (file)
@@ -358,6 +358,7 @@ struct hostapd_bss_config {
        u8 *extra_cred;
        size_t extra_cred_len;
        int wps_cred_processing;
+       int force_per_enrollee_psk;
        u8 *ap_settings;
        size_t ap_settings_len;
        char *upnp_iface;
index 3304c06360ae1c779adc1753f108536b9d91c024..4f627c894781cef9fded57923a3a9e8c2282ea7e 100644 (file)
@@ -1145,6 +1145,7 @@ int hostapd_init_wps(struct hostapd_data *hapd,
                cfg.dualband = 1;
        if (cfg.dualband)
                wpa_printf(MSG_DEBUG, "WPS: Dualband AP");
+       cfg.force_per_enrollee_psk = conf->force_per_enrollee_psk;
 
        wps->registrar = wps_registrar_init(wps, &cfg);
        if (wps->registrar == NULL) {
index dc82c4462418c2903f6c4f14c566cb7dde5e0ecb..2e6719f4033d650f9891bd0e773bd34612c436db 100644 (file)
@@ -382,6 +382,14 @@ struct wps_registrar_config {
         * dualband - Whether this is a concurrent dualband AP
         */
        int dualband;
+
+       /**
+        * force_per_enrollee_psk - Force per-Enrollee random PSK
+        *
+        * This forces per-Enrollee random PSK to be generated even if a default
+        * PSK is set for a network.
+        */
+       int force_per_enrollee_psk;
 };
 
 
index 318445f28ba31bc3a1e79bc3894315b1611e20fc..20a8b7f62f919dd683cc3da204b3152b7ed6c19b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Wi-Fi Protected Setup - Registrar
- * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2008-2013, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -171,6 +171,7 @@ struct wps_registrar {
        int sel_reg_config_methods_override;
        int static_wep_only;
        int dualband;
+       int force_per_enrollee_psk;
 
        struct wps_registrar_device *devices;
 
@@ -667,6 +668,7 @@ wps_registrar_init(struct wps_context *wps,
        reg->sel_reg_config_methods_override = -1;
        reg->static_wep_only = cfg->static_wep_only;
        reg->dualband = cfg->dualband;
+       reg->force_per_enrollee_psk = cfg->force_per_enrollee_psk;
 
        if (wps_set_ie(reg)) {
                wps_registrar_deinit(reg);
@@ -1640,13 +1642,15 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
                                      wps->new_psk, wps->new_psk_len);
                os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
                wps->cred.key_len = wps->new_psk_len;
-       } else if (wps->use_psk_key && wps->wps->psk_set) {
+       } else if (!wps->wps->registrar->force_per_enrollee_psk &&
+                  wps->use_psk_key && wps->wps->psk_set) {
                char hex[65];
                wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
                wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
                os_memcpy(wps->cred.key, hex, 32 * 2);
                wps->cred.key_len = 32 * 2;
-       } else if (wps->wps->network_key) {
+       } else if (!wps->wps->registrar->force_per_enrollee_psk &&
+                  wps->wps->network_key) {
                os_memcpy(wps->cred.key, wps->wps->network_key,
                          wps->wps->network_key_len);
                wps->cred.key_len = wps->wps->network_key_len;
index 2950d2d1a18e0cbf934fb16d6954ec167e40672e..99c6d8aa46cef4972a8f9d4f9e62727b2fe8886f 100644 (file)
@@ -148,6 +148,7 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
        }
 
        bss->isolate = !wpa_s->conf->p2p_intra_bss;
+       bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
 #endif /* CONFIG_P2P */
 
        if (ssid->ssid_len == 0) {
index 03ffde05512aff769a600e4a52174079421ab212..2abcf74c107d31965fed93cdd2ec2c849540da78 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant / Control interface (shared code for all backends)
- * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -4559,6 +4559,11 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
                                        max_disc_int, max_disc_tu);
        }
 
+       if (os_strcmp(cmd, "per_sta_psk") == 0) {
+               wpa_s->global->p2p_per_sta_psk = !!atoi(param);
+               return 0;
+       }
+
        wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
                   cmd);
 
index 8875d3b71220a6e8915fd36174418299ae2ec405..9817eda689000a2fa294f726fad0467d3cb538b9 100644 (file)
@@ -2076,6 +2076,7 @@ static char ** wpa_cli_complete_p2p_set(const char *str, int pos)
                "client_apsd",
                "disallow_freq",
                "disc_int",
+               "per_sta_psk",
        };
        int i, num_fields = sizeof(fields) / sizeof(fields[0]);
 
index 604997e57ee19de1b71fc2aead229acd6a08e053..f808f491f9c529f2f2724cefcea9ba885e970d1f 100644 (file)
@@ -265,6 +265,7 @@ struct wpa_global {
                WPA_CONC_PREF_P2P
        } conc_pref;
        unsigned int p2p_cb_on_scan_complete:1;
+       unsigned int p2p_per_sta_psk:1;
 
 #ifdef CONFIG_WIFI_DISPLAY
        int wifi_display;