From: Shivani Baranwal Date: Wed, 3 Jul 2024 16:41:26 +0000 (+0530) Subject: P2P2: Support for GO to allow a client to join the group X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bfd79912602a6bfeab81277476f84f645bde5d39;p=thirdparty%2Fhostap.git P2P2: Support for GO to allow a client to join the group Enable P2P GO to authorize a client device to join the group. In the case of opportunistic bootstrapping, P2P GO must share the password with the client device during PASN authentication in an Encrypted Data element. P2P GO retrieves the ssid->sae_password and stores it in p2p->dev_sae_password and authorizes the client. The SAE password and the random passphrase derived for WPA-PSK connection are same. This allows use of the get_passphrase API to connect a P2P-R1 and P2P-R2 client in PCC mode which will be covered in separate commits. The P2P Client initiates PASN authentication with the GO using either the password or opportunistic bootstrapping method. In the password method, the client initiates PASN authentication with SAE tunneling using the password and proceeds with the connection using open authentication. In the opportunistic bootstrapping method, the client obtains the SAE password from the GO and initiates the connection with SAE authentication. Signed-off-by: Shivani Baranwal --- diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index dcbbb0736..6eaf33011 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1864,6 +1864,14 @@ int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) p2p_random(params->passphrase, p2p->cfg->passphrase_len); params->passphrase[p2p->cfg->passphrase_len] = '\0'; + + if (params->p2p2) { + os_strlcpy(p2p->dev_sae_password, params->passphrase, + sizeof(p2p->dev_sae_password)); + os_strlcpy(params->sae_password, p2p->dev_sae_password, + sizeof(params->sae_password)); + } + return 0; } @@ -6117,6 +6125,17 @@ void p2p_process_usd_elems(struct p2p_data *p2p, const u8 *ies, u16 ies_len, #ifdef CONFIG_PASN +int p2p_config_sae_password(struct p2p_data *p2p, const char *pw) +{ + os_memset(p2p->dev_sae_password, 0, sizeof(p2p->dev_sae_password)); + if (os_strlen(pw) >= sizeof(p2p->dev_sae_password)) + return -1; + + os_strlcpy(p2p->dev_sae_password, pw, sizeof(p2p->dev_sae_password)); + return 0; +} + + static int p2p_prepare_pasn_extra_ie(struct p2p_data *p2p, struct wpabuf *extra_ies, const struct wpabuf *frame) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index cce681347..f1d8890c5 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -2703,5 +2703,6 @@ int p2p_prepare_data_element(struct p2p_data *p2p, const u8 *peer_addr); int p2p_parse_data_element(struct p2p_data *p2p, const u8 *data, size_t len); int p2p_pasn_auth_tx_status(struct p2p_data *p2p, const u8 *data, size_t data_len, bool acked, bool verify); +int p2p_config_sae_password(struct p2p_data *p2p, const char *pw); #endif /* P2P_H */ diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index bbed564e5..72e8dfe26 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -5699,6 +5699,20 @@ static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s) } +#ifdef CONFIG_PASN +static int wpas_p2p_config_sae_password(struct wpa_supplicant *wpa_s, + struct wpa_ssid *ssid) +{ + struct p2p_data *p2p = wpa_s->global->p2p; + + if (wpa_s->global->p2p_disabled || !p2p || !ssid->sae_password) + return -2; + + return p2p_config_sae_password(p2p, ssid->sae_password); +} +#endif /* CONFIG_PASN */ + + static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s, const u8 *peer_addr, enum p2p_wps_method wps_method, @@ -6585,11 +6599,55 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, if (join || auto_join) { u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN]; if (auth) { +#ifdef CONFIG_PASN + struct wpa_supplicant *ifs; +#endif /* CONFIG_PASN */ + wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to " "connect a running group from " MACSTR, MAC2STR(peer_addr)); os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); + +#ifdef CONFIG_PASN + if (!wpa_s->p2p2) + return ret; + + wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s); + if (wpa_s->create_p2p_iface) { + if_addr = wpa_s->pending_interface_addr; + } else { + if (wpa_s->p2p_mgmt) + if_addr = wpa_s->parent->own_addr; + else + if_addr = wpa_s->own_addr; + os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN); + } + + dl_list_for_each(ifs, &wpa_s->radio->ifaces, + struct wpa_supplicant, radio_list) { + if (!ifs->current_ssid || + ifs->current_ssid->mode != WPAS_MODE_P2P_GO) + continue; + + ssid = ifs->current_ssid; + + if (bootstrap == P2P_PBMA_OPPORTUNISTIC && + wpas_p2p_config_sae_password(wpa_s, ssid)) { + ssid = NULL; + continue; + } + break; + } + p2p_set_go_role(wpa_s->global->p2p, true); + return wpas_p2p_auth_go_neg(wpa_s, peer_addr, + wps_method, 15, if_addr, + force_freq, + persistent_group, ssid, + pref_freq, bootstrap, + password); +#else /* CONFIG_PASN */ return ret; +#endif /* CONFIG_PASN */ } os_memcpy(dev_addr, peer_addr, ETH_ALEN); if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr,