Patchwork [RFC] P2P: Use PSK instead of passphrase for persistent GO fast boot

login
register
mail settings
Submitter Masashi Honma
Date Nov. 27, 2012, 11:46 a.m.
Message ID <CAFk-A4mh9G7byrk=bmUi6x9Otuq2nk=QG3oTZE2VHAO9oD1RWw@mail.gmail.com>
Download mbox | patch
Permalink /patch/202186/
State Accepted
Commit bb4d4deb4bbb7b094faa16fa41f1f49b062cbf22
Headers show

Comments

Masashi Honma - Nov. 27, 2012, 11:46 a.m.
As I mentioned in previous post [1], pbkdf2_sha1() is a bottleneck for
persistent GO initialization. So I will propose saving a psk instead of a
passphrase for persistent GO to skip re-calculation in pbkdf2_sha1().

I suppose this sequence to boot GO.
-------------
add_net
set_network 0 ssid '"DIRECT-X1"'
set_network 0 bssid xx:xx:x:xx:xx:xx
set_network 0 psk
1122334455667788990011223344556677889900112233445566778899001122
set_network 0 proto RSN
set_network 0 key_mgmt WPA-PSK
set_network 0 pairwise CCMP
set_network 0 auth_alg OPEN
set_network 0 mode 3
set_network 0 disabled 2
p2p_group_add persistent=0 freq=2412
-------------

As you know, this change breaks Wi-Fi spec. Because [2] says "A P2P Group Owner
shall maintain a WPA2-PSK pass-phrase for delivery to Legacy Clients." at 3.2.1
P2P Group ID section. This change breaks interop for legacy STA (STA doesn't
have WPS).
So I used CONFIG_P2P_STRICT macro for user who want to conform with [2].

How do you think about this patch ?

[1] http://lists.shmoo.com/pipermail/hostap/2012-November/026841.html
[2] Wi-Fi Peer-to-Peer (P2P) Technical Specification Version 1.1

Signed-hostap: Masashi Honma <masashi.honma@gmail.com>


 		os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk));
@@ -4098,14 +4114,21 @@ int wpas_p2p_group_add_persistent(struct
wpa_supplicant *wpa_s,
 	params.psk_set = ssid->psk_set;
 	if (params.psk_set)
 		os_memcpy(params.psk, ssid->psk, sizeof(params.psk));
-	if (ssid->passphrase == NULL ||
-	    os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) {
-		wpa_printf(MSG_DEBUG, "P2P: Invalid passphrase in persistent "
-			   "group");
+	if (ssid->passphrase == NULL) {
+#ifdef CONFIG_P2P_STRICT
+		wpa_printf(MSG_ERROR, "P2P: No passphrase found in "
+			   "persistent group");
 		return -1;
+#endif /* CONFIG_P2P_STRICT */
+	} else {
+		if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) {
+			wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in "
+				   "persistent group");
+			return -1;
+		}
+		os_strlcpy(params.passphrase, ssid->passphrase,
+			   sizeof(params.passphrase));
 	}
-	os_strlcpy(params.passphrase, ssid->passphrase,
-		   sizeof(params.passphrase));
 	os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len);
 	params.ssid_len = ssid->ssid_len;
 	params.persistent_group = 1;


Regards,
Masashi Honma.
Jouni Malinen - Dec. 25, 2012, 12:24 p.m.
On Tue, Nov 27, 2012 at 08:46:52PM +0900, Masashi Honma wrote:
> As I mentioned in previous post [1], pbkdf2_sha1() is a bottleneck for
> persistent GO initialization. So I will propose saving a psk instead of a
> passphrase for persistent GO to skip re-calculation in pbkdf2_sha1().

Thanks.

> As you know, this change breaks Wi-Fi spec. Because [2] says "A P2P Group Owner
> shall maintain a WPA2-PSK pass-phrase for delivery to Legacy Clients." at 3.2.1
> P2P Group ID section. This change breaks interop for legacy STA (STA doesn't
> have WPS).
> So I used CONFIG_P2P_STRICT macro for user who want to conform with [2].

While this would not comply with the requirements, it does not really
break interoperability completely, i.e., this is only preventing manual
configuration using the passphrase. It would still be possible to
configure legacy STAs using the PSK even though it would not be exactly
convenient to write that long string manually.

CONFIG_P2P_STRICT is mainly used to validate incoming messages, so I
don't think it is necessary to add that validation step here for local
behavior that is fully in control of the device.

> How do you think about this patch ?

I applied it with a rewritten commit log and that CONFIG_P2P_STRICT part
removed.

Patch

diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index e44bb3a..6d0f262 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -796,15 +796,28 @@  static void p2p_go_configured(void *ctx, void *data)
 		wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning");
 		if (wpa_s->global->p2p_group_formation == wpa_s)
 			wpa_s->global->p2p_group_formation = NULL;
-		wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
-			"%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" "
-			"go_dev_addr=" MACSTR "%s",
-			wpa_s->ifname,
-			wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
-			ssid->frequency,
-			params->passphrase ? params->passphrase : "",
-			MAC2STR(wpa_s->global->p2p_dev_addr),
-			params->persistent_group ? " [PERSISTENT]" : "");
+		if (os_strlen(params->passphrase) > 0)
+			wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
+				"%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" "
+				"go_dev_addr=" MACSTR "%s", wpa_s->ifname,
+				wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
+				ssid->frequency, params->passphrase,
+				MAC2STR(wpa_s->global->p2p_dev_addr),
+				params->persistent_group ? " [PERSISTENT]" :
+				"");
+		else {
+			char psk[65];
+			wpa_snprintf_hex(psk, sizeof(psk), params->psk,
+					 sizeof(params->psk));
+			wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
+				"%s GO ssid=\"%s\" freq=%d psk=%s "
+				"go_dev_addr=" MACSTR "%s", wpa_s->ifname,
+				wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
+				ssid->frequency, psk,
+				MAC2STR(wpa_s->global->p2p_dev_addr),
+				params->persistent_group ? " [PERSISTENT]" :
+				"");
+		}

 		if (params->persistent_group)
 			network_id = wpas_p2p_store_persistent_group(
@@ -874,13 +887,16 @@  static void wpas_start_wps_go(struct
wpa_supplicant *wpa_s,
 	ssid->key_mgmt = WPA_KEY_MGMT_PSK;
 	ssid->proto = WPA_PROTO_RSN;
 	ssid->pairwise_cipher = WPA_CIPHER_CCMP;
-	ssid->passphrase = os_strdup(params->passphrase);
-	if (ssid->passphrase == NULL) {
-		wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to copy passphrase for "
-			"GO");
-		wpa_config_remove_network(wpa_s->conf, ssid->id);
-		return;
-	}
+	if (os_strlen(params->passphrase) > 0) {
+		ssid->passphrase = os_strdup(params->passphrase);
+		if (ssid->passphrase == NULL) {
+			wpa_msg(wpa_s, MSG_ERROR, "P2P: Failed to copy "
+				"passphrase for GO");
+			wpa_config_remove_network(wpa_s->conf, ssid->id);
+			return;
+		}
+	} else
+		ssid->passphrase = NULL;
 	ssid->psk_set = params->psk_set;
 	if (ssid->psk_set)