P2P: Allow per-device PSK to be assigned

"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>
This commit is contained in:
Jouni Malinen 2013-09-01 10:08:30 +03:00
parent 698e921b9e
commit 05766ed8de
8 changed files with 26 additions and 4 deletions

View 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;

View 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) {

View 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;
};

View 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;