1 /*
2  * hostapd / DPP integration
3  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4  * Copyright (c) 2018-2020, The Linux Foundation
5  * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "utils/includes.h"
12 
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "common/dpp.h"
16 #include "common/gas.h"
17 #include "common/wpa_ctrl.h"
18 #include "crypto/random.h"
19 #include "hostapd.h"
20 #include "ap_drv_ops.h"
21 #include "gas_query_ap.h"
22 #include "gas_serv.h"
23 #include "wpa_auth.h"
24 #include "beacon.h"
25 #include "dpp_hostapd.h"
26 
27 
28 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
29 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
30                                                          void *timeout_ctx);
31 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
32 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
33 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
34 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
35                                                       struct dpp_authentication *auth);
36 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd);
37 #ifdef CONFIG_DPP2
38 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
39                                                                 void *timeout_ctx);
40 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
41                                                     struct dpp_authentication *auth,
42                                                     struct dpp_config_obj *conf);
43 static int hostapd_dpp_process_conf_obj(void *ctx,
44                                                   struct dpp_authentication *auth);
45 #endif /* CONFIG_DPP2 */
46 
47 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
48 
49 
50 /**
51  * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
52  * @hapd: Pointer to hostapd_data
53  * @cmd: DPP URI read from a QR Code
54  * Returns: Identifier of the stored info or -1 on failure
55  */
hostapd_dpp_qr_code(struct hostapd_data * hapd,const char * cmd)56 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
57 {
58           struct dpp_bootstrap_info *bi;
59           struct dpp_authentication *auth = hapd->dpp_auth;
60 
61           bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
62           if (!bi)
63                     return -1;
64 
65           if (auth && auth->response_pending &&
66               dpp_notify_new_qr_code(auth, bi) == 1) {
67                     wpa_printf(MSG_DEBUG,
68                                  "DPP: Sending out pending authentication response");
69                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
70                               " freq=%u type=%d",
71                               MAC2STR(auth->peer_mac_addr), auth->curr_freq,
72                               DPP_PA_AUTHENTICATION_RESP);
73                     hostapd_drv_send_action(hapd, auth->curr_freq, 0,
74                                                   auth->peer_mac_addr,
75                                                   wpabuf_head(hapd->dpp_auth->resp_msg),
76                                                   wpabuf_len(hapd->dpp_auth->resp_msg));
77           }
78 
79 #ifdef CONFIG_DPP2
80           dpp_controller_new_qr_code(hapd->iface->interfaces->dpp, bi);
81 #endif /* CONFIG_DPP2 */
82 
83           return bi->id;
84 }
85 
86 
87 /**
88  * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
89  * @hapd: Pointer to hostapd_data
90  * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
91  * Returns: Identifier of the stored info or -1 on failure
92  */
hostapd_dpp_nfc_uri(struct hostapd_data * hapd,const char * cmd)93 int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
94 {
95           struct dpp_bootstrap_info *bi;
96 
97           bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
98           if (!bi)
99                     return -1;
100 
101           return bi->id;
102 }
103 
104 
hostapd_dpp_nfc_handover_req(struct hostapd_data * hapd,const char * cmd)105 int hostapd_dpp_nfc_handover_req(struct hostapd_data *hapd, const char *cmd)
106 {
107           const char *pos;
108           struct dpp_bootstrap_info *peer_bi, *own_bi;
109 
110           pos = os_strstr(cmd, " own=");
111           if (!pos)
112                     return -1;
113           pos += 5;
114           own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
115           if (!own_bi)
116                     return -1;
117 
118           pos = os_strstr(cmd, " uri=");
119           if (!pos)
120                     return -1;
121           pos += 5;
122           peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
123           if (!peer_bi) {
124                     wpa_printf(MSG_INFO,
125                                  "DPP: Failed to parse URI from NFC Handover Request");
126                     return -1;
127           }
128 
129           if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
130                     return -1;
131 
132           return peer_bi->id;
133 }
134 
135 
hostapd_dpp_nfc_handover_sel(struct hostapd_data * hapd,const char * cmd)136 int hostapd_dpp_nfc_handover_sel(struct hostapd_data *hapd, const char *cmd)
137 {
138           const char *pos;
139           struct dpp_bootstrap_info *peer_bi, *own_bi;
140 
141           pos = os_strstr(cmd, " own=");
142           if (!pos)
143                     return -1;
144           pos += 5;
145           own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
146           if (!own_bi)
147                     return -1;
148 
149           pos = os_strstr(cmd, " uri=");
150           if (!pos)
151                     return -1;
152           pos += 5;
153           peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
154           if (!peer_bi) {
155                     wpa_printf(MSG_INFO,
156                                  "DPP: Failed to parse URI from NFC Handover Select");
157                     return -1;
158           }
159 
160           if (peer_bi->curve != own_bi->curve) {
161                     wpa_printf(MSG_INFO,
162                                  "DPP: Peer (NFC Handover Selector) used different curve");
163                     return -1;
164           }
165 
166           return peer_bi->id;
167 }
168 
169 
hostapd_dpp_auth_resp_retry_timeout(void * eloop_ctx,void * timeout_ctx)170 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
171                                                             void *timeout_ctx)
172 {
173           struct hostapd_data *hapd = eloop_ctx;
174           struct dpp_authentication *auth = hapd->dpp_auth;
175 
176           if (!auth || !auth->resp_msg)
177                     return;
178 
179           wpa_printf(MSG_DEBUG,
180                        "DPP: Retry Authentication Response after timeout");
181           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
182                     " freq=%u type=%d",
183                     MAC2STR(auth->peer_mac_addr), auth->curr_freq,
184                     DPP_PA_AUTHENTICATION_RESP);
185           hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
186                                         wpabuf_head(auth->resp_msg),
187                                         wpabuf_len(auth->resp_msg));
188 }
189 
190 
hostapd_dpp_auth_resp_retry(struct hostapd_data * hapd)191 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
192 {
193           struct dpp_authentication *auth = hapd->dpp_auth;
194           unsigned int wait_time, max_tries;
195 
196           if (!auth || !auth->resp_msg)
197                     return;
198 
199           if (hapd->dpp_resp_max_tries)
200                     max_tries = hapd->dpp_resp_max_tries;
201           else
202                     max_tries = 5;
203           auth->auth_resp_tries++;
204           if (auth->auth_resp_tries >= max_tries) {
205                     wpa_printf(MSG_INFO,
206                                  "DPP: No confirm received from initiator - stopping exchange");
207                     hostapd_drv_send_action_cancel_wait(hapd);
208                     dpp_auth_deinit(hapd->dpp_auth);
209                     hapd->dpp_auth = NULL;
210                     return;
211           }
212 
213           if (hapd->dpp_resp_retry_time)
214                     wait_time = hapd->dpp_resp_retry_time;
215           else
216                     wait_time = 1000;
217           wpa_printf(MSG_DEBUG,
218                        "DPP: Schedule retransmission of Authentication Response frame in %u ms",
219                     wait_time);
220           eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
221           eloop_register_timeout(wait_time / 1000,
222                                      (wait_time % 1000) * 1000,
223                                      hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
224 }
225 
226 
hostapd_dpp_allow_ir(struct hostapd_data * hapd,unsigned int freq)227 static int hostapd_dpp_allow_ir(struct hostapd_data *hapd, unsigned int freq)
228 {
229           int i, j;
230 
231           if (!hapd->iface->hw_features)
232                     return -1;
233 
234           for (i = 0; i < hapd->iface->num_hw_features; i++) {
235                     struct hostapd_hw_modes *mode = &hapd->iface->hw_features[i];
236 
237                     for (j = 0; j < mode->num_channels; j++) {
238                               struct hostapd_channel_data *chan = &mode->channels[j];
239 
240                               if (chan->freq != (int) freq)
241                                         continue;
242 
243                               if (chan->flag & (HOSTAPD_CHAN_DISABLED |
244                                                     HOSTAPD_CHAN_NO_IR |
245                                                     HOSTAPD_CHAN_RADAR))
246                                         continue;
247 
248                               return 1;
249                     }
250           }
251 
252           wpa_printf(MSG_DEBUG,
253                        "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
254                        freq);
255 
256           return 0;
257 }
258 
259 
hostapd_dpp_pkex_next_channel(struct hostapd_data * hapd,struct dpp_pkex * pkex)260 static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
261                                                    struct dpp_pkex *pkex)
262 {
263           if (pkex->freq == 2437)
264                     pkex->freq = 5745;
265           else if (pkex->freq == 5745)
266                     pkex->freq = 5220;
267           else if (pkex->freq == 5220)
268                     pkex->freq = 60480;
269           else
270                     return -1; /* no more channels to try */
271 
272           if (hostapd_dpp_allow_ir(hapd, pkex->freq) == 1) {
273                     wpa_printf(MSG_DEBUG, "DPP: Try to initiate on %u MHz",
274                                  pkex->freq);
275                     return 0;
276           }
277 
278           /* Could not use this channel - try the next one */
279           return hostapd_dpp_pkex_next_channel(hapd, pkex);
280 }
281 
282 
hostapd_dpp_pkex_clear_code(struct hostapd_data * hapd)283 static void hostapd_dpp_pkex_clear_code(struct hostapd_data *hapd)
284 {
285           if (!hapd->dpp_pkex_code && !hapd->dpp_pkex_identifier)
286                     return;
287 
288           /* Delete PKEX code and identifier on successful completion of
289            * PKEX. We are not supposed to reuse these without being
290            * explicitly requested to perform PKEX again. */
291           wpa_printf(MSG_DEBUG, "DPP: Delete PKEX code/identifier");
292           os_free(hapd->dpp_pkex_code);
293           hapd->dpp_pkex_code = NULL;
294           os_free(hapd->dpp_pkex_identifier);
295           hapd->dpp_pkex_identifier = NULL;
296 }
297 
298 
299 #ifdef CONFIG_DPP2
hostapd_dpp_pkex_done(void * ctx,void * conn,struct dpp_bootstrap_info * peer_bi)300 static int hostapd_dpp_pkex_done(void *ctx, void *conn,
301                                          struct dpp_bootstrap_info *peer_bi)
302 {
303           struct hostapd_data *hapd = ctx;
304           char cmd[500];
305           const char *pos;
306           u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
307           struct dpp_bootstrap_info *own_bi = NULL;
308           struct dpp_authentication *auth;
309 
310           hostapd_dpp_pkex_clear_code(hapd);
311 
312           os_snprintf(cmd, sizeof(cmd), " peer=%u %s", peer_bi->id,
313                         hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
314           wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
315                        cmd);
316 
317           pos = os_strstr(cmd, " own=");
318           if (pos) {
319                     pos += 5;
320                     own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
321                                                         atoi(pos));
322                     if (!own_bi) {
323                               wpa_printf(MSG_INFO,
324                                            "DPP: Could not find bootstrapping info for the identified local entry");
325                               return -1;
326                     }
327 
328                     if (peer_bi->curve != own_bi->curve) {
329                               wpa_printf(MSG_INFO,
330                                            "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
331                                            peer_bi->curve->name, own_bi->curve->name);
332                               return -1;
333                     }
334           }
335 
336           pos = os_strstr(cmd, " role=");
337           if (pos) {
338                     pos += 6;
339                     if (os_strncmp(pos, "configurator", 12) == 0)
340                               allowed_roles = DPP_CAPAB_CONFIGURATOR;
341                     else if (os_strncmp(pos, "enrollee", 8) == 0)
342                               allowed_roles = DPP_CAPAB_ENROLLEE;
343                     else if (os_strncmp(pos, "either", 6) == 0)
344                               allowed_roles = DPP_CAPAB_CONFIGURATOR |
345                                         DPP_CAPAB_ENROLLEE;
346                     else
347                               return -1;
348           }
349 
350           auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
351                                    peer_bi, own_bi, allowed_roles, 0,
352                                    hapd->iface->hw_features,
353                                    hapd->iface->num_hw_features);
354           if (!auth)
355                     return -1;
356 
357           hostapd_dpp_set_testing_options(hapd, auth);
358           if (dpp_set_configurator(auth, cmd) < 0) {
359                     dpp_auth_deinit(auth);
360                     return -1;
361           }
362 
363           return dpp_tcp_auth(hapd->iface->interfaces->dpp, conn, auth,
364                                   hapd->conf->dpp_name, DPP_NETROLE_AP,
365                                   hapd->conf->dpp_mud_url,
366                                   hapd->conf->dpp_extra_conf_req_name,
367                                   hapd->conf->dpp_extra_conf_req_value,
368                                   hostapd_dpp_process_conf_obj, NULL);
369 }
370 #endif /* CONFIG_DPP2 */
371 
372 
hostapd_dpp_pkex_init(struct hostapd_data * hapd,enum dpp_pkex_ver ver,const struct hostapd_ip_addr * ipaddr,int tcp_port)373 static int hostapd_dpp_pkex_init(struct hostapd_data *hapd,
374                                          enum dpp_pkex_ver ver,
375                                          const struct hostapd_ip_addr *ipaddr,
376                                          int tcp_port)
377 {
378           struct dpp_pkex *pkex;
379           struct wpabuf *msg;
380           unsigned int wait_time;
381           bool v2 = ver != PKEX_VER_ONLY_1;
382 
383           wpa_printf(MSG_DEBUG, "DPP: Initiating PKEXv%d", v2 ? 2 : 1);
384           dpp_pkex_free(hapd->dpp_pkex);
385           hapd->dpp_pkex = NULL;
386           pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
387                                    hapd->dpp_pkex_identifier,
388                                    hapd->dpp_pkex_code, hapd->dpp_pkex_code_len, v2);
389           if (!pkex)
390                     return -1;
391           pkex->forced_ver = ver != PKEX_VER_AUTO;
392 
393           if (ipaddr) {
394 #ifdef CONFIG_DPP2
395                     return dpp_tcp_pkex_init(hapd->iface->interfaces->dpp, pkex,
396                                                    ipaddr, tcp_port,
397                                                    hapd->msg_ctx, hapd,
398                                                    hostapd_dpp_pkex_done);
399 #else /* CONFIG_DPP2 */
400                     return -1;
401 #endif /* CONFIG_DPP2 */
402           }
403 
404           hapd->dpp_pkex = pkex;
405           msg = hapd->dpp_pkex->exchange_req;
406           wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
407           pkex->freq = 2437;
408           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
409                     " freq=%u type=%d", MAC2STR(broadcast), pkex->freq,
410                     v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
411                     DPP_PA_PKEX_V1_EXCHANGE_REQ);
412           hostapd_drv_send_action(hapd, pkex->freq, 0, broadcast,
413                                         wpabuf_head(msg), wpabuf_len(msg));
414           pkex->exch_req_wait_time = wait_time;
415           pkex->exch_req_tries = 1;
416 
417           return 0;
418 }
419 
420 
hostapd_dpp_pkex_retry_timeout(void * eloop_ctx,void * timeout_ctx)421 static void hostapd_dpp_pkex_retry_timeout(void *eloop_ctx, void *timeout_ctx)
422 {
423           struct hostapd_data *hapd = eloop_ctx;
424           struct dpp_pkex *pkex = hapd->dpp_pkex;
425 
426           if (!pkex || !pkex->exchange_req)
427                     return;
428           if (pkex->exch_req_tries >= 5) {
429                     if (hostapd_dpp_pkex_next_channel(hapd, pkex) < 0) {
430 #ifdef CONFIG_DPP3
431                               if (pkex->v2 && !pkex->forced_ver) {
432                                         wpa_printf(MSG_DEBUG,
433                                                      "DPP: Fall back to PKEXv1");
434                                         hostapd_dpp_pkex_init(hapd, PKEX_VER_ONLY_1,
435                                                                   NULL, 0);
436                                         return;
437                               }
438 #endif /* CONFIG_DPP3 */
439                               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
440                                         "No response from PKEX peer");
441                               dpp_pkex_free(pkex);
442                               hapd->dpp_pkex = NULL;
443                               return;
444                     }
445                     pkex->exch_req_tries = 0;
446           }
447 
448           pkex->exch_req_tries++;
449           wpa_printf(MSG_DEBUG, "DPP: Retransmit PKEX Exchange Request (try %u)",
450                        pkex->exch_req_tries);
451           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
452                     " freq=%u type=%d",
453                     MAC2STR(broadcast), pkex->freq,
454                     pkex->v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
455                     DPP_PA_PKEX_V1_EXCHANGE_REQ);
456           hostapd_drv_send_action(hapd, pkex->freq, pkex->exch_req_wait_time,
457                                         broadcast,
458                                         wpabuf_head(pkex->exchange_req),
459                                         wpabuf_len(pkex->exchange_req));
460 }
461 
462 
hostapd_dpp_pkex_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)463 static void hostapd_dpp_pkex_tx_status(struct hostapd_data *hapd, const u8 *dst,
464                                                const u8 *data, size_t data_len, int ok)
465 {
466           struct dpp_pkex *pkex = hapd->dpp_pkex;
467 
468           if (pkex->failed) {
469                     wpa_printf(MSG_DEBUG,
470                                  "DPP: Terminate PKEX exchange due to an earlier error");
471                     if (pkex->t > pkex->own_bi->pkex_t)
472                               pkex->own_bi->pkex_t = pkex->t;
473                     dpp_pkex_free(pkex);
474                     hapd->dpp_pkex = NULL;
475                     return;
476           }
477 
478           if (pkex->exch_req_wait_time && pkex->exchange_req) {
479                     /* Wait for PKEX Exchange Response frame and retry request if
480                      * no response is seen. */
481                     eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd,
482                                              NULL);
483                     eloop_register_timeout(pkex->exch_req_wait_time / 1000,
484                                                (pkex->exch_req_wait_time % 1000) * 1000,
485                                                hostapd_dpp_pkex_retry_timeout, hapd,
486                                                NULL);
487           }
488 }
489 
490 
hostapd_dpp_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)491 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
492                                  const u8 *data, size_t data_len, int ok)
493 {
494           struct dpp_authentication *auth = hapd->dpp_auth;
495 
496           wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
497                        MAC2STR(dst), ok);
498           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
499                     " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
500 
501           if (!hapd->dpp_auth) {
502                     if (hapd->dpp_pkex) {
503                               hostapd_dpp_pkex_tx_status(hapd, dst, data, data_len,
504                                                                ok);
505                               return;
506                     }
507                     wpa_printf(MSG_DEBUG,
508                                  "DPP: Ignore TX status since there is no ongoing authentication exchange");
509                     return;
510           }
511 
512 #ifdef CONFIG_DPP2
513           if (auth->connect_on_tx_status) {
514                     wpa_printf(MSG_DEBUG,
515                                  "DPP: Complete exchange on configuration result");
516                     dpp_auth_deinit(hapd->dpp_auth);
517                     hapd->dpp_auth = NULL;
518                     return;
519           }
520 #endif /* CONFIG_DPP2 */
521 
522           if (hapd->dpp_auth->remove_on_tx_status) {
523                     wpa_printf(MSG_DEBUG,
524                                  "DPP: Terminate authentication exchange due to an earlier error");
525                     eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
526                     eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
527                                              hapd, NULL);
528                     eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
529                                              hapd, NULL);
530                     eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
531                                              NULL);
532 #ifdef CONFIG_DPP2
533                     eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
534                                              hapd, NULL);
535 #endif /* CONFIG_DPP2 */
536                     hostapd_drv_send_action_cancel_wait(hapd);
537                     dpp_auth_deinit(hapd->dpp_auth);
538                     hapd->dpp_auth = NULL;
539                     return;
540           }
541 
542           if (hapd->dpp_auth_ok_on_ack) {
543                     hostapd_dpp_auth_success(hapd, 1);
544                     if (!hapd->dpp_auth) {
545                               /* The authentication session could have been removed in
546                                * some error cases, e.g., when starting GAS client and
547                                * failing to send the initial request. */
548                               return;
549                     }
550           }
551 
552           if (!is_broadcast_ether_addr(dst) && !ok) {
553                     wpa_printf(MSG_DEBUG,
554                                  "DPP: Unicast DPP Action frame was not ACKed");
555                     if (auth->waiting_auth_resp) {
556                               /* In case of DPP Authentication Request frame, move to
557                                * the next channel immediately. */
558                               hostapd_drv_send_action_cancel_wait(hapd);
559                               hostapd_dpp_auth_init_next(hapd);
560                               return;
561                     }
562                     if (auth->waiting_auth_conf) {
563                               hostapd_dpp_auth_resp_retry(hapd);
564                               return;
565                     }
566           }
567 
568           if (auth->waiting_auth_conf &&
569               auth->auth_resp_status == DPP_STATUS_OK) {
570                     /* Make sure we do not get stuck waiting for Auth Confirm
571                      * indefinitely after successfully transmitted Auth Response to
572                      * allow new authentication exchanges to be started. */
573                     eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd,
574                                              NULL);
575                     eloop_register_timeout(1, 0, hostapd_dpp_auth_conf_wait_timeout,
576                                                hapd, NULL);
577           }
578 
579           if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
580                     /* Allow timeout handling to stop iteration if no response is
581                      * received from a peer that has ACKed a request. */
582                     auth->auth_req_ack = 1;
583           }
584 
585           if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
586               hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
587                     wpa_printf(MSG_DEBUG,
588                                  "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
589                                  hapd->dpp_auth->curr_freq,
590                                  hapd->dpp_auth->neg_freq);
591                     hostapd_drv_send_action_cancel_wait(hapd);
592 
593                     if (hapd->dpp_auth->neg_freq !=
594                         (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
595                               /* TODO: Listen operation on non-operating channel */
596                               wpa_printf(MSG_INFO,
597                                            "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
598                                            hapd->dpp_auth->neg_freq, hapd->iface->freq);
599                     }
600           }
601 
602           if (hapd->dpp_auth_ok_on_ack)
603                     hapd->dpp_auth_ok_on_ack = 0;
604 }
605 
606 
hostapd_dpp_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)607 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
608 {
609           struct hostapd_data *hapd = eloop_ctx;
610           struct dpp_authentication *auth = hapd->dpp_auth;
611           unsigned int freq;
612           struct os_reltime now, diff;
613           unsigned int wait_time, diff_ms;
614 
615           if (!auth || !auth->waiting_auth_resp)
616                     return;
617 
618           wait_time = hapd->dpp_resp_wait_time ?
619                     hapd->dpp_resp_wait_time : 2000;
620           os_get_reltime(&now);
621           os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
622           diff_ms = diff.sec * 1000 + diff.usec / 1000;
623           wpa_printf(MSG_DEBUG,
624                        "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
625                        wait_time, diff_ms);
626 
627           if (auth->auth_req_ack && diff_ms >= wait_time) {
628                     /* Peer ACK'ed Authentication Request frame, but did not reply
629                      * with Authentication Response frame within two seconds. */
630                     wpa_printf(MSG_INFO,
631                                  "DPP: No response received from responder - stopping initiation attempt");
632                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
633                     hostapd_drv_send_action_cancel_wait(hapd);
634                     hostapd_dpp_listen_stop(hapd);
635                     dpp_auth_deinit(auth);
636                     hapd->dpp_auth = NULL;
637                     return;
638           }
639 
640           if (diff_ms >= wait_time) {
641                     /* Authentication Request frame was not ACK'ed and no reply
642                      * was receiving within two seconds. */
643                     wpa_printf(MSG_DEBUG,
644                                  "DPP: Continue Initiator channel iteration");
645                     hostapd_drv_send_action_cancel_wait(hapd);
646                     hostapd_dpp_listen_stop(hapd);
647                     hostapd_dpp_auth_init_next(hapd);
648                     return;
649           }
650 
651           /* Driver did not support 2000 ms long wait_time with TX command, so
652            * schedule listen operation to continue waiting for the response.
653            *
654            * DPP listen operations continue until stopped, so simply schedule a
655            * new call to this function at the point when the two second reply
656            * wait has expired. */
657           wait_time -= diff_ms;
658 
659           freq = auth->curr_freq;
660           if (auth->neg_freq > 0)
661                     freq = auth->neg_freq;
662           wpa_printf(MSG_DEBUG,
663                        "DPP: Continue reply wait on channel %u MHz for %u ms",
664                        freq, wait_time);
665           hapd->dpp_in_response_listen = 1;
666 
667           if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
668                     /* TODO: Listen operation on non-operating channel */
669                     wpa_printf(MSG_INFO,
670                                  "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
671                                  freq, hapd->iface->freq);
672           }
673 
674           eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
675                                      hostapd_dpp_reply_wait_timeout, hapd, NULL);
676 }
677 
678 
hostapd_dpp_auth_conf_wait_timeout(void * eloop_ctx,void * timeout_ctx)679 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
680                                                          void *timeout_ctx)
681 {
682           struct hostapd_data *hapd = eloop_ctx;
683           struct dpp_authentication *auth = hapd->dpp_auth;
684 
685           if (!auth || !auth->waiting_auth_conf)
686                     return;
687 
688           wpa_printf(MSG_DEBUG,
689                        "DPP: Terminate authentication exchange due to Auth Confirm timeout");
690           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
691                     "No Auth Confirm received");
692           hostapd_drv_send_action_cancel_wait(hapd);
693           dpp_auth_deinit(auth);
694           hapd->dpp_auth = NULL;
695 }
696 
697 
hostapd_dpp_set_testing_options(struct hostapd_data * hapd,struct dpp_authentication * auth)698 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
699                                                       struct dpp_authentication *auth)
700 {
701 #ifdef CONFIG_TESTING_OPTIONS
702           if (hapd->dpp_config_obj_override)
703                     auth->config_obj_override =
704                               os_strdup(hapd->dpp_config_obj_override);
705           if (hapd->dpp_discovery_override)
706                     auth->discovery_override =
707                               os_strdup(hapd->dpp_discovery_override);
708           if (hapd->dpp_groups_override)
709                     auth->groups_override = os_strdup(hapd->dpp_groups_override);
710           auth->ignore_netaccesskey_mismatch =
711                     hapd->dpp_ignore_netaccesskey_mismatch;
712 #endif /* CONFIG_TESTING_OPTIONS */
713 }
714 
715 
hostapd_dpp_init_timeout(void * eloop_ctx,void * timeout_ctx)716 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
717 {
718           struct hostapd_data *hapd = eloop_ctx;
719 
720           if (!hapd->dpp_auth)
721                     return;
722           wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
723           hostapd_dpp_auth_init_next(hapd);
724 }
725 
726 
hostapd_dpp_auth_init_next(struct hostapd_data * hapd)727 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
728 {
729           struct dpp_authentication *auth = hapd->dpp_auth;
730           const u8 *dst;
731           unsigned int wait_time, max_wait_time, freq, max_tries, used;
732           struct os_reltime now, diff;
733 
734           if (!auth)
735                     return -1;
736 
737           if (auth->freq_idx == 0)
738                     os_get_reltime(&hapd->dpp_init_iter_start);
739 
740           if (auth->freq_idx >= auth->num_freq) {
741                     auth->num_freq_iters++;
742                     if (hapd->dpp_init_max_tries)
743                               max_tries = hapd->dpp_init_max_tries;
744                     else
745                               max_tries = 5;
746                     if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
747                               wpa_printf(MSG_INFO,
748                                            "DPP: No response received from responder - stopping initiation attempt");
749                               wpa_msg(hapd->msg_ctx, MSG_INFO,
750                                         DPP_EVENT_AUTH_INIT_FAILED);
751                               eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
752                                                        hapd, NULL);
753                               hostapd_drv_send_action_cancel_wait(hapd);
754                               dpp_auth_deinit(hapd->dpp_auth);
755                               hapd->dpp_auth = NULL;
756                               return -1;
757                     }
758                     auth->freq_idx = 0;
759                     eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
760                     if (hapd->dpp_init_retry_time)
761                               wait_time = hapd->dpp_init_retry_time;
762                     else
763                               wait_time = 10000;
764                     os_get_reltime(&now);
765                     os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
766                     used = diff.sec * 1000 + diff.usec / 1000;
767                     if (used > wait_time)
768                               wait_time = 0;
769                     else
770                               wait_time -= used;
771                     wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
772                                  wait_time);
773                     eloop_register_timeout(wait_time / 1000,
774                                                (wait_time % 1000) * 1000,
775                                                hostapd_dpp_init_timeout, hapd,
776                                                NULL);
777                     return 0;
778           }
779           freq = auth->freq[auth->freq_idx++];
780           auth->curr_freq = freq;
781 
782           if (!is_zero_ether_addr(auth->peer_mac_addr))
783                     dst = auth->peer_mac_addr;
784           else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
785                     dst = broadcast;
786           else
787                     dst = auth->peer_bi->mac_addr;
788           hapd->dpp_auth_ok_on_ack = 0;
789           eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
790           wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
791           max_wait_time = hapd->dpp_resp_wait_time ?
792                     hapd->dpp_resp_wait_time : 2000;
793           if (wait_time > max_wait_time)
794                     wait_time = max_wait_time;
795           wait_time += 10; /* give the driver some extra time to complete */
796           eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
797                                      hostapd_dpp_reply_wait_timeout, hapd, NULL);
798           wait_time -= 10;
799           if (auth->neg_freq > 0 && freq != auth->neg_freq) {
800                     wpa_printf(MSG_DEBUG,
801                                  "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
802                                  freq, auth->neg_freq);
803           }
804           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
805                     " freq=%u type=%d",
806                     MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
807           auth->auth_req_ack = 0;
808           os_get_reltime(&hapd->dpp_last_init);
809           return hostapd_drv_send_action(hapd, freq, wait_time,
810                                                dst,
811                                                wpabuf_head(hapd->dpp_auth->req_msg),
812                                                wpabuf_len(hapd->dpp_auth->req_msg));
813 }
814 
815 
816 #ifdef CONFIG_DPP2
hostapd_dpp_process_conf_obj(void * ctx,struct dpp_authentication * auth)817 static int hostapd_dpp_process_conf_obj(void *ctx,
818                                              struct dpp_authentication *auth)
819 {
820           struct hostapd_data *hapd = ctx;
821           unsigned int i;
822 
823           for (i = 0; i < auth->num_conf_obj; i++)
824                     hostapd_dpp_handle_config_obj(hapd, auth,
825                                                         &auth->conf_obj[i]);
826 
827           return 0;
828 }
829 #endif /* CONFIG_DPP2 */
830 
831 
hostapd_dpp_auth_init(struct hostapd_data * hapd,const char * cmd)832 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
833 {
834           const char *pos;
835           struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
836           struct dpp_authentication *auth;
837           u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
838           unsigned int neg_freq = 0;
839           int tcp = 0;
840 #ifdef CONFIG_DPP2
841           int tcp_port = DPP_TCP_PORT;
842           struct hostapd_ip_addr ipaddr;
843           char *addr;
844 #endif /* CONFIG_DPP2 */
845 
846           pos = os_strstr(cmd, " peer=");
847           if (!pos)
848                     return -1;
849           pos += 6;
850           peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
851           if (!peer_bi) {
852                     wpa_printf(MSG_INFO,
853                                  "DPP: Could not find bootstrapping info for the identified peer");
854                     return -1;
855           }
856 
857 #ifdef CONFIG_DPP2
858           pos = os_strstr(cmd, " tcp_port=");
859           if (pos) {
860                     pos += 10;
861                     tcp_port = atoi(pos);
862           }
863 
864           addr = get_param(cmd, " tcp_addr=");
865           if (addr && os_strcmp(addr, "from-uri") == 0) {
866                     os_free(addr);
867                     if (!peer_bi->host) {
868                               wpa_printf(MSG_INFO,
869                                            "DPP: TCP address not available in peer URI");
870                               return -1;
871                     }
872                     tcp = 1;
873                     os_memcpy(&ipaddr, peer_bi->host, sizeof(ipaddr));
874                     tcp_port = peer_bi->port;
875           } else if (addr) {
876                     int res;
877 
878                     res = hostapd_parse_ip_addr(addr, &ipaddr);
879                     os_free(addr);
880                     if (res)
881                               return -1;
882                     tcp = 1;
883           }
884 #endif /* CONFIG_DPP2 */
885 
886           pos = os_strstr(cmd, " own=");
887           if (pos) {
888                     pos += 5;
889                     own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
890                                                         atoi(pos));
891                     if (!own_bi) {
892                               wpa_printf(MSG_INFO,
893                                            "DPP: Could not find bootstrapping info for the identified local entry");
894                               return -1;
895                     }
896 
897                     if (peer_bi->curve != own_bi->curve) {
898                               wpa_printf(MSG_INFO,
899                                            "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
900                                            peer_bi->curve->name, own_bi->curve->name);
901                               return -1;
902                     }
903           }
904 
905           pos = os_strstr(cmd, " role=");
906           if (pos) {
907                     pos += 6;
908                     if (os_strncmp(pos, "configurator", 12) == 0)
909                               allowed_roles = DPP_CAPAB_CONFIGURATOR;
910                     else if (os_strncmp(pos, "enrollee", 8) == 0)
911                               allowed_roles = DPP_CAPAB_ENROLLEE;
912                     else if (os_strncmp(pos, "either", 6) == 0)
913                               allowed_roles = DPP_CAPAB_CONFIGURATOR |
914                                         DPP_CAPAB_ENROLLEE;
915                     else
916                               goto fail;
917           }
918 
919           pos = os_strstr(cmd, " neg_freq=");
920           if (pos)
921                     neg_freq = atoi(pos + 10);
922 
923           if (!tcp && hapd->dpp_auth) {
924                     eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
925                     eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
926                                              hapd, NULL);
927                     eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
928                                              hapd, NULL);
929                     eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
930                                              NULL);
931 #ifdef CONFIG_DPP2
932                     eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
933                                              hapd, NULL);
934 #endif /* CONFIG_DPP2 */
935                     hostapd_drv_send_action_cancel_wait(hapd);
936                     dpp_auth_deinit(hapd->dpp_auth);
937           }
938 
939           auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
940                                    peer_bi, own_bi, allowed_roles, neg_freq,
941                                    hapd->iface->hw_features,
942                                    hapd->iface->num_hw_features);
943           if (!auth)
944                     goto fail;
945           hostapd_dpp_set_testing_options(hapd, auth);
946           if (dpp_set_configurator(auth, cmd) < 0) {
947                     dpp_auth_deinit(auth);
948                     goto fail;
949           }
950 
951           auth->neg_freq = neg_freq;
952 
953           if (!is_zero_ether_addr(peer_bi->mac_addr))
954                     os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
955 
956 #ifdef CONFIG_DPP2
957           if (tcp)
958                     return dpp_tcp_init(hapd->iface->interfaces->dpp, auth,
959                                             &ipaddr, tcp_port, hapd->conf->dpp_name,
960                                             DPP_NETROLE_AP, hapd->conf->dpp_mud_url,
961                                             hapd->conf->dpp_extra_conf_req_name,
962                                             hapd->conf->dpp_extra_conf_req_value,
963                                             hapd->msg_ctx, hapd,
964                                             hostapd_dpp_process_conf_obj, NULL);
965 #endif /* CONFIG_DPP2 */
966 
967           hapd->dpp_auth = auth;
968           return hostapd_dpp_auth_init_next(hapd);
969 fail:
970           return -1;
971 }
972 
973 
hostapd_dpp_listen(struct hostapd_data * hapd,const char * cmd)974 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
975 {
976           int freq;
977 
978           freq = atoi(cmd);
979           if (freq <= 0)
980                     return -1;
981 
982           if (os_strstr(cmd, " role=configurator"))
983                     hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
984           else if (os_strstr(cmd, " role=enrollee"))
985                     hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
986           else
987                     hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
988                               DPP_CAPAB_ENROLLEE;
989           hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
990 
991           if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
992                     /* TODO: Listen operation on non-operating channel */
993                     wpa_printf(MSG_INFO,
994                                  "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
995                                  freq, hapd->iface->freq);
996                     return -1;
997           }
998 
999           hostapd_drv_dpp_listen(hapd, true);
1000           return 0;
1001 }
1002 
1003 
hostapd_dpp_listen_stop(struct hostapd_data * hapd)1004 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
1005 {
1006           hostapd_drv_dpp_listen(hapd, false);
1007           /* TODO: Stop listen operation on non-operating channel */
1008 }
1009 
1010 
1011 #ifdef CONFIG_DPP2
1012 static void
hostapd_dpp_relay_needs_controller(struct hostapd_data * hapd,const u8 * src,enum dpp_public_action_frame_type type)1013 hostapd_dpp_relay_needs_controller(struct hostapd_data *hapd, const u8 *src,
1014                                            enum dpp_public_action_frame_type type)
1015 {
1016           struct os_reltime now;
1017 
1018           if (!hapd->conf->dpp_relay_port)
1019                     return;
1020 
1021           os_get_reltime(&now);
1022           if (hapd->dpp_relay_last_needs_ctrl.sec &&
1023               !os_reltime_expired(&now, &hapd->dpp_relay_last_needs_ctrl, 60))
1024                     return;
1025           hapd->dpp_relay_last_needs_ctrl = now;
1026           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RELAY_NEEDS_CONTROLLER
1027                     MACSTR " %u", MAC2STR(src), type);
1028 }
1029 #endif /* CONFIG_DPP2 */
1030 
1031 
hostapd_dpp_rx_auth_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1032 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
1033                                             const u8 *hdr, const u8 *buf, size_t len,
1034                                             unsigned int freq)
1035 {
1036           const u8 *r_bootstrap, *i_bootstrap;
1037           u16 r_bootstrap_len, i_bootstrap_len;
1038           struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
1039 
1040           if (!hapd->iface->interfaces->dpp)
1041                     return;
1042 
1043           wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
1044                        MAC2STR(src));
1045 
1046 #ifdef CONFIG_DPP2
1047           hostapd_dpp_chirp_stop(hapd);
1048 #endif /* CONFIG_DPP2 */
1049 
1050           r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1051                                            &r_bootstrap_len);
1052           if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1053                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1054                               "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1055                     return;
1056           }
1057           wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1058                         r_bootstrap, r_bootstrap_len);
1059 
1060           i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
1061                                            &i_bootstrap_len);
1062           if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
1063                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1064                               "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
1065                     return;
1066           }
1067           wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
1068                         i_bootstrap, i_bootstrap_len);
1069 
1070           /* Try to find own and peer bootstrapping key matches based on the
1071            * received hash values */
1072           dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
1073                                         r_bootstrap, &own_bi, &peer_bi);
1074 #ifdef CONFIG_DPP2
1075           if (!own_bi) {
1076                     if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1077                                                   src, hdr, buf, len, freq, i_bootstrap,
1078                                                   r_bootstrap, hapd) == 0)
1079                               return;
1080                     hostapd_dpp_relay_needs_controller(hapd, src,
1081                                                                DPP_PA_AUTHENTICATION_REQ);
1082           }
1083 #endif /* CONFIG_DPP2 */
1084           if (!own_bi) {
1085                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1086                               "No matching own bootstrapping key found - ignore message");
1087                     return;
1088           }
1089 
1090           if (own_bi->type == DPP_BOOTSTRAP_PKEX) {
1091                     if (!peer_bi || peer_bi->type != DPP_BOOTSTRAP_PKEX) {
1092                               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1093                                         "No matching peer bootstrapping key found for PKEX - ignore message");
1094                               return;
1095                     }
1096 
1097                     if (os_memcmp(peer_bi->pubkey_hash, own_bi->peer_pubkey_hash,
1098                                     SHA256_MAC_LEN) != 0) {
1099                               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1100                                         "Mismatching peer PKEX bootstrapping key - ignore message");
1101                               return;
1102                     }
1103           }
1104 
1105           if (hapd->dpp_auth) {
1106                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1107                               "Already in DPP authentication exchange - ignore new one");
1108                     return;
1109           }
1110 
1111           hapd->dpp_auth_ok_on_ack = 0;
1112           hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
1113                                                    hapd->msg_ctx, hapd->dpp_allowed_roles,
1114                                                    hapd->dpp_qr_mutual,
1115                                                    peer_bi, own_bi, freq, hdr, buf, len);
1116           if (!hapd->dpp_auth) {
1117                     wpa_printf(MSG_DEBUG, "DPP: No response generated");
1118                     return;
1119           }
1120           hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
1121           if (dpp_set_configurator(hapd->dpp_auth,
1122                                          hapd->dpp_configurator_params) < 0) {
1123                     dpp_auth_deinit(hapd->dpp_auth);
1124                     hapd->dpp_auth = NULL;
1125                     return;
1126           }
1127           os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
1128 
1129           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1130                     " freq=%u type=%d",
1131                     MAC2STR(src), hapd->dpp_auth->curr_freq,
1132                     DPP_PA_AUTHENTICATION_RESP);
1133           hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
1134                                         src, wpabuf_head(hapd->dpp_auth->resp_msg),
1135                                         wpabuf_len(hapd->dpp_auth->resp_msg));
1136 }
1137 
1138 
hostapd_dpp_handle_config_obj(struct hostapd_data * hapd,struct dpp_authentication * auth,struct dpp_config_obj * conf)1139 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
1140                                                     struct dpp_authentication *auth,
1141                                                     struct dpp_config_obj *conf)
1142 {
1143           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
1144           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
1145                     dpp_akm_str(conf->akm));
1146           if (conf->ssid_len)
1147                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
1148                               wpa_ssid_txt(conf->ssid, conf->ssid_len));
1149           if (conf->connector) {
1150                     /* TODO: Save the Connector and consider using a command
1151                      * to fetch the value instead of sending an event with
1152                      * it. The Connector could end up being larger than what
1153                      * most clients are ready to receive as an event
1154                      * message. */
1155                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
1156                               conf->connector);
1157           }
1158           if (conf->passphrase[0]) {
1159                     char hex[64 * 2 + 1];
1160 
1161                     wpa_snprintf_hex(hex, sizeof(hex),
1162                                          (const u8 *) conf->passphrase,
1163                                          os_strlen(conf->passphrase));
1164                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
1165                               hex);
1166           } else if (conf->psk_set) {
1167                     char hex[PMK_LEN * 2 + 1];
1168 
1169                     wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
1170                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
1171                               hex);
1172           }
1173           if (conf->c_sign_key) {
1174                     char *hex;
1175                     size_t hexlen;
1176 
1177                     hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
1178                     hex = os_malloc(hexlen);
1179                     if (hex) {
1180                               wpa_snprintf_hex(hex, hexlen,
1181                                                    wpabuf_head(conf->c_sign_key),
1182                                                    wpabuf_len(conf->c_sign_key));
1183                               wpa_msg(hapd->msg_ctx, MSG_INFO,
1184                                         DPP_EVENT_C_SIGN_KEY "%s", hex);
1185                               os_free(hex);
1186                     }
1187           }
1188           if (auth->net_access_key) {
1189                     char *hex;
1190                     size_t hexlen;
1191 
1192                     hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
1193                     hex = os_malloc(hexlen);
1194                     if (hex) {
1195                               wpa_snprintf_hex(hex, hexlen,
1196                                                    wpabuf_head(auth->net_access_key),
1197                                                    wpabuf_len(auth->net_access_key));
1198                               if (auth->net_access_key_expiry)
1199                                         wpa_msg(hapd->msg_ctx, MSG_INFO,
1200                                                   DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
1201                                                   (unsigned long)
1202                                                   auth->net_access_key_expiry);
1203                               else
1204                                         wpa_msg(hapd->msg_ctx, MSG_INFO,
1205                                                   DPP_EVENT_NET_ACCESS_KEY "%s", hex);
1206                               os_free(hex);
1207                     }
1208           }
1209 }
1210 
1211 
hostapd_dpp_handle_key_pkg(struct hostapd_data * hapd,struct dpp_asymmetric_key * key)1212 static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
1213                                               struct dpp_asymmetric_key *key)
1214 {
1215 #ifdef CONFIG_DPP2
1216           int res;
1217 
1218           if (!key)
1219                     return 0;
1220 
1221           wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
1222           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
1223 
1224           while (key) {
1225                     res = dpp_configurator_from_backup(
1226                               hapd->iface->interfaces->dpp, key);
1227                     if (res < 0)
1228                               return -1;
1229                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
1230                               res);
1231                     key = key->next;
1232           }
1233 #endif /* CONFIG_DPP2 */
1234 
1235           return 0;
1236 }
1237 
1238 
1239 #ifdef CONFIG_DPP3
hostapd_dpp_build_new_key(void * eloop_ctx,void * timeout_ctx)1240 static void hostapd_dpp_build_new_key(void *eloop_ctx, void *timeout_ctx)
1241 {
1242           struct hostapd_data *hapd = eloop_ctx;
1243           struct dpp_authentication *auth = hapd->dpp_auth;
1244 
1245           if (!auth || !auth->waiting_new_key)
1246                     return;
1247 
1248           wpa_printf(MSG_DEBUG, "DPP: Build config request with a new key");
1249           hostapd_dpp_start_gas_client(hapd);
1250 }
1251 #endif /* CONFIG_DPP3 */
1252 
1253 
hostapd_dpp_gas_resp_cb(void * ctx,const u8 * addr,u8 dialog_token,enum gas_query_ap_result result,const struct wpabuf * adv_proto,const struct wpabuf * resp,u16 status_code)1254 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
1255                                             enum gas_query_ap_result result,
1256                                             const struct wpabuf *adv_proto,
1257                                             const struct wpabuf *resp, u16 status_code)
1258 {
1259           struct hostapd_data *hapd = ctx;
1260           const u8 *pos;
1261           struct dpp_authentication *auth = hapd->dpp_auth;
1262           enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
1263           int res;
1264 
1265           if (!auth || !auth->auth_success) {
1266                     wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1267                     return;
1268           }
1269           if (result != GAS_QUERY_AP_SUCCESS ||
1270               !resp || status_code != WLAN_STATUS_SUCCESS) {
1271                     wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
1272                     goto fail;
1273           }
1274 
1275           wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
1276                               adv_proto);
1277           wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
1278                               resp);
1279 
1280           if (wpabuf_len(adv_proto) != 10 ||
1281               !(pos = wpabuf_head(adv_proto)) ||
1282               pos[0] != WLAN_EID_ADV_PROTO ||
1283               pos[1] != 8 ||
1284               pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
1285               pos[4] != 5 ||
1286               WPA_GET_BE24(&pos[5]) != OUI_WFA ||
1287               pos[8] != 0x1a ||
1288               pos[9] != 1) {
1289                     wpa_printf(MSG_DEBUG,
1290                                  "DPP: Not a DPP Advertisement Protocol ID");
1291                     goto fail;
1292           }
1293 
1294           res = dpp_conf_resp_rx(auth, resp);
1295 #ifdef CONFIG_DPP3
1296           if (res == -3) {
1297                     wpa_printf(MSG_DEBUG, "DPP: New protocol key needed");
1298                     eloop_register_timeout(0, 0, hostapd_dpp_build_new_key, hapd,
1299                                                NULL);
1300                     return;
1301           }
1302 #endif /* CONFIG_DPP3 */
1303           if (res < 0) {
1304                     wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
1305                     goto fail;
1306           }
1307 
1308           hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
1309           if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
1310                     goto fail;
1311 
1312           status = DPP_STATUS_OK;
1313 #ifdef CONFIG_TESTING_OPTIONS
1314           if (dpp_test == DPP_TEST_REJECT_CONFIG) {
1315                     wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
1316                     status = DPP_STATUS_CONFIG_REJECTED;
1317           }
1318 #endif /* CONFIG_TESTING_OPTIONS */
1319 fail:
1320           if (status != DPP_STATUS_OK)
1321                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1322 #ifdef CONFIG_DPP2
1323           if (auth->peer_version >= 2 &&
1324               auth->conf_resp_status == DPP_STATUS_OK) {
1325                     struct wpabuf *msg;
1326 
1327                     wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
1328                     msg = dpp_build_conf_result(auth, status);
1329                     if (!msg)
1330                               goto fail2;
1331 
1332                     wpa_msg(hapd->msg_ctx, MSG_INFO,
1333                               DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
1334                               MAC2STR(addr), auth->curr_freq,
1335                               DPP_PA_CONFIGURATION_RESULT);
1336                     hostapd_drv_send_action(hapd, auth->curr_freq, 0,
1337                                                   addr, wpabuf_head(msg),
1338                                                   wpabuf_len(msg));
1339                     wpabuf_free(msg);
1340 
1341                     /* This exchange will be terminated in the TX status handler */
1342                     auth->connect_on_tx_status = 1;
1343                     return;
1344           }
1345 fail2:
1346 #endif /* CONFIG_DPP2 */
1347           dpp_auth_deinit(hapd->dpp_auth);
1348           hapd->dpp_auth = NULL;
1349 }
1350 
1351 
hostapd_dpp_start_gas_client(struct hostapd_data * hapd)1352 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
1353 {
1354           struct dpp_authentication *auth = hapd->dpp_auth;
1355           struct wpabuf *buf;
1356           int res;
1357 
1358           buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
1359                                                   DPP_NETROLE_AP,
1360                                                   hapd->conf->dpp_mud_url, NULL,
1361                                                   hapd->conf->dpp_extra_conf_req_name,
1362                                                   hapd->conf->dpp_extra_conf_req_value);
1363           if (!buf) {
1364                     wpa_printf(MSG_DEBUG,
1365                                  "DPP: No configuration request data available");
1366                     return;
1367           }
1368 
1369           wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
1370                        MAC2STR(auth->peer_mac_addr), auth->curr_freq);
1371 
1372           res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
1373                                      buf, hostapd_dpp_gas_resp_cb, hapd);
1374           if (res < 0) {
1375                     wpa_msg(hapd->msg_ctx, MSG_DEBUG,
1376                               "GAS: Failed to send Query Request");
1377                     wpabuf_free(buf);
1378           } else {
1379                     wpa_printf(MSG_DEBUG,
1380                                  "DPP: GAS query started with dialog token %u", res);
1381           }
1382 }
1383 
1384 
hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)1385 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
1386 {
1387           wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
1388           dpp_notify_auth_success(hapd->dpp_auth, initiator);
1389 #ifdef CONFIG_TESTING_OPTIONS
1390           if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1391                     wpa_printf(MSG_INFO,
1392                                  "DPP: TESTING - stop at Authentication Confirm");
1393                     if (hapd->dpp_auth->configurator) {
1394                               /* Prevent GAS response */
1395                               hapd->dpp_auth->auth_success = 0;
1396                     }
1397                     return;
1398           }
1399 #endif /* CONFIG_TESTING_OPTIONS */
1400 
1401           if (!hapd->dpp_auth->configurator)
1402                     hostapd_dpp_start_gas_client(hapd);
1403 }
1404 
1405 
hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1406 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
1407                                              const u8 *hdr, const u8 *buf, size_t len,
1408                                              unsigned int freq)
1409 {
1410           struct dpp_authentication *auth = hapd->dpp_auth;
1411           struct wpabuf *msg;
1412 
1413           wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
1414                        MAC2STR(src));
1415 
1416           if (!auth) {
1417                     wpa_printf(MSG_DEBUG,
1418                                  "DPP: No DPP Authentication in progress - drop");
1419                     return;
1420           }
1421 
1422           if (!is_zero_ether_addr(auth->peer_mac_addr) &&
1423               !ether_addr_equal(src, auth->peer_mac_addr)) {
1424                     wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1425                                  MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1426                     return;
1427           }
1428 
1429           eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1430 
1431           if (auth->curr_freq != freq && auth->neg_freq == freq) {
1432                     wpa_printf(MSG_DEBUG,
1433                                  "DPP: Responder accepted request for different negotiation channel");
1434                     auth->curr_freq = freq;
1435           }
1436 
1437           eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1438           msg = dpp_auth_resp_rx(auth, hdr, buf, len);
1439           if (!msg) {
1440                     if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
1441                               wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
1442                               return;
1443                     }
1444                     wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
1445                     return;
1446           }
1447           os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1448 
1449           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1450                     " freq=%u type=%d", MAC2STR(src), auth->curr_freq,
1451                     DPP_PA_AUTHENTICATION_CONF);
1452           hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
1453                                         wpabuf_head(msg), wpabuf_len(msg));
1454           wpabuf_free(msg);
1455           hapd->dpp_auth_ok_on_ack = 1;
1456 }
1457 
1458 
hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1459 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
1460                                              const u8 *hdr, const u8 *buf, size_t len)
1461 {
1462           struct dpp_authentication *auth = hapd->dpp_auth;
1463 
1464           wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
1465                        MAC2STR(src));
1466 
1467           if (!auth) {
1468                     wpa_printf(MSG_DEBUG,
1469                                  "DPP: No DPP Authentication in progress - drop");
1470                     return;
1471           }
1472 
1473           if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1474                     wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1475                                  MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1476                     return;
1477           }
1478 
1479           if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1480                     wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1481                     return;
1482           }
1483 
1484           hostapd_dpp_auth_success(hapd, 0);
1485 }
1486 
1487 
1488 #ifdef CONFIG_DPP2
1489 
hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1490 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1491                                                                void *timeout_ctx)
1492 {
1493           struct hostapd_data *hapd = eloop_ctx;
1494           struct dpp_authentication *auth = hapd->dpp_auth;
1495 
1496           if (!auth || !auth->waiting_conf_result)
1497                     return;
1498 
1499           wpa_printf(MSG_DEBUG,
1500                        "DPP: Timeout while waiting for Configuration Result");
1501           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1502           dpp_auth_deinit(auth);
1503           hapd->dpp_auth = NULL;
1504 }
1505 
1506 
hostapd_dpp_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1507 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1508                                                                       void *timeout_ctx)
1509 {
1510           struct hostapd_data *hapd = eloop_ctx;
1511           struct dpp_authentication *auth = hapd->dpp_auth;
1512 
1513           if (!auth || !auth->waiting_conf_result)
1514                     return;
1515 
1516           wpa_printf(MSG_DEBUG,
1517                        "DPP: Timeout while waiting for Connection Status Result");
1518           wpa_msg(hapd->msg_ctx, MSG_INFO,
1519                     DPP_EVENT_CONN_STATUS_RESULT "timeout");
1520           dpp_auth_deinit(auth);
1521           hapd->dpp_auth = NULL;
1522 }
1523 
1524 
1525 #ifdef CONFIG_DPP3
1526 
hostapd_dpp_pb_active(struct hostapd_data * hapd)1527 static bool hostapd_dpp_pb_active(struct hostapd_data *hapd)
1528 {
1529           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1530 
1531           return ifaces && (ifaces->dpp_pb_time.sec ||
1532                                 ifaces->dpp_pb_time.usec);
1533 }
1534 
1535 
hostapd_dpp_remove_pb_hash(struct hostapd_data * hapd)1536 static void hostapd_dpp_remove_pb_hash(struct hostapd_data *hapd)
1537 {
1538           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1539           int i;
1540 
1541           if (!ifaces->dpp_pb_bi)
1542                     return;
1543           for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
1544                     struct dpp_pb_info *info = &ifaces->dpp_pb[i];
1545 
1546                     if (info->rx_time.sec == 0 && info->rx_time.usec == 0)
1547                               continue;
1548                     if (os_memcmp(info->hash, ifaces->dpp_pb_resp_hash,
1549                                     SHA256_MAC_LEN) == 0) {
1550                               /* Allow a new push button session to be established
1551                                * immediately without the successfully completed
1552                                * session triggering session overlap. */
1553                               info->rx_time.sec = 0;
1554                               info->rx_time.usec = 0;
1555                               wpa_printf(MSG_DEBUG,
1556                                            "DPP: Removed PB hash from session overlap detection due to successfully completed provisioning");
1557                     }
1558           }
1559 }
1560 
1561 #endif /* CONFIG_DPP3 */
1562 
1563 
hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1564 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1565                                                const u8 *hdr, const u8 *buf, size_t len)
1566 {
1567           struct dpp_authentication *auth = hapd->dpp_auth;
1568           enum dpp_status_error status;
1569 #ifdef CONFIG_DPP3
1570           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
1571 #endif /* CONFIG_DPP3 */
1572 
1573           wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
1574                        MAC2STR(src));
1575 
1576           if (!auth || !auth->waiting_conf_result) {
1577                     wpa_printf(MSG_DEBUG,
1578                                  "DPP: No DPP Configuration waiting for result - drop");
1579                     return;
1580           }
1581 
1582           if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1583                     wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1584                                  MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1585                     return;
1586           }
1587 
1588           status = dpp_conf_result_rx(auth, hdr, buf, len);
1589 
1590           if (status == DPP_STATUS_OK && auth->send_conn_status) {
1591                     wpa_msg(hapd->msg_ctx, MSG_INFO,
1592                               DPP_EVENT_CONF_SENT "wait_conn_status=1 conf_status=%d",
1593                               auth->conf_resp_status);
1594                     wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1595                     eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1596                                              hapd, NULL);
1597                     auth->waiting_conn_status_result = 1;
1598                     eloop_cancel_timeout(
1599                               hostapd_dpp_conn_status_result_wait_timeout,
1600                               hapd, NULL);
1601                     eloop_register_timeout(
1602                               16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1603                               hapd, NULL);
1604                     return;
1605           }
1606           hostapd_drv_send_action_cancel_wait(hapd);
1607           hostapd_dpp_listen_stop(hapd);
1608           if (status == DPP_STATUS_OK)
1609                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
1610                               "conf_status=%d", auth->conf_resp_status);
1611           else
1612                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1613           dpp_auth_deinit(auth);
1614           hapd->dpp_auth = NULL;
1615           eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1616                                    NULL);
1617 #ifdef CONFIG_DPP3
1618           if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
1619                     if (status == DPP_STATUS_OK)
1620                               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1621                                         "success");
1622                     else
1623                               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
1624                                         "no-configuration-available");
1625                     ifaces->dpp_pb_result_indicated = true;
1626                     if (status == DPP_STATUS_OK)
1627                               hostapd_dpp_remove_pb_hash(hapd);
1628                     hostapd_dpp_push_button_stop(hapd);
1629           }
1630 #endif /* CONFIG_DPP3 */
1631 }
1632 
1633 
hostapd_dpp_rx_conn_status_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1634 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1635                                                         const u8 *src, const u8 *hdr,
1636                                                         const u8 *buf, size_t len)
1637 {
1638           struct dpp_authentication *auth = hapd->dpp_auth;
1639           enum dpp_status_error status;
1640           u8 ssid[SSID_MAX_LEN];
1641           size_t ssid_len = 0;
1642           char *channel_list = NULL;
1643 
1644           wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1645 
1646           if (!auth || !auth->waiting_conn_status_result) {
1647                     wpa_printf(MSG_DEBUG,
1648                                  "DPP: No DPP Configuration waiting for connection status result - drop");
1649                     return;
1650           }
1651 
1652           status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1653                                                      ssid, &ssid_len, &channel_list);
1654           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1655                     "result=%d ssid=%s channel_list=%s",
1656                     status, wpa_ssid_txt(ssid, ssid_len),
1657                     channel_list ? channel_list : "N/A");
1658           os_free(channel_list);
1659           hostapd_drv_send_action_cancel_wait(hapd);
1660           hostapd_dpp_listen_stop(hapd);
1661           dpp_auth_deinit(auth);
1662           hapd->dpp_auth = NULL;
1663           eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1664                                    hapd, NULL);
1665 }
1666 
1667 
1668 static void
hostapd_dpp_rx_presence_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1669 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1670                                              const u8 *hdr, const u8 *buf, size_t len,
1671                                              unsigned int freq)
1672 {
1673           const u8 *r_bootstrap;
1674           u16 r_bootstrap_len;
1675           struct dpp_bootstrap_info *peer_bi;
1676           struct dpp_authentication *auth;
1677 
1678           wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
1679                        MAC2STR(src));
1680 
1681           r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1682                                            &r_bootstrap_len);
1683           if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1684                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1685                               "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1686                     return;
1687           }
1688           wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1689                         r_bootstrap, r_bootstrap_len);
1690           peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1691                                                      r_bootstrap);
1692           dpp_notify_chirp_received(hapd->msg_ctx,
1693                                           peer_bi ? (int) peer_bi->id : -1,
1694                                           src, freq, r_bootstrap);
1695           if (!peer_bi) {
1696                     if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1697                                                   src, hdr, buf, len, freq, NULL,
1698                                                   r_bootstrap, hapd) == 0)
1699                               return;
1700                     wpa_printf(MSG_DEBUG,
1701                                  "DPP: No matching bootstrapping information found");
1702                     hostapd_dpp_relay_needs_controller(
1703                               hapd, src, DPP_PA_PRESENCE_ANNOUNCEMENT);
1704                     return;
1705           }
1706 
1707           if (hapd->dpp_auth) {
1708                     wpa_printf(MSG_DEBUG,
1709                                  "DPP: Ignore Presence Announcement during ongoing Authentication");
1710                     return;
1711           }
1712 
1713           auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1714                                    peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1715                                    0);
1716           if (!auth)
1717                     return;
1718           hostapd_dpp_set_testing_options(hapd, auth);
1719           if (dpp_set_configurator(auth,
1720                                          hapd->dpp_configurator_params) < 0) {
1721                     dpp_auth_deinit(auth);
1722                     return;
1723           }
1724 
1725           auth->neg_freq = freq;
1726 
1727           /* The source address of the Presence Announcement frame overrides any
1728            * MAC address information from the bootstrapping information. */
1729           os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1730 
1731           hapd->dpp_auth = auth;
1732           if (hostapd_dpp_auth_init_next(hapd) < 0) {
1733                     dpp_auth_deinit(hapd->dpp_auth);
1734                     hapd->dpp_auth = NULL;
1735           }
1736 }
1737 
1738 
hostapd_dpp_reconfig_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)1739 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
1740                                                                 void *timeout_ctx)
1741 {
1742           struct hostapd_data *hapd = eloop_ctx;
1743           struct dpp_authentication *auth = hapd->dpp_auth;
1744 
1745           if (!auth)
1746                     return;
1747 
1748           wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
1749           hostapd_dpp_listen_stop(hapd);
1750           dpp_auth_deinit(auth);
1751           hapd->dpp_auth = NULL;
1752 }
1753 
1754 
1755 static void
hostapd_dpp_rx_reconfig_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1756 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
1757                                              const u8 *hdr, const u8 *buf, size_t len,
1758                                              unsigned int freq)
1759 {
1760           const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1761           u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1762           struct dpp_configurator *conf;
1763           struct dpp_authentication *auth;
1764           unsigned int wait_time, max_wait_time;
1765           u16 group;
1766 
1767           if (hapd->dpp_auth) {
1768                     wpa_printf(MSG_DEBUG,
1769                                  "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1770                     return;
1771           }
1772 
1773           wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR,
1774                        MAC2STR(src));
1775 
1776           csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1777                                           &csign_hash_len);
1778           if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1779                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1780                               "Missing or invalid required Configurator C-sign key Hash attribute");
1781                     return;
1782           }
1783           wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1784                         csign_hash, csign_hash_len);
1785           conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp,
1786                                                    csign_hash);
1787           if (!conf) {
1788                     if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1789                                                   src, hdr, buf, len, freq, NULL,
1790                                                   NULL, hapd) == 0)
1791                               return;
1792                     wpa_printf(MSG_DEBUG,
1793                                  "DPP: No matching Configurator information found");
1794                     hostapd_dpp_relay_needs_controller(
1795                               hapd, src, DPP_PA_RECONFIG_ANNOUNCEMENT);
1796                     return;
1797           }
1798 
1799           fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1800                                      &fcgroup_len);
1801           if (!fcgroup || fcgroup_len != 2) {
1802                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1803                               "Missing or invalid required Finite Cyclic Group attribute");
1804                     return;
1805           }
1806           group = WPA_GET_LE16(fcgroup);
1807           wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1808 
1809           a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1810           e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1811 
1812           auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1813                                          conf, freq, group, a_nonce, a_nonce_len,
1814                                          e_id, e_id_len);
1815           if (!auth)
1816                     return;
1817           hostapd_dpp_set_testing_options(hapd, auth);
1818           if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
1819                     dpp_auth_deinit(auth);
1820                     return;
1821           }
1822 
1823           os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1824           hapd->dpp_auth = auth;
1825 
1826           hapd->dpp_in_response_listen = 0;
1827           hapd->dpp_auth_ok_on_ack = 0;
1828           wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
1829           max_wait_time = hapd->dpp_resp_wait_time ?
1830                     hapd->dpp_resp_wait_time : 2000;
1831           if (wait_time > max_wait_time)
1832                     wait_time = max_wait_time;
1833           wait_time += 10; /* give the driver some extra time to complete */
1834           eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
1835                                      hostapd_dpp_reconfig_reply_wait_timeout,
1836                                      hapd, NULL);
1837           wait_time -= 10;
1838 
1839           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1840                     " freq=%u type=%d",
1841                     MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
1842           if (hostapd_drv_send_action(hapd, freq, wait_time, src,
1843                                             wpabuf_head(auth->reconfig_req_msg),
1844                                             wpabuf_len(auth->reconfig_req_msg)) < 0) {
1845                     dpp_auth_deinit(hapd->dpp_auth);
1846                     hapd->dpp_auth = NULL;
1847           }
1848 }
1849 
1850 
1851 static void
hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1852 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src,
1853                                           const u8 *hdr, const u8 *buf, size_t len,
1854                                           unsigned int freq)
1855 {
1856           struct dpp_authentication *auth = hapd->dpp_auth;
1857           struct wpabuf *conf;
1858 
1859           wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
1860                        MACSTR, MAC2STR(src));
1861 
1862           if (!auth || !auth->reconfig || !auth->configurator) {
1863                     wpa_printf(MSG_DEBUG,
1864                                  "DPP: No DPP Reconfig Authentication in progress - drop");
1865                     return;
1866           }
1867 
1868           if (!ether_addr_equal(src, auth->peer_mac_addr)) {
1869                     wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1870                                  MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
1871                     return;
1872           }
1873 
1874           conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1875           if (!conf)
1876                     return;
1877 
1878           eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1879                                    hapd, NULL);
1880 
1881           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1882                     " freq=%u type=%d",
1883                     MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
1884           if (hostapd_drv_send_action(hapd, freq, 500, src,
1885                                             wpabuf_head(conf), wpabuf_len(conf)) < 0) {
1886                     wpabuf_free(conf);
1887                     dpp_auth_deinit(hapd->dpp_auth);
1888                     hapd->dpp_auth = NULL;
1889                     return;
1890           }
1891           wpabuf_free(conf);
1892 }
1893 
1894 #endif /* CONFIG_DPP2 */
1895 
1896 
hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)1897 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1898                                                       const u8 *src, unsigned int freq,
1899                                                       u8 trans_id,
1900                                                       enum dpp_status_error status)
1901 {
1902           struct wpabuf *msg;
1903           size_t len;
1904 
1905           len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
1906 #ifdef CONFIG_DPP2
1907           len += 5;
1908 #endif /* CONFIG_DPP2 */
1909           msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len);
1910           if (!msg)
1911                     return;
1912 
1913 #ifdef CONFIG_TESTING_OPTIONS
1914           if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1915                     wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1916                     goto skip_trans_id;
1917           }
1918           if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1919                     wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1920                     trans_id ^= 0x01;
1921           }
1922 #endif /* CONFIG_TESTING_OPTIONS */
1923 
1924           /* Transaction ID */
1925           wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1926           wpabuf_put_le16(msg, 1);
1927           wpabuf_put_u8(msg, trans_id);
1928 
1929 #ifdef CONFIG_TESTING_OPTIONS
1930 skip_trans_id:
1931           if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1932                     wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1933                     goto skip_status;
1934           }
1935           if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1936                     wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1937                     status = 254;
1938           }
1939 #endif /* CONFIG_TESTING_OPTIONS */
1940 
1941           /* DPP Status */
1942           wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1943           wpabuf_put_le16(msg, 1);
1944           wpabuf_put_u8(msg, status);
1945 
1946 #ifdef CONFIG_TESTING_OPTIONS
1947 skip_status:
1948           if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1949                     wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1950                     goto skip_connector;
1951           }
1952           if (status == DPP_STATUS_OK &&
1953               dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1954                     char *connector;
1955 
1956                     wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1957                     connector = dpp_corrupt_connector_signature(
1958                               hapd->conf->dpp_connector);
1959                     if (!connector) {
1960                               wpabuf_free(msg);
1961                               return;
1962                     }
1963                     wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1964                     wpabuf_put_le16(msg, os_strlen(connector));
1965                     wpabuf_put_str(msg, connector);
1966                     os_free(connector);
1967                     goto skip_connector;
1968           }
1969 #endif /* CONFIG_TESTING_OPTIONS */
1970 
1971           /* DPP Connector */
1972           if (status == DPP_STATUS_OK) {
1973                     wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1974                     wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1975                     wpabuf_put_str(msg, hapd->conf->dpp_connector);
1976           }
1977 
1978 #ifdef CONFIG_TESTING_OPTIONS
1979 skip_connector:
1980           if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) {
1981                     wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
1982                     goto skip_proto_ver;
1983           }
1984 #endif /* CONFIG_TESTING_OPTIONS */
1985 
1986 #ifdef CONFIG_DPP2
1987           if (DPP_VERSION > 1) {
1988                     u8 ver = DPP_VERSION;
1989 #ifdef CONFIG_DPP3
1990                     int conn_ver;
1991 
1992                     conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
1993                     if (conn_ver > 0 && ver != conn_ver) {
1994                               wpa_printf(MSG_DEBUG,
1995                                            "DPP: Use Connector version %d instead of current protocol version %d",
1996                                            conn_ver, ver);
1997                               ver = conn_ver;
1998                     }
1999 #endif /* CONFIG_DPP3 */
2000 
2001 #ifdef CONFIG_TESTING_OPTIONS
2002           if (dpp_test == DPP_TEST_INVALID_PROTOCOL_VERSION_PEER_DISC_RESP) {
2003                     wpa_printf(MSG_INFO, "DPP: TESTING - invalid Protocol Version");
2004                     ver = 1;
2005           }
2006 #endif /* CONFIG_TESTING_OPTIONS */
2007 
2008                     /* Protocol Version */
2009                     wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2010                     wpabuf_put_le16(msg, 1);
2011                     wpabuf_put_u8(msg, ver);
2012           }
2013 #endif /* CONFIG_DPP2 */
2014 
2015 #ifdef CONFIG_TESTING_OPTIONS
2016 skip_proto_ver:
2017 #endif /* CONFIG_TESTING_OPTIONS */
2018 
2019           wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
2020                        " status=%d", MAC2STR(src), status);
2021           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2022                     " freq=%u type=%d status=%d", MAC2STR(src), freq,
2023                     DPP_PA_PEER_DISCOVERY_RESP, status);
2024           hostapd_drv_send_action(hapd, freq, 0, src,
2025                                         wpabuf_head(msg), wpabuf_len(msg));
2026           wpabuf_free(msg);
2027 }
2028 
2029 
hapd_dpp_connector_available(struct hostapd_data * hapd)2030 static bool hapd_dpp_connector_available(struct hostapd_data *hapd)
2031 {
2032           if (!hapd->wpa_auth ||
2033               !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
2034               !(hapd->conf->wpa & WPA_PROTO_RSN)) {
2035                     wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
2036                     return false;
2037           }
2038 
2039           if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
2040               !hapd->conf->dpp_csign) {
2041                     wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
2042                     return false;
2043           }
2044 
2045           return true;
2046 }
2047 
2048 
hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2049 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
2050                                                    const u8 *src,
2051                                                    const u8 *buf, size_t len,
2052                                                    unsigned int freq)
2053 {
2054           const u8 *connector, *trans_id;
2055           u16 connector_len, trans_id_len;
2056           struct os_time now;
2057           struct dpp_introduction intro;
2058           os_time_t expire;
2059           int expiration;
2060           enum dpp_status_error res;
2061           u8 pkhash[SHA256_MAC_LEN];
2062 
2063           os_memset(&intro, 0, sizeof(intro));
2064 
2065           wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
2066                        MAC2STR(src));
2067           if (!hapd_dpp_connector_available(hapd))
2068                     return;
2069 
2070           os_get_time(&now);
2071 
2072           if (hapd->conf->dpp_netaccesskey_expiry &&
2073               (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2074                     wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2075                     return;
2076           }
2077 
2078           trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2079                                      &trans_id_len);
2080           if (!trans_id || trans_id_len != 1) {
2081                     wpa_printf(MSG_DEBUG,
2082                                  "DPP: Peer did not include Transaction ID");
2083                     return;
2084           }
2085 
2086           connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
2087           if (!connector) {
2088                     wpa_printf(MSG_DEBUG,
2089                                  "DPP: Peer did not include its Connector");
2090                     return;
2091           }
2092 
2093           res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2094                                    wpabuf_head(hapd->conf->dpp_netaccesskey),
2095                                    wpabuf_len(hapd->conf->dpp_netaccesskey),
2096                                    wpabuf_head(hapd->conf->dpp_csign),
2097                                    wpabuf_len(hapd->conf->dpp_csign),
2098                                    connector, connector_len, &expire, pkhash);
2099           if (res == 255) {
2100                     wpa_printf(MSG_INFO,
2101                                  "DPP: Network Introduction protocol resulted in internal failure (peer "
2102                                  MACSTR ")", MAC2STR(src));
2103                     goto done;
2104           }
2105           if (res != DPP_STATUS_OK) {
2106                     wpa_printf(MSG_INFO,
2107                                  "DPP: Network Introduction protocol resulted in failure (peer "
2108                                  MACSTR " status %d)", MAC2STR(src), res);
2109                     hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2110                                                             res);
2111                     goto done;
2112           }
2113 
2114 #ifdef CONFIG_DPP3
2115           if (intro.peer_version && intro.peer_version >= 2) {
2116                     const u8 *version;
2117                     u16 version_len;
2118                     u8 attr_version = 1;
2119 
2120                     version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2121                                                &version_len);
2122                     if (version && version_len >= 1)
2123                               attr_version = version[0];
2124                     if (attr_version != intro.peer_version) {
2125                               wpa_printf(MSG_INFO,
2126                                            "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2127                                            intro.peer_version, attr_version);
2128                               hostapd_dpp_send_peer_disc_resp(hapd, src, freq,
2129                                                                       trans_id[0],
2130                                                                       DPP_STATUS_NO_MATCH);
2131                               goto done;
2132                     }
2133           }
2134 #endif /* CONFIG_DPP3 */
2135 
2136           if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2137                     expire = hapd->conf->dpp_netaccesskey_expiry;
2138           if (expire)
2139                     expiration = expire - now.sec;
2140           else
2141                     expiration = 0;
2142 
2143           if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2144                                         intro.pmkid, expiration,
2145                                         WPA_KEY_MGMT_DPP, pkhash) < 0) {
2146                     wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2147                     goto done;
2148           }
2149 
2150           hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
2151                                                   DPP_STATUS_OK);
2152 done:
2153           dpp_peer_intro_deinit(&intro);
2154 }
2155 
2156 
2157 static void
hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq,bool v2)2158 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
2159                                          const u8 *hdr, const u8 *buf, size_t len,
2160                                          unsigned int freq, bool v2)
2161 {
2162           struct wpabuf *msg;
2163 
2164           wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
2165                        MAC2STR(src));
2166 
2167           if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_1 && v2) {
2168                     wpa_printf(MSG_DEBUG,
2169                                  "DPP: Ignore PKEXv2 Exchange Request when configured to be PKEX v1 only");
2170                     return;
2171           }
2172           if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_2 && !v2) {
2173                     wpa_printf(MSG_DEBUG,
2174                                  "DPP: Ignore PKEXv1 Exchange Request when configured to be PKEX v2 only");
2175                     return;
2176           }
2177 
2178           /* TODO: Support multiple PKEX codes by iterating over all the enabled
2179            * values here */
2180 
2181           if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
2182                     wpa_printf(MSG_DEBUG,
2183                                  "DPP: No PKEX code configured - ignore request");
2184                     goto try_relay;
2185           }
2186 
2187 #ifdef CONFIG_DPP2
2188           if (dpp_controller_is_own_pkex_req(hapd->iface->interfaces->dpp,
2189                                                      buf, len)) {
2190                     wpa_printf(MSG_DEBUG,
2191                                  "DPP: PKEX Exchange Request is from local Controller - ignore request");
2192                     return;
2193           }
2194 #endif /* CONFIG_DPP2 */
2195 
2196           if (hapd->dpp_pkex) {
2197                     /* TODO: Support parallel operations */
2198                     wpa_printf(MSG_DEBUG,
2199                                  "DPP: Already in PKEX session - ignore new request");
2200                     goto try_relay;
2201           }
2202 
2203           hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
2204                                                               hapd->dpp_pkex_bi,
2205                                                               hapd->own_addr, src,
2206                                                               hapd->dpp_pkex_identifier,
2207                                                               hapd->dpp_pkex_code,
2208                                                               hapd->dpp_pkex_code_len,
2209                                                               buf, len, v2);
2210           if (!hapd->dpp_pkex) {
2211                     wpa_printf(MSG_DEBUG,
2212                                  "DPP: Failed to process the request - ignore it");
2213                     goto try_relay;
2214           }
2215 
2216           msg = hapd->dpp_pkex->exchange_resp;
2217           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2218                     " freq=%u type=%d", MAC2STR(src), freq,
2219                     DPP_PA_PKEX_EXCHANGE_RESP);
2220           hostapd_drv_send_action(hapd, freq, 0, src,
2221                                         wpabuf_head(msg), wpabuf_len(msg));
2222           if (hapd->dpp_pkex->failed) {
2223                     wpa_printf(MSG_DEBUG,
2224                                  "DPP: Terminate PKEX exchange due to an earlier error");
2225                     if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2226                               hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
2227                     dpp_pkex_free(hapd->dpp_pkex);
2228                     hapd->dpp_pkex = NULL;
2229           }
2230 
2231           return;
2232 
2233 try_relay:
2234 #ifdef CONFIG_DPP2
2235           if (v2 && dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2236                                               src, hdr, buf, len, freq, NULL, NULL,
2237                                               hapd) != 0) {
2238                     wpa_printf(MSG_DEBUG,
2239                                  "DPP: No Relay available for the message");
2240                     hostapd_dpp_relay_needs_controller(hapd, src,
2241                                                                DPP_PA_PKEX_EXCHANGE_REQ);
2242           }
2243 #else /* CONFIG_DPP2 */
2244           wpa_printf(MSG_DEBUG, "DPP: No relay functionality included - skip");
2245 #endif /* CONFIG_DPP2 */
2246 }
2247 
2248 
2249 static void
hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2250 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
2251                                           const u8 *buf, size_t len, unsigned int freq)
2252 {
2253           struct wpabuf *msg;
2254 
2255           wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
2256                        MAC2STR(src));
2257 
2258           /* TODO: Support multiple PKEX codes by iterating over all the enabled
2259            * values here */
2260 
2261           if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
2262               hapd->dpp_pkex->exchange_done) {
2263                     wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2264                     return;
2265           }
2266 
2267           eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
2268           hapd->dpp_pkex->exch_req_wait_time = 0;
2269 
2270           msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
2271           if (!msg) {
2272                     wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2273                     return;
2274           }
2275 
2276           wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
2277                        MAC2STR(src));
2278 
2279           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2280                     " freq=%u type=%d", MAC2STR(src), freq,
2281                     DPP_PA_PKEX_COMMIT_REVEAL_REQ);
2282           hostapd_drv_send_action(hapd, freq, 0, src,
2283                                         wpabuf_head(msg), wpabuf_len(msg));
2284           wpabuf_free(msg);
2285 }
2286 
2287 
2288 static void
hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2289 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
2290                                               const u8 *hdr, const u8 *buf, size_t len,
2291                                               unsigned int freq)
2292 {
2293           struct wpabuf *msg;
2294           struct dpp_pkex *pkex = hapd->dpp_pkex;
2295           struct dpp_bootstrap_info *bi;
2296 
2297           wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
2298                        MAC2STR(src));
2299 
2300           if (!pkex || pkex->initiator || !pkex->exchange_done) {
2301                     wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2302                     return;
2303           }
2304 
2305           msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
2306           if (!msg) {
2307                     wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
2308                     if (hapd->dpp_pkex->failed) {
2309                               wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
2310                               if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
2311                                         hapd->dpp_pkex->own_bi->pkex_t =
2312                                                   hapd->dpp_pkex->t;
2313                               dpp_pkex_free(hapd->dpp_pkex);
2314                               hapd->dpp_pkex = NULL;
2315                     }
2316                     return;
2317           }
2318 
2319           wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
2320                        MACSTR, MAC2STR(src));
2321 
2322           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2323                     " freq=%u type=%d", MAC2STR(src), freq,
2324                     DPP_PA_PKEX_COMMIT_REVEAL_RESP);
2325           hostapd_drv_send_action(hapd, freq, 0, src,
2326                                         wpabuf_head(msg), wpabuf_len(msg));
2327           wpabuf_free(msg);
2328 
2329           hostapd_dpp_pkex_clear_code(hapd);
2330           bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
2331           if (!bi)
2332                     return;
2333           hapd->dpp_pkex = NULL;
2334 }
2335 
2336 
2337 static void
hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2338 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
2339                                                const u8 *hdr, const u8 *buf, size_t len,
2340                                                unsigned int freq)
2341 {
2342           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2343           int res;
2344           struct dpp_bootstrap_info *bi;
2345           struct dpp_pkex *pkex = hapd->dpp_pkex;
2346           char cmd[500];
2347 
2348           wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
2349                        MAC2STR(src));
2350 
2351           if (!pkex || !pkex->initiator || !pkex->exchange_done) {
2352                     wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
2353                     return;
2354           }
2355 
2356           res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
2357           if (res < 0) {
2358                     wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
2359                     return;
2360           }
2361 
2362           hostapd_dpp_pkex_clear_code(hapd);
2363           bi = dpp_pkex_finish(ifaces->dpp, pkex, src, freq);
2364           if (!bi)
2365                     return;
2366           hapd->dpp_pkex = NULL;
2367 
2368 #ifdef CONFIG_DPP3
2369           if (ifaces->dpp_pb_bi &&
2370               os_memcmp(bi->pubkey_hash_chirp, ifaces->dpp_pb_resp_hash,
2371                           SHA256_MAC_LEN) != 0) {
2372                     char id[20];
2373 
2374                     wpa_printf(MSG_INFO,
2375                                  "DPP: Peer bootstrap key from PKEX does not match PB announcement hash");
2376                     wpa_hexdump(MSG_DEBUG,
2377                                   "DPP: Peer provided bootstrap key hash(chirp) from PB PKEX",
2378                                   bi->pubkey_hash_chirp, SHA256_MAC_LEN);
2379                     wpa_hexdump(MSG_DEBUG,
2380                                   "DPP: Peer provided bootstrap key hash(chirp) from PB announcement",
2381                                   ifaces->dpp_pb_resp_hash, SHA256_MAC_LEN);
2382 
2383                     os_snprintf(id, sizeof(id), "%u", bi->id);
2384                     dpp_bootstrap_remove(ifaces->dpp, id);
2385                     hostapd_dpp_push_button_stop(hapd);
2386                     return;
2387           }
2388 #endif /* CONFIG_DPP3 */
2389 
2390           os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
2391                         bi->id,
2392                         hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
2393           wpa_printf(MSG_DEBUG,
2394                        "DPP: Start authentication after PKEX with parameters: %s",
2395                        cmd);
2396           if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
2397                     wpa_printf(MSG_DEBUG,
2398                                  "DPP: Authentication initialization failed");
2399                     return;
2400           }
2401 }
2402 
2403 
2404 #ifdef CONFIG_DPP3
2405 
hostapd_dpp_pb_pkex_init(struct hostapd_data * hapd,unsigned int freq,const u8 * src,const u8 * r_hash)2406 static void hostapd_dpp_pb_pkex_init(struct hostapd_data *hapd,
2407                                              unsigned int freq, const u8 *src,
2408                                              const u8 *r_hash)
2409 {
2410           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2411           struct dpp_pkex *pkex;
2412           struct wpabuf *msg;
2413           char ssid_hex[2 * SSID_MAX_LEN + 1], *pass_hex = NULL;
2414           char cmd[300];
2415           const char *password = NULL;
2416 #ifdef CONFIG_SAE
2417           struct sae_password_entry *e;
2418 #endif /* CONFIG_SAE */
2419           int conf_id = -1;
2420           bool sae = false, psk = false;
2421           size_t len;
2422 
2423           if (hapd->dpp_pkex) {
2424                     wpa_printf(MSG_DEBUG,
2425                                  "PDP: Sending previously generated PKEX Exchange Request to "
2426                                  MACSTR, MAC2STR(src));
2427                     msg = hapd->dpp_pkex->exchange_req;
2428                     hostapd_drv_send_action(hapd, freq, 0, src,
2429                                                   wpabuf_head(msg), wpabuf_len(msg));
2430                     return;
2431           }
2432 
2433           wpa_printf(MSG_DEBUG, "DPP: Initiate PKEX for push button with "
2434                        MACSTR, MAC2STR(src));
2435 
2436           hapd->dpp_pkex_bi = ifaces->dpp_pb_bi;
2437           os_memcpy(ifaces->dpp_pb_resp_hash, r_hash, SHA256_MAC_LEN);
2438 
2439           pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr,
2440                                    "PBPKEX", (const char *) ifaces->dpp_pb_c_nonce,
2441                                    ifaces->dpp_pb_bi->curve->nonce_len,
2442                                    true);
2443           if (!pkex) {
2444                     hostapd_dpp_push_button_stop(hapd);
2445                     return;
2446           }
2447           pkex->freq = freq;
2448 
2449           hapd->dpp_pkex = pkex;
2450           msg = hapd->dpp_pkex->exchange_req;
2451 
2452           if (ifaces->dpp_pb_cmd) {
2453                     /* Use the externally provided configuration */
2454                     os_free(hapd->dpp_pkex_auth_cmd);
2455                     len = 30 + os_strlen(ifaces->dpp_pb_cmd);
2456                     hapd->dpp_pkex_auth_cmd = os_malloc(len);
2457                     if (!hapd->dpp_pkex_auth_cmd) {
2458                               hostapd_dpp_push_button_stop(hapd);
2459                               return;
2460                     }
2461                     os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2462                                   hapd->dpp_pkex_bi->id, ifaces->dpp_pb_cmd);
2463                     goto send_frame;
2464           }
2465 
2466           /* Build config based on the current AP configuration */
2467           wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
2468                                (const u8 *) hapd->conf->ssid.ssid,
2469                                hapd->conf->ssid.ssid_len);
2470 
2471           if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
2472                     /* TODO: If a local Configurator has been enabled, allow a
2473                      * DPP AKM credential to be provisioned by setting conf_id. */
2474           }
2475 
2476           if (hapd->conf->wpa & WPA_PROTO_RSN) {
2477                     psk = hapd->conf->wpa_key_mgmt & (WPA_KEY_MGMT_PSK |
2478                                                               WPA_KEY_MGMT_PSK_SHA256);
2479 #ifdef CONFIG_SAE
2480                     sae = hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE;
2481 #endif /* CONFIG_SAE */
2482           }
2483 
2484 #ifdef CONFIG_SAE
2485           for (e = hapd->conf->sae_passwords; sae && e && !password;
2486                e = e->next) {
2487                     if (e->identifier || !is_broadcast_ether_addr(e->peer_addr))
2488                               continue;
2489                     password = e->password;
2490           }
2491 #endif /* CONFIG_SAE */
2492           if (!password && hapd->conf->ssid.wpa_passphrase_set &&
2493               hapd->conf->ssid.wpa_passphrase)
2494                     password = hapd->conf->ssid.wpa_passphrase;
2495           if (password) {
2496                     len = 2 * os_strlen(password) + 1;
2497                     pass_hex = os_malloc(len);
2498                     if (!pass_hex) {
2499                               hostapd_dpp_push_button_stop(hapd);
2500                               return;
2501                     }
2502                     wpa_snprintf_hex(pass_hex, len, (const u8 *) password,
2503                                          os_strlen(password));
2504           }
2505 
2506           if (conf_id > 0 && sae && psk && pass_hex) {
2507                     os_snprintf(cmd, sizeof(cmd),
2508                                   "conf=sta-dpp+psk+sae configurator=%d ssid=%s pass=%s",
2509                                   conf_id, ssid_hex, pass_hex);
2510           } else if (conf_id > 0 && sae && pass_hex) {
2511                     os_snprintf(cmd, sizeof(cmd),
2512                                   "conf=sta-dpp+sae configurator=%d ssid=%s pass=%s",
2513                                   conf_id, ssid_hex, pass_hex);
2514           } else if (conf_id > 0) {
2515                     os_snprintf(cmd, sizeof(cmd),
2516                                   "conf=sta-dpp configurator=%d ssid=%s",
2517                                   conf_id, ssid_hex);
2518           } if (sae && psk && pass_hex) {
2519                     os_snprintf(cmd, sizeof(cmd),
2520                                   "conf=sta-psk+sae ssid=%s pass=%s",
2521                                   ssid_hex, pass_hex);
2522           } else if (sae && pass_hex) {
2523                     os_snprintf(cmd, sizeof(cmd),
2524                                   "conf=sta-sae ssid=%s pass=%s",
2525                                   ssid_hex, pass_hex);
2526           } else if (psk && pass_hex) {
2527                     os_snprintf(cmd, sizeof(cmd),
2528                                   "conf=sta-psk ssid=%s pass=%s",
2529                                   ssid_hex, pass_hex);
2530           } else {
2531                     wpa_printf(MSG_INFO,
2532                                  "DPP: Unsupported AP configuration for push button");
2533                     str_clear_free(pass_hex);
2534                     hostapd_dpp_push_button_stop(hapd);
2535                     return;
2536           }
2537           str_clear_free(pass_hex);
2538 
2539           os_free(hapd->dpp_pkex_auth_cmd);
2540           len = 30 + os_strlen(cmd);
2541           hapd->dpp_pkex_auth_cmd = os_malloc(len);
2542           if (hapd->dpp_pkex_auth_cmd)
2543                     os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s",
2544                                   hapd->dpp_pkex_bi->id, cmd);
2545           forced_memzero(cmd, sizeof(cmd));
2546           if (!hapd->dpp_pkex_auth_cmd) {
2547                     hostapd_dpp_push_button_stop(hapd);
2548                     return;
2549           }
2550 
2551 send_frame:
2552           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2553                     " freq=%u type=%d", MAC2STR(src), freq,
2554                     DPP_PA_PKEX_EXCHANGE_REQ);
2555           hostapd_drv_send_action(hapd, pkex->freq, 0, src,
2556                                         wpabuf_head(msg), wpabuf_len(msg));
2557           pkex->exch_req_wait_time = 2000;
2558           pkex->exch_req_tries = 1;
2559 }
2560 
2561 
2562 static void
hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2563 hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data *hapd,
2564                                                   const u8 *src, const u8 *hdr,
2565                                                   const u8 *buf, size_t len,
2566                                                   unsigned int freq)
2567 {
2568           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
2569           const u8 *r_hash;
2570           u16 r_hash_len;
2571           unsigned int i;
2572           bool found = false;
2573           struct dpp_pb_info *info, *tmp;
2574           struct os_reltime now, age;
2575           struct wpabuf *msg;
2576 
2577           if (!ifaces)
2578                     return;
2579 
2580           os_get_reltime(&now);
2581           wpa_printf(MSG_DEBUG, "DPP: Push Button Presence Announcement from "
2582                        MACSTR, MAC2STR(src));
2583 
2584           r_hash = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
2585                                     &r_hash_len);
2586           if (!r_hash || r_hash_len != SHA256_MAC_LEN) {
2587                     wpa_printf(MSG_DEBUG,
2588                                  "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
2589                     return;
2590           }
2591           wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
2592                         r_hash, r_hash_len);
2593 
2594           for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2595                     info = &ifaces->dpp_pb[i];
2596                     if ((info->rx_time.sec == 0 && info->rx_time.usec == 0) ||
2597                         os_memcmp(r_hash, info->hash, SHA256_MAC_LEN) != 0)
2598                               continue;
2599                     wpa_printf(MSG_DEBUG,
2600                                  "DPP: Active push button Enrollee already known");
2601                     found = true;
2602                     info->rx_time = now;
2603           }
2604 
2605           if (!found) {
2606                     for (i = 0; i < DPP_PB_INFO_COUNT; i++) {
2607                               tmp = &ifaces->dpp_pb[i];
2608                               if (tmp->rx_time.sec == 0 && tmp->rx_time.usec == 0)
2609                                         continue;
2610 
2611                               if (os_reltime_expired(&now, &tmp->rx_time, 120)) {
2612                                         wpa_hexdump(MSG_DEBUG,
2613                                                       "DPP: Push button Enrollee hash expired",
2614                                                       tmp->hash, SHA256_MAC_LEN);
2615                                         tmp->rx_time.sec = 0;
2616                                         tmp->rx_time.usec = 0;
2617                                         continue;
2618                               }
2619 
2620                               wpa_hexdump(MSG_DEBUG,
2621                                             "DPP: Push button session overlap with hash",
2622                                             tmp->hash, SHA256_MAC_LEN);
2623                               if (!ifaces->dpp_pb_result_indicated &&
2624                                   hostapd_dpp_pb_active(hapd)) {
2625                                         wpa_msg(hapd->msg_ctx, MSG_INFO,
2626                                                   DPP_EVENT_PB_RESULT "session-overlap");
2627                                         ifaces->dpp_pb_result_indicated = true;
2628                               }
2629                               hostapd_dpp_push_button_stop(hapd);
2630                               return;
2631                     }
2632 
2633                     /* Replace the oldest entry */
2634                     info = &ifaces->dpp_pb[0];
2635                     for (i = 1; i < DPP_PB_INFO_COUNT; i++) {
2636                               tmp = &ifaces->dpp_pb[i];
2637                               if (os_reltime_before(&tmp->rx_time, &info->rx_time))
2638                                         info = tmp;
2639                     }
2640                     wpa_printf(MSG_DEBUG, "DPP: New active push button Enrollee");
2641                     os_memcpy(info->hash, r_hash, SHA256_MAC_LEN);
2642                     info->rx_time = now;
2643           }
2644 
2645           if (!hostapd_dpp_pb_active(hapd)) {
2646                     wpa_printf(MSG_DEBUG,
2647                                  "DPP: Discard message since own push button has not been pressed");
2648                     return;
2649           }
2650 
2651           if (ifaces->dpp_pb_announce_time.sec == 0 &&
2652               ifaces->dpp_pb_announce_time.usec == 0) {
2653                     /* Start a wait before allowing PKEX to be initiated */
2654                     ifaces->dpp_pb_announce_time = now;
2655           }
2656 
2657           if (!ifaces->dpp_pb_bi) {
2658                     int res;
2659 
2660                     res = dpp_bootstrap_gen(ifaces->dpp, "type=pkex");
2661                     if (res < 0)
2662                               return;
2663                     ifaces->dpp_pb_bi = dpp_bootstrap_get_id(ifaces->dpp, res);
2664                     if (!ifaces->dpp_pb_bi)
2665                               return;
2666 
2667                     if (random_get_bytes(ifaces->dpp_pb_c_nonce,
2668                                              ifaces->dpp_pb_bi->curve->nonce_len)) {
2669                               wpa_printf(MSG_ERROR,
2670                                            "DPP: Failed to generate C-nonce");
2671                               hostapd_dpp_push_button_stop(hapd);
2672                               return;
2673                     }
2674           }
2675 
2676           /* Skip the response if one was sent within last 50 ms since the
2677            * Enrollee is going to send out at least three announcement messages.
2678            */
2679           os_reltime_sub(&now, &ifaces->dpp_pb_last_resp, &age);
2680           if (age.sec == 0 && age.usec < 50000) {
2681                     wpa_printf(MSG_DEBUG,
2682                                  "DPP: Skip Push Button Presence Announcement Response frame immediately after having sent one");
2683                     return;
2684           }
2685 
2686           msg = dpp_build_pb_announcement_resp(
2687                     ifaces->dpp_pb_bi, r_hash, ifaces->dpp_pb_c_nonce,
2688                     ifaces->dpp_pb_bi->curve->nonce_len);
2689           if (!msg) {
2690                     hostapd_dpp_push_button_stop(hapd);
2691                     return;
2692           }
2693 
2694           wpa_printf(MSG_DEBUG,
2695                        "DPP: Send Push Button Presence Announcement Response to "
2696                        MACSTR, MAC2STR(src));
2697           ifaces->dpp_pb_last_resp = now;
2698 
2699           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2700                     " freq=%u type=%d", MAC2STR(src), freq,
2701                     DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP);
2702           hostapd_drv_send_action(hapd, freq, 0, src,
2703                                         wpabuf_head(msg), wpabuf_len(msg));
2704           wpabuf_free(msg);
2705 
2706           if (os_reltime_expired(&now, &ifaces->dpp_pb_announce_time, 15))
2707                     hostapd_dpp_pb_pkex_init(hapd, freq, src, r_hash);
2708 }
2709 
2710 
2711 static void
hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2712 hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data *hapd, const u8 *src,
2713                                              const u8 *hdr, const u8 *buf, size_t len,
2714                                              unsigned int freq)
2715 {
2716           const u8 *trans_id, *version;
2717           u16 trans_id_len, version_len;
2718           struct wpabuf *msg;
2719           u8 ver = DPP_VERSION;
2720           int conn_ver;
2721 
2722           wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Query from "
2723                        MACSTR, MAC2STR(src));
2724 
2725           if (!hapd_dpp_connector_available(hapd))
2726                     return;
2727 
2728           trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2729                                      &trans_id_len);
2730           if (!trans_id || trans_id_len != 1) {
2731                     wpa_printf(MSG_DEBUG,
2732                                  "DPP: Peer did not include Transaction ID");
2733                     return;
2734           }
2735 
2736           version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
2737                                      &version_len);
2738           if (!version || version_len != 1) {
2739                     wpa_printf(MSG_DEBUG,
2740                                  "DPP: Peer did not include Protocol Version");
2741                     return;
2742           }
2743 
2744           wpa_printf(MSG_DEBUG, "DPP: Transaction ID %u, Version %u",
2745                        trans_id[0], version[0]);
2746 
2747           len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
2748           msg = dpp_alloc_msg(DPP_PA_PRIV_PEER_INTRO_NOTIFY, len);
2749           if (!msg)
2750                     return;
2751 
2752           /* Transaction ID */
2753           wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
2754           wpabuf_put_le16(msg, 1);
2755           wpabuf_put_u8(msg, trans_id[0]);
2756 
2757           /* Protocol Version */
2758           conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
2759           if (conn_ver > 0 && ver != conn_ver) {
2760                     wpa_printf(MSG_DEBUG,
2761                                  "DPP: Use Connector version %d instead of current protocol version %d",
2762                                  conn_ver, ver);
2763                     ver = conn_ver;
2764           }
2765           wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
2766           wpabuf_put_le16(msg, 1);
2767           wpabuf_put_u8(msg, ver);
2768 
2769           /* DPP Connector */
2770           wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
2771           wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
2772           wpabuf_put_str(msg, hapd->conf->dpp_connector);
2773 
2774           wpa_printf(MSG_DEBUG, "DPP: Send Private Peer Introduction Notify to "
2775                        MACSTR, MAC2STR(src));
2776           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2777                     " freq=%u type=%d", MAC2STR(src), freq,
2778                     DPP_PA_PRIV_PEER_INTRO_NOTIFY);
2779           hostapd_drv_send_action(hapd, freq, 0, src,
2780                                         wpabuf_head(msg), wpabuf_len(msg));
2781           wpabuf_free(msg);
2782 }
2783 
2784 
2785 static void
hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)2786 hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data *hapd, const u8 *src,
2787                                               const u8 *hdr, const u8 *buf, size_t len,
2788                                               unsigned int freq)
2789 {
2790           struct crypto_ec_key *own_key;
2791           const struct dpp_curve_params *curve;
2792           enum hpke_kem_id kem_id;
2793           enum hpke_kdf_id kdf_id;
2794           enum hpke_aead_id aead_id;
2795           const u8 *aad = hdr;
2796           size_t aad_len = DPP_HDR_LEN;
2797           struct wpabuf *pt;
2798           const u8 *trans_id, *wrapped, *version, *connector;
2799           u16 trans_id_len, wrapped_len, version_len, connector_len;
2800           struct os_time now;
2801           struct dpp_introduction intro;
2802           os_time_t expire;
2803           int expiration;
2804           enum dpp_status_error res;
2805           u8 pkhash[SHA256_MAC_LEN];
2806 
2807           os_memset(&intro, 0, sizeof(intro));
2808 
2809           wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Update from "
2810                        MACSTR, MAC2STR(src));
2811 
2812           if (!hapd_dpp_connector_available(hapd))
2813                     return;
2814 
2815           os_get_time(&now);
2816 
2817           if (hapd->conf->dpp_netaccesskey_expiry &&
2818               (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
2819                     wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
2820                     return;
2821           }
2822 
2823           trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
2824                                      &trans_id_len);
2825           if (!trans_id || trans_id_len != 1) {
2826                     wpa_printf(MSG_DEBUG,
2827                                  "DPP: Peer did not include Transaction ID");
2828                     return;
2829           }
2830 
2831           wrapped = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
2832                                      &wrapped_len);
2833           if (!wrapped) {
2834                     wpa_printf(MSG_DEBUG, "DPP: Peer did not include Wrapped Data");
2835                     return;
2836           }
2837 
2838           own_key = dpp_set_keypair(&curve,
2839                                           wpabuf_head(hapd->conf->dpp_netaccesskey),
2840                                           wpabuf_len(hapd->conf->dpp_netaccesskey));
2841           if (!own_key) {
2842                     wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
2843                     return;
2844           }
2845 
2846           if (dpp_hpke_suite(curve->ike_group, &kem_id, &kdf_id, &aead_id) < 0) {
2847                     wpa_printf(MSG_ERROR, "DPP: Unsupported curve %d",
2848                                  curve->ike_group);
2849                     crypto_ec_key_deinit(own_key);
2850                     return;
2851           }
2852 
2853           pt = hpke_base_open(kem_id, kdf_id, aead_id, own_key, NULL, 0,
2854                                   aad, aad_len, wrapped, wrapped_len);
2855           crypto_ec_key_deinit(own_key);
2856           if (!pt) {
2857                     wpa_printf(MSG_INFO, "DPP: Failed to decrypt Connector");
2858                     return;
2859           }
2860           wpa_hexdump_buf(MSG_MSGDUMP, "DPP: HPKE-Decrypted Wrapped Data", pt);
2861 
2862           connector = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2863                                          DPP_ATTR_CONNECTOR, &connector_len);
2864           if (!connector) {
2865                     wpa_printf(MSG_DEBUG,
2866                                  "DPP: Peer did not include its Connector");
2867                     goto done;
2868           }
2869 
2870           version = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt),
2871                                      DPP_ATTR_PROTOCOL_VERSION, &version_len);
2872           if (!version || version_len < 1) {
2873                     wpa_printf(MSG_DEBUG,
2874                                  "DPP: Peer did not include Protocol Version");
2875                     goto done;
2876           }
2877 
2878           res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
2879                                    wpabuf_head(hapd->conf->dpp_netaccesskey),
2880                                    wpabuf_len(hapd->conf->dpp_netaccesskey),
2881                                    wpabuf_head(hapd->conf->dpp_csign),
2882                                    wpabuf_len(hapd->conf->dpp_csign),
2883                                    connector, connector_len, &expire, pkhash);
2884           if (res == 255) {
2885                     wpa_printf(MSG_INFO,
2886                                  "DPP: Network Introduction protocol resulted in internal failure (peer "
2887                                  MACSTR ")", MAC2STR(src));
2888                     goto done;
2889           }
2890           if (res != DPP_STATUS_OK) {
2891                     wpa_printf(MSG_INFO,
2892                                  "DPP: Network Introduction protocol resulted in failure (peer "
2893                                  MACSTR " status %d)", MAC2STR(src), res);
2894                     goto done;
2895           }
2896 
2897           if (intro.peer_version && intro.peer_version >= 2) {
2898                     u8 attr_version = 1;
2899 
2900                     if (version && version_len >= 1)
2901                               attr_version = version[0];
2902                     if (attr_version != intro.peer_version) {
2903                               wpa_printf(MSG_INFO,
2904                                            "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
2905                                            intro.peer_version, attr_version);
2906                               goto done;
2907                     }
2908           }
2909 
2910           if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
2911                     expire = hapd->conf->dpp_netaccesskey_expiry;
2912           if (expire)
2913                     expiration = expire - now.sec;
2914           else
2915                     expiration = 0;
2916 
2917           if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
2918                                         intro.pmkid, expiration,
2919                                         WPA_KEY_MGMT_DPP, pkhash) < 0) {
2920                     wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
2921                     goto done;
2922           }
2923 
2924           wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction completed with "
2925                        MACSTR, MAC2STR(src));
2926 
2927 done:
2928           dpp_peer_intro_deinit(&intro);
2929           wpabuf_free(pt);
2930 }
2931 
2932 #endif /* CONFIG_DPP3 */
2933 
2934 
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2935 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
2936                                  const u8 *buf, size_t len, unsigned int freq)
2937 {
2938           u8 crypto_suite;
2939           enum dpp_public_action_frame_type type;
2940           const u8 *hdr;
2941           unsigned int pkex_t;
2942 
2943           if (len < DPP_HDR_LEN)
2944                     return;
2945           if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
2946                     return;
2947           hdr = buf;
2948           buf += 4;
2949           len -= 4;
2950           crypto_suite = *buf++;
2951           type = *buf++;
2952           len -= 2;
2953 
2954           wpa_printf(MSG_DEBUG,
2955                        "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2956                        MACSTR " freq=%u",
2957                        crypto_suite, type, MAC2STR(src), freq);
2958           if (crypto_suite != 1) {
2959                     wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
2960                                  crypto_suite);
2961                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2962                               " freq=%u type=%d ignore=unsupported-crypto-suite",
2963                               MAC2STR(src), freq, type);
2964                     return;
2965           }
2966           wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
2967           if (dpp_check_attrs(buf, len) < 0) {
2968                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2969                               " freq=%u type=%d ignore=invalid-attributes",
2970                               MAC2STR(src), freq, type);
2971                     return;
2972           }
2973           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
2974                     " freq=%u type=%d", MAC2STR(src), freq, type);
2975 
2976 #ifdef CONFIG_DPP2
2977           if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
2978                                         src, hdr, buf, len, freq, NULL, NULL,
2979                                         hapd) == 0)
2980                     return;
2981 #endif /* CONFIG_DPP2 */
2982 
2983           switch (type) {
2984           case DPP_PA_AUTHENTICATION_REQ:
2985                     hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
2986                     break;
2987           case DPP_PA_AUTHENTICATION_RESP:
2988                     hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
2989                     break;
2990           case DPP_PA_AUTHENTICATION_CONF:
2991                     hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
2992                     break;
2993           case DPP_PA_PEER_DISCOVERY_REQ:
2994                     hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
2995                     break;
2996 #ifdef CONFIG_DPP3
2997           case DPP_PA_PKEX_EXCHANGE_REQ:
2998                     /* This is for PKEXv2, but for now, process only with
2999                      * CONFIG_DPP3 to avoid issues with a capability that has not
3000                      * been tested with other implementations. */
3001                     hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3002                                                              true);
3003                     break;
3004 #endif /* CONFIG_DPP3 */
3005           case DPP_PA_PKEX_V1_EXCHANGE_REQ:
3006                     hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq,
3007                                                              false);
3008                     break;
3009           case DPP_PA_PKEX_EXCHANGE_RESP:
3010                     hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
3011                     break;
3012           case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
3013                     hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
3014                                                                   freq);
3015                     break;
3016           case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
3017                     hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
3018                                                                    freq);
3019                     break;
3020 #ifdef CONFIG_DPP2
3021           case DPP_PA_CONFIGURATION_RESULT:
3022                     hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
3023                     break;
3024           case DPP_PA_CONNECTION_STATUS_RESULT:
3025                     hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
3026                     break;
3027           case DPP_PA_PRESENCE_ANNOUNCEMENT:
3028                     hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
3029                                                                  freq);
3030                     break;
3031           case DPP_PA_RECONFIG_ANNOUNCEMENT:
3032                     hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
3033                                                                  freq);
3034                     break;
3035           case DPP_PA_RECONFIG_AUTH_RESP:
3036                     hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
3037                                                               freq);
3038                     break;
3039 #endif /* CONFIG_DPP2 */
3040 #ifdef CONFIG_DPP3
3041           case DPP_PA_PB_PRESENCE_ANNOUNCEMENT:
3042                     hostapd_dpp_rx_pb_presence_announcement(hapd, src, hdr,
3043                                                                       buf, len, freq);
3044                     break;
3045           case DPP_PA_PRIV_PEER_INTRO_QUERY:
3046                     hostapd_dpp_rx_priv_peer_intro_query(hapd, src, hdr,
3047                                                                  buf, len, freq);
3048                     break;
3049           case DPP_PA_PRIV_PEER_INTRO_UPDATE:
3050                     hostapd_dpp_rx_priv_peer_intro_update(hapd, src, hdr,
3051                                                                   buf, len, freq);
3052                     break;
3053 #endif /* CONFIG_DPP3 */
3054           default:
3055                     wpa_printf(MSG_DEBUG,
3056                                  "DPP: Ignored unsupported frame subtype %d", type);
3057                     break;
3058           }
3059 
3060           if (hapd->dpp_pkex)
3061                     pkex_t = hapd->dpp_pkex->t;
3062           else if (hapd->dpp_pkex_bi)
3063                     pkex_t = hapd->dpp_pkex_bi->pkex_t;
3064           else
3065                     pkex_t = 0;
3066           if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
3067                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
3068                     hostapd_dpp_pkex_remove(hapd, "*");
3069           }
3070 }
3071 
3072 
3073 struct wpabuf *
hostapd_dpp_gas_req_handler(struct hostapd_data * hapd,const u8 * sa,const u8 * query,size_t query_len,const u8 * data,size_t data_len)3074 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
3075                                   const u8 *query, size_t query_len,
3076                                   const u8 *data, size_t data_len)
3077 {
3078           struct dpp_authentication *auth = hapd->dpp_auth;
3079           struct wpabuf *resp;
3080 
3081           wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
3082           if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
3083               !ether_addr_equal(sa, auth->peer_mac_addr)) {
3084 #ifdef CONFIG_DPP2
3085                     if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
3086                                              data_len) == 0) {
3087                               /* Response will be forwarded once received over TCP */
3088                               return NULL;
3089                     }
3090 #endif /* CONFIG_DPP2 */
3091                     wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
3092                     return NULL;
3093           }
3094 
3095           if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
3096                     wpa_printf(MSG_DEBUG,
3097                                  "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
3098                     /* hostapd_dpp_auth_success() would normally have been called
3099                      * from TX status handler, but since there was no such handler
3100                      * call yet, simply send out the event message and proceed with
3101                      * exchange. */
3102                     dpp_notify_auth_success(hapd->dpp_auth, 1);
3103                     hapd->dpp_auth_ok_on_ack = 0;
3104 #ifdef CONFIG_TESTING_OPTIONS
3105                     if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
3106                               wpa_printf(MSG_INFO,
3107                                            "DPP: TESTING - stop at Authentication Confirm");
3108                               return NULL;
3109                     }
3110 #endif /* CONFIG_TESTING_OPTIONS */
3111           }
3112 
3113           wpa_hexdump(MSG_DEBUG,
3114                         "DPP: Received Configuration Request (GAS Query Request)",
3115                         query, query_len);
3116           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
3117                     MAC2STR(sa));
3118           resp = dpp_conf_req_rx(auth, query, query_len);
3119           if (!resp)
3120                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3121           return resp;
3122 }
3123 
3124 
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)3125 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
3126 {
3127           struct dpp_authentication *auth = hapd->dpp_auth;
3128 #ifdef CONFIG_DPP3
3129           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3130 #endif /* CONFIG_DPP3 */
3131 
3132           if (!auth)
3133                     return;
3134 
3135 #ifdef CONFIG_DPP3
3136           if (auth->waiting_new_key && ok) {
3137                     wpa_printf(MSG_DEBUG, "DPP: Waiting for a new key");
3138                     return;
3139           }
3140 #endif /* CONFIG_DPP3 */
3141 
3142           wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
3143                        ok);
3144           eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3145           eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3146           eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3147 #ifdef CONFIG_DPP2
3148                     eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3149                                              hapd, NULL);
3150           if (ok && auth->peer_version >= 2 &&
3151               auth->conf_resp_status == DPP_STATUS_OK) {
3152                     wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
3153                     auth->waiting_conf_result = 1;
3154                     eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
3155                                              hapd, NULL);
3156                     eloop_register_timeout(2, 0,
3157                                                hostapd_dpp_config_result_wait_timeout,
3158                                                hapd, NULL);
3159                     return;
3160           }
3161 #endif /* CONFIG_DPP2 */
3162           hostapd_drv_send_action_cancel_wait(hapd);
3163 
3164           if (ok)
3165                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT
3166                               "conf_status=%d", auth->conf_resp_status);
3167           else
3168                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
3169           dpp_auth_deinit(hapd->dpp_auth);
3170           hapd->dpp_auth = NULL;
3171 #ifdef CONFIG_DPP3
3172           if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) {
3173                     if (ok)
3174                               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3175                                         "success");
3176                     else
3177                               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT
3178                                         "could-not-connect");
3179                     ifaces->dpp_pb_result_indicated = true;
3180                     if (ok)
3181                               hostapd_dpp_remove_pb_hash(hapd);
3182                     hostapd_dpp_push_button_stop(hapd);
3183           }
3184 #endif /* CONFIG_DPP3 */
3185 }
3186 
3187 
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)3188 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
3189 {
3190           struct dpp_authentication *auth;
3191           int ret = -1;
3192           char *curve = NULL;
3193 
3194           auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
3195           if (!auth)
3196                     return -1;
3197 
3198           curve = get_param(cmd, " curve=");
3199           hostapd_dpp_set_testing_options(hapd, auth);
3200           if (dpp_set_configurator(auth, cmd) == 0 &&
3201               dpp_configurator_own_config(auth, curve, 1) == 0) {
3202                     hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
3203                     ret = 0;
3204           }
3205 
3206           dpp_auth_deinit(auth);
3207           os_free(curve);
3208 
3209           return ret;
3210 }
3211 
3212 
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)3213 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
3214 {
3215           struct dpp_bootstrap_info *own_bi;
3216           const char *pos, *end;
3217 #ifdef CONFIG_DPP3
3218                     enum dpp_pkex_ver ver = PKEX_VER_AUTO;
3219 #else /* CONFIG_DPP3 */
3220                     enum dpp_pkex_ver ver = PKEX_VER_ONLY_1;
3221 #endif /* CONFIG_DPP3 */
3222           int tcp_port = DPP_TCP_PORT;
3223           struct hostapd_ip_addr *ipaddr = NULL;
3224 #ifdef CONFIG_DPP2
3225           struct hostapd_ip_addr ipaddr_buf;
3226           char *addr;
3227 
3228           pos = os_strstr(cmd, " tcp_port=");
3229           if (pos) {
3230                     pos += 10;
3231                     tcp_port = atoi(pos);
3232           }
3233 
3234           addr = get_param(cmd, " tcp_addr=");
3235           if (addr) {
3236                     int res;
3237 
3238                     res = hostapd_parse_ip_addr(addr, &ipaddr_buf);
3239                     os_free(addr);
3240                     if (res)
3241                               return -1;
3242                     ipaddr = &ipaddr_buf;
3243           }
3244 #endif /* CONFIG_DPP2 */
3245 
3246           pos = os_strstr(cmd, " own=");
3247           if (!pos)
3248                     return -1;
3249           pos += 5;
3250           own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3251           if (!own_bi) {
3252                     wpa_printf(MSG_DEBUG,
3253                                  "DPP: Identified bootstrap info not found");
3254                     return -1;
3255           }
3256           if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
3257                     wpa_printf(MSG_DEBUG,
3258                                  "DPP: Identified bootstrap info not for PKEX");
3259                     return -1;
3260           }
3261           hapd->dpp_pkex_bi = own_bi;
3262           own_bi->pkex_t = 0; /* clear pending errors on new code */
3263 
3264           os_free(hapd->dpp_pkex_identifier);
3265           hapd->dpp_pkex_identifier = NULL;
3266           pos = os_strstr(cmd, " identifier=");
3267           if (pos) {
3268                     pos += 12;
3269                     end = os_strchr(pos, ' ');
3270                     if (!end)
3271                               return -1;
3272                     hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
3273                     if (!hapd->dpp_pkex_identifier)
3274                               return -1;
3275                     os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
3276                     hapd->dpp_pkex_identifier[end - pos] = '\0';
3277           }
3278 
3279           pos = os_strstr(cmd, " code=");
3280           if (!pos)
3281                     return -1;
3282           os_free(hapd->dpp_pkex_code);
3283           hapd->dpp_pkex_code = os_strdup(pos + 6);
3284           if (!hapd->dpp_pkex_code)
3285                     return -1;
3286           hapd->dpp_pkex_code_len = os_strlen(hapd->dpp_pkex_code);
3287 
3288           pos = os_strstr(cmd, " ver=");
3289           if (pos) {
3290                     int v;
3291 
3292                     pos += 5;
3293                     v = atoi(pos);
3294                     if (v == 1)
3295                               ver = PKEX_VER_ONLY_1;
3296                     else if (v == 2)
3297                               ver = PKEX_VER_ONLY_2;
3298                     else
3299                               return -1;
3300           }
3301           hapd->dpp_pkex_ver = ver;
3302 
3303           if (os_strstr(cmd, " init=1")) {
3304                     if (hostapd_dpp_pkex_init(hapd, ver, ipaddr, tcp_port) < 0)
3305                               return -1;
3306           } else {
3307 #ifdef CONFIG_DPP2
3308                     dpp_controller_pkex_add(hapd->iface->interfaces->dpp, own_bi,
3309                                                   hapd->dpp_pkex_code,
3310                                                   hapd->dpp_pkex_identifier);
3311 #endif /* CONFIG_DPP2 */
3312           }
3313 
3314           /* TODO: Support multiple PKEX info entries */
3315 
3316           os_free(hapd->dpp_pkex_auth_cmd);
3317           hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
3318 
3319           return 1;
3320 }
3321 
3322 
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)3323 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
3324 {
3325           unsigned int id_val;
3326 
3327           if (os_strcmp(id, "*") == 0) {
3328                     id_val = 0;
3329           } else {
3330                     id_val = atoi(id);
3331                     if (id_val == 0)
3332                               return -1;
3333           }
3334 
3335           if ((id_val != 0 && id_val != 1))
3336                     return -1;
3337 
3338           /* TODO: Support multiple PKEX entries */
3339           os_free(hapd->dpp_pkex_code);
3340           hapd->dpp_pkex_code = NULL;
3341           os_free(hapd->dpp_pkex_identifier);
3342           hapd->dpp_pkex_identifier = NULL;
3343           os_free(hapd->dpp_pkex_auth_cmd);
3344           hapd->dpp_pkex_auth_cmd = NULL;
3345           hapd->dpp_pkex_bi = NULL;
3346           /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
3347           dpp_pkex_free(hapd->dpp_pkex);
3348           hapd->dpp_pkex = NULL;
3349           return 0;
3350 }
3351 
3352 
hostapd_dpp_stop(struct hostapd_data * hapd)3353 void hostapd_dpp_stop(struct hostapd_data *hapd)
3354 {
3355           dpp_auth_deinit(hapd->dpp_auth);
3356           hapd->dpp_auth = NULL;
3357           dpp_pkex_free(hapd->dpp_pkex);
3358           hapd->dpp_pkex = NULL;
3359 #ifdef CONFIG_DPP3
3360           hostapd_dpp_push_button_stop(hapd);
3361 #endif /* CONFIG_DPP3 */
3362 }
3363 
3364 
3365 #ifdef CONFIG_DPP2
3366 
hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)3367 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
3368                                          const u8 *msg, size_t len)
3369 {
3370           struct hostapd_data *hapd = ctx;
3371           u8 *buf;
3372 
3373           if (freq == 0)
3374                     freq = hapd->iface->freq;
3375 
3376           wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u",
3377                        MAC2STR(addr), freq);
3378           buf = os_malloc(2 + len);
3379           if (!buf)
3380                     return;
3381           buf[0] = WLAN_ACTION_PUBLIC;
3382           buf[1] = WLAN_PA_VENDOR_SPECIFIC;
3383           os_memcpy(buf + 2, msg, len);
3384           hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
3385           os_free(buf);
3386 }
3387 
3388 
hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)3389 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
3390                                                     u8 dialog_token, int prot,
3391                                                     struct wpabuf *buf)
3392 {
3393           struct hostapd_data *hapd = ctx;
3394 
3395           gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf, 0);
3396 }
3397 
3398 #endif /* CONFIG_DPP2 */
3399 
3400 
hostapd_dpp_add_controllers(struct hostapd_data * hapd)3401 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
3402 {
3403 #ifdef CONFIG_DPP2
3404           struct dpp_controller_conf *ctrl;
3405           struct dpp_relay_config config;
3406 
3407           os_memset(&config, 0, sizeof(config));
3408           config.msg_ctx = hapd->msg_ctx;
3409           config.cb_ctx = hapd;
3410           config.tx = hostapd_dpp_relay_tx;
3411           config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3412           for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
3413                     config.ipaddr = &ctrl->ipaddr;
3414                     config.pkhash = ctrl->pkhash;
3415                     if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
3416                                                        &config) < 0)
3417                               return -1;
3418           }
3419 
3420           if (hapd->conf->dpp_relay_port)
3421                     dpp_relay_listen(hapd->iface->interfaces->dpp,
3422                                          hapd->conf->dpp_relay_port,
3423                                          &config);
3424 #endif /* CONFIG_DPP2 */
3425 
3426           return 0;
3427 }
3428 
3429 
3430 #ifdef CONFIG_DPP2
3431 
hostapd_dpp_add_controller(struct hostapd_data * hapd,const char * cmd)3432 int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd)
3433 {
3434           struct dpp_relay_config config;
3435           struct hostapd_ip_addr addr;
3436           u8 pkhash[SHA256_MAC_LEN];
3437           char *pos, *tmp;
3438           int ret = -1;
3439           bool prev_state, new_state;
3440           struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3441 
3442           tmp = os_strdup(cmd);
3443           if (!tmp)
3444                     goto fail;
3445           pos = os_strchr(tmp, ' ');
3446           if (!pos)
3447                     goto fail;
3448           *pos++ = '\0';
3449           if (hostapd_parse_ip_addr(tmp, &addr) < 0 ||
3450               hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0)
3451                     goto fail;
3452 
3453           os_memset(&config, 0, sizeof(config));
3454           config.msg_ctx = hapd->msg_ctx;
3455           config.cb_ctx = hapd;
3456           config.tx = hostapd_dpp_relay_tx;
3457           config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
3458           config.ipaddr = &addr;
3459           config.pkhash = pkhash;
3460           prev_state = dpp_relay_controller_available(dpp);
3461           ret = dpp_relay_add_controller(dpp, &config);
3462           new_state = dpp_relay_controller_available(dpp);
3463           if (new_state != prev_state)
3464                     ieee802_11_update_beacons(hapd->iface);
3465 fail:
3466           os_free(tmp);
3467           return ret;
3468 }
3469 
3470 
hostapd_dpp_remove_controller(struct hostapd_data * hapd,const char * cmd)3471 void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd)
3472 {
3473           struct hostapd_ip_addr addr;
3474           bool prev_state, new_state;
3475           struct dpp_global *dpp = hapd->iface->interfaces->dpp;
3476 
3477           if (hostapd_parse_ip_addr(cmd, &addr) < 0)
3478                     return;
3479           prev_state = dpp_relay_controller_available(dpp);
3480           dpp_relay_remove_controller(dpp, &addr);
3481           new_state = dpp_relay_controller_available(dpp);
3482           if (new_state != prev_state)
3483                     ieee802_11_update_beacons(hapd->iface);
3484 }
3485 
3486 #endif /* CONFIG_DPP2 */
3487 
3488 
hostapd_dpp_init(struct hostapd_data * hapd)3489 int hostapd_dpp_init(struct hostapd_data *hapd)
3490 {
3491           hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
3492           hapd->dpp_init_done = 1;
3493           return hostapd_dpp_add_controllers(hapd);
3494 }
3495 
3496 
hostapd_dpp_deinit(struct hostapd_data * hapd)3497 void hostapd_dpp_deinit(struct hostapd_data *hapd)
3498 {
3499 #ifdef CONFIG_TESTING_OPTIONS
3500           os_free(hapd->dpp_config_obj_override);
3501           hapd->dpp_config_obj_override = NULL;
3502           os_free(hapd->dpp_discovery_override);
3503           hapd->dpp_discovery_override = NULL;
3504           os_free(hapd->dpp_groups_override);
3505           hapd->dpp_groups_override = NULL;
3506           hapd->dpp_ignore_netaccesskey_mismatch = 0;
3507 #endif /* CONFIG_TESTING_OPTIONS */
3508           if (!hapd->dpp_init_done)
3509                     return;
3510           eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL);
3511           eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
3512           eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
3513           eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
3514           eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
3515 #ifdef CONFIG_DPP2
3516           eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
3517                                    hapd, NULL);
3518           eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
3519                                    NULL);
3520           eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
3521                                    NULL);
3522           hostapd_dpp_chirp_stop(hapd);
3523           if (hapd->iface->interfaces) {
3524                     dpp_relay_stop_listen(hapd->iface->interfaces->dpp);
3525                     dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
3526           }
3527 #endif /* CONFIG_DPP2 */
3528 #ifdef CONFIG_DPP3
3529           eloop_cancel_timeout(hostapd_dpp_build_new_key, hapd, NULL);
3530           hostapd_dpp_push_button_stop(hapd);
3531 #endif /* CONFIG_DPP3 */
3532           dpp_auth_deinit(hapd->dpp_auth);
3533           hapd->dpp_auth = NULL;
3534           hostapd_dpp_pkex_remove(hapd, "*");
3535           hapd->dpp_pkex = NULL;
3536           os_free(hapd->dpp_configurator_params);
3537           hapd->dpp_configurator_params = NULL;
3538           os_free(hapd->dpp_pkex_auth_cmd);
3539           hapd->dpp_pkex_auth_cmd = NULL;
3540 }
3541 
3542 
3543 #ifdef CONFIG_DPP2
3544 
hostapd_dpp_controller_start(struct hostapd_data * hapd,const char * cmd)3545 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd)
3546 {
3547           struct dpp_controller_config config;
3548           const char *pos;
3549 
3550           os_memset(&config, 0, sizeof(config));
3551           config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
3552           config.netrole = DPP_NETROLE_AP;
3553           config.msg_ctx = hapd->msg_ctx;
3554           config.cb_ctx = hapd;
3555           config.process_conf_obj = hostapd_dpp_process_conf_obj;
3556           if (cmd) {
3557                     pos = os_strstr(cmd, " tcp_port=");
3558                     if (pos) {
3559                               pos += 10;
3560                               config.tcp_port = atoi(pos);
3561                     }
3562 
3563                     pos = os_strstr(cmd, " role=");
3564                     if (pos) {
3565                               pos += 6;
3566                               if (os_strncmp(pos, "configurator", 12) == 0)
3567                                         config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
3568                               else if (os_strncmp(pos, "enrollee", 8) == 0)
3569                                         config.allowed_roles = DPP_CAPAB_ENROLLEE;
3570                               else if (os_strncmp(pos, "either", 6) == 0)
3571                                         config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
3572                                                   DPP_CAPAB_ENROLLEE;
3573                               else
3574                                         return -1;
3575                     }
3576 
3577                     config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
3578           }
3579           config.configurator_params = hapd->dpp_configurator_params;
3580           return dpp_controller_start(hapd->iface->interfaces->dpp, &config);
3581 }
3582 
3583 
3584 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
3585 
hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)3586 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
3587 {
3588           struct hostapd_data *hapd = eloop_ctx;
3589 
3590           wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
3591           hostapd_drv_send_action_cancel_wait(hapd);
3592           hostapd_dpp_chirp_next(hapd, NULL);
3593 }
3594 
3595 
hostapd_dpp_chirp_start(struct hostapd_data * hapd)3596 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
3597 {
3598           struct wpabuf *msg;
3599           int type;
3600 
3601           msg = hapd->dpp_presence_announcement;
3602           type = DPP_PA_PRESENCE_ANNOUNCEMENT;
3603           wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
3604           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
3605                     " freq=%u type=%d",
3606                     MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
3607           if (hostapd_drv_send_action(
3608                         hapd, hapd->dpp_chirp_freq, 2000, broadcast,
3609                         wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
3610               eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
3611                                            hapd, NULL) < 0)
3612                     hostapd_dpp_chirp_stop(hapd);
3613 }
3614 
3615 
3616 static struct hostapd_hw_modes *
dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)3617 dpp_get_mode(struct hostapd_data *hapd,
3618                enum hostapd_hw_mode mode)
3619 {
3620           struct hostapd_hw_modes *modes = hapd->iface->hw_features;
3621           u16 num_modes = hapd->iface->num_hw_features;
3622           u16 i;
3623 
3624           for (i = 0; i < num_modes; i++) {
3625                     if (modes[i].mode != mode ||
3626                         !modes[i].num_channels || !modes[i].channels)
3627                               continue;
3628                     return &modes[i];
3629           }
3630 
3631           return NULL;
3632 }
3633 
3634 
3635 static void
hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)3636 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
3637 {
3638           struct hostapd_data *hapd = iface->bss[0];
3639           struct wpa_scan_results *scan_res;
3640           struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
3641           unsigned int i;
3642           struct hostapd_hw_modes *mode;
3643           int c;
3644           bool chan6 = hapd->iface->hw_features == NULL;
3645 
3646           if (!bi)
3647                     return;
3648 
3649           hapd->dpp_chirp_scan_done = 1;
3650 
3651           scan_res = hostapd_driver_get_scan_results(hapd);
3652 
3653           os_free(hapd->dpp_chirp_freqs);
3654           hapd->dpp_chirp_freqs = NULL;
3655 
3656           /* Channels from own bootstrapping info */
3657           if (bi) {
3658                     for (i = 0; i < bi->num_freq; i++)
3659                               int_array_add_unique(&hapd->dpp_chirp_freqs,
3660                                                        bi->freq[i]);
3661           }
3662 
3663           /* Preferred chirping channels */
3664           mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
3665           if (mode) {
3666                     for (c = 0; c < mode->num_channels; c++) {
3667                               struct hostapd_channel_data *chan = &mode->channels[c];
3668 
3669                               if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3670                                                     HOSTAPD_CHAN_RADAR) ||
3671                                   chan->freq != 2437)
3672                                         continue;
3673                               chan6 = true;
3674                               break;
3675                     }
3676           }
3677           if (chan6)
3678                     int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
3679 
3680           mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
3681           if (mode) {
3682                     int chan44 = 0, chan149 = 0;
3683 
3684                     for (c = 0; c < mode->num_channels; c++) {
3685                               struct hostapd_channel_data *chan = &mode->channels[c];
3686 
3687                               if (chan->flag & (HOSTAPD_CHAN_DISABLED |
3688                                                     HOSTAPD_CHAN_RADAR))
3689                                         continue;
3690                               if (chan->freq == 5220)
3691                                         chan44 = 1;
3692                               if (chan->freq == 5745)
3693                                         chan149 = 1;
3694                     }
3695                     if (chan149)
3696                               int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
3697                     else if (chan44)
3698                               int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
3699           }
3700 
3701           mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
3702           if (mode) {
3703                     for (c = 0; c < mode->num_channels; c++) {
3704                               struct hostapd_channel_data *chan = &mode->channels[c];
3705 
3706                               if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
3707                                                      HOSTAPD_CHAN_RADAR)) ||
3708                                   chan->freq != 60480)
3709                                         continue;
3710                               int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
3711                               break;
3712                     }
3713           }
3714 
3715           /* Add channels from scan results for APs that advertise Configurator
3716            * Connectivity element */
3717           for (i = 0; scan_res && i < scan_res->num; i++) {
3718                     struct wpa_scan_res *bss = scan_res->res[i];
3719                     size_t ie_len = bss->ie_len;
3720 
3721                     if (!ie_len)
3722                               ie_len = bss->beacon_ie_len;
3723                     if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
3724                                           DPP_CC_IE_VENDOR_TYPE))
3725                               int_array_add_unique(&hapd->dpp_chirp_freqs,
3726                                                        bss->freq);
3727           }
3728 
3729           if (!hapd->dpp_chirp_freqs ||
3730               eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
3731                                            hapd, NULL) < 0)
3732                     hostapd_dpp_chirp_stop(hapd);
3733 
3734           wpa_scan_results_free(scan_res);
3735 }
3736 
3737 
hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)3738 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
3739 {
3740           struct hostapd_data *hapd = eloop_ctx;
3741           int i;
3742 
3743           if (hapd->dpp_chirp_listen)
3744                     hostapd_dpp_listen_stop(hapd);
3745 
3746           if (hapd->dpp_chirp_freq == 0) {
3747                     if (hapd->dpp_chirp_round % 4 == 0 &&
3748                         !hapd->dpp_chirp_scan_done) {
3749                               struct wpa_driver_scan_params params;
3750                               int ret;
3751 
3752                               wpa_printf(MSG_DEBUG,
3753                                            "DPP: Update channel list for chirping");
3754                               os_memset(&params, 0, sizeof(params));
3755                               ret = hostapd_driver_scan(hapd, &params);
3756                               if (ret < 0) {
3757                                         wpa_printf(MSG_DEBUG,
3758                                                      "DPP: Failed to request a scan ret=%d (%s)",
3759                                                      ret, strerror(-ret));
3760                                         hostapd_dpp_chirp_scan_res_handler(hapd->iface);
3761                               } else {
3762                                         hapd->iface->scan_cb =
3763                                                   hostapd_dpp_chirp_scan_res_handler;
3764                               }
3765                               return;
3766                     }
3767                     hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
3768                     hapd->dpp_chirp_round++;
3769                     wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
3770                                  hapd->dpp_chirp_round);
3771           } else {
3772                     for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
3773                               if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
3774                                         break;
3775                     if (!hapd->dpp_chirp_freqs[i]) {
3776                               wpa_printf(MSG_DEBUG,
3777                                            "DPP: Previous chirp freq %d not found",
3778                                            hapd->dpp_chirp_freq);
3779                               return;
3780                     }
3781                     i++;
3782                     if (hapd->dpp_chirp_freqs[i]) {
3783                               hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
3784                     } else {
3785                               hapd->dpp_chirp_iter--;
3786                               if (hapd->dpp_chirp_iter <= 0) {
3787                                         wpa_printf(MSG_DEBUG,
3788                                                      "DPP: Chirping iterations completed");
3789                                         hostapd_dpp_chirp_stop(hapd);
3790                                         return;
3791                               }
3792                               hapd->dpp_chirp_freq = 0;
3793                               hapd->dpp_chirp_scan_done = 0;
3794                               if (eloop_register_timeout(30, 0,
3795                                                                hostapd_dpp_chirp_next,
3796                                                                hapd, NULL) < 0) {
3797                                         hostapd_dpp_chirp_stop(hapd);
3798                                         return;
3799                               }
3800                               if (hapd->dpp_chirp_listen) {
3801                                         wpa_printf(MSG_DEBUG,
3802                                                      "DPP: Listen on %d MHz during chirp 30 second wait",
3803                                                   hapd->dpp_chirp_listen);
3804                                         /* TODO: start listen on the channel */
3805                               } else {
3806                                         wpa_printf(MSG_DEBUG,
3807                                                      "DPP: Wait 30 seconds before starting the next chirping round");
3808                               }
3809                               return;
3810                     }
3811           }
3812 
3813           hostapd_dpp_chirp_start(hapd);
3814 }
3815 
3816 
hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)3817 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
3818 {
3819           const char *pos;
3820           int iter = 1, listen_freq = 0;
3821           struct dpp_bootstrap_info *bi;
3822 
3823           pos = os_strstr(cmd, " own=");
3824           if (!pos)
3825                     return -1;
3826           pos += 5;
3827           bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
3828           if (!bi) {
3829                     wpa_printf(MSG_DEBUG,
3830                                  "DPP: Identified bootstrap info not found");
3831                     return -1;
3832           }
3833 
3834           pos = os_strstr(cmd, " iter=");
3835           if (pos) {
3836                     iter = atoi(pos + 6);
3837                     if (iter <= 0)
3838                               return -1;
3839           }
3840 
3841           pos = os_strstr(cmd, " listen=");
3842           if (pos) {
3843                     listen_freq = atoi(pos + 8);
3844                     if (listen_freq <= 0)
3845                               return -1;
3846           }
3847 
3848           hostapd_dpp_chirp_stop(hapd);
3849           hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
3850           hapd->dpp_qr_mutual = 0;
3851           hapd->dpp_chirp_bi = bi;
3852           hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
3853           if (!hapd->dpp_presence_announcement)
3854                     return -1;
3855           hapd->dpp_chirp_iter = iter;
3856           hapd->dpp_chirp_round = 0;
3857           hapd->dpp_chirp_scan_done = 0;
3858           hapd->dpp_chirp_listen = listen_freq;
3859 
3860           return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
3861 }
3862 
3863 
hostapd_dpp_chirp_stop(struct hostapd_data * hapd)3864 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
3865 {
3866           if (hapd->dpp_presence_announcement) {
3867                     hostapd_drv_send_action_cancel_wait(hapd);
3868                     wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
3869           }
3870           hapd->dpp_chirp_bi = NULL;
3871           wpabuf_free(hapd->dpp_presence_announcement);
3872           hapd->dpp_presence_announcement = NULL;
3873           if (hapd->dpp_chirp_listen)
3874                     hostapd_dpp_listen_stop(hapd);
3875           hapd->dpp_chirp_listen = 0;
3876           hapd->dpp_chirp_freq = 0;
3877           os_free(hapd->dpp_chirp_freqs);
3878           hapd->dpp_chirp_freqs = NULL;
3879           eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
3880           eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
3881           if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
3882                     /* TODO: abort ongoing scan */
3883                     hapd->iface->scan_cb = NULL;
3884           }
3885 }
3886 
3887 
handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)3888 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
3889 {
3890           struct dpp_bootstrap_info *bi = ctx;
3891           size_t i;
3892 
3893           for (i = 0; i < iface->num_bss; i++) {
3894                     struct hostapd_data *hapd = iface->bss[i];
3895 
3896                     if (bi == hapd->dpp_chirp_bi)
3897                               hostapd_dpp_chirp_stop(hapd);
3898           }
3899 
3900           return 0;
3901 }
3902 
3903 
hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)3904 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
3905 {
3906           struct hapd_interfaces *interfaces = ctx;
3907 
3908           hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
3909 }
3910 
3911 #endif /* CONFIG_DPP2 */
3912 
3913 
3914 #ifdef CONFIG_DPP3
3915 
hostapd_dpp_push_button_expire(void * eloop_ctx,void * timeout_ctx)3916 static void hostapd_dpp_push_button_expire(void *eloop_ctx, void *timeout_ctx)
3917 {
3918           struct hostapd_data *hapd = eloop_ctx;
3919 
3920           wpa_printf(MSG_DEBUG, "DPP: Active push button mode expired");
3921           hostapd_dpp_push_button_stop(hapd);
3922 }
3923 
3924 
hostapd_dpp_push_button(struct hostapd_data * hapd,const char * cmd)3925 int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd)
3926 {
3927           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3928 
3929           if (!ifaces || !ifaces->dpp)
3930                     return -1;
3931           os_get_reltime(&ifaces->dpp_pb_time);
3932           ifaces->dpp_pb_announce_time.sec = 0;
3933           ifaces->dpp_pb_announce_time.usec = 0;
3934           str_clear_free(ifaces->dpp_pb_cmd);
3935           ifaces->dpp_pb_cmd = NULL;
3936           if (cmd) {
3937                     ifaces->dpp_pb_cmd = os_strdup(cmd);
3938                     if (!ifaces->dpp_pb_cmd)
3939                               return -1;
3940           }
3941           eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
3942                                      hapd, NULL);
3943 
3944           wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started");
3945           return 0;
3946 }
3947 
3948 
hostapd_dpp_push_button_stop(struct hostapd_data * hapd)3949 void hostapd_dpp_push_button_stop(struct hostapd_data *hapd)
3950 {
3951           struct hapd_interfaces *ifaces = hapd->iface->interfaces;
3952 
3953           if (!ifaces || !ifaces->dpp)
3954                     return;
3955           eloop_cancel_timeout(hostapd_dpp_push_button_expire, hapd, NULL);
3956           if (hostapd_dpp_pb_active(hapd)) {
3957                     wpa_printf(MSG_DEBUG, "DPP: Stop active push button mode");
3958                     if (!ifaces->dpp_pb_result_indicated)
3959                               wpa_msg(hapd->msg_ctx, MSG_INFO,
3960                                         DPP_EVENT_PB_RESULT "failed");
3961           }
3962           ifaces->dpp_pb_time.sec = 0;
3963           ifaces->dpp_pb_time.usec = 0;
3964           dpp_pkex_free(hapd->dpp_pkex);
3965           hapd->dpp_pkex = NULL;
3966           hapd->dpp_pkex_bi = NULL;
3967           os_free(hapd->dpp_pkex_auth_cmd);
3968           hapd->dpp_pkex_auth_cmd = NULL;
3969 
3970           if (ifaces->dpp_pb_bi) {
3971                     char id[20];
3972                     size_t i;
3973 
3974                     for (i = 0; i < ifaces->count; i++) {
3975                               struct hostapd_iface *iface = ifaces->iface[i];
3976                               size_t j;
3977 
3978                               for (j = 0; iface && j < iface->num_bss; j++) {
3979                                         struct hostapd_data *h = iface->bss[j];
3980 
3981                                         if (h->dpp_pkex_bi == ifaces->dpp_pb_bi)
3982                                                   h->dpp_pkex_bi = NULL;
3983                               }
3984                     }
3985 
3986                     os_snprintf(id, sizeof(id), "%u", ifaces->dpp_pb_bi->id);
3987                     dpp_bootstrap_remove(ifaces->dpp, id);
3988                     ifaces->dpp_pb_bi = NULL;
3989           }
3990 
3991           ifaces->dpp_pb_result_indicated = false;
3992 
3993           str_clear_free(ifaces->dpp_pb_cmd);
3994           ifaces->dpp_pb_cmd = NULL;
3995 }
3996 
3997 #endif /* CONFIG_DPP3 */
3998 
3999 
4000 #ifdef CONFIG_DPP2
hostapd_dpp_configurator_connectivity(struct hostapd_data * hapd)4001 bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd)
4002 {
4003           return hapd->conf->dpp_configurator_connectivity ||
4004                     (hapd->iface->interfaces &&
4005                      dpp_relay_controller_available(hapd->iface->interfaces->dpp));
4006 }
4007 #endif /* CONFIG_DPP2 */
4008