]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P2: Support for GO to allow a client to join the group
authorShivani Baranwal <quic_shivbara@quicinc.com>
Wed, 3 Jul 2024 16:41:26 +0000 (22:11 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 31 Oct 2024 11:57:53 +0000 (13:57 +0200)
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 <quic_shivbara@quicinc.com>
src/p2p/p2p.c
src/p2p/p2p.h
wpa_supplicant/p2p_supplicant.c

index dcbbb0736454f36ee62bff0197517d9147fe8ea6..6eaf330112d5a6ba86599c2c6c1d5e3a6da64f70 100644 (file)
@@ -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)
index cce681347f9c8ef5510af19f4d3bf7be973fa600..f1d8890c568fe9c9894df5a62928ec7dc812bf76 100644 (file)
@@ -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 */
index bbed564e5b5fc2874a531975c05914085fabb80b..72e8dfe26c2e5ac690f0bcd36180d185cf73fba0 100644 (file)
@@ -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,