1 /* 2 * hostapd / DPP integration 3 * Copyright (c) 2017, Qualcomm Atheros, Inc. 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "utils/includes.h" 10 11 #include "utils/common.h" 12 #include "utils/eloop.h" 13 #include "common/dpp.h" 14 #include "common/gas.h" 15 #include "common/wpa_ctrl.h" 16 #include "hostapd.h" 17 #include "ap_drv_ops.h" 18 #include "gas_query_ap.h" 19 #include "wpa_auth.h" 20 #include "dpp_hostapd.h" 21 22 23 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx); 24 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator); 25 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx); 26 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd); 27 28 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 29 30 31 /** 32 * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code 33 * @hapd: Pointer to hostapd_data 34 * @cmd: DPP URI read from a QR Code 35 * Returns: Identifier of the stored info or -1 on failure 36 */ 37 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd) 38 { 39 struct dpp_bootstrap_info *bi; 40 struct dpp_authentication *auth = hapd->dpp_auth; 41 42 bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd); 43 if (!bi) 44 return -1; 45 46 if (auth && auth->response_pending && 47 dpp_notify_new_qr_code(auth, bi) == 1) { 48 wpa_printf(MSG_DEBUG, 49 "DPP: Sending out pending authentication response"); 50 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 51 " freq=%u type=%d", 52 MAC2STR(auth->peer_mac_addr), auth->curr_freq, 53 DPP_PA_AUTHENTICATION_RESP); 54 hostapd_drv_send_action(hapd, auth->curr_freq, 0, 55 auth->peer_mac_addr, 56 wpabuf_head(hapd->dpp_auth->resp_msg), 57 wpabuf_len(hapd->dpp_auth->resp_msg)); 58 } 59 60 return bi->id; 61 } 62 63 64 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx, 65 void *timeout_ctx) 66 { 67 struct hostapd_data *hapd = eloop_ctx; 68 struct dpp_authentication *auth = hapd->dpp_auth; 69 70 if (!auth || !auth->resp_msg) 71 return; 72 73 wpa_printf(MSG_DEBUG, 74 "DPP: Retry Authentication Response after timeout"); 75 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 76 " freq=%u type=%d", 77 MAC2STR(auth->peer_mac_addr), auth->curr_freq, 78 DPP_PA_AUTHENTICATION_RESP); 79 hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr, 80 wpabuf_head(auth->resp_msg), 81 wpabuf_len(auth->resp_msg)); 82 } 83 84 85 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd) 86 { 87 struct dpp_authentication *auth = hapd->dpp_auth; 88 unsigned int wait_time, max_tries; 89 90 if (!auth || !auth->resp_msg) 91 return; 92 93 if (hapd->dpp_resp_max_tries) 94 max_tries = hapd->dpp_resp_max_tries; 95 else 96 max_tries = 5; 97 auth->auth_resp_tries++; 98 if (auth->auth_resp_tries >= max_tries) { 99 wpa_printf(MSG_INFO, 100 "DPP: No confirm received from initiator - stopping exchange"); 101 hostapd_drv_send_action_cancel_wait(hapd); 102 dpp_auth_deinit(hapd->dpp_auth); 103 hapd->dpp_auth = NULL; 104 return; 105 } 106 107 if (hapd->dpp_resp_retry_time) 108 wait_time = hapd->dpp_resp_retry_time; 109 else 110 wait_time = 1000; 111 wpa_printf(MSG_DEBUG, 112 "DPP: Schedule retransmission of Authentication Response frame in %u ms", 113 wait_time); 114 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 115 eloop_register_timeout(wait_time / 1000, 116 (wait_time % 1000) * 1000, 117 hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 118 } 119 120 121 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst, 122 const u8 *data, size_t data_len, int ok) 123 { 124 struct dpp_authentication *auth = hapd->dpp_auth; 125 126 wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d", 127 MAC2STR(dst), ok); 128 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR 129 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED"); 130 131 if (!hapd->dpp_auth) { 132 wpa_printf(MSG_DEBUG, 133 "DPP: Ignore TX status since there is no ongoing authentication exchange"); 134 return; 135 } 136 137 #ifdef CONFIG_DPP2 138 if (auth->connect_on_tx_status) { 139 wpa_printf(MSG_DEBUG, 140 "DPP: Complete exchange on configuration result"); 141 dpp_auth_deinit(hapd->dpp_auth); 142 hapd->dpp_auth = NULL; 143 return; 144 } 145 #endif /* CONFIG_DPP2 */ 146 147 if (hapd->dpp_auth->remove_on_tx_status) { 148 wpa_printf(MSG_DEBUG, 149 "DPP: Terminate authentication exchange due to an earlier error"); 150 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 151 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, 152 hapd, NULL); 153 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, 154 NULL); 155 hostapd_drv_send_action_cancel_wait(hapd); 156 dpp_auth_deinit(hapd->dpp_auth); 157 hapd->dpp_auth = NULL; 158 return; 159 } 160 161 if (hapd->dpp_auth_ok_on_ack) 162 hostapd_dpp_auth_success(hapd, 1); 163 164 if (!is_broadcast_ether_addr(dst) && !ok) { 165 wpa_printf(MSG_DEBUG, 166 "DPP: Unicast DPP Action frame was not ACKed"); 167 if (auth->waiting_auth_resp) { 168 /* In case of DPP Authentication Request frame, move to 169 * the next channel immediately. */ 170 hostapd_drv_send_action_cancel_wait(hapd); 171 hostapd_dpp_auth_init_next(hapd); 172 return; 173 } 174 if (auth->waiting_auth_conf) { 175 hostapd_dpp_auth_resp_retry(hapd); 176 return; 177 } 178 } 179 180 if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) { 181 /* Allow timeout handling to stop iteration if no response is 182 * received from a peer that has ACKed a request. */ 183 auth->auth_req_ack = 1; 184 } 185 186 if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 && 187 hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) { 188 wpa_printf(MSG_DEBUG, 189 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response", 190 hapd->dpp_auth->curr_freq, 191 hapd->dpp_auth->neg_freq); 192 hostapd_drv_send_action_cancel_wait(hapd); 193 194 if (hapd->dpp_auth->neg_freq != 195 (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) { 196 /* TODO: Listen operation on non-operating channel */ 197 wpa_printf(MSG_INFO, 198 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)", 199 hapd->dpp_auth->neg_freq, hapd->iface->freq); 200 } 201 } 202 203 if (hapd->dpp_auth_ok_on_ack) 204 hapd->dpp_auth_ok_on_ack = 0; 205 } 206 207 208 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx) 209 { 210 struct hostapd_data *hapd = eloop_ctx; 211 struct dpp_authentication *auth = hapd->dpp_auth; 212 unsigned int freq; 213 struct os_reltime now, diff; 214 unsigned int wait_time, diff_ms; 215 216 if (!auth || !auth->waiting_auth_resp) 217 return; 218 219 wait_time = hapd->dpp_resp_wait_time ? 220 hapd->dpp_resp_wait_time : 2000; 221 os_get_reltime(&now); 222 os_reltime_sub(&now, &hapd->dpp_last_init, &diff); 223 diff_ms = diff.sec * 1000 + diff.usec / 1000; 224 wpa_printf(MSG_DEBUG, 225 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u", 226 wait_time, diff_ms); 227 228 if (auth->auth_req_ack && diff_ms >= wait_time) { 229 /* Peer ACK'ed Authentication Request frame, but did not reply 230 * with Authentication Response frame within two seconds. */ 231 wpa_printf(MSG_INFO, 232 "DPP: No response received from responder - stopping initiation attempt"); 233 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED); 234 hostapd_drv_send_action_cancel_wait(hapd); 235 hostapd_dpp_listen_stop(hapd); 236 dpp_auth_deinit(auth); 237 hapd->dpp_auth = NULL; 238 return; 239 } 240 241 if (diff_ms >= wait_time) { 242 /* Authentication Request frame was not ACK'ed and no reply 243 * was receiving within two seconds. */ 244 wpa_printf(MSG_DEBUG, 245 "DPP: Continue Initiator channel iteration"); 246 hostapd_drv_send_action_cancel_wait(hapd); 247 hostapd_dpp_listen_stop(hapd); 248 hostapd_dpp_auth_init_next(hapd); 249 return; 250 } 251 252 /* Driver did not support 2000 ms long wait_time with TX command, so 253 * schedule listen operation to continue waiting for the response. 254 * 255 * DPP listen operations continue until stopped, so simply schedule a 256 * new call to this function at the point when the two second reply 257 * wait has expired. */ 258 wait_time -= diff_ms; 259 260 freq = auth->curr_freq; 261 if (auth->neg_freq > 0) 262 freq = auth->neg_freq; 263 wpa_printf(MSG_DEBUG, 264 "DPP: Continue reply wait on channel %u MHz for %u ms", 265 freq, wait_time); 266 hapd->dpp_in_response_listen = 1; 267 268 if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) { 269 /* TODO: Listen operation on non-operating channel */ 270 wpa_printf(MSG_INFO, 271 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)", 272 freq, hapd->iface->freq); 273 } 274 275 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000, 276 hostapd_dpp_reply_wait_timeout, hapd, NULL); 277 } 278 279 280 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd, 281 struct dpp_authentication *auth) 282 { 283 #ifdef CONFIG_TESTING_OPTIONS 284 if (hapd->dpp_config_obj_override) 285 auth->config_obj_override = 286 os_strdup(hapd->dpp_config_obj_override); 287 if (hapd->dpp_discovery_override) 288 auth->discovery_override = 289 os_strdup(hapd->dpp_discovery_override); 290 if (hapd->dpp_groups_override) 291 auth->groups_override = os_strdup(hapd->dpp_groups_override); 292 auth->ignore_netaccesskey_mismatch = 293 hapd->dpp_ignore_netaccesskey_mismatch; 294 #endif /* CONFIG_TESTING_OPTIONS */ 295 } 296 297 298 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx) 299 { 300 struct hostapd_data *hapd = eloop_ctx; 301 302 if (!hapd->dpp_auth) 303 return; 304 wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout"); 305 hostapd_dpp_auth_init_next(hapd); 306 } 307 308 309 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd) 310 { 311 struct dpp_authentication *auth = hapd->dpp_auth; 312 const u8 *dst; 313 unsigned int wait_time, max_wait_time, freq, max_tries, used; 314 struct os_reltime now, diff; 315 316 if (!auth) 317 return -1; 318 319 if (auth->freq_idx == 0) 320 os_get_reltime(&hapd->dpp_init_iter_start); 321 322 if (auth->freq_idx >= auth->num_freq) { 323 auth->num_freq_iters++; 324 if (hapd->dpp_init_max_tries) 325 max_tries = hapd->dpp_init_max_tries; 326 else 327 max_tries = 5; 328 if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) { 329 wpa_printf(MSG_INFO, 330 "DPP: No response received from responder - stopping initiation attempt"); 331 wpa_msg(hapd->msg_ctx, MSG_INFO, 332 DPP_EVENT_AUTH_INIT_FAILED); 333 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, 334 hapd, NULL); 335 hostapd_drv_send_action_cancel_wait(hapd); 336 dpp_auth_deinit(hapd->dpp_auth); 337 hapd->dpp_auth = NULL; 338 return -1; 339 } 340 auth->freq_idx = 0; 341 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 342 if (hapd->dpp_init_retry_time) 343 wait_time = hapd->dpp_init_retry_time; 344 else 345 wait_time = 10000; 346 os_get_reltime(&now); 347 os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff); 348 used = diff.sec * 1000 + diff.usec / 1000; 349 if (used > wait_time) 350 wait_time = 0; 351 else 352 wait_time -= used; 353 wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms", 354 wait_time); 355 eloop_register_timeout(wait_time / 1000, 356 (wait_time % 1000) * 1000, 357 hostapd_dpp_init_timeout, hapd, 358 NULL); 359 return 0; 360 } 361 freq = auth->freq[auth->freq_idx++]; 362 auth->curr_freq = freq; 363 364 if (is_zero_ether_addr(auth->peer_bi->mac_addr)) 365 dst = broadcast; 366 else 367 dst = auth->peer_bi->mac_addr; 368 hapd->dpp_auth_ok_on_ack = 0; 369 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 370 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */ 371 max_wait_time = hapd->dpp_resp_wait_time ? 372 hapd->dpp_resp_wait_time : 2000; 373 if (wait_time > max_wait_time) 374 wait_time = max_wait_time; 375 wait_time += 10; /* give the driver some extra time to complete */ 376 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000, 377 hostapd_dpp_reply_wait_timeout, hapd, NULL); 378 wait_time -= 10; 379 if (auth->neg_freq > 0 && freq != auth->neg_freq) { 380 wpa_printf(MSG_DEBUG, 381 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response", 382 freq, auth->neg_freq); 383 } 384 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 385 " freq=%u type=%d", 386 MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ); 387 auth->auth_req_ack = 0; 388 os_get_reltime(&hapd->dpp_last_init); 389 return hostapd_drv_send_action(hapd, freq, wait_time, 390 dst, 391 wpabuf_head(hapd->dpp_auth->req_msg), 392 wpabuf_len(hapd->dpp_auth->req_msg)); 393 } 394 395 396 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd) 397 { 398 const char *pos; 399 struct dpp_bootstrap_info *peer_bi, *own_bi = NULL; 400 u8 allowed_roles = DPP_CAPAB_CONFIGURATOR; 401 unsigned int neg_freq = 0; 402 403 pos = os_strstr(cmd, " peer="); 404 if (!pos) 405 return -1; 406 pos += 6; 407 peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos)); 408 if (!peer_bi) { 409 wpa_printf(MSG_INFO, 410 "DPP: Could not find bootstrapping info for the identified peer"); 411 return -1; 412 } 413 414 pos = os_strstr(cmd, " own="); 415 if (pos) { 416 pos += 5; 417 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, 418 atoi(pos)); 419 if (!own_bi) { 420 wpa_printf(MSG_INFO, 421 "DPP: Could not find bootstrapping info for the identified local entry"); 422 return -1; 423 } 424 425 if (peer_bi->curve != own_bi->curve) { 426 wpa_printf(MSG_INFO, 427 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)", 428 peer_bi->curve->name, own_bi->curve->name); 429 return -1; 430 } 431 } 432 433 pos = os_strstr(cmd, " role="); 434 if (pos) { 435 pos += 6; 436 if (os_strncmp(pos, "configurator", 12) == 0) 437 allowed_roles = DPP_CAPAB_CONFIGURATOR; 438 else if (os_strncmp(pos, "enrollee", 8) == 0) 439 allowed_roles = DPP_CAPAB_ENROLLEE; 440 else if (os_strncmp(pos, "either", 6) == 0) 441 allowed_roles = DPP_CAPAB_CONFIGURATOR | 442 DPP_CAPAB_ENROLLEE; 443 else 444 goto fail; 445 } 446 447 pos = os_strstr(cmd, " neg_freq="); 448 if (pos) 449 neg_freq = atoi(pos + 10); 450 451 if (hapd->dpp_auth) { 452 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 453 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, 454 hapd, NULL); 455 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, 456 NULL); 457 hostapd_drv_send_action_cancel_wait(hapd); 458 dpp_auth_deinit(hapd->dpp_auth); 459 } 460 461 hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi, 462 allowed_roles, neg_freq, 463 hapd->iface->hw_features, 464 hapd->iface->num_hw_features); 465 if (!hapd->dpp_auth) 466 goto fail; 467 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth); 468 if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx, 469 hapd->dpp_auth, cmd) < 0) { 470 dpp_auth_deinit(hapd->dpp_auth); 471 hapd->dpp_auth = NULL; 472 goto fail; 473 } 474 475 hapd->dpp_auth->neg_freq = neg_freq; 476 477 if (!is_zero_ether_addr(peer_bi->mac_addr)) 478 os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr, 479 ETH_ALEN); 480 481 return hostapd_dpp_auth_init_next(hapd); 482 fail: 483 return -1; 484 } 485 486 487 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd) 488 { 489 int freq; 490 491 freq = atoi(cmd); 492 if (freq <= 0) 493 return -1; 494 495 if (os_strstr(cmd, " role=configurator")) 496 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR; 497 else if (os_strstr(cmd, " role=enrollee")) 498 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE; 499 else 500 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | 501 DPP_CAPAB_ENROLLEE; 502 hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL; 503 504 if (freq != hapd->iface->freq && hapd->iface->freq > 0) { 505 /* TODO: Listen operation on non-operating channel */ 506 wpa_printf(MSG_INFO, 507 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)", 508 freq, hapd->iface->freq); 509 return -1; 510 } 511 512 return 0; 513 } 514 515 516 void hostapd_dpp_listen_stop(struct hostapd_data *hapd) 517 { 518 /* TODO: Stop listen operation on non-operating channel */ 519 } 520 521 522 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src, 523 const u8 *hdr, const u8 *buf, size_t len, 524 unsigned int freq) 525 { 526 const u8 *r_bootstrap, *i_bootstrap; 527 u16 r_bootstrap_len, i_bootstrap_len; 528 struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL; 529 530 if (!hapd->iface->interfaces->dpp) 531 return; 532 533 wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR, 534 MAC2STR(src)); 535 536 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 537 &r_bootstrap_len); 538 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { 539 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 540 "Missing or invalid required Responder Bootstrapping Key Hash attribute"); 541 return; 542 } 543 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash", 544 r_bootstrap, r_bootstrap_len); 545 546 i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 547 &i_bootstrap_len); 548 if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) { 549 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 550 "Missing or invalid required Initiator Bootstrapping Key Hash attribute"); 551 return; 552 } 553 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash", 554 i_bootstrap, i_bootstrap_len); 555 556 /* Try to find own and peer bootstrapping key matches based on the 557 * received hash values */ 558 dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap, 559 r_bootstrap, &own_bi, &peer_bi); 560 if (!own_bi) { 561 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 562 "No matching own bootstrapping key found - ignore message"); 563 return; 564 } 565 566 if (hapd->dpp_auth) { 567 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 568 "Already in DPP authentication exchange - ignore new one"); 569 return; 570 } 571 572 hapd->dpp_auth_ok_on_ack = 0; 573 hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles, 574 hapd->dpp_qr_mutual, 575 peer_bi, own_bi, freq, hdr, buf, len); 576 if (!hapd->dpp_auth) { 577 wpa_printf(MSG_DEBUG, "DPP: No response generated"); 578 return; 579 } 580 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth); 581 if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx, 582 hapd->dpp_auth, 583 hapd->dpp_configurator_params) < 0) { 584 dpp_auth_deinit(hapd->dpp_auth); 585 hapd->dpp_auth = NULL; 586 return; 587 } 588 os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN); 589 590 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 591 " freq=%u type=%d", 592 MAC2STR(src), hapd->dpp_auth->curr_freq, 593 DPP_PA_AUTHENTICATION_RESP); 594 hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0, 595 src, wpabuf_head(hapd->dpp_auth->resp_msg), 596 wpabuf_len(hapd->dpp_auth->resp_msg)); 597 } 598 599 600 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd, 601 struct dpp_authentication *auth) 602 { 603 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED); 604 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s", 605 dpp_akm_str(auth->akm)); 606 if (auth->ssid_len) 607 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s", 608 wpa_ssid_txt(auth->ssid, auth->ssid_len)); 609 if (auth->connector) { 610 /* TODO: Save the Connector and consider using a command 611 * to fetch the value instead of sending an event with 612 * it. The Connector could end up being larger than what 613 * most clients are ready to receive as an event 614 * message. */ 615 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s", 616 auth->connector); 617 } else if (auth->passphrase[0]) { 618 char hex[64 * 2 + 1]; 619 620 wpa_snprintf_hex(hex, sizeof(hex), 621 (const u8 *) auth->passphrase, 622 os_strlen(auth->passphrase)); 623 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s", 624 hex); 625 } else if (auth->psk_set) { 626 char hex[PMK_LEN * 2 + 1]; 627 628 wpa_snprintf_hex(hex, sizeof(hex), auth->psk, PMK_LEN); 629 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s", 630 hex); 631 } 632 if (auth->c_sign_key) { 633 char *hex; 634 size_t hexlen; 635 636 hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1; 637 hex = os_malloc(hexlen); 638 if (hex) { 639 wpa_snprintf_hex(hex, hexlen, 640 wpabuf_head(auth->c_sign_key), 641 wpabuf_len(auth->c_sign_key)); 642 wpa_msg(hapd->msg_ctx, MSG_INFO, 643 DPP_EVENT_C_SIGN_KEY "%s", hex); 644 os_free(hex); 645 } 646 } 647 if (auth->net_access_key) { 648 char *hex; 649 size_t hexlen; 650 651 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1; 652 hex = os_malloc(hexlen); 653 if (hex) { 654 wpa_snprintf_hex(hex, hexlen, 655 wpabuf_head(auth->net_access_key), 656 wpabuf_len(auth->net_access_key)); 657 if (auth->net_access_key_expiry) 658 wpa_msg(hapd->msg_ctx, MSG_INFO, 659 DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex, 660 (unsigned long) 661 auth->net_access_key_expiry); 662 else 663 wpa_msg(hapd->msg_ctx, MSG_INFO, 664 DPP_EVENT_NET_ACCESS_KEY "%s", hex); 665 os_free(hex); 666 } 667 } 668 } 669 670 671 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, 672 enum gas_query_ap_result result, 673 const struct wpabuf *adv_proto, 674 const struct wpabuf *resp, u16 status_code) 675 { 676 struct hostapd_data *hapd = ctx; 677 const u8 *pos; 678 struct dpp_authentication *auth = hapd->dpp_auth; 679 enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED; 680 681 if (!auth || !auth->auth_success) { 682 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); 683 return; 684 } 685 if (!resp || status_code != WLAN_STATUS_SUCCESS) { 686 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed"); 687 goto fail; 688 } 689 690 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto", 691 adv_proto); 692 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)", 693 resp); 694 695 if (wpabuf_len(adv_proto) != 10 || 696 !(pos = wpabuf_head(adv_proto)) || 697 pos[0] != WLAN_EID_ADV_PROTO || 698 pos[1] != 8 || 699 pos[3] != WLAN_EID_VENDOR_SPECIFIC || 700 pos[4] != 5 || 701 WPA_GET_BE24(&pos[5]) != OUI_WFA || 702 pos[8] != 0x1a || 703 pos[9] != 1) { 704 wpa_printf(MSG_DEBUG, 705 "DPP: Not a DPP Advertisement Protocol ID"); 706 goto fail; 707 } 708 709 if (dpp_conf_resp_rx(auth, resp) < 0) { 710 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed"); 711 goto fail; 712 } 713 714 hostapd_dpp_handle_config_obj(hapd, auth); 715 status = DPP_STATUS_OK; 716 #ifdef CONFIG_TESTING_OPTIONS 717 if (dpp_test == DPP_TEST_REJECT_CONFIG) { 718 wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object"); 719 status = DPP_STATUS_CONFIG_REJECTED; 720 } 721 #endif /* CONFIG_TESTING_OPTIONS */ 722 fail: 723 if (status != DPP_STATUS_OK) 724 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 725 #ifdef CONFIG_DPP2 726 if (auth->peer_version >= 2 && 727 auth->conf_resp_status == DPP_STATUS_OK) { 728 struct wpabuf *msg; 729 730 wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result"); 731 msg = dpp_build_conf_result(auth, status); 732 if (!msg) 733 goto fail2; 734 735 wpa_msg(hapd->msg_ctx, MSG_INFO, 736 DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d", 737 MAC2STR(addr), auth->curr_freq, 738 DPP_PA_CONFIGURATION_RESULT); 739 hostapd_drv_send_action(hapd, auth->curr_freq, 0, 740 addr, wpabuf_head(msg), 741 wpabuf_len(msg)); 742 wpabuf_free(msg); 743 744 /* This exchange will be terminated in the TX status handler */ 745 auth->connect_on_tx_status = 1; 746 return; 747 } 748 fail2: 749 #endif /* CONFIG_DPP2 */ 750 dpp_auth_deinit(hapd->dpp_auth); 751 hapd->dpp_auth = NULL; 752 } 753 754 755 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd) 756 { 757 struct dpp_authentication *auth = hapd->dpp_auth; 758 struct wpabuf *buf; 759 char json[100]; 760 int res; 761 int netrole_ap = 1; 762 763 os_snprintf(json, sizeof(json), 764 "{\"name\":\"Test\"," 765 "\"wi-fi_tech\":\"infra\"," 766 "\"netRole\":\"%s\"}", 767 netrole_ap ? "ap" : "sta"); 768 wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json); 769 770 buf = dpp_build_conf_req(auth, json); 771 if (!buf) { 772 wpa_printf(MSG_DEBUG, 773 "DPP: No configuration request data available"); 774 return; 775 } 776 777 wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)", 778 MAC2STR(auth->peer_mac_addr), auth->curr_freq); 779 780 res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq, 781 buf, hostapd_dpp_gas_resp_cb, hapd); 782 if (res < 0) { 783 wpa_msg(hapd->msg_ctx, MSG_DEBUG, 784 "GAS: Failed to send Query Request"); 785 wpabuf_free(buf); 786 } else { 787 wpa_printf(MSG_DEBUG, 788 "DPP: GAS query started with dialog token %u", res); 789 } 790 } 791 792 793 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator) 794 { 795 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded"); 796 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d", 797 initiator); 798 #ifdef CONFIG_TESTING_OPTIONS 799 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) { 800 wpa_printf(MSG_INFO, 801 "DPP: TESTING - stop at Authentication Confirm"); 802 if (hapd->dpp_auth->configurator) { 803 /* Prevent GAS response */ 804 hapd->dpp_auth->auth_success = 0; 805 } 806 return; 807 } 808 #endif /* CONFIG_TESTING_OPTIONS */ 809 810 if (!hapd->dpp_auth->configurator) 811 hostapd_dpp_start_gas_client(hapd); 812 } 813 814 815 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src, 816 const u8 *hdr, const u8 *buf, size_t len, 817 unsigned int freq) 818 { 819 struct dpp_authentication *auth = hapd->dpp_auth; 820 struct wpabuf *msg; 821 822 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR, 823 MAC2STR(src)); 824 825 if (!auth) { 826 wpa_printf(MSG_DEBUG, 827 "DPP: No DPP Authentication in progress - drop"); 828 return; 829 } 830 831 if (!is_zero_ether_addr(auth->peer_mac_addr) && 832 os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { 833 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 834 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 835 return; 836 } 837 838 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 839 840 if (auth->curr_freq != freq && auth->neg_freq == freq) { 841 wpa_printf(MSG_DEBUG, 842 "DPP: Responder accepted request for different negotiation channel"); 843 auth->curr_freq = freq; 844 } 845 846 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 847 msg = dpp_auth_resp_rx(auth, hdr, buf, len); 848 if (!msg) { 849 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) { 850 wpa_printf(MSG_DEBUG, "DPP: Wait for full response"); 851 return; 852 } 853 wpa_printf(MSG_DEBUG, "DPP: No confirm generated"); 854 return; 855 } 856 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN); 857 858 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 859 " freq=%u type=%d", MAC2STR(src), auth->curr_freq, 860 DPP_PA_AUTHENTICATION_CONF); 861 hostapd_drv_send_action(hapd, auth->curr_freq, 0, src, 862 wpabuf_head(msg), wpabuf_len(msg)); 863 wpabuf_free(msg); 864 hapd->dpp_auth_ok_on_ack = 1; 865 } 866 867 868 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src, 869 const u8 *hdr, const u8 *buf, size_t len) 870 { 871 struct dpp_authentication *auth = hapd->dpp_auth; 872 873 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR, 874 MAC2STR(src)); 875 876 if (!auth) { 877 wpa_printf(MSG_DEBUG, 878 "DPP: No DPP Authentication in progress - drop"); 879 return; 880 } 881 882 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { 883 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 884 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 885 return; 886 } 887 888 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) { 889 wpa_printf(MSG_DEBUG, "DPP: Authentication failed"); 890 return; 891 } 892 893 hostapd_dpp_auth_success(hapd, 0); 894 } 895 896 897 #ifdef CONFIG_DPP2 898 899 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx, 900 void *timeout_ctx) 901 { 902 struct hostapd_data *hapd = eloop_ctx; 903 struct dpp_authentication *auth = hapd->dpp_auth; 904 905 if (!auth || !auth->waiting_conf_result) 906 return; 907 908 wpa_printf(MSG_DEBUG, 909 "DPP: Timeout while waiting for Configuration Result"); 910 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 911 dpp_auth_deinit(auth); 912 hapd->dpp_auth = NULL; 913 } 914 915 916 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src, 917 const u8 *hdr, const u8 *buf, size_t len) 918 { 919 struct dpp_authentication *auth = hapd->dpp_auth; 920 enum dpp_status_error status; 921 922 wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR, 923 MAC2STR(src)); 924 925 if (!auth || !auth->waiting_conf_result) { 926 wpa_printf(MSG_DEBUG, 927 "DPP: No DPP Configuration waiting for result - drop"); 928 return; 929 } 930 931 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { 932 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 933 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 934 return; 935 } 936 937 status = dpp_conf_result_rx(auth, hdr, buf, len); 938 939 hostapd_drv_send_action_cancel_wait(hapd); 940 hostapd_dpp_listen_stop(hapd); 941 if (status == DPP_STATUS_OK) 942 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT); 943 else 944 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 945 dpp_auth_deinit(auth); 946 hapd->dpp_auth = NULL; 947 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd, 948 NULL); 949 } 950 951 #endif /* CONFIG_DPP2 */ 952 953 954 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd, 955 const u8 *src, unsigned int freq, 956 u8 trans_id, 957 enum dpp_status_error status) 958 { 959 struct wpabuf *msg; 960 961 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, 962 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector)); 963 if (!msg) 964 return; 965 966 #ifdef CONFIG_TESTING_OPTIONS 967 if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) { 968 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID"); 969 goto skip_trans_id; 970 } 971 if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) { 972 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID"); 973 trans_id ^= 0x01; 974 } 975 #endif /* CONFIG_TESTING_OPTIONS */ 976 977 /* Transaction ID */ 978 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID); 979 wpabuf_put_le16(msg, 1); 980 wpabuf_put_u8(msg, trans_id); 981 982 #ifdef CONFIG_TESTING_OPTIONS 983 skip_trans_id: 984 if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) { 985 wpa_printf(MSG_INFO, "DPP: TESTING - no Status"); 986 goto skip_status; 987 } 988 if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) { 989 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status"); 990 status = 254; 991 } 992 #endif /* CONFIG_TESTING_OPTIONS */ 993 994 /* DPP Status */ 995 wpabuf_put_le16(msg, DPP_ATTR_STATUS); 996 wpabuf_put_le16(msg, 1); 997 wpabuf_put_u8(msg, status); 998 999 #ifdef CONFIG_TESTING_OPTIONS 1000 skip_status: 1001 if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) { 1002 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector"); 1003 goto skip_connector; 1004 } 1005 if (status == DPP_STATUS_OK && 1006 dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) { 1007 char *connector; 1008 1009 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector"); 1010 connector = dpp_corrupt_connector_signature( 1011 hapd->conf->dpp_connector); 1012 if (!connector) { 1013 wpabuf_free(msg); 1014 return; 1015 } 1016 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 1017 wpabuf_put_le16(msg, os_strlen(connector)); 1018 wpabuf_put_str(msg, connector); 1019 os_free(connector); 1020 goto skip_connector; 1021 } 1022 #endif /* CONFIG_TESTING_OPTIONS */ 1023 1024 /* DPP Connector */ 1025 if (status == DPP_STATUS_OK) { 1026 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 1027 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector)); 1028 wpabuf_put_str(msg, hapd->conf->dpp_connector); 1029 } 1030 1031 #ifdef CONFIG_TESTING_OPTIONS 1032 skip_connector: 1033 #endif /* CONFIG_TESTING_OPTIONS */ 1034 1035 wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR 1036 " status=%d", MAC2STR(src), status); 1037 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1038 " freq=%u type=%d status=%d", MAC2STR(src), freq, 1039 DPP_PA_PEER_DISCOVERY_RESP, status); 1040 hostapd_drv_send_action(hapd, freq, 0, src, 1041 wpabuf_head(msg), wpabuf_len(msg)); 1042 wpabuf_free(msg); 1043 } 1044 1045 1046 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, 1047 const u8 *src, 1048 const u8 *buf, size_t len, 1049 unsigned int freq) 1050 { 1051 const u8 *connector, *trans_id; 1052 u16 connector_len, trans_id_len; 1053 struct os_time now; 1054 struct dpp_introduction intro; 1055 os_time_t expire; 1056 int expiration; 1057 enum dpp_status_error res; 1058 1059 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR, 1060 MAC2STR(src)); 1061 if (!hapd->wpa_auth || 1062 !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) || 1063 !(hapd->conf->wpa & WPA_PROTO_RSN)) { 1064 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use"); 1065 return; 1066 } 1067 1068 if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey || 1069 !hapd->conf->dpp_csign) { 1070 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set"); 1071 return; 1072 } 1073 1074 os_get_time(&now); 1075 1076 if (hapd->conf->dpp_netaccesskey_expiry && 1077 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) { 1078 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired"); 1079 return; 1080 } 1081 1082 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, 1083 &trans_id_len); 1084 if (!trans_id || trans_id_len != 1) { 1085 wpa_printf(MSG_DEBUG, 1086 "DPP: Peer did not include Transaction ID"); 1087 return; 1088 } 1089 1090 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len); 1091 if (!connector) { 1092 wpa_printf(MSG_DEBUG, 1093 "DPP: Peer did not include its Connector"); 1094 return; 1095 } 1096 1097 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector, 1098 wpabuf_head(hapd->conf->dpp_netaccesskey), 1099 wpabuf_len(hapd->conf->dpp_netaccesskey), 1100 wpabuf_head(hapd->conf->dpp_csign), 1101 wpabuf_len(hapd->conf->dpp_csign), 1102 connector, connector_len, &expire); 1103 if (res == 255) { 1104 wpa_printf(MSG_INFO, 1105 "DPP: Network Introduction protocol resulted in internal failure (peer " 1106 MACSTR ")", MAC2STR(src)); 1107 return; 1108 } 1109 if (res != DPP_STATUS_OK) { 1110 wpa_printf(MSG_INFO, 1111 "DPP: Network Introduction protocol resulted in failure (peer " 1112 MACSTR " status %d)", MAC2STR(src), res); 1113 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0], 1114 res); 1115 return; 1116 } 1117 1118 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire) 1119 expire = hapd->conf->dpp_netaccesskey_expiry; 1120 if (expire) 1121 expiration = expire - now.sec; 1122 else 1123 expiration = 0; 1124 1125 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, 1126 intro.pmkid, expiration, 1127 WPA_KEY_MGMT_DPP) < 0) { 1128 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry"); 1129 return; 1130 } 1131 1132 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0], 1133 DPP_STATUS_OK); 1134 } 1135 1136 1137 static void 1138 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src, 1139 const u8 *buf, size_t len, 1140 unsigned int freq) 1141 { 1142 struct wpabuf *msg; 1143 1144 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR, 1145 MAC2STR(src)); 1146 1147 /* TODO: Support multiple PKEX codes by iterating over all the enabled 1148 * values here */ 1149 1150 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) { 1151 wpa_printf(MSG_DEBUG, 1152 "DPP: No PKEX code configured - ignore request"); 1153 return; 1154 } 1155 1156 if (hapd->dpp_pkex) { 1157 /* TODO: Support parallel operations */ 1158 wpa_printf(MSG_DEBUG, 1159 "DPP: Already in PKEX session - ignore new request"); 1160 return; 1161 } 1162 1163 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx, 1164 hapd->dpp_pkex_bi, 1165 hapd->own_addr, src, 1166 hapd->dpp_pkex_identifier, 1167 hapd->dpp_pkex_code, 1168 buf, len); 1169 if (!hapd->dpp_pkex) { 1170 wpa_printf(MSG_DEBUG, 1171 "DPP: Failed to process the request - ignore it"); 1172 return; 1173 } 1174 1175 msg = hapd->dpp_pkex->exchange_resp; 1176 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1177 " freq=%u type=%d", MAC2STR(src), freq, 1178 DPP_PA_PKEX_EXCHANGE_RESP); 1179 hostapd_drv_send_action(hapd, freq, 0, src, 1180 wpabuf_head(msg), wpabuf_len(msg)); 1181 if (hapd->dpp_pkex->failed) { 1182 wpa_printf(MSG_DEBUG, 1183 "DPP: Terminate PKEX exchange due to an earlier error"); 1184 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t) 1185 hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t; 1186 dpp_pkex_free(hapd->dpp_pkex); 1187 hapd->dpp_pkex = NULL; 1188 } 1189 } 1190 1191 1192 static void 1193 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src, 1194 const u8 *buf, size_t len, unsigned int freq) 1195 { 1196 struct wpabuf *msg; 1197 1198 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR, 1199 MAC2STR(src)); 1200 1201 /* TODO: Support multiple PKEX codes by iterating over all the enabled 1202 * values here */ 1203 1204 if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator || 1205 hapd->dpp_pkex->exchange_done) { 1206 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1207 return; 1208 } 1209 1210 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len); 1211 if (!msg) { 1212 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 1213 return; 1214 } 1215 1216 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR, 1217 MAC2STR(src)); 1218 1219 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1220 " freq=%u type=%d", MAC2STR(src), freq, 1221 DPP_PA_PKEX_COMMIT_REVEAL_REQ); 1222 hostapd_drv_send_action(hapd, freq, 0, src, 1223 wpabuf_head(msg), wpabuf_len(msg)); 1224 wpabuf_free(msg); 1225 } 1226 1227 1228 static void 1229 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src, 1230 const u8 *hdr, const u8 *buf, size_t len, 1231 unsigned int freq) 1232 { 1233 struct wpabuf *msg; 1234 struct dpp_pkex *pkex = hapd->dpp_pkex; 1235 struct dpp_bootstrap_info *bi; 1236 1237 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR, 1238 MAC2STR(src)); 1239 1240 if (!pkex || pkex->initiator || !pkex->exchange_done) { 1241 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1242 return; 1243 } 1244 1245 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len); 1246 if (!msg) { 1247 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request"); 1248 if (hapd->dpp_pkex->failed) { 1249 wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange"); 1250 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t) 1251 hapd->dpp_pkex->own_bi->pkex_t = 1252 hapd->dpp_pkex->t; 1253 dpp_pkex_free(hapd->dpp_pkex); 1254 hapd->dpp_pkex = NULL; 1255 } 1256 return; 1257 } 1258 1259 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to " 1260 MACSTR, MAC2STR(src)); 1261 1262 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1263 " freq=%u type=%d", MAC2STR(src), freq, 1264 DPP_PA_PKEX_COMMIT_REVEAL_RESP); 1265 hostapd_drv_send_action(hapd, freq, 0, src, 1266 wpabuf_head(msg), wpabuf_len(msg)); 1267 wpabuf_free(msg); 1268 1269 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq); 1270 if (!bi) 1271 return; 1272 hapd->dpp_pkex = NULL; 1273 } 1274 1275 1276 static void 1277 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src, 1278 const u8 *hdr, const u8 *buf, size_t len, 1279 unsigned int freq) 1280 { 1281 int res; 1282 struct dpp_bootstrap_info *bi; 1283 struct dpp_pkex *pkex = hapd->dpp_pkex; 1284 char cmd[500]; 1285 1286 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR, 1287 MAC2STR(src)); 1288 1289 if (!pkex || !pkex->initiator || !pkex->exchange_done) { 1290 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1291 return; 1292 } 1293 1294 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len); 1295 if (res < 0) { 1296 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 1297 return; 1298 } 1299 1300 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq); 1301 if (!bi) 1302 return; 1303 hapd->dpp_pkex = NULL; 1304 1305 os_snprintf(cmd, sizeof(cmd), " peer=%u %s", 1306 bi->id, 1307 hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : ""); 1308 wpa_printf(MSG_DEBUG, 1309 "DPP: Start authentication after PKEX with parameters: %s", 1310 cmd); 1311 if (hostapd_dpp_auth_init(hapd, cmd) < 0) { 1312 wpa_printf(MSG_DEBUG, 1313 "DPP: Authentication initialization failed"); 1314 return; 1315 } 1316 } 1317 1318 1319 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src, 1320 const u8 *buf, size_t len, unsigned int freq) 1321 { 1322 u8 crypto_suite; 1323 enum dpp_public_action_frame_type type; 1324 const u8 *hdr; 1325 unsigned int pkex_t; 1326 1327 if (len < DPP_HDR_LEN) 1328 return; 1329 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE) 1330 return; 1331 hdr = buf; 1332 buf += 4; 1333 len -= 4; 1334 crypto_suite = *buf++; 1335 type = *buf++; 1336 len -= 2; 1337 1338 wpa_printf(MSG_DEBUG, 1339 "DPP: Received DPP Public Action frame crypto suite %u type %d from " 1340 MACSTR " freq=%u", 1341 crypto_suite, type, MAC2STR(src), freq); 1342 if (crypto_suite != 1) { 1343 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u", 1344 crypto_suite); 1345 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 1346 " freq=%u type=%d ignore=unsupported-crypto-suite", 1347 MAC2STR(src), freq, type); 1348 return; 1349 } 1350 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len); 1351 if (dpp_check_attrs(buf, len) < 0) { 1352 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 1353 " freq=%u type=%d ignore=invalid-attributes", 1354 MAC2STR(src), freq, type); 1355 return; 1356 } 1357 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 1358 " freq=%u type=%d", MAC2STR(src), freq, type); 1359 1360 switch (type) { 1361 case DPP_PA_AUTHENTICATION_REQ: 1362 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq); 1363 break; 1364 case DPP_PA_AUTHENTICATION_RESP: 1365 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq); 1366 break; 1367 case DPP_PA_AUTHENTICATION_CONF: 1368 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len); 1369 break; 1370 case DPP_PA_PEER_DISCOVERY_REQ: 1371 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq); 1372 break; 1373 case DPP_PA_PKEX_EXCHANGE_REQ: 1374 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq); 1375 break; 1376 case DPP_PA_PKEX_EXCHANGE_RESP: 1377 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq); 1378 break; 1379 case DPP_PA_PKEX_COMMIT_REVEAL_REQ: 1380 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len, 1381 freq); 1382 break; 1383 case DPP_PA_PKEX_COMMIT_REVEAL_RESP: 1384 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len, 1385 freq); 1386 break; 1387 #ifdef CONFIG_DPP2 1388 case DPP_PA_CONFIGURATION_RESULT: 1389 hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len); 1390 break; 1391 #endif /* CONFIG_DPP2 */ 1392 default: 1393 wpa_printf(MSG_DEBUG, 1394 "DPP: Ignored unsupported frame subtype %d", type); 1395 break; 1396 } 1397 1398 if (hapd->dpp_pkex) 1399 pkex_t = hapd->dpp_pkex->t; 1400 else if (hapd->dpp_pkex_bi) 1401 pkex_t = hapd->dpp_pkex_bi->pkex_t; 1402 else 1403 pkex_t = 0; 1404 if (pkex_t >= PKEX_COUNTER_T_LIMIT) { 1405 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0"); 1406 hostapd_dpp_pkex_remove(hapd, "*"); 1407 } 1408 } 1409 1410 1411 struct wpabuf * 1412 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa, 1413 const u8 *query, size_t query_len) 1414 { 1415 struct dpp_authentication *auth = hapd->dpp_auth; 1416 struct wpabuf *resp; 1417 1418 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa)); 1419 if (!auth || !auth->auth_success || 1420 os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) { 1421 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); 1422 return NULL; 1423 } 1424 wpa_hexdump(MSG_DEBUG, 1425 "DPP: Received Configuration Request (GAS Query Request)", 1426 query, query_len); 1427 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR, 1428 MAC2STR(sa)); 1429 resp = dpp_conf_req_rx(auth, query, query_len); 1430 if (!resp) 1431 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1432 return resp; 1433 } 1434 1435 1436 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok) 1437 { 1438 struct dpp_authentication *auth = hapd->dpp_auth; 1439 1440 if (!auth) 1441 return; 1442 1443 wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)", 1444 ok); 1445 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 1446 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 1447 #ifdef CONFIG_DPP2 1448 if (ok && auth->peer_version >= 2 && 1449 auth->conf_resp_status == DPP_STATUS_OK) { 1450 wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result"); 1451 auth->waiting_conf_result = 1; 1452 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, 1453 hapd, NULL); 1454 eloop_register_timeout(2, 0, 1455 hostapd_dpp_config_result_wait_timeout, 1456 hapd, NULL); 1457 return; 1458 } 1459 #endif /* CONFIG_DPP2 */ 1460 hostapd_drv_send_action_cancel_wait(hapd); 1461 1462 if (ok) 1463 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT); 1464 else 1465 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1466 dpp_auth_deinit(hapd->dpp_auth); 1467 hapd->dpp_auth = NULL; 1468 } 1469 1470 1471 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd) 1472 { 1473 struct dpp_authentication *auth; 1474 int ret = -1; 1475 char *curve = NULL; 1476 1477 auth = os_zalloc(sizeof(*auth)); 1478 if (!auth) 1479 return -1; 1480 1481 curve = get_param(cmd, " curve="); 1482 hostapd_dpp_set_testing_options(hapd, auth); 1483 if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx, 1484 auth, cmd) == 0 && 1485 dpp_configurator_own_config(auth, curve, 1) == 0) { 1486 hostapd_dpp_handle_config_obj(hapd, auth); 1487 ret = 0; 1488 } 1489 1490 dpp_auth_deinit(auth); 1491 os_free(curve); 1492 1493 return ret; 1494 } 1495 1496 1497 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd) 1498 { 1499 struct dpp_bootstrap_info *own_bi; 1500 const char *pos, *end; 1501 1502 pos = os_strstr(cmd, " own="); 1503 if (!pos) 1504 return -1; 1505 pos += 5; 1506 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos)); 1507 if (!own_bi) { 1508 wpa_printf(MSG_DEBUG, 1509 "DPP: Identified bootstrap info not found"); 1510 return -1; 1511 } 1512 if (own_bi->type != DPP_BOOTSTRAP_PKEX) { 1513 wpa_printf(MSG_DEBUG, 1514 "DPP: Identified bootstrap info not for PKEX"); 1515 return -1; 1516 } 1517 hapd->dpp_pkex_bi = own_bi; 1518 own_bi->pkex_t = 0; /* clear pending errors on new code */ 1519 1520 os_free(hapd->dpp_pkex_identifier); 1521 hapd->dpp_pkex_identifier = NULL; 1522 pos = os_strstr(cmd, " identifier="); 1523 if (pos) { 1524 pos += 12; 1525 end = os_strchr(pos, ' '); 1526 if (!end) 1527 return -1; 1528 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1); 1529 if (!hapd->dpp_pkex_identifier) 1530 return -1; 1531 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos); 1532 hapd->dpp_pkex_identifier[end - pos] = '\0'; 1533 } 1534 1535 pos = os_strstr(cmd, " code="); 1536 if (!pos) 1537 return -1; 1538 os_free(hapd->dpp_pkex_code); 1539 hapd->dpp_pkex_code = os_strdup(pos + 6); 1540 if (!hapd->dpp_pkex_code) 1541 return -1; 1542 1543 if (os_strstr(cmd, " init=1")) { 1544 struct wpabuf *msg; 1545 1546 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX"); 1547 dpp_pkex_free(hapd->dpp_pkex); 1548 hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi, 1549 hapd->own_addr, 1550 hapd->dpp_pkex_identifier, 1551 hapd->dpp_pkex_code); 1552 if (!hapd->dpp_pkex) 1553 return -1; 1554 1555 msg = hapd->dpp_pkex->exchange_req; 1556 /* TODO: Which channel to use? */ 1557 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1558 " freq=%u type=%d", MAC2STR(broadcast), 2437, 1559 DPP_PA_PKEX_EXCHANGE_REQ); 1560 hostapd_drv_send_action(hapd, 2437, 0, broadcast, 1561 wpabuf_head(msg), wpabuf_len(msg)); 1562 } 1563 1564 /* TODO: Support multiple PKEX info entries */ 1565 1566 os_free(hapd->dpp_pkex_auth_cmd); 1567 hapd->dpp_pkex_auth_cmd = os_strdup(cmd); 1568 1569 return 1; 1570 } 1571 1572 1573 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id) 1574 { 1575 unsigned int id_val; 1576 1577 if (os_strcmp(id, "*") == 0) { 1578 id_val = 0; 1579 } else { 1580 id_val = atoi(id); 1581 if (id_val == 0) 1582 return -1; 1583 } 1584 1585 if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code) 1586 return -1; 1587 1588 /* TODO: Support multiple PKEX entries */ 1589 os_free(hapd->dpp_pkex_code); 1590 hapd->dpp_pkex_code = NULL; 1591 os_free(hapd->dpp_pkex_identifier); 1592 hapd->dpp_pkex_identifier = NULL; 1593 os_free(hapd->dpp_pkex_auth_cmd); 1594 hapd->dpp_pkex_auth_cmd = NULL; 1595 hapd->dpp_pkex_bi = NULL; 1596 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */ 1597 dpp_pkex_free(hapd->dpp_pkex); 1598 hapd->dpp_pkex = NULL; 1599 return 0; 1600 } 1601 1602 1603 void hostapd_dpp_stop(struct hostapd_data *hapd) 1604 { 1605 dpp_auth_deinit(hapd->dpp_auth); 1606 hapd->dpp_auth = NULL; 1607 dpp_pkex_free(hapd->dpp_pkex); 1608 hapd->dpp_pkex = NULL; 1609 } 1610 1611 1612 int hostapd_dpp_init(struct hostapd_data *hapd) 1613 { 1614 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE; 1615 hapd->dpp_init_done = 1; 1616 return 0; 1617 } 1618 1619 1620 void hostapd_dpp_deinit(struct hostapd_data *hapd) 1621 { 1622 #ifdef CONFIG_TESTING_OPTIONS 1623 os_free(hapd->dpp_config_obj_override); 1624 hapd->dpp_config_obj_override = NULL; 1625 os_free(hapd->dpp_discovery_override); 1626 hapd->dpp_discovery_override = NULL; 1627 os_free(hapd->dpp_groups_override); 1628 hapd->dpp_groups_override = NULL; 1629 hapd->dpp_ignore_netaccesskey_mismatch = 0; 1630 #endif /* CONFIG_TESTING_OPTIONS */ 1631 if (!hapd->dpp_init_done) 1632 return; 1633 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 1634 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 1635 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 1636 #ifdef CONFIG_DPP2 1637 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd, 1638 NULL); 1639 #endif /* CONFIG_DPP2 */ 1640 dpp_auth_deinit(hapd->dpp_auth); 1641 hapd->dpp_auth = NULL; 1642 hostapd_dpp_pkex_remove(hapd, "*"); 1643 hapd->dpp_pkex = NULL; 1644 os_free(hapd->dpp_configurator_params); 1645 hapd->dpp_configurator_params = NULL; 1646 } 1647