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_gas_req_wait(void * eloop_ctx,void * timeout_ctx)1385 static void hostapd_gas_req_wait(void *eloop_ctx, void *timeout_ctx) 1386 { 1387 struct hostapd_data *hapd = eloop_ctx; 1388 struct dpp_authentication *auth = hapd->dpp_auth; 1389 1390 if (!auth) 1391 return; 1392 1393 wpa_printf(MSG_DEBUG, "DPP: Timeout while waiting for Config Request"); 1394 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1395 dpp_auth_deinit(auth); 1396 hapd->dpp_auth = NULL; 1397 } 1398 1399 hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)1400 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator) 1401 { 1402 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded"); 1403 dpp_notify_auth_success(hapd->dpp_auth, initiator); 1404 #ifdef CONFIG_TESTING_OPTIONS 1405 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) { 1406 wpa_printf(MSG_INFO, 1407 "DPP: TESTING - stop at Authentication Confirm"); 1408 if (hapd->dpp_auth->configurator) { 1409 /* Prevent GAS response */ 1410 hapd->dpp_auth->auth_success = 0; 1411 } 1412 return; 1413 } 1414 #endif /* CONFIG_TESTING_OPTIONS */ 1415 1416 if (!hapd->dpp_auth->configurator) 1417 hostapd_dpp_start_gas_client(hapd); 1418 else 1419 eloop_register_timeout(10, 0, hostapd_gas_req_wait, 1420 hapd, NULL); 1421 } 1422 1423 hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1424 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src, 1425 const u8 *hdr, const u8 *buf, size_t len, 1426 unsigned int freq) 1427 { 1428 struct dpp_authentication *auth = hapd->dpp_auth; 1429 struct wpabuf *msg; 1430 1431 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR, 1432 MAC2STR(src)); 1433 1434 if (!auth) { 1435 wpa_printf(MSG_DEBUG, 1436 "DPP: No DPP Authentication in progress - drop"); 1437 return; 1438 } 1439 1440 if (!is_zero_ether_addr(auth->peer_mac_addr) && 1441 !ether_addr_equal(src, auth->peer_mac_addr)) { 1442 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1443 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1444 return; 1445 } 1446 1447 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 1448 1449 if (auth->curr_freq != freq && auth->neg_freq == freq) { 1450 wpa_printf(MSG_DEBUG, 1451 "DPP: Responder accepted request for different negotiation channel"); 1452 auth->curr_freq = freq; 1453 } 1454 1455 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 1456 msg = dpp_auth_resp_rx(auth, hdr, buf, len); 1457 if (!msg) { 1458 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) { 1459 wpa_printf(MSG_DEBUG, "DPP: Wait for full response"); 1460 return; 1461 } 1462 wpa_printf(MSG_DEBUG, "DPP: No confirm generated"); 1463 return; 1464 } 1465 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN); 1466 1467 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1468 " freq=%u type=%d", MAC2STR(src), auth->curr_freq, 1469 DPP_PA_AUTHENTICATION_CONF); 1470 hostapd_drv_send_action(hapd, auth->curr_freq, 0, src, 1471 wpabuf_head(msg), wpabuf_len(msg)); 1472 wpabuf_free(msg); 1473 hapd->dpp_auth_ok_on_ack = 1; 1474 } 1475 1476 hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1477 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src, 1478 const u8 *hdr, const u8 *buf, size_t len) 1479 { 1480 struct dpp_authentication *auth = hapd->dpp_auth; 1481 1482 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR, 1483 MAC2STR(src)); 1484 1485 if (!auth) { 1486 wpa_printf(MSG_DEBUG, 1487 "DPP: No DPP Authentication in progress - drop"); 1488 return; 1489 } 1490 1491 if (!ether_addr_equal(src, auth->peer_mac_addr)) { 1492 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1493 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1494 return; 1495 } 1496 1497 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) { 1498 wpa_printf(MSG_DEBUG, "DPP: Authentication failed"); 1499 return; 1500 } 1501 1502 hostapd_dpp_auth_success(hapd, 0); 1503 } 1504 1505 1506 #ifdef CONFIG_DPP2 1507 hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1508 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx, 1509 void *timeout_ctx) 1510 { 1511 struct hostapd_data *hapd = eloop_ctx; 1512 struct dpp_authentication *auth = hapd->dpp_auth; 1513 1514 if (!auth || !auth->waiting_conf_result) 1515 return; 1516 1517 wpa_printf(MSG_DEBUG, 1518 "DPP: Timeout while waiting for Configuration Result"); 1519 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1520 dpp_auth_deinit(auth); 1521 hapd->dpp_auth = NULL; 1522 } 1523 1524 hostapd_dpp_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1525 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx, 1526 void *timeout_ctx) 1527 { 1528 struct hostapd_data *hapd = eloop_ctx; 1529 struct dpp_authentication *auth = hapd->dpp_auth; 1530 1531 if (!auth || !auth->waiting_conf_result) 1532 return; 1533 1534 wpa_printf(MSG_DEBUG, 1535 "DPP: Timeout while waiting for Connection Status Result"); 1536 wpa_msg(hapd->msg_ctx, MSG_INFO, 1537 DPP_EVENT_CONN_STATUS_RESULT "timeout"); 1538 dpp_auth_deinit(auth); 1539 hapd->dpp_auth = NULL; 1540 } 1541 1542 1543 #ifdef CONFIG_DPP3 1544 hostapd_dpp_pb_active(struct hostapd_data * hapd)1545 static bool hostapd_dpp_pb_active(struct hostapd_data *hapd) 1546 { 1547 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 1548 1549 return ifaces && (ifaces->dpp_pb_time.sec || 1550 ifaces->dpp_pb_time.usec); 1551 } 1552 1553 hostapd_dpp_remove_pb_hash(struct hostapd_data * hapd)1554 static void hostapd_dpp_remove_pb_hash(struct hostapd_data *hapd) 1555 { 1556 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 1557 int i; 1558 1559 if (!ifaces->dpp_pb_bi) 1560 return; 1561 for (i = 0; i < DPP_PB_INFO_COUNT; i++) { 1562 struct dpp_pb_info *info = &ifaces->dpp_pb[i]; 1563 1564 if (info->rx_time.sec == 0 && info->rx_time.usec == 0) 1565 continue; 1566 if (os_memcmp(info->hash, ifaces->dpp_pb_resp_hash, 1567 SHA256_MAC_LEN) == 0) { 1568 /* Allow a new push button session to be established 1569 * immediately without the successfully completed 1570 * session triggering session overlap. */ 1571 info->rx_time.sec = 0; 1572 info->rx_time.usec = 0; 1573 wpa_printf(MSG_DEBUG, 1574 "DPP: Removed PB hash from session overlap detection due to successfully completed provisioning"); 1575 } 1576 } 1577 } 1578 1579 #endif /* CONFIG_DPP3 */ 1580 1581 hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1582 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src, 1583 const u8 *hdr, const u8 *buf, size_t len) 1584 { 1585 struct dpp_authentication *auth = hapd->dpp_auth; 1586 enum dpp_status_error status; 1587 #ifdef CONFIG_DPP3 1588 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 1589 #endif /* CONFIG_DPP3 */ 1590 1591 wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR, 1592 MAC2STR(src)); 1593 1594 if (!auth || !auth->waiting_conf_result) { 1595 wpa_printf(MSG_DEBUG, 1596 "DPP: No DPP Configuration waiting for result - drop"); 1597 return; 1598 } 1599 1600 if (!ether_addr_equal(src, auth->peer_mac_addr)) { 1601 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1602 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1603 return; 1604 } 1605 1606 status = dpp_conf_result_rx(auth, hdr, buf, len); 1607 1608 if (status == DPP_STATUS_OK && auth->send_conn_status) { 1609 wpa_msg(hapd->msg_ctx, MSG_INFO, 1610 DPP_EVENT_CONF_SENT "wait_conn_status=1 conf_status=%d", 1611 auth->conf_resp_status); 1612 wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result"); 1613 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, 1614 hapd, NULL); 1615 auth->waiting_conn_status_result = 1; 1616 eloop_cancel_timeout( 1617 hostapd_dpp_conn_status_result_wait_timeout, 1618 hapd, NULL); 1619 eloop_register_timeout( 1620 16, 0, hostapd_dpp_conn_status_result_wait_timeout, 1621 hapd, NULL); 1622 return; 1623 } 1624 hostapd_drv_send_action_cancel_wait(hapd); 1625 hostapd_dpp_listen_stop(hapd); 1626 if (status == DPP_STATUS_OK) 1627 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT 1628 "conf_status=%d", auth->conf_resp_status); 1629 else 1630 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1631 dpp_auth_deinit(auth); 1632 hapd->dpp_auth = NULL; 1633 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd, 1634 NULL); 1635 #ifdef CONFIG_DPP3 1636 if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) { 1637 if (status == DPP_STATUS_OK) 1638 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT 1639 "success"); 1640 else 1641 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT 1642 "no-configuration-available"); 1643 ifaces->dpp_pb_result_indicated = true; 1644 if (status == DPP_STATUS_OK) 1645 hostapd_dpp_remove_pb_hash(hapd); 1646 hostapd_dpp_push_button_stop(hapd); 1647 } 1648 #endif /* CONFIG_DPP3 */ 1649 } 1650 1651 hostapd_dpp_rx_conn_status_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1652 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd, 1653 const u8 *src, const u8 *hdr, 1654 const u8 *buf, size_t len) 1655 { 1656 struct dpp_authentication *auth = hapd->dpp_auth; 1657 enum dpp_status_error status; 1658 u8 ssid[SSID_MAX_LEN]; 1659 size_t ssid_len = 0; 1660 char *channel_list = NULL; 1661 1662 wpa_printf(MSG_DEBUG, "DPP: Connection Status Result"); 1663 1664 if (!auth || !auth->waiting_conn_status_result) { 1665 wpa_printf(MSG_DEBUG, 1666 "DPP: No DPP Configuration waiting for connection status result - drop"); 1667 return; 1668 } 1669 1670 status = dpp_conn_status_result_rx(auth, hdr, buf, len, 1671 ssid, &ssid_len, &channel_list); 1672 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT 1673 "result=%d ssid=%s channel_list=%s", 1674 status, wpa_ssid_txt(ssid, ssid_len), 1675 channel_list ? channel_list : "N/A"); 1676 os_free(channel_list); 1677 hostapd_drv_send_action_cancel_wait(hapd); 1678 hostapd_dpp_listen_stop(hapd); 1679 dpp_auth_deinit(auth); 1680 hapd->dpp_auth = NULL; 1681 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, 1682 hapd, NULL); 1683 } 1684 1685 1686 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)1687 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src, 1688 const u8 *hdr, const u8 *buf, size_t len, 1689 unsigned int freq) 1690 { 1691 const u8 *r_bootstrap; 1692 u16 r_bootstrap_len; 1693 struct dpp_bootstrap_info *peer_bi; 1694 struct dpp_authentication *auth; 1695 1696 wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR, 1697 MAC2STR(src)); 1698 1699 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 1700 &r_bootstrap_len); 1701 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { 1702 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 1703 "Missing or invalid required Responder Bootstrapping Key Hash attribute"); 1704 return; 1705 } 1706 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash", 1707 r_bootstrap, r_bootstrap_len); 1708 peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp, 1709 r_bootstrap); 1710 dpp_notify_chirp_received(hapd->msg_ctx, 1711 peer_bi ? (int) peer_bi->id : -1, 1712 src, freq, r_bootstrap); 1713 if (!peer_bi) { 1714 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp, 1715 src, hdr, buf, len, freq, NULL, 1716 r_bootstrap, hapd) == 0) 1717 return; 1718 wpa_printf(MSG_DEBUG, 1719 "DPP: No matching bootstrapping information found"); 1720 hostapd_dpp_relay_needs_controller( 1721 hapd, src, DPP_PA_PRESENCE_ANNOUNCEMENT); 1722 return; 1723 } 1724 1725 if (hapd->dpp_auth) { 1726 wpa_printf(MSG_DEBUG, 1727 "DPP: Ignore Presence Announcement during ongoing Authentication"); 1728 return; 1729 } 1730 1731 auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx, 1732 peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL, 1733 0); 1734 if (!auth) 1735 return; 1736 hostapd_dpp_set_testing_options(hapd, auth); 1737 if (dpp_set_configurator(auth, 1738 hapd->dpp_configurator_params) < 0) { 1739 dpp_auth_deinit(auth); 1740 return; 1741 } 1742 1743 auth->neg_freq = freq; 1744 1745 /* The source address of the Presence Announcement frame overrides any 1746 * MAC address information from the bootstrapping information. */ 1747 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN); 1748 1749 hapd->dpp_auth = auth; 1750 if (hostapd_dpp_auth_init_next(hapd) < 0) { 1751 dpp_auth_deinit(hapd->dpp_auth); 1752 hapd->dpp_auth = NULL; 1753 } 1754 } 1755 1756 hostapd_dpp_reconfig_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)1757 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx, 1758 void *timeout_ctx) 1759 { 1760 struct hostapd_data *hapd = eloop_ctx; 1761 struct dpp_authentication *auth = hapd->dpp_auth; 1762 1763 if (!auth) 1764 return; 1765 1766 wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout"); 1767 hostapd_dpp_listen_stop(hapd); 1768 dpp_auth_deinit(auth); 1769 hapd->dpp_auth = NULL; 1770 } 1771 1772 1773 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)1774 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src, 1775 const u8 *hdr, const u8 *buf, size_t len, 1776 unsigned int freq) 1777 { 1778 const u8 *csign_hash, *fcgroup, *a_nonce, *e_id; 1779 u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len; 1780 struct dpp_configurator *conf; 1781 struct dpp_authentication *auth; 1782 unsigned int wait_time, max_wait_time; 1783 u16 group; 1784 1785 if (hapd->dpp_auth) { 1786 wpa_printf(MSG_DEBUG, 1787 "DPP: Ignore Reconfig Announcement during ongoing Authentication"); 1788 return; 1789 } 1790 1791 wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR, 1792 MAC2STR(src)); 1793 1794 csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH, 1795 &csign_hash_len); 1796 if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) { 1797 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 1798 "Missing or invalid required Configurator C-sign key Hash attribute"); 1799 return; 1800 } 1801 wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)", 1802 csign_hash, csign_hash_len); 1803 conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp, 1804 csign_hash); 1805 if (!conf) { 1806 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp, 1807 src, hdr, buf, len, freq, NULL, 1808 NULL, hapd) == 0) 1809 return; 1810 wpa_printf(MSG_DEBUG, 1811 "DPP: No matching Configurator information found"); 1812 hostapd_dpp_relay_needs_controller( 1813 hapd, src, DPP_PA_RECONFIG_ANNOUNCEMENT); 1814 return; 1815 } 1816 1817 fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP, 1818 &fcgroup_len); 1819 if (!fcgroup || fcgroup_len != 2) { 1820 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 1821 "Missing or invalid required Finite Cyclic Group attribute"); 1822 return; 1823 } 1824 group = WPA_GET_LE16(fcgroup); 1825 wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group); 1826 1827 a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len); 1828 e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len); 1829 1830 auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx, 1831 conf, freq, group, a_nonce, a_nonce_len, 1832 e_id, e_id_len); 1833 if (!auth) 1834 return; 1835 hostapd_dpp_set_testing_options(hapd, auth); 1836 if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) { 1837 dpp_auth_deinit(auth); 1838 return; 1839 } 1840 1841 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN); 1842 hapd->dpp_auth = auth; 1843 1844 hapd->dpp_in_response_listen = 0; 1845 hapd->dpp_auth_ok_on_ack = 0; 1846 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */ 1847 max_wait_time = hapd->dpp_resp_wait_time ? 1848 hapd->dpp_resp_wait_time : 2000; 1849 if (wait_time > max_wait_time) 1850 wait_time = max_wait_time; 1851 wait_time += 10; /* give the driver some extra time to complete */ 1852 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000, 1853 hostapd_dpp_reconfig_reply_wait_timeout, 1854 hapd, NULL); 1855 wait_time -= 10; 1856 1857 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1858 " freq=%u type=%d", 1859 MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ); 1860 if (hostapd_drv_send_action(hapd, freq, wait_time, src, 1861 wpabuf_head(auth->reconfig_req_msg), 1862 wpabuf_len(auth->reconfig_req_msg)) < 0) { 1863 dpp_auth_deinit(hapd->dpp_auth); 1864 hapd->dpp_auth = NULL; 1865 } 1866 } 1867 1868 1869 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)1870 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src, 1871 const u8 *hdr, const u8 *buf, size_t len, 1872 unsigned int freq) 1873 { 1874 struct dpp_authentication *auth = hapd->dpp_auth; 1875 struct wpabuf *conf; 1876 1877 wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from " 1878 MACSTR, MAC2STR(src)); 1879 1880 if (!auth || !auth->reconfig || !auth->configurator) { 1881 wpa_printf(MSG_DEBUG, 1882 "DPP: No DPP Reconfig Authentication in progress - drop"); 1883 return; 1884 } 1885 1886 if (!ether_addr_equal(src, auth->peer_mac_addr)) { 1887 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1888 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1889 return; 1890 } 1891 1892 conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len); 1893 if (!conf) 1894 return; 1895 1896 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout, 1897 hapd, NULL); 1898 1899 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1900 " freq=%u type=%d", 1901 MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF); 1902 if (hostapd_drv_send_action(hapd, freq, 500, src, 1903 wpabuf_head(conf), wpabuf_len(conf)) < 0) { 1904 wpabuf_free(conf); 1905 dpp_auth_deinit(hapd->dpp_auth); 1906 hapd->dpp_auth = NULL; 1907 return; 1908 } 1909 wpabuf_free(conf); 1910 } 1911 1912 #endif /* CONFIG_DPP2 */ 1913 1914 hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)1915 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd, 1916 const u8 *src, unsigned int freq, 1917 u8 trans_id, 1918 enum dpp_status_error status) 1919 { 1920 struct wpabuf *msg; 1921 size_t len; 1922 1923 len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector); 1924 #ifdef CONFIG_DPP2 1925 len += 5; 1926 #endif /* CONFIG_DPP2 */ 1927 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len); 1928 if (!msg) 1929 return; 1930 1931 #ifdef CONFIG_TESTING_OPTIONS 1932 if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) { 1933 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID"); 1934 goto skip_trans_id; 1935 } 1936 if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) { 1937 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID"); 1938 trans_id ^= 0x01; 1939 } 1940 #endif /* CONFIG_TESTING_OPTIONS */ 1941 1942 /* Transaction ID */ 1943 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID); 1944 wpabuf_put_le16(msg, 1); 1945 wpabuf_put_u8(msg, trans_id); 1946 1947 #ifdef CONFIG_TESTING_OPTIONS 1948 skip_trans_id: 1949 if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) { 1950 wpa_printf(MSG_INFO, "DPP: TESTING - no Status"); 1951 goto skip_status; 1952 } 1953 if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) { 1954 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status"); 1955 status = 254; 1956 } 1957 #endif /* CONFIG_TESTING_OPTIONS */ 1958 1959 /* DPP Status */ 1960 wpabuf_put_le16(msg, DPP_ATTR_STATUS); 1961 wpabuf_put_le16(msg, 1); 1962 wpabuf_put_u8(msg, status); 1963 1964 #ifdef CONFIG_TESTING_OPTIONS 1965 skip_status: 1966 if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) { 1967 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector"); 1968 goto skip_connector; 1969 } 1970 if (status == DPP_STATUS_OK && 1971 dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) { 1972 char *connector; 1973 1974 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector"); 1975 connector = dpp_corrupt_connector_signature( 1976 hapd->conf->dpp_connector); 1977 if (!connector) { 1978 wpabuf_free(msg); 1979 return; 1980 } 1981 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 1982 wpabuf_put_le16(msg, os_strlen(connector)); 1983 wpabuf_put_str(msg, connector); 1984 os_free(connector); 1985 goto skip_connector; 1986 } 1987 #endif /* CONFIG_TESTING_OPTIONS */ 1988 1989 /* DPP Connector */ 1990 if (status == DPP_STATUS_OK) { 1991 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 1992 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector)); 1993 wpabuf_put_str(msg, hapd->conf->dpp_connector); 1994 } 1995 1996 #ifdef CONFIG_TESTING_OPTIONS 1997 skip_connector: 1998 if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) { 1999 wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version"); 2000 goto skip_proto_ver; 2001 } 2002 #endif /* CONFIG_TESTING_OPTIONS */ 2003 2004 #ifdef CONFIG_DPP2 2005 if (DPP_VERSION > 1) { 2006 u8 ver = DPP_VERSION; 2007 #ifdef CONFIG_DPP3 2008 int conn_ver; 2009 2010 conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector); 2011 if (conn_ver > 0 && ver != conn_ver) { 2012 wpa_printf(MSG_DEBUG, 2013 "DPP: Use Connector version %d instead of current protocol version %d", 2014 conn_ver, ver); 2015 ver = conn_ver; 2016 } 2017 #endif /* CONFIG_DPP3 */ 2018 2019 #ifdef CONFIG_TESTING_OPTIONS 2020 if (dpp_test == DPP_TEST_INVALID_PROTOCOL_VERSION_PEER_DISC_RESP) { 2021 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Protocol Version"); 2022 ver = 1; 2023 } 2024 #endif /* CONFIG_TESTING_OPTIONS */ 2025 2026 /* Protocol Version */ 2027 wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); 2028 wpabuf_put_le16(msg, 1); 2029 wpabuf_put_u8(msg, ver); 2030 } 2031 #endif /* CONFIG_DPP2 */ 2032 2033 #ifdef CONFIG_TESTING_OPTIONS 2034 skip_proto_ver: 2035 #endif /* CONFIG_TESTING_OPTIONS */ 2036 2037 wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR 2038 " status=%d", MAC2STR(src), status); 2039 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 2040 " freq=%u type=%d status=%d", MAC2STR(src), freq, 2041 DPP_PA_PEER_DISCOVERY_RESP, status); 2042 hostapd_drv_send_action(hapd, freq, 0, src, 2043 wpabuf_head(msg), wpabuf_len(msg)); 2044 wpabuf_free(msg); 2045 } 2046 2047 hapd_dpp_connector_available(struct hostapd_data * hapd)2048 static bool hapd_dpp_connector_available(struct hostapd_data *hapd) 2049 { 2050 if (!hapd->wpa_auth || 2051 !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) || 2052 !(hapd->conf->wpa & WPA_PROTO_RSN)) { 2053 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use"); 2054 return false; 2055 } 2056 2057 if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey || 2058 !hapd->conf->dpp_csign) { 2059 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set"); 2060 return false; 2061 } 2062 2063 return true; 2064 } 2065 2066 hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2067 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, 2068 const u8 *src, 2069 const u8 *buf, size_t len, 2070 unsigned int freq) 2071 { 2072 const u8 *connector, *trans_id; 2073 u16 connector_len, trans_id_len; 2074 struct os_time now; 2075 struct dpp_introduction intro; 2076 os_time_t expire; 2077 int expiration; 2078 enum dpp_status_error res; 2079 u8 pkhash[SHA256_MAC_LEN]; 2080 2081 os_memset(&intro, 0, sizeof(intro)); 2082 2083 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR, 2084 MAC2STR(src)); 2085 if (!hapd_dpp_connector_available(hapd)) 2086 return; 2087 2088 os_get_time(&now); 2089 2090 if (hapd->conf->dpp_netaccesskey_expiry && 2091 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) { 2092 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired"); 2093 return; 2094 } 2095 2096 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, 2097 &trans_id_len); 2098 if (!trans_id || trans_id_len != 1) { 2099 wpa_printf(MSG_DEBUG, 2100 "DPP: Peer did not include Transaction ID"); 2101 return; 2102 } 2103 2104 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len); 2105 if (!connector) { 2106 wpa_printf(MSG_DEBUG, 2107 "DPP: Peer did not include its Connector"); 2108 return; 2109 } 2110 2111 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector, 2112 wpabuf_head(hapd->conf->dpp_netaccesskey), 2113 wpabuf_len(hapd->conf->dpp_netaccesskey), 2114 wpabuf_head(hapd->conf->dpp_csign), 2115 wpabuf_len(hapd->conf->dpp_csign), 2116 connector, connector_len, &expire, pkhash); 2117 if (res == 255) { 2118 wpa_printf(MSG_INFO, 2119 "DPP: Network Introduction protocol resulted in internal failure (peer " 2120 MACSTR ")", MAC2STR(src)); 2121 goto done; 2122 } 2123 if (res != DPP_STATUS_OK) { 2124 wpa_printf(MSG_INFO, 2125 "DPP: Network Introduction protocol resulted in failure (peer " 2126 MACSTR " status %d)", MAC2STR(src), res); 2127 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0], 2128 res); 2129 goto done; 2130 } 2131 2132 #ifdef CONFIG_DPP3 2133 if (intro.peer_version && intro.peer_version >= 2) { 2134 const u8 *version; 2135 u16 version_len; 2136 u8 attr_version = 1; 2137 2138 version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION, 2139 &version_len); 2140 if (version && version_len >= 1) 2141 attr_version = version[0]; 2142 if (attr_version != intro.peer_version) { 2143 wpa_printf(MSG_INFO, 2144 "DPP: Protocol version mismatch (Connector: %d Attribute: %d", 2145 intro.peer_version, attr_version); 2146 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, 2147 trans_id[0], 2148 DPP_STATUS_NO_MATCH); 2149 goto done; 2150 } 2151 } 2152 #endif /* CONFIG_DPP3 */ 2153 2154 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire) 2155 expire = hapd->conf->dpp_netaccesskey_expiry; 2156 if (expire) 2157 expiration = expire - now.sec; 2158 else 2159 expiration = 0; 2160 2161 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, 2162 intro.pmkid, expiration, 2163 WPA_KEY_MGMT_DPP, pkhash, false) < 0) { 2164 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry"); 2165 goto done; 2166 } 2167 2168 #ifdef CONFIG_IEEE80211BE 2169 if (hapd->conf->mld_ap && 2170 wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, 2171 intro.pmkid, expiration, 2172 WPA_KEY_MGMT_DPP, pkhash, true) < 0) { 2173 wpa_printf(MSG_ERROR, 2174 "DPP: Failed to add PMKSA cache entry (MLD)"); 2175 goto done; 2176 } 2177 #endif /* CONFIG_IEEE80211BE */ 2178 2179 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0], 2180 DPP_STATUS_OK); 2181 done: 2182 dpp_peer_intro_deinit(&intro); 2183 } 2184 2185 2186 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)2187 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src, 2188 const u8 *hdr, const u8 *buf, size_t len, 2189 unsigned int freq, bool v2) 2190 { 2191 struct wpabuf *msg; 2192 2193 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR, 2194 MAC2STR(src)); 2195 2196 if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_1 && v2) { 2197 wpa_printf(MSG_DEBUG, 2198 "DPP: Ignore PKEXv2 Exchange Request when configured to be PKEX v1 only"); 2199 return; 2200 } 2201 if (hapd->dpp_pkex_ver == PKEX_VER_ONLY_2 && !v2) { 2202 wpa_printf(MSG_DEBUG, 2203 "DPP: Ignore PKEXv1 Exchange Request when configured to be PKEX v2 only"); 2204 return; 2205 } 2206 2207 /* TODO: Support multiple PKEX codes by iterating over all the enabled 2208 * values here */ 2209 2210 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) { 2211 wpa_printf(MSG_DEBUG, 2212 "DPP: No PKEX code configured - ignore request"); 2213 goto try_relay; 2214 } 2215 2216 #ifdef CONFIG_DPP2 2217 if (dpp_controller_is_own_pkex_req(hapd->iface->interfaces->dpp, 2218 buf, len)) { 2219 wpa_printf(MSG_DEBUG, 2220 "DPP: PKEX Exchange Request is from local Controller - ignore request"); 2221 return; 2222 } 2223 #endif /* CONFIG_DPP2 */ 2224 2225 if (hapd->dpp_pkex) { 2226 /* TODO: Support parallel operations */ 2227 wpa_printf(MSG_DEBUG, 2228 "DPP: Already in PKEX session - ignore new request"); 2229 goto try_relay; 2230 } 2231 2232 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx, 2233 hapd->dpp_pkex_bi, 2234 hapd->own_addr, src, 2235 hapd->dpp_pkex_identifier, 2236 hapd->dpp_pkex_code, 2237 hapd->dpp_pkex_code_len, 2238 buf, len, v2); 2239 if (!hapd->dpp_pkex) { 2240 wpa_printf(MSG_DEBUG, 2241 "DPP: Failed to process the request - ignore it"); 2242 goto try_relay; 2243 } 2244 2245 msg = hapd->dpp_pkex->exchange_resp; 2246 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 2247 " freq=%u type=%d", MAC2STR(src), freq, 2248 DPP_PA_PKEX_EXCHANGE_RESP); 2249 hostapd_drv_send_action(hapd, freq, 0, src, 2250 wpabuf_head(msg), wpabuf_len(msg)); 2251 if (hapd->dpp_pkex->failed) { 2252 wpa_printf(MSG_DEBUG, 2253 "DPP: Terminate PKEX exchange due to an earlier error"); 2254 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t) 2255 hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t; 2256 dpp_pkex_free(hapd->dpp_pkex); 2257 hapd->dpp_pkex = NULL; 2258 } 2259 2260 return; 2261 2262 try_relay: 2263 #ifdef CONFIG_DPP2 2264 if (v2 && dpp_relay_rx_action(hapd->iface->interfaces->dpp, 2265 src, hdr, buf, len, freq, NULL, NULL, 2266 hapd) != 0) { 2267 wpa_printf(MSG_DEBUG, 2268 "DPP: No Relay available for the message"); 2269 hostapd_dpp_relay_needs_controller(hapd, src, 2270 DPP_PA_PKEX_EXCHANGE_REQ); 2271 } 2272 #else /* CONFIG_DPP2 */ 2273 wpa_printf(MSG_DEBUG, "DPP: No relay functionality included - skip"); 2274 #endif /* CONFIG_DPP2 */ 2275 } 2276 2277 2278 static void hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2279 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src, 2280 const u8 *buf, size_t len, unsigned int freq) 2281 { 2282 struct wpabuf *msg; 2283 2284 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR, 2285 MAC2STR(src)); 2286 2287 /* TODO: Support multiple PKEX codes by iterating over all the enabled 2288 * values here */ 2289 2290 if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator || 2291 hapd->dpp_pkex->exchange_done) { 2292 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 2293 return; 2294 } 2295 2296 eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL); 2297 hapd->dpp_pkex->exch_req_wait_time = 0; 2298 2299 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len); 2300 if (!msg) { 2301 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 2302 return; 2303 } 2304 2305 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR, 2306 MAC2STR(src)); 2307 2308 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 2309 " freq=%u type=%d", MAC2STR(src), freq, 2310 DPP_PA_PKEX_COMMIT_REVEAL_REQ); 2311 hostapd_drv_send_action(hapd, freq, 0, src, 2312 wpabuf_head(msg), wpabuf_len(msg)); 2313 wpabuf_free(msg); 2314 } 2315 2316 2317 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)2318 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src, 2319 const u8 *hdr, const u8 *buf, size_t len, 2320 unsigned int freq) 2321 { 2322 struct wpabuf *msg; 2323 struct dpp_pkex *pkex = hapd->dpp_pkex; 2324 struct dpp_bootstrap_info *bi; 2325 2326 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR, 2327 MAC2STR(src)); 2328 2329 if (!pkex || pkex->initiator || !pkex->exchange_done) { 2330 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 2331 return; 2332 } 2333 2334 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len); 2335 if (!msg) { 2336 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request"); 2337 if (hapd->dpp_pkex->failed) { 2338 wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange"); 2339 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t) 2340 hapd->dpp_pkex->own_bi->pkex_t = 2341 hapd->dpp_pkex->t; 2342 dpp_pkex_free(hapd->dpp_pkex); 2343 hapd->dpp_pkex = NULL; 2344 } 2345 return; 2346 } 2347 2348 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to " 2349 MACSTR, MAC2STR(src)); 2350 2351 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 2352 " freq=%u type=%d", MAC2STR(src), freq, 2353 DPP_PA_PKEX_COMMIT_REVEAL_RESP); 2354 hostapd_drv_send_action(hapd, freq, 0, src, 2355 wpabuf_head(msg), wpabuf_len(msg)); 2356 wpabuf_free(msg); 2357 2358 hostapd_dpp_pkex_clear_code(hapd); 2359 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq); 2360 if (!bi) 2361 return; 2362 hapd->dpp_pkex = NULL; 2363 } 2364 2365 2366 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)2367 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src, 2368 const u8 *hdr, const u8 *buf, size_t len, 2369 unsigned int freq) 2370 { 2371 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 2372 int res; 2373 struct dpp_bootstrap_info *bi; 2374 struct dpp_pkex *pkex = hapd->dpp_pkex; 2375 char cmd[500]; 2376 2377 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR, 2378 MAC2STR(src)); 2379 2380 if (!pkex || !pkex->initiator || !pkex->exchange_done) { 2381 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 2382 return; 2383 } 2384 2385 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len); 2386 if (res < 0) { 2387 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 2388 return; 2389 } 2390 2391 hostapd_dpp_pkex_clear_code(hapd); 2392 bi = dpp_pkex_finish(ifaces->dpp, pkex, src, freq); 2393 if (!bi) 2394 return; 2395 hapd->dpp_pkex = NULL; 2396 2397 #ifdef CONFIG_DPP3 2398 if (ifaces->dpp_pb_bi && 2399 os_memcmp(bi->pubkey_hash_chirp, ifaces->dpp_pb_resp_hash, 2400 SHA256_MAC_LEN) != 0) { 2401 char id[20]; 2402 2403 wpa_printf(MSG_INFO, 2404 "DPP: Peer bootstrap key from PKEX does not match PB announcement hash"); 2405 wpa_hexdump(MSG_DEBUG, 2406 "DPP: Peer provided bootstrap key hash(chirp) from PB PKEX", 2407 bi->pubkey_hash_chirp, SHA256_MAC_LEN); 2408 wpa_hexdump(MSG_DEBUG, 2409 "DPP: Peer provided bootstrap key hash(chirp) from PB announcement", 2410 ifaces->dpp_pb_resp_hash, SHA256_MAC_LEN); 2411 2412 os_snprintf(id, sizeof(id), "%u", bi->id); 2413 dpp_bootstrap_remove(ifaces->dpp, id); 2414 hostapd_dpp_push_button_stop(hapd); 2415 return; 2416 } 2417 #endif /* CONFIG_DPP3 */ 2418 2419 os_snprintf(cmd, sizeof(cmd), " peer=%u %s", 2420 bi->id, 2421 hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : ""); 2422 wpa_printf(MSG_DEBUG, 2423 "DPP: Start authentication after PKEX with parameters: %s", 2424 cmd); 2425 if (hostapd_dpp_auth_init(hapd, cmd) < 0) { 2426 wpa_printf(MSG_DEBUG, 2427 "DPP: Authentication initialization failed"); 2428 return; 2429 } 2430 } 2431 2432 2433 #ifdef CONFIG_DPP3 2434 hostapd_dpp_pb_pkex_init(struct hostapd_data * hapd,unsigned int freq,const u8 * src,const u8 * r_hash)2435 static void hostapd_dpp_pb_pkex_init(struct hostapd_data *hapd, 2436 unsigned int freq, const u8 *src, 2437 const u8 *r_hash) 2438 { 2439 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 2440 struct dpp_pkex *pkex; 2441 struct wpabuf *msg; 2442 char ssid_hex[2 * SSID_MAX_LEN + 1], *pass_hex = NULL; 2443 char cmd[300]; 2444 const char *password = NULL; 2445 #ifdef CONFIG_SAE 2446 struct sae_password_entry *e; 2447 #endif /* CONFIG_SAE */ 2448 int conf_id = -1; 2449 bool sae = false, psk = false; 2450 size_t len; 2451 2452 if (hapd->dpp_pkex) { 2453 wpa_printf(MSG_DEBUG, 2454 "PDP: Sending previously generated PKEX Exchange Request to " 2455 MACSTR, MAC2STR(src)); 2456 msg = hapd->dpp_pkex->exchange_req; 2457 hostapd_drv_send_action(hapd, freq, 0, src, 2458 wpabuf_head(msg), wpabuf_len(msg)); 2459 return; 2460 } 2461 2462 wpa_printf(MSG_DEBUG, "DPP: Initiate PKEX for push button with " 2463 MACSTR, MAC2STR(src)); 2464 2465 hapd->dpp_pkex_bi = ifaces->dpp_pb_bi; 2466 os_memcpy(ifaces->dpp_pb_resp_hash, r_hash, SHA256_MAC_LEN); 2467 2468 pkex = dpp_pkex_init(hapd->msg_ctx, hapd->dpp_pkex_bi, hapd->own_addr, 2469 "PBPKEX", (const char *) ifaces->dpp_pb_c_nonce, 2470 ifaces->dpp_pb_bi->curve->nonce_len, 2471 true); 2472 if (!pkex) { 2473 hostapd_dpp_push_button_stop(hapd); 2474 return; 2475 } 2476 pkex->freq = freq; 2477 2478 hapd->dpp_pkex = pkex; 2479 msg = hapd->dpp_pkex->exchange_req; 2480 2481 if (ifaces->dpp_pb_cmd) { 2482 /* Use the externally provided configuration */ 2483 os_free(hapd->dpp_pkex_auth_cmd); 2484 len = 30 + os_strlen(ifaces->dpp_pb_cmd); 2485 hapd->dpp_pkex_auth_cmd = os_malloc(len); 2486 if (!hapd->dpp_pkex_auth_cmd) { 2487 hostapd_dpp_push_button_stop(hapd); 2488 return; 2489 } 2490 os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s", 2491 hapd->dpp_pkex_bi->id, ifaces->dpp_pb_cmd); 2492 goto send_frame; 2493 } 2494 2495 /* Build config based on the current AP configuration */ 2496 wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex), 2497 (const u8 *) hapd->conf->ssid.ssid, 2498 hapd->conf->ssid.ssid_len); 2499 2500 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) { 2501 /* TODO: If a local Configurator has been enabled, allow a 2502 * DPP AKM credential to be provisioned by setting conf_id. */ 2503 } 2504 2505 if (hapd->conf->wpa & WPA_PROTO_RSN) { 2506 psk = hapd->conf->wpa_key_mgmt & (WPA_KEY_MGMT_PSK | 2507 WPA_KEY_MGMT_PSK_SHA256); 2508 #ifdef CONFIG_SAE 2509 sae = hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE; 2510 #endif /* CONFIG_SAE */ 2511 } 2512 2513 #ifdef CONFIG_SAE 2514 for (e = hapd->conf->sae_passwords; sae && e && !password; 2515 e = e->next) { 2516 if (e->identifier || !is_broadcast_ether_addr(e->peer_addr)) 2517 continue; 2518 password = e->password; 2519 } 2520 #endif /* CONFIG_SAE */ 2521 if (!password && hapd->conf->ssid.wpa_passphrase_set && 2522 hapd->conf->ssid.wpa_passphrase) 2523 password = hapd->conf->ssid.wpa_passphrase; 2524 if (password) { 2525 len = 2 * os_strlen(password) + 1; 2526 pass_hex = os_malloc(len); 2527 if (!pass_hex) { 2528 hostapd_dpp_push_button_stop(hapd); 2529 return; 2530 } 2531 wpa_snprintf_hex(pass_hex, len, (const u8 *) password, 2532 os_strlen(password)); 2533 } 2534 2535 if (conf_id > 0 && sae && psk && pass_hex) { 2536 os_snprintf(cmd, sizeof(cmd), 2537 "conf=sta-dpp+psk+sae configurator=%d ssid=%s pass=%s", 2538 conf_id, ssid_hex, pass_hex); 2539 } else if (conf_id > 0 && sae && pass_hex) { 2540 os_snprintf(cmd, sizeof(cmd), 2541 "conf=sta-dpp+sae configurator=%d ssid=%s pass=%s", 2542 conf_id, ssid_hex, pass_hex); 2543 } else if (conf_id > 0) { 2544 os_snprintf(cmd, sizeof(cmd), 2545 "conf=sta-dpp configurator=%d ssid=%s", 2546 conf_id, ssid_hex); 2547 } if (sae && psk && pass_hex) { 2548 os_snprintf(cmd, sizeof(cmd), 2549 "conf=sta-psk+sae ssid=%s pass=%s", 2550 ssid_hex, pass_hex); 2551 } else if (sae && pass_hex) { 2552 os_snprintf(cmd, sizeof(cmd), 2553 "conf=sta-sae ssid=%s pass=%s", 2554 ssid_hex, pass_hex); 2555 } else if (psk && pass_hex) { 2556 os_snprintf(cmd, sizeof(cmd), 2557 "conf=sta-psk ssid=%s pass=%s", 2558 ssid_hex, pass_hex); 2559 } else { 2560 wpa_printf(MSG_INFO, 2561 "DPP: Unsupported AP configuration for push button"); 2562 str_clear_free(pass_hex); 2563 hostapd_dpp_push_button_stop(hapd); 2564 return; 2565 } 2566 str_clear_free(pass_hex); 2567 2568 os_free(hapd->dpp_pkex_auth_cmd); 2569 len = 30 + os_strlen(cmd); 2570 hapd->dpp_pkex_auth_cmd = os_malloc(len); 2571 if (hapd->dpp_pkex_auth_cmd) 2572 os_snprintf(hapd->dpp_pkex_auth_cmd, len, " own=%d %s", 2573 hapd->dpp_pkex_bi->id, cmd); 2574 forced_memzero(cmd, sizeof(cmd)); 2575 if (!hapd->dpp_pkex_auth_cmd) { 2576 hostapd_dpp_push_button_stop(hapd); 2577 return; 2578 } 2579 2580 send_frame: 2581 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 2582 " freq=%u type=%d", MAC2STR(src), freq, 2583 DPP_PA_PKEX_EXCHANGE_REQ); 2584 hostapd_drv_send_action(hapd, pkex->freq, 0, src, 2585 wpabuf_head(msg), wpabuf_len(msg)); 2586 pkex->exch_req_wait_time = 2000; 2587 pkex->exch_req_tries = 1; 2588 } 2589 2590 2591 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)2592 hostapd_dpp_rx_pb_presence_announcement(struct hostapd_data *hapd, 2593 const u8 *src, const u8 *hdr, 2594 const u8 *buf, size_t len, 2595 unsigned int freq) 2596 { 2597 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 2598 const u8 *r_hash; 2599 u16 r_hash_len; 2600 unsigned int i; 2601 bool found = false; 2602 struct dpp_pb_info *info, *tmp; 2603 struct os_reltime now, age; 2604 struct wpabuf *msg; 2605 2606 if (!ifaces) 2607 return; 2608 2609 os_get_reltime(&now); 2610 wpa_printf(MSG_DEBUG, "DPP: Push Button Presence Announcement from " 2611 MACSTR, MAC2STR(src)); 2612 2613 r_hash = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 2614 &r_hash_len); 2615 if (!r_hash || r_hash_len != SHA256_MAC_LEN) { 2616 wpa_printf(MSG_DEBUG, 2617 "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute"); 2618 return; 2619 } 2620 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash", 2621 r_hash, r_hash_len); 2622 2623 for (i = 0; i < DPP_PB_INFO_COUNT; i++) { 2624 info = &ifaces->dpp_pb[i]; 2625 if ((info->rx_time.sec == 0 && info->rx_time.usec == 0) || 2626 os_memcmp(r_hash, info->hash, SHA256_MAC_LEN) != 0) 2627 continue; 2628 wpa_printf(MSG_DEBUG, 2629 "DPP: Active push button Enrollee already known"); 2630 found = true; 2631 info->rx_time = now; 2632 } 2633 2634 if (!found) { 2635 for (i = 0; i < DPP_PB_INFO_COUNT; i++) { 2636 tmp = &ifaces->dpp_pb[i]; 2637 if (tmp->rx_time.sec == 0 && tmp->rx_time.usec == 0) 2638 continue; 2639 2640 if (os_reltime_expired(&now, &tmp->rx_time, 120)) { 2641 wpa_hexdump(MSG_DEBUG, 2642 "DPP: Push button Enrollee hash expired", 2643 tmp->hash, SHA256_MAC_LEN); 2644 tmp->rx_time.sec = 0; 2645 tmp->rx_time.usec = 0; 2646 continue; 2647 } 2648 2649 wpa_hexdump(MSG_DEBUG, 2650 "DPP: Push button session overlap with hash", 2651 tmp->hash, SHA256_MAC_LEN); 2652 if (!ifaces->dpp_pb_result_indicated && 2653 hostapd_dpp_pb_active(hapd)) { 2654 wpa_msg(hapd->msg_ctx, MSG_INFO, 2655 DPP_EVENT_PB_RESULT "session-overlap"); 2656 ifaces->dpp_pb_result_indicated = true; 2657 } 2658 hostapd_dpp_push_button_stop(hapd); 2659 return; 2660 } 2661 2662 /* Replace the oldest entry */ 2663 info = &ifaces->dpp_pb[0]; 2664 for (i = 1; i < DPP_PB_INFO_COUNT; i++) { 2665 tmp = &ifaces->dpp_pb[i]; 2666 if (os_reltime_before(&tmp->rx_time, &info->rx_time)) 2667 info = tmp; 2668 } 2669 wpa_printf(MSG_DEBUG, "DPP: New active push button Enrollee"); 2670 os_memcpy(info->hash, r_hash, SHA256_MAC_LEN); 2671 info->rx_time = now; 2672 } 2673 2674 if (!hostapd_dpp_pb_active(hapd)) { 2675 wpa_printf(MSG_DEBUG, 2676 "DPP: Discard message since own push button has not been pressed"); 2677 return; 2678 } 2679 2680 if (ifaces->dpp_pb_announce_time.sec == 0 && 2681 ifaces->dpp_pb_announce_time.usec == 0) { 2682 /* Start a wait before allowing PKEX to be initiated */ 2683 ifaces->dpp_pb_announce_time = now; 2684 } 2685 2686 if (!ifaces->dpp_pb_bi) { 2687 int res; 2688 2689 res = dpp_bootstrap_gen(ifaces->dpp, "type=pkex"); 2690 if (res < 0) 2691 return; 2692 ifaces->dpp_pb_bi = dpp_bootstrap_get_id(ifaces->dpp, res); 2693 if (!ifaces->dpp_pb_bi) 2694 return; 2695 2696 if (random_get_bytes(ifaces->dpp_pb_c_nonce, 2697 ifaces->dpp_pb_bi->curve->nonce_len)) { 2698 wpa_printf(MSG_ERROR, 2699 "DPP: Failed to generate C-nonce"); 2700 hostapd_dpp_push_button_stop(hapd); 2701 return; 2702 } 2703 } 2704 2705 /* Skip the response if one was sent within last 50 ms since the 2706 * Enrollee is going to send out at least three announcement messages. 2707 */ 2708 os_reltime_sub(&now, &ifaces->dpp_pb_last_resp, &age); 2709 if (age.sec == 0 && age.usec < 50000) { 2710 wpa_printf(MSG_DEBUG, 2711 "DPP: Skip Push Button Presence Announcement Response frame immediately after having sent one"); 2712 return; 2713 } 2714 2715 msg = dpp_build_pb_announcement_resp( 2716 ifaces->dpp_pb_bi, r_hash, ifaces->dpp_pb_c_nonce, 2717 ifaces->dpp_pb_bi->curve->nonce_len); 2718 if (!msg) { 2719 hostapd_dpp_push_button_stop(hapd); 2720 return; 2721 } 2722 2723 wpa_printf(MSG_DEBUG, 2724 "DPP: Send Push Button Presence Announcement Response to " 2725 MACSTR, MAC2STR(src)); 2726 ifaces->dpp_pb_last_resp = now; 2727 2728 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 2729 " freq=%u type=%d", MAC2STR(src), freq, 2730 DPP_PA_PB_PRESENCE_ANNOUNCEMENT_RESP); 2731 hostapd_drv_send_action(hapd, freq, 0, src, 2732 wpabuf_head(msg), wpabuf_len(msg)); 2733 wpabuf_free(msg); 2734 2735 if (os_reltime_expired(&now, &ifaces->dpp_pb_announce_time, 15)) 2736 hostapd_dpp_pb_pkex_init(hapd, freq, src, r_hash); 2737 } 2738 2739 2740 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)2741 hostapd_dpp_rx_priv_peer_intro_query(struct hostapd_data *hapd, const u8 *src, 2742 const u8 *hdr, const u8 *buf, size_t len, 2743 unsigned int freq) 2744 { 2745 const u8 *trans_id, *version; 2746 u16 trans_id_len, version_len; 2747 struct wpabuf *msg; 2748 u8 ver = DPP_VERSION; 2749 int conn_ver; 2750 2751 wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Query from " 2752 MACSTR, MAC2STR(src)); 2753 2754 if (!hapd_dpp_connector_available(hapd)) 2755 return; 2756 2757 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, 2758 &trans_id_len); 2759 if (!trans_id || trans_id_len != 1) { 2760 wpa_printf(MSG_DEBUG, 2761 "DPP: Peer did not include Transaction ID"); 2762 return; 2763 } 2764 2765 version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION, 2766 &version_len); 2767 if (!version || version_len != 1) { 2768 wpa_printf(MSG_DEBUG, 2769 "DPP: Peer did not include Protocol Version"); 2770 return; 2771 } 2772 2773 wpa_printf(MSG_DEBUG, "DPP: Transaction ID %u, Version %u", 2774 trans_id[0], version[0]); 2775 2776 len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector); 2777 msg = dpp_alloc_msg(DPP_PA_PRIV_PEER_INTRO_NOTIFY, len); 2778 if (!msg) 2779 return; 2780 2781 /* Transaction ID */ 2782 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID); 2783 wpabuf_put_le16(msg, 1); 2784 wpabuf_put_u8(msg, trans_id[0]); 2785 2786 /* Protocol Version */ 2787 conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector); 2788 if (conn_ver > 0 && ver != conn_ver) { 2789 wpa_printf(MSG_DEBUG, 2790 "DPP: Use Connector version %d instead of current protocol version %d", 2791 conn_ver, ver); 2792 ver = conn_ver; 2793 } 2794 wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); 2795 wpabuf_put_le16(msg, 1); 2796 wpabuf_put_u8(msg, ver); 2797 2798 /* DPP Connector */ 2799 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 2800 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector)); 2801 wpabuf_put_str(msg, hapd->conf->dpp_connector); 2802 2803 wpa_printf(MSG_DEBUG, "DPP: Send Private Peer Introduction Notify to " 2804 MACSTR, MAC2STR(src)); 2805 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 2806 " freq=%u type=%d", MAC2STR(src), freq, 2807 DPP_PA_PRIV_PEER_INTRO_NOTIFY); 2808 hostapd_drv_send_action(hapd, freq, 0, src, 2809 wpabuf_head(msg), wpabuf_len(msg)); 2810 wpabuf_free(msg); 2811 } 2812 2813 2814 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)2815 hostapd_dpp_rx_priv_peer_intro_update(struct hostapd_data *hapd, const u8 *src, 2816 const u8 *hdr, const u8 *buf, size_t len, 2817 unsigned int freq) 2818 { 2819 struct crypto_ec_key *own_key; 2820 const struct dpp_curve_params *curve; 2821 enum hpke_kem_id kem_id; 2822 enum hpke_kdf_id kdf_id; 2823 enum hpke_aead_id aead_id; 2824 const u8 *aad = hdr; 2825 size_t aad_len = DPP_HDR_LEN; 2826 struct wpabuf *pt; 2827 const u8 *trans_id, *wrapped, *version, *connector; 2828 u16 trans_id_len, wrapped_len, version_len, connector_len; 2829 struct os_time now; 2830 struct dpp_introduction intro; 2831 os_time_t expire; 2832 int expiration; 2833 enum dpp_status_error res; 2834 u8 pkhash[SHA256_MAC_LEN]; 2835 2836 os_memset(&intro, 0, sizeof(intro)); 2837 2838 wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction Update from " 2839 MACSTR, MAC2STR(src)); 2840 2841 if (!hapd_dpp_connector_available(hapd)) 2842 return; 2843 2844 os_get_time(&now); 2845 2846 if (hapd->conf->dpp_netaccesskey_expiry && 2847 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) { 2848 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired"); 2849 return; 2850 } 2851 2852 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, 2853 &trans_id_len); 2854 if (!trans_id || trans_id_len != 1) { 2855 wpa_printf(MSG_DEBUG, 2856 "DPP: Peer did not include Transaction ID"); 2857 return; 2858 } 2859 2860 wrapped = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA, 2861 &wrapped_len); 2862 if (!wrapped) { 2863 wpa_printf(MSG_DEBUG, "DPP: Peer did not include Wrapped Data"); 2864 return; 2865 } 2866 2867 own_key = dpp_set_keypair(&curve, 2868 wpabuf_head(hapd->conf->dpp_netaccesskey), 2869 wpabuf_len(hapd->conf->dpp_netaccesskey)); 2870 if (!own_key) { 2871 wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey"); 2872 return; 2873 } 2874 2875 if (dpp_hpke_suite(curve->ike_group, &kem_id, &kdf_id, &aead_id) < 0) { 2876 wpa_printf(MSG_ERROR, "DPP: Unsupported curve %d", 2877 curve->ike_group); 2878 crypto_ec_key_deinit(own_key); 2879 return; 2880 } 2881 2882 pt = hpke_base_open(kem_id, kdf_id, aead_id, own_key, NULL, 0, 2883 aad, aad_len, wrapped, wrapped_len); 2884 crypto_ec_key_deinit(own_key); 2885 if (!pt) { 2886 wpa_printf(MSG_INFO, "DPP: Failed to decrypt Connector"); 2887 return; 2888 } 2889 wpa_hexdump_buf(MSG_MSGDUMP, "DPP: HPKE-Decrypted Wrapped Data", pt); 2890 2891 connector = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt), 2892 DPP_ATTR_CONNECTOR, &connector_len); 2893 if (!connector) { 2894 wpa_printf(MSG_DEBUG, 2895 "DPP: Peer did not include its Connector"); 2896 goto done; 2897 } 2898 2899 version = dpp_get_attr(wpabuf_head(pt), wpabuf_len(pt), 2900 DPP_ATTR_PROTOCOL_VERSION, &version_len); 2901 if (!version || version_len < 1) { 2902 wpa_printf(MSG_DEBUG, 2903 "DPP: Peer did not include Protocol Version"); 2904 goto done; 2905 } 2906 2907 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector, 2908 wpabuf_head(hapd->conf->dpp_netaccesskey), 2909 wpabuf_len(hapd->conf->dpp_netaccesskey), 2910 wpabuf_head(hapd->conf->dpp_csign), 2911 wpabuf_len(hapd->conf->dpp_csign), 2912 connector, connector_len, &expire, pkhash); 2913 if (res == 255) { 2914 wpa_printf(MSG_INFO, 2915 "DPP: Network Introduction protocol resulted in internal failure (peer " 2916 MACSTR ")", MAC2STR(src)); 2917 goto done; 2918 } 2919 if (res != DPP_STATUS_OK) { 2920 wpa_printf(MSG_INFO, 2921 "DPP: Network Introduction protocol resulted in failure (peer " 2922 MACSTR " status %d)", MAC2STR(src), res); 2923 goto done; 2924 } 2925 2926 if (intro.peer_version && intro.peer_version >= 2) { 2927 u8 attr_version = 1; 2928 2929 if (version && version_len >= 1) 2930 attr_version = version[0]; 2931 if (attr_version != intro.peer_version) { 2932 wpa_printf(MSG_INFO, 2933 "DPP: Protocol version mismatch (Connector: %d Attribute: %d", 2934 intro.peer_version, attr_version); 2935 goto done; 2936 } 2937 } 2938 2939 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire) 2940 expire = hapd->conf->dpp_netaccesskey_expiry; 2941 if (expire) 2942 expiration = expire - now.sec; 2943 else 2944 expiration = 0; 2945 2946 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, 2947 intro.pmkid, expiration, 2948 WPA_KEY_MGMT_DPP, pkhash, false) < 0) { 2949 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry"); 2950 goto done; 2951 } 2952 2953 #ifdef CONFIG_IEEE80211BE 2954 if (hapd->conf->mld_ap && 2955 wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, 2956 intro.pmkid, expiration, 2957 WPA_KEY_MGMT_DPP, pkhash, true) < 0) { 2958 wpa_printf(MSG_ERROR, 2959 "DPP: Failed to add PMKSA cache entry (MLD)"); 2960 goto done; 2961 } 2962 #endif /* CONFIG_IEEE80211BE */ 2963 2964 wpa_printf(MSG_DEBUG, "DPP: Private Peer Introduction completed with " 2965 MACSTR, MAC2STR(src)); 2966 2967 done: 2968 dpp_peer_intro_deinit(&intro); 2969 wpabuf_free(pt); 2970 } 2971 2972 #endif /* CONFIG_DPP3 */ 2973 2974 hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)2975 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src, 2976 const u8 *buf, size_t len, unsigned int freq) 2977 { 2978 u8 crypto_suite; 2979 enum dpp_public_action_frame_type type; 2980 const u8 *hdr; 2981 unsigned int pkex_t; 2982 2983 /* Discard DPP Action frames if there is no global DPP context */ 2984 if (!hapd->iface->interfaces || !hapd->iface->interfaces->dpp) 2985 return; 2986 2987 if (len < DPP_HDR_LEN) 2988 return; 2989 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE) 2990 return; 2991 hdr = buf; 2992 buf += 4; 2993 len -= 4; 2994 crypto_suite = *buf++; 2995 type = *buf++; 2996 len -= 2; 2997 2998 wpa_printf(MSG_DEBUG, 2999 "DPP: Received DPP Public Action frame crypto suite %u type %d from " 3000 MACSTR " freq=%u", 3001 crypto_suite, type, MAC2STR(src), freq); 3002 if (crypto_suite != 1) { 3003 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u", 3004 crypto_suite); 3005 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 3006 " freq=%u type=%d ignore=unsupported-crypto-suite", 3007 MAC2STR(src), freq, type); 3008 return; 3009 } 3010 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len); 3011 if (dpp_check_attrs(buf, len) < 0) { 3012 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 3013 " freq=%u type=%d ignore=invalid-attributes", 3014 MAC2STR(src), freq, type); 3015 return; 3016 } 3017 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 3018 " freq=%u type=%d", MAC2STR(src), freq, type); 3019 3020 #ifdef CONFIG_DPP2 3021 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp, 3022 src, hdr, buf, len, freq, NULL, NULL, 3023 hapd) == 0) 3024 return; 3025 #endif /* CONFIG_DPP2 */ 3026 3027 switch (type) { 3028 case DPP_PA_AUTHENTICATION_REQ: 3029 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq); 3030 break; 3031 case DPP_PA_AUTHENTICATION_RESP: 3032 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq); 3033 break; 3034 case DPP_PA_AUTHENTICATION_CONF: 3035 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len); 3036 break; 3037 case DPP_PA_PEER_DISCOVERY_REQ: 3038 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq); 3039 break; 3040 #ifdef CONFIG_DPP3 3041 case DPP_PA_PKEX_EXCHANGE_REQ: 3042 /* This is for PKEXv2, but for now, process only with 3043 * CONFIG_DPP3 to avoid issues with a capability that has not 3044 * been tested with other implementations. */ 3045 hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq, 3046 true); 3047 break; 3048 #endif /* CONFIG_DPP3 */ 3049 case DPP_PA_PKEX_V1_EXCHANGE_REQ: 3050 hostapd_dpp_rx_pkex_exchange_req(hapd, src, hdr, buf, len, freq, 3051 false); 3052 break; 3053 case DPP_PA_PKEX_EXCHANGE_RESP: 3054 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq); 3055 break; 3056 case DPP_PA_PKEX_COMMIT_REVEAL_REQ: 3057 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len, 3058 freq); 3059 break; 3060 case DPP_PA_PKEX_COMMIT_REVEAL_RESP: 3061 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len, 3062 freq); 3063 break; 3064 #ifdef CONFIG_DPP2 3065 case DPP_PA_CONFIGURATION_RESULT: 3066 hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len); 3067 break; 3068 case DPP_PA_CONNECTION_STATUS_RESULT: 3069 hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len); 3070 break; 3071 case DPP_PA_PRESENCE_ANNOUNCEMENT: 3072 hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len, 3073 freq); 3074 break; 3075 case DPP_PA_RECONFIG_ANNOUNCEMENT: 3076 hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len, 3077 freq); 3078 break; 3079 case DPP_PA_RECONFIG_AUTH_RESP: 3080 hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len, 3081 freq); 3082 break; 3083 #endif /* CONFIG_DPP2 */ 3084 #ifdef CONFIG_DPP3 3085 case DPP_PA_PB_PRESENCE_ANNOUNCEMENT: 3086 hostapd_dpp_rx_pb_presence_announcement(hapd, src, hdr, 3087 buf, len, freq); 3088 break; 3089 case DPP_PA_PRIV_PEER_INTRO_QUERY: 3090 hostapd_dpp_rx_priv_peer_intro_query(hapd, src, hdr, 3091 buf, len, freq); 3092 break; 3093 case DPP_PA_PRIV_PEER_INTRO_UPDATE: 3094 hostapd_dpp_rx_priv_peer_intro_update(hapd, src, hdr, 3095 buf, len, freq); 3096 break; 3097 #endif /* CONFIG_DPP3 */ 3098 default: 3099 wpa_printf(MSG_DEBUG, 3100 "DPP: Ignored unsupported frame subtype %d", type); 3101 break; 3102 } 3103 3104 if (hapd->dpp_pkex) 3105 pkex_t = hapd->dpp_pkex->t; 3106 else if (hapd->dpp_pkex_bi) 3107 pkex_t = hapd->dpp_pkex_bi->pkex_t; 3108 else 3109 pkex_t = 0; 3110 if (pkex_t >= PKEX_COUNTER_T_LIMIT) { 3111 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0"); 3112 hostapd_dpp_pkex_remove(hapd, "*"); 3113 } 3114 } 3115 3116 3117 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)3118 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa, 3119 const u8 *query, size_t query_len, 3120 const u8 *data, size_t data_len) 3121 { 3122 struct dpp_authentication *auth = hapd->dpp_auth; 3123 struct wpabuf *resp; 3124 3125 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa)); 3126 eloop_cancel_timeout(hostapd_gas_req_wait, hapd, NULL); 3127 if (!auth || (!auth->auth_success && !auth->reconfig_success) || 3128 !ether_addr_equal(sa, auth->peer_mac_addr)) { 3129 #ifdef CONFIG_DPP2 3130 if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data, 3131 data_len) == 0) { 3132 /* Response will be forwarded once received over TCP */ 3133 return NULL; 3134 } 3135 #endif /* CONFIG_DPP2 */ 3136 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); 3137 return NULL; 3138 } 3139 3140 if (hapd->dpp_auth_ok_on_ack && auth->configurator) { 3141 wpa_printf(MSG_DEBUG, 3142 "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request"); 3143 /* hostapd_dpp_auth_success() would normally have been called 3144 * from TX status handler, but since there was no such handler 3145 * call yet, simply send out the event message and proceed with 3146 * exchange. */ 3147 dpp_notify_auth_success(hapd->dpp_auth, 1); 3148 hapd->dpp_auth_ok_on_ack = 0; 3149 #ifdef CONFIG_TESTING_OPTIONS 3150 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) { 3151 wpa_printf(MSG_INFO, 3152 "DPP: TESTING - stop at Authentication Confirm"); 3153 return NULL; 3154 } 3155 #endif /* CONFIG_TESTING_OPTIONS */ 3156 } 3157 3158 wpa_hexdump(MSG_DEBUG, 3159 "DPP: Received Configuration Request (GAS Query Request)", 3160 query, query_len); 3161 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR, 3162 MAC2STR(sa)); 3163 resp = dpp_conf_req_rx(auth, query, query_len); 3164 if (!resp) 3165 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 3166 return resp; 3167 } 3168 3169 hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)3170 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok) 3171 { 3172 struct dpp_authentication *auth = hapd->dpp_auth; 3173 #ifdef CONFIG_DPP3 3174 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 3175 #endif /* CONFIG_DPP3 */ 3176 3177 if (!auth) 3178 return; 3179 3180 #ifdef CONFIG_DPP3 3181 if (auth->waiting_new_key && ok) { 3182 wpa_printf(MSG_DEBUG, "DPP: Waiting for a new key"); 3183 return; 3184 } 3185 #endif /* CONFIG_DPP3 */ 3186 3187 wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)", 3188 ok); 3189 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 3190 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL); 3191 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 3192 #ifdef CONFIG_DPP2 3193 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout, 3194 hapd, NULL); 3195 if (ok && auth->peer_version >= 2 && 3196 auth->conf_resp_status == DPP_STATUS_OK) { 3197 wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result"); 3198 auth->waiting_conf_result = 1; 3199 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, 3200 hapd, NULL); 3201 eloop_register_timeout(2, 0, 3202 hostapd_dpp_config_result_wait_timeout, 3203 hapd, NULL); 3204 return; 3205 } 3206 #endif /* CONFIG_DPP2 */ 3207 hostapd_drv_send_action_cancel_wait(hapd); 3208 3209 if (ok) 3210 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT 3211 "conf_status=%d", auth->conf_resp_status); 3212 else 3213 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 3214 dpp_auth_deinit(hapd->dpp_auth); 3215 hapd->dpp_auth = NULL; 3216 #ifdef CONFIG_DPP3 3217 if (!ifaces->dpp_pb_result_indicated && hostapd_dpp_pb_active(hapd)) { 3218 if (ok) 3219 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT 3220 "success"); 3221 else 3222 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_RESULT 3223 "could-not-connect"); 3224 ifaces->dpp_pb_result_indicated = true; 3225 if (ok) 3226 hostapd_dpp_remove_pb_hash(hapd); 3227 hostapd_dpp_push_button_stop(hapd); 3228 } 3229 #endif /* CONFIG_DPP3 */ 3230 } 3231 3232 hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)3233 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd) 3234 { 3235 struct dpp_authentication *auth; 3236 int ret = -1; 3237 char *curve = NULL; 3238 3239 auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx); 3240 if (!auth) 3241 return -1; 3242 3243 curve = get_param(cmd, " curve="); 3244 hostapd_dpp_set_testing_options(hapd, auth); 3245 if (dpp_set_configurator(auth, cmd) == 0 && 3246 dpp_configurator_own_config(auth, curve, 1) == 0) { 3247 hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]); 3248 ret = 0; 3249 } 3250 3251 dpp_auth_deinit(auth); 3252 os_free(curve); 3253 3254 return ret; 3255 } 3256 3257 hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)3258 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd) 3259 { 3260 struct dpp_bootstrap_info *own_bi; 3261 const char *pos, *end; 3262 #ifdef CONFIG_DPP3 3263 enum dpp_pkex_ver ver = PKEX_VER_AUTO; 3264 #else /* CONFIG_DPP3 */ 3265 enum dpp_pkex_ver ver = PKEX_VER_ONLY_1; 3266 #endif /* CONFIG_DPP3 */ 3267 int tcp_port = DPP_TCP_PORT; 3268 struct hostapd_ip_addr *ipaddr = NULL; 3269 #ifdef CONFIG_DPP2 3270 struct hostapd_ip_addr ipaddr_buf; 3271 char *addr; 3272 3273 pos = os_strstr(cmd, " tcp_port="); 3274 if (pos) { 3275 pos += 10; 3276 tcp_port = atoi(pos); 3277 } 3278 3279 addr = get_param(cmd, " tcp_addr="); 3280 if (addr) { 3281 int res; 3282 3283 res = hostapd_parse_ip_addr(addr, &ipaddr_buf); 3284 os_free(addr); 3285 if (res) 3286 return -1; 3287 ipaddr = &ipaddr_buf; 3288 } 3289 #endif /* CONFIG_DPP2 */ 3290 3291 pos = os_strstr(cmd, " own="); 3292 if (!pos) 3293 return -1; 3294 pos += 5; 3295 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos)); 3296 if (!own_bi) { 3297 wpa_printf(MSG_DEBUG, 3298 "DPP: Identified bootstrap info not found"); 3299 return -1; 3300 } 3301 if (own_bi->type != DPP_BOOTSTRAP_PKEX) { 3302 wpa_printf(MSG_DEBUG, 3303 "DPP: Identified bootstrap info not for PKEX"); 3304 return -1; 3305 } 3306 hapd->dpp_pkex_bi = own_bi; 3307 own_bi->pkex_t = 0; /* clear pending errors on new code */ 3308 3309 os_free(hapd->dpp_pkex_identifier); 3310 hapd->dpp_pkex_identifier = NULL; 3311 pos = os_strstr(cmd, " identifier="); 3312 if (pos) { 3313 pos += 12; 3314 end = os_strchr(pos, ' '); 3315 if (!end) 3316 return -1; 3317 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1); 3318 if (!hapd->dpp_pkex_identifier) 3319 return -1; 3320 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos); 3321 hapd->dpp_pkex_identifier[end - pos] = '\0'; 3322 } 3323 3324 pos = os_strstr(cmd, " code="); 3325 if (!pos) 3326 return -1; 3327 os_free(hapd->dpp_pkex_code); 3328 hapd->dpp_pkex_code = os_strdup(pos + 6); 3329 if (!hapd->dpp_pkex_code) 3330 return -1; 3331 hapd->dpp_pkex_code_len = os_strlen(hapd->dpp_pkex_code); 3332 3333 pos = os_strstr(cmd, " ver="); 3334 if (pos) { 3335 int v; 3336 3337 pos += 5; 3338 v = atoi(pos); 3339 if (v == 1) 3340 ver = PKEX_VER_ONLY_1; 3341 else if (v == 2) 3342 ver = PKEX_VER_ONLY_2; 3343 else 3344 return -1; 3345 } 3346 hapd->dpp_pkex_ver = ver; 3347 3348 if (os_strstr(cmd, " init=1")) { 3349 if (hostapd_dpp_pkex_init(hapd, ver, ipaddr, tcp_port) < 0) 3350 return -1; 3351 } else { 3352 #ifdef CONFIG_DPP2 3353 dpp_controller_pkex_add(hapd->iface->interfaces->dpp, own_bi, 3354 hapd->dpp_pkex_code, 3355 hapd->dpp_pkex_identifier); 3356 #endif /* CONFIG_DPP2 */ 3357 } 3358 3359 /* TODO: Support multiple PKEX info entries */ 3360 3361 os_free(hapd->dpp_pkex_auth_cmd); 3362 hapd->dpp_pkex_auth_cmd = os_strdup(cmd); 3363 3364 return 1; 3365 } 3366 3367 hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)3368 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id) 3369 { 3370 unsigned int id_val; 3371 3372 if (os_strcmp(id, "*") == 0) { 3373 id_val = 0; 3374 } else { 3375 id_val = atoi(id); 3376 if (id_val == 0) 3377 return -1; 3378 } 3379 3380 if ((id_val != 0 && id_val != 1)) 3381 return -1; 3382 3383 /* TODO: Support multiple PKEX entries */ 3384 os_free(hapd->dpp_pkex_code); 3385 hapd->dpp_pkex_code = NULL; 3386 os_free(hapd->dpp_pkex_identifier); 3387 hapd->dpp_pkex_identifier = NULL; 3388 os_free(hapd->dpp_pkex_auth_cmd); 3389 hapd->dpp_pkex_auth_cmd = NULL; 3390 hapd->dpp_pkex_bi = NULL; 3391 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */ 3392 dpp_pkex_free(hapd->dpp_pkex); 3393 hapd->dpp_pkex = NULL; 3394 return 0; 3395 } 3396 3397 hostapd_dpp_stop(struct hostapd_data * hapd)3398 void hostapd_dpp_stop(struct hostapd_data *hapd) 3399 { 3400 dpp_auth_deinit(hapd->dpp_auth); 3401 hapd->dpp_auth = NULL; 3402 dpp_pkex_free(hapd->dpp_pkex); 3403 hapd->dpp_pkex = NULL; 3404 #ifdef CONFIG_DPP3 3405 hostapd_dpp_push_button_stop(hapd); 3406 #endif /* CONFIG_DPP3 */ 3407 eloop_cancel_timeout(hostapd_gas_req_wait, hapd, NULL); 3408 } 3409 3410 3411 #ifdef CONFIG_DPP2 3412 hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)3413 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq, 3414 const u8 *msg, size_t len) 3415 { 3416 struct hostapd_data *hapd = ctx; 3417 u8 *buf; 3418 3419 if (freq == 0) 3420 freq = hapd->iface->freq; 3421 3422 wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR " freq=%u", 3423 MAC2STR(addr), freq); 3424 buf = os_malloc(2 + len); 3425 if (!buf) 3426 return; 3427 buf[0] = WLAN_ACTION_PUBLIC; 3428 buf[1] = WLAN_PA_VENDOR_SPECIFIC; 3429 os_memcpy(buf + 2, msg, len); 3430 hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len); 3431 os_free(buf); 3432 } 3433 3434 hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)3435 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr, 3436 u8 dialog_token, int prot, 3437 struct wpabuf *buf) 3438 { 3439 struct hostapd_data *hapd = ctx; 3440 3441 gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf, 0); 3442 } 3443 3444 #endif /* CONFIG_DPP2 */ 3445 3446 hostapd_dpp_add_controllers(struct hostapd_data * hapd)3447 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd) 3448 { 3449 #ifdef CONFIG_DPP2 3450 struct dpp_controller_conf *ctrl; 3451 struct dpp_relay_config config; 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 for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) { 3459 config.ipaddr = &ctrl->ipaddr; 3460 config.pkhash = ctrl->pkhash; 3461 if (dpp_relay_add_controller(hapd->iface->interfaces->dpp, 3462 &config) < 0) 3463 return -1; 3464 } 3465 3466 if (hapd->conf->dpp_relay_port) 3467 dpp_relay_listen(hapd->iface->interfaces->dpp, 3468 hapd->conf->dpp_relay_port, 3469 &config); 3470 #endif /* CONFIG_DPP2 */ 3471 3472 return 0; 3473 } 3474 3475 3476 #ifdef CONFIG_DPP2 3477 hostapd_dpp_add_controller(struct hostapd_data * hapd,const char * cmd)3478 int hostapd_dpp_add_controller(struct hostapd_data *hapd, const char *cmd) 3479 { 3480 struct dpp_relay_config config; 3481 struct hostapd_ip_addr addr; 3482 u8 pkhash[SHA256_MAC_LEN]; 3483 char *pos, *tmp; 3484 int ret = -1; 3485 bool prev_state, new_state; 3486 struct dpp_global *dpp = hapd->iface->interfaces->dpp; 3487 3488 tmp = os_strdup(cmd); 3489 if (!tmp) 3490 goto fail; 3491 pos = os_strchr(tmp, ' '); 3492 if (!pos) 3493 goto fail; 3494 *pos++ = '\0'; 3495 if (hostapd_parse_ip_addr(tmp, &addr) < 0 || 3496 hexstr2bin(pos, pkhash, SHA256_MAC_LEN) < 0) 3497 goto fail; 3498 3499 os_memset(&config, 0, sizeof(config)); 3500 config.msg_ctx = hapd->msg_ctx; 3501 config.cb_ctx = hapd; 3502 config.tx = hostapd_dpp_relay_tx; 3503 config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx; 3504 config.ipaddr = &addr; 3505 config.pkhash = pkhash; 3506 prev_state = dpp_relay_controller_available(dpp); 3507 ret = dpp_relay_add_controller(dpp, &config); 3508 new_state = dpp_relay_controller_available(dpp); 3509 if (new_state != prev_state) 3510 ieee802_11_update_beacons(hapd->iface); 3511 fail: 3512 os_free(tmp); 3513 return ret; 3514 } 3515 3516 hostapd_dpp_remove_controller(struct hostapd_data * hapd,const char * cmd)3517 void hostapd_dpp_remove_controller(struct hostapd_data *hapd, const char *cmd) 3518 { 3519 struct hostapd_ip_addr addr; 3520 bool prev_state, new_state; 3521 struct dpp_global *dpp = hapd->iface->interfaces->dpp; 3522 3523 if (hostapd_parse_ip_addr(cmd, &addr) < 0) 3524 return; 3525 prev_state = dpp_relay_controller_available(dpp); 3526 dpp_relay_remove_controller(dpp, &addr); 3527 new_state = dpp_relay_controller_available(dpp); 3528 if (new_state != prev_state) 3529 ieee802_11_update_beacons(hapd->iface); 3530 } 3531 3532 #endif /* CONFIG_DPP2 */ 3533 3534 hostapd_dpp_init(struct hostapd_data * hapd)3535 int hostapd_dpp_init(struct hostapd_data *hapd) 3536 { 3537 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE; 3538 hapd->dpp_init_done = 1; 3539 return hostapd_dpp_add_controllers(hapd); 3540 } 3541 3542 hostapd_dpp_deinit(struct hostapd_data * hapd)3543 void hostapd_dpp_deinit(struct hostapd_data *hapd) 3544 { 3545 #ifdef CONFIG_TESTING_OPTIONS 3546 os_free(hapd->dpp_config_obj_override); 3547 hapd->dpp_config_obj_override = NULL; 3548 os_free(hapd->dpp_discovery_override); 3549 hapd->dpp_discovery_override = NULL; 3550 os_free(hapd->dpp_groups_override); 3551 hapd->dpp_groups_override = NULL; 3552 hapd->dpp_ignore_netaccesskey_mismatch = 0; 3553 #endif /* CONFIG_TESTING_OPTIONS */ 3554 if (!hapd->dpp_init_done) 3555 return; 3556 eloop_cancel_timeout(hostapd_dpp_pkex_retry_timeout, hapd, NULL); 3557 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 3558 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL); 3559 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 3560 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 3561 eloop_cancel_timeout(hostapd_gas_req_wait, hapd, NULL); 3562 #ifdef CONFIG_DPP2 3563 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout, 3564 hapd, NULL); 3565 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd, 3566 NULL); 3567 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd, 3568 NULL); 3569 hostapd_dpp_chirp_stop(hapd); 3570 if (hapd->iface->interfaces) { 3571 dpp_relay_stop_listen(hapd->iface->interfaces->dpp); 3572 dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd); 3573 } 3574 #endif /* CONFIG_DPP2 */ 3575 #ifdef CONFIG_DPP3 3576 eloop_cancel_timeout(hostapd_dpp_build_new_key, hapd, NULL); 3577 hostapd_dpp_push_button_stop(hapd); 3578 #endif /* CONFIG_DPP3 */ 3579 dpp_auth_deinit(hapd->dpp_auth); 3580 hapd->dpp_auth = NULL; 3581 hostapd_dpp_pkex_remove(hapd, "*"); 3582 hapd->dpp_pkex = NULL; 3583 os_free(hapd->dpp_configurator_params); 3584 hapd->dpp_configurator_params = NULL; 3585 os_free(hapd->dpp_pkex_auth_cmd); 3586 hapd->dpp_pkex_auth_cmd = NULL; 3587 } 3588 3589 3590 #ifdef CONFIG_DPP2 3591 hostapd_dpp_controller_start(struct hostapd_data * hapd,const char * cmd)3592 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd) 3593 { 3594 struct dpp_controller_config config; 3595 const char *pos; 3596 3597 os_memset(&config, 0, sizeof(config)); 3598 config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR; 3599 config.netrole = DPP_NETROLE_AP; 3600 config.msg_ctx = hapd->msg_ctx; 3601 config.cb_ctx = hapd; 3602 config.process_conf_obj = hostapd_dpp_process_conf_obj; 3603 if (cmd) { 3604 pos = os_strstr(cmd, " tcp_port="); 3605 if (pos) { 3606 pos += 10; 3607 config.tcp_port = atoi(pos); 3608 } 3609 3610 pos = os_strstr(cmd, " role="); 3611 if (pos) { 3612 pos += 6; 3613 if (os_strncmp(pos, "configurator", 12) == 0) 3614 config.allowed_roles = DPP_CAPAB_CONFIGURATOR; 3615 else if (os_strncmp(pos, "enrollee", 8) == 0) 3616 config.allowed_roles = DPP_CAPAB_ENROLLEE; 3617 else if (os_strncmp(pos, "either", 6) == 0) 3618 config.allowed_roles = DPP_CAPAB_CONFIGURATOR | 3619 DPP_CAPAB_ENROLLEE; 3620 else 3621 return -1; 3622 } 3623 3624 config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL; 3625 } 3626 config.configurator_params = hapd->dpp_configurator_params; 3627 return dpp_controller_start(hapd->iface->interfaces->dpp, &config); 3628 } 3629 3630 3631 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx); 3632 hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)3633 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx) 3634 { 3635 struct hostapd_data *hapd = eloop_ctx; 3636 3637 wpa_printf(MSG_DEBUG, "DPP: No chirp response received"); 3638 hostapd_drv_send_action_cancel_wait(hapd); 3639 hostapd_dpp_chirp_next(hapd, NULL); 3640 } 3641 3642 hostapd_dpp_chirp_start(struct hostapd_data * hapd)3643 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd) 3644 { 3645 struct wpabuf *msg; 3646 int type; 3647 3648 msg = hapd->dpp_presence_announcement; 3649 type = DPP_PA_PRESENCE_ANNOUNCEMENT; 3650 wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq); 3651 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 3652 " freq=%u type=%d", 3653 MAC2STR(broadcast), hapd->dpp_chirp_freq, type); 3654 if (hostapd_drv_send_action( 3655 hapd, hapd->dpp_chirp_freq, 2000, broadcast, 3656 wpabuf_head(msg), wpabuf_len(msg)) < 0 || 3657 eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout, 3658 hapd, NULL) < 0) 3659 hostapd_dpp_chirp_stop(hapd); 3660 } 3661 3662 3663 static struct hostapd_hw_modes * dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)3664 dpp_get_mode(struct hostapd_data *hapd, 3665 enum hostapd_hw_mode mode) 3666 { 3667 struct hostapd_hw_modes *modes = hapd->iface->hw_features; 3668 u16 num_modes = hapd->iface->num_hw_features; 3669 u16 i; 3670 3671 for (i = 0; i < num_modes; i++) { 3672 if (modes[i].mode != mode || 3673 !modes[i].num_channels || !modes[i].channels) 3674 continue; 3675 return &modes[i]; 3676 } 3677 3678 return NULL; 3679 } 3680 3681 3682 static void hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)3683 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface) 3684 { 3685 struct hostapd_data *hapd = iface->bss[0]; 3686 struct wpa_scan_results *scan_res; 3687 struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi; 3688 unsigned int i; 3689 struct hostapd_hw_modes *mode; 3690 int c; 3691 bool chan6 = hapd->iface->hw_features == NULL; 3692 3693 if (!bi) 3694 return; 3695 3696 hapd->dpp_chirp_scan_done = 1; 3697 3698 scan_res = hostapd_driver_get_scan_results(hapd); 3699 3700 os_free(hapd->dpp_chirp_freqs); 3701 hapd->dpp_chirp_freqs = NULL; 3702 3703 /* Channels from own bootstrapping info */ 3704 if (bi) { 3705 for (i = 0; i < bi->num_freq; i++) 3706 int_array_add_unique(&hapd->dpp_chirp_freqs, 3707 bi->freq[i]); 3708 } 3709 3710 /* Preferred chirping channels */ 3711 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G); 3712 if (mode) { 3713 for (c = 0; c < mode->num_channels; c++) { 3714 struct hostapd_channel_data *chan = &mode->channels[c]; 3715 3716 if (chan->flag & (HOSTAPD_CHAN_DISABLED | 3717 HOSTAPD_CHAN_RADAR) || 3718 chan->freq != 2437) 3719 continue; 3720 chan6 = true; 3721 break; 3722 } 3723 } 3724 if (chan6) 3725 int_array_add_unique(&hapd->dpp_chirp_freqs, 2437); 3726 3727 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A); 3728 if (mode) { 3729 int chan44 = 0, chan149 = 0; 3730 3731 for (c = 0; c < mode->num_channels; c++) { 3732 struct hostapd_channel_data *chan = &mode->channels[c]; 3733 3734 if (chan->flag & (HOSTAPD_CHAN_DISABLED | 3735 HOSTAPD_CHAN_RADAR)) 3736 continue; 3737 if (chan->freq == 5220) 3738 chan44 = 1; 3739 if (chan->freq == 5745) 3740 chan149 = 1; 3741 } 3742 if (chan149) 3743 int_array_add_unique(&hapd->dpp_chirp_freqs, 5745); 3744 else if (chan44) 3745 int_array_add_unique(&hapd->dpp_chirp_freqs, 5220); 3746 } 3747 3748 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD); 3749 if (mode) { 3750 for (c = 0; c < mode->num_channels; c++) { 3751 struct hostapd_channel_data *chan = &mode->channels[c]; 3752 3753 if ((chan->flag & (HOSTAPD_CHAN_DISABLED | 3754 HOSTAPD_CHAN_RADAR)) || 3755 chan->freq != 60480) 3756 continue; 3757 int_array_add_unique(&hapd->dpp_chirp_freqs, 60480); 3758 break; 3759 } 3760 } 3761 3762 /* Add channels from scan results for APs that advertise Configurator 3763 * Connectivity element */ 3764 for (i = 0; scan_res && i < scan_res->num; i++) { 3765 struct wpa_scan_res *bss = scan_res->res[i]; 3766 size_t ie_len = bss->ie_len; 3767 3768 if (!ie_len) 3769 ie_len = bss->beacon_ie_len; 3770 if (get_vendor_ie((const u8 *) (bss + 1), ie_len, 3771 DPP_CC_IE_VENDOR_TYPE)) 3772 int_array_add_unique(&hapd->dpp_chirp_freqs, 3773 bss->freq); 3774 } 3775 3776 if (!hapd->dpp_chirp_freqs || 3777 eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, 3778 hapd, NULL) < 0) 3779 hostapd_dpp_chirp_stop(hapd); 3780 3781 wpa_scan_results_free(scan_res); 3782 } 3783 3784 hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)3785 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx) 3786 { 3787 struct hostapd_data *hapd = eloop_ctx; 3788 int i; 3789 3790 if (hapd->dpp_chirp_listen) 3791 hostapd_dpp_listen_stop(hapd); 3792 3793 if (hapd->dpp_chirp_freq == 0) { 3794 if (hapd->dpp_chirp_round % 4 == 0 && 3795 !hapd->dpp_chirp_scan_done) { 3796 struct wpa_driver_scan_params params; 3797 int ret; 3798 3799 wpa_printf(MSG_DEBUG, 3800 "DPP: Update channel list for chirping"); 3801 os_memset(¶ms, 0, sizeof(params)); 3802 ret = hostapd_driver_scan(hapd, ¶ms); 3803 if (ret < 0) { 3804 wpa_printf(MSG_DEBUG, 3805 "DPP: Failed to request a scan ret=%d (%s)", 3806 ret, strerror(-ret)); 3807 hostapd_dpp_chirp_scan_res_handler(hapd->iface); 3808 } else { 3809 hapd->iface->scan_cb = 3810 hostapd_dpp_chirp_scan_res_handler; 3811 } 3812 return; 3813 } 3814 hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0]; 3815 hapd->dpp_chirp_round++; 3816 wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d", 3817 hapd->dpp_chirp_round); 3818 } else { 3819 for (i = 0; hapd->dpp_chirp_freqs[i]; i++) 3820 if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq) 3821 break; 3822 if (!hapd->dpp_chirp_freqs[i]) { 3823 wpa_printf(MSG_DEBUG, 3824 "DPP: Previous chirp freq %d not found", 3825 hapd->dpp_chirp_freq); 3826 return; 3827 } 3828 i++; 3829 if (hapd->dpp_chirp_freqs[i]) { 3830 hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i]; 3831 } else { 3832 hapd->dpp_chirp_iter--; 3833 if (hapd->dpp_chirp_iter <= 0) { 3834 wpa_printf(MSG_DEBUG, 3835 "DPP: Chirping iterations completed"); 3836 hostapd_dpp_chirp_stop(hapd); 3837 return; 3838 } 3839 hapd->dpp_chirp_freq = 0; 3840 hapd->dpp_chirp_scan_done = 0; 3841 if (eloop_register_timeout(30, 0, 3842 hostapd_dpp_chirp_next, 3843 hapd, NULL) < 0) { 3844 hostapd_dpp_chirp_stop(hapd); 3845 return; 3846 } 3847 if (hapd->dpp_chirp_listen) { 3848 wpa_printf(MSG_DEBUG, 3849 "DPP: Listen on %d MHz during chirp 30 second wait", 3850 hapd->dpp_chirp_listen); 3851 /* TODO: start listen on the channel */ 3852 } else { 3853 wpa_printf(MSG_DEBUG, 3854 "DPP: Wait 30 seconds before starting the next chirping round"); 3855 } 3856 return; 3857 } 3858 } 3859 3860 hostapd_dpp_chirp_start(hapd); 3861 } 3862 3863 hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)3864 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd) 3865 { 3866 const char *pos; 3867 int iter = 1, listen_freq = 0; 3868 struct dpp_bootstrap_info *bi; 3869 3870 pos = os_strstr(cmd, " own="); 3871 if (!pos) 3872 return -1; 3873 pos += 5; 3874 bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos)); 3875 if (!bi) { 3876 wpa_printf(MSG_DEBUG, 3877 "DPP: Identified bootstrap info not found"); 3878 return -1; 3879 } 3880 3881 pos = os_strstr(cmd, " iter="); 3882 if (pos) { 3883 iter = atoi(pos + 6); 3884 if (iter <= 0) 3885 return -1; 3886 } 3887 3888 pos = os_strstr(cmd, " listen="); 3889 if (pos) { 3890 listen_freq = atoi(pos + 8); 3891 if (listen_freq <= 0) 3892 return -1; 3893 } 3894 3895 hostapd_dpp_chirp_stop(hapd); 3896 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE; 3897 hapd->dpp_qr_mutual = 0; 3898 hapd->dpp_chirp_bi = bi; 3899 hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi); 3900 if (!hapd->dpp_presence_announcement) 3901 return -1; 3902 hapd->dpp_chirp_iter = iter; 3903 hapd->dpp_chirp_round = 0; 3904 hapd->dpp_chirp_scan_done = 0; 3905 hapd->dpp_chirp_listen = listen_freq; 3906 3907 return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL); 3908 } 3909 3910 hostapd_dpp_chirp_stop(struct hostapd_data * hapd)3911 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd) 3912 { 3913 if (hapd->dpp_presence_announcement) { 3914 hostapd_drv_send_action_cancel_wait(hapd); 3915 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED); 3916 } 3917 hapd->dpp_chirp_bi = NULL; 3918 wpabuf_free(hapd->dpp_presence_announcement); 3919 hapd->dpp_presence_announcement = NULL; 3920 if (hapd->dpp_chirp_listen) 3921 hostapd_dpp_listen_stop(hapd); 3922 hapd->dpp_chirp_listen = 0; 3923 hapd->dpp_chirp_freq = 0; 3924 os_free(hapd->dpp_chirp_freqs); 3925 hapd->dpp_chirp_freqs = NULL; 3926 eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL); 3927 eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL); 3928 if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) { 3929 /* TODO: abort ongoing scan */ 3930 hapd->iface->scan_cb = NULL; 3931 } 3932 } 3933 3934 handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)3935 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx) 3936 { 3937 struct dpp_bootstrap_info *bi = ctx; 3938 size_t i; 3939 3940 for (i = 0; i < iface->num_bss; i++) { 3941 struct hostapd_data *hapd = iface->bss[i]; 3942 3943 if (bi == hapd->dpp_chirp_bi) 3944 hostapd_dpp_chirp_stop(hapd); 3945 } 3946 3947 return 0; 3948 } 3949 3950 hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)3951 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi) 3952 { 3953 struct hapd_interfaces *interfaces = ctx; 3954 3955 hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi); 3956 } 3957 3958 #endif /* CONFIG_DPP2 */ 3959 3960 3961 #ifdef CONFIG_DPP3 3962 hostapd_dpp_push_button_expire(void * eloop_ctx,void * timeout_ctx)3963 static void hostapd_dpp_push_button_expire(void *eloop_ctx, void *timeout_ctx) 3964 { 3965 struct hostapd_data *hapd = eloop_ctx; 3966 3967 wpa_printf(MSG_DEBUG, "DPP: Active push button mode expired"); 3968 hostapd_dpp_push_button_stop(hapd); 3969 } 3970 3971 hostapd_dpp_push_button(struct hostapd_data * hapd,const char * cmd)3972 int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd) 3973 { 3974 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 3975 3976 if (!ifaces || !ifaces->dpp) 3977 return -1; 3978 os_get_reltime(&ifaces->dpp_pb_time); 3979 ifaces->dpp_pb_announce_time.sec = 0; 3980 ifaces->dpp_pb_announce_time.usec = 0; 3981 str_clear_free(ifaces->dpp_pb_cmd); 3982 ifaces->dpp_pb_cmd = NULL; 3983 if (cmd) { 3984 ifaces->dpp_pb_cmd = os_strdup(cmd); 3985 if (!ifaces->dpp_pb_cmd) 3986 return -1; 3987 } 3988 eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire, 3989 hapd, NULL); 3990 3991 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started"); 3992 return 0; 3993 } 3994 3995 hostapd_dpp_push_button_stop(struct hostapd_data * hapd)3996 void hostapd_dpp_push_button_stop(struct hostapd_data *hapd) 3997 { 3998 struct hapd_interfaces *ifaces = hapd->iface->interfaces; 3999 4000 if (!ifaces || !ifaces->dpp) 4001 return; 4002 eloop_cancel_timeout(hostapd_dpp_push_button_expire, hapd, NULL); 4003 if (hostapd_dpp_pb_active(hapd)) { 4004 wpa_printf(MSG_DEBUG, "DPP: Stop active push button mode"); 4005 if (!ifaces->dpp_pb_result_indicated) 4006 wpa_msg(hapd->msg_ctx, MSG_INFO, 4007 DPP_EVENT_PB_RESULT "failed"); 4008 } 4009 ifaces->dpp_pb_time.sec = 0; 4010 ifaces->dpp_pb_time.usec = 0; 4011 dpp_pkex_free(hapd->dpp_pkex); 4012 hapd->dpp_pkex = NULL; 4013 hapd->dpp_pkex_bi = NULL; 4014 os_free(hapd->dpp_pkex_auth_cmd); 4015 hapd->dpp_pkex_auth_cmd = NULL; 4016 4017 if (ifaces->dpp_pb_bi) { 4018 char id[20]; 4019 size_t i; 4020 4021 for (i = 0; i < ifaces->count; i++) { 4022 struct hostapd_iface *iface = ifaces->iface[i]; 4023 size_t j; 4024 4025 for (j = 0; iface && j < iface->num_bss; j++) { 4026 struct hostapd_data *h = iface->bss[j]; 4027 4028 if (h->dpp_pkex_bi == ifaces->dpp_pb_bi) 4029 h->dpp_pkex_bi = NULL; 4030 } 4031 } 4032 4033 os_snprintf(id, sizeof(id), "%u", ifaces->dpp_pb_bi->id); 4034 dpp_bootstrap_remove(ifaces->dpp, id); 4035 ifaces->dpp_pb_bi = NULL; 4036 } 4037 4038 ifaces->dpp_pb_result_indicated = false; 4039 4040 str_clear_free(ifaces->dpp_pb_cmd); 4041 ifaces->dpp_pb_cmd = NULL; 4042 } 4043 4044 #endif /* CONFIG_DPP3 */ 4045 4046 4047 #ifdef CONFIG_DPP2 hostapd_dpp_configurator_connectivity(struct hostapd_data * hapd)4048 bool hostapd_dpp_configurator_connectivity(struct hostapd_data *hapd) 4049 { 4050 return hapd->conf->dpp_configurator_connectivity || 4051 (hapd->iface->interfaces && 4052 dpp_relay_controller_available(hapd->iface->interfaces->dpp)); 4053 } 4054 #endif /* CONFIG_DPP2 */ 4055