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 static struct dpp_configurator * 32 hostapd_dpp_configurator_get_id(struct hostapd_data *hapd, unsigned int id) 33 { 34 struct dpp_configurator *conf; 35 36 dl_list_for_each(conf, &hapd->iface->interfaces->dpp_configurator, 37 struct dpp_configurator, list) { 38 if (conf->id == id) 39 return conf; 40 } 41 return NULL; 42 } 43 44 45 static unsigned int hapd_dpp_next_id(struct hostapd_data *hapd) 46 { 47 struct dpp_bootstrap_info *bi; 48 unsigned int max_id = 0; 49 50 dl_list_for_each(bi, &hapd->iface->interfaces->dpp_bootstrap, 51 struct dpp_bootstrap_info, list) { 52 if (bi->id > max_id) 53 max_id = bi->id; 54 } 55 return max_id + 1; 56 } 57 58 59 /** 60 * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code 61 * @hapd: Pointer to hostapd_data 62 * @cmd: DPP URI read from a QR Code 63 * Returns: Identifier of the stored info or -1 on failure 64 */ 65 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd) 66 { 67 struct dpp_bootstrap_info *bi; 68 struct dpp_authentication *auth = hapd->dpp_auth; 69 70 bi = dpp_parse_qr_code(cmd); 71 if (!bi) 72 return -1; 73 74 bi->id = hapd_dpp_next_id(hapd); 75 dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list); 76 77 if (auth && auth->response_pending && 78 dpp_notify_new_qr_code(auth, bi) == 1) { 79 wpa_printf(MSG_DEBUG, 80 "DPP: Sending out pending authentication response"); 81 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 82 " freq=%u type=%d", 83 MAC2STR(auth->peer_mac_addr), auth->curr_freq, 84 DPP_PA_AUTHENTICATION_RESP); 85 hostapd_drv_send_action(hapd, auth->curr_freq, 0, 86 auth->peer_mac_addr, 87 wpabuf_head(hapd->dpp_auth->resp_msg), 88 wpabuf_len(hapd->dpp_auth->resp_msg)); 89 } 90 91 return bi->id; 92 } 93 94 95 static char * get_param(const char *cmd, const char *param) 96 { 97 const char *pos, *end; 98 char *val; 99 size_t len; 100 101 pos = os_strstr(cmd, param); 102 if (!pos) 103 return NULL; 104 105 pos += os_strlen(param); 106 end = os_strchr(pos, ' '); 107 if (end) 108 len = end - pos; 109 else 110 len = os_strlen(pos); 111 val = os_malloc(len + 1); 112 if (!val) 113 return NULL; 114 os_memcpy(val, pos, len); 115 val[len] = '\0'; 116 return val; 117 } 118 119 120 int hostapd_dpp_bootstrap_gen(struct hostapd_data *hapd, const char *cmd) 121 { 122 char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL; 123 char *key = NULL; 124 u8 *privkey = NULL; 125 size_t privkey_len = 0; 126 size_t len; 127 int ret = -1; 128 struct dpp_bootstrap_info *bi; 129 130 bi = os_zalloc(sizeof(*bi)); 131 if (!bi) 132 goto fail; 133 134 if (os_strstr(cmd, "type=qrcode")) 135 bi->type = DPP_BOOTSTRAP_QR_CODE; 136 else if (os_strstr(cmd, "type=pkex")) 137 bi->type = DPP_BOOTSTRAP_PKEX; 138 else 139 goto fail; 140 141 chan = get_param(cmd, " chan="); 142 mac = get_param(cmd, " mac="); 143 info = get_param(cmd, " info="); 144 curve = get_param(cmd, " curve="); 145 key = get_param(cmd, " key="); 146 147 if (key) { 148 privkey_len = os_strlen(key) / 2; 149 privkey = os_malloc(privkey_len); 150 if (!privkey || 151 hexstr2bin(key, privkey, privkey_len) < 0) 152 goto fail; 153 } 154 155 pk = dpp_keygen(bi, curve, privkey, privkey_len); 156 if (!pk) 157 goto fail; 158 159 len = 4; /* "DPP:" */ 160 if (chan) { 161 if (dpp_parse_uri_chan_list(bi, chan) < 0) 162 goto fail; 163 len += 3 + os_strlen(chan); /* C:...; */ 164 } 165 if (mac) { 166 if (dpp_parse_uri_mac(bi, mac) < 0) 167 goto fail; 168 len += 3 + os_strlen(mac); /* M:...; */ 169 } 170 if (info) { 171 if (dpp_parse_uri_info(bi, info) < 0) 172 goto fail; 173 len += 3 + os_strlen(info); /* I:...; */ 174 } 175 len += 4 + os_strlen(pk); 176 bi->uri = os_malloc(len + 1); 177 if (!bi->uri) 178 goto fail; 179 os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;", 180 chan ? "C:" : "", chan ? chan : "", chan ? ";" : "", 181 mac ? "M:" : "", mac ? mac : "", mac ? ";" : "", 182 info ? "I:" : "", info ? info : "", info ? ";" : "", 183 pk); 184 bi->id = hapd_dpp_next_id(hapd); 185 dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list); 186 ret = bi->id; 187 bi = NULL; 188 fail: 189 os_free(curve); 190 os_free(pk); 191 os_free(chan); 192 os_free(mac); 193 os_free(info); 194 str_clear_free(key); 195 bin_clear_free(privkey, privkey_len); 196 dpp_bootstrap_info_free(bi); 197 return ret; 198 } 199 200 201 static struct dpp_bootstrap_info * 202 dpp_bootstrap_get_id(struct hostapd_data *hapd, unsigned int id) 203 { 204 struct dpp_bootstrap_info *bi; 205 206 dl_list_for_each(bi, &hapd->iface->interfaces->dpp_bootstrap, 207 struct dpp_bootstrap_info, list) { 208 if (bi->id == id) 209 return bi; 210 } 211 return NULL; 212 } 213 214 215 static int dpp_bootstrap_del(struct hapd_interfaces *ifaces, unsigned int id) 216 { 217 struct dpp_bootstrap_info *bi, *tmp; 218 int found = 0; 219 220 dl_list_for_each_safe(bi, tmp, &ifaces->dpp_bootstrap, 221 struct dpp_bootstrap_info, list) { 222 if (id && bi->id != id) 223 continue; 224 found = 1; 225 dl_list_del(&bi->list); 226 dpp_bootstrap_info_free(bi); 227 } 228 229 if (id == 0) 230 return 0; /* flush succeeds regardless of entries found */ 231 return found ? 0 : -1; 232 } 233 234 235 int hostapd_dpp_bootstrap_remove(struct hostapd_data *hapd, const char *id) 236 { 237 unsigned int id_val; 238 239 if (os_strcmp(id, "*") == 0) { 240 id_val = 0; 241 } else { 242 id_val = atoi(id); 243 if (id_val == 0) 244 return -1; 245 } 246 247 return dpp_bootstrap_del(hapd->iface->interfaces, id_val); 248 } 249 250 251 const char * hostapd_dpp_bootstrap_get_uri(struct hostapd_data *hapd, 252 unsigned int id) 253 { 254 struct dpp_bootstrap_info *bi; 255 256 bi = dpp_bootstrap_get_id(hapd, id); 257 if (!bi) 258 return NULL; 259 return bi->uri; 260 } 261 262 263 int hostapd_dpp_bootstrap_info(struct hostapd_data *hapd, int id, 264 char *reply, int reply_size) 265 { 266 struct dpp_bootstrap_info *bi; 267 268 bi = dpp_bootstrap_get_id(hapd, id); 269 if (!bi) 270 return -1; 271 return os_snprintf(reply, reply_size, "type=%s\n" 272 "mac_addr=" MACSTR "\n" 273 "info=%s\n" 274 "num_freq=%u\n" 275 "curve=%s\n", 276 dpp_bootstrap_type_txt(bi->type), 277 MAC2STR(bi->mac_addr), 278 bi->info ? bi->info : "", 279 bi->num_freq, 280 bi->curve->name); 281 } 282 283 284 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx, 285 void *timeout_ctx) 286 { 287 struct hostapd_data *hapd = eloop_ctx; 288 struct dpp_authentication *auth = hapd->dpp_auth; 289 290 if (!auth || !auth->resp_msg) 291 return; 292 293 wpa_printf(MSG_DEBUG, 294 "DPP: Retry Authentication Response after timeout"); 295 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 296 " freq=%u type=%d", 297 MAC2STR(auth->peer_mac_addr), auth->curr_freq, 298 DPP_PA_AUTHENTICATION_RESP); 299 hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr, 300 wpabuf_head(auth->resp_msg), 301 wpabuf_len(auth->resp_msg)); 302 } 303 304 305 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd) 306 { 307 struct dpp_authentication *auth = hapd->dpp_auth; 308 unsigned int wait_time, max_tries; 309 310 if (!auth || !auth->resp_msg) 311 return; 312 313 if (hapd->dpp_resp_max_tries) 314 max_tries = hapd->dpp_resp_max_tries; 315 else 316 max_tries = 5; 317 auth->auth_resp_tries++; 318 if (auth->auth_resp_tries >= max_tries) { 319 wpa_printf(MSG_INFO, 320 "DPP: No confirm received from initiator - stopping exchange"); 321 hostapd_drv_send_action_cancel_wait(hapd); 322 dpp_auth_deinit(hapd->dpp_auth); 323 hapd->dpp_auth = NULL; 324 return; 325 } 326 327 if (hapd->dpp_resp_retry_time) 328 wait_time = hapd->dpp_resp_retry_time; 329 else 330 wait_time = 1000; 331 wpa_printf(MSG_DEBUG, 332 "DPP: Schedule retransmission of Authentication Response frame in %u ms", 333 wait_time); 334 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 335 eloop_register_timeout(wait_time / 1000, 336 (wait_time % 1000) * 1000, 337 hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 338 } 339 340 341 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst, 342 const u8 *data, size_t data_len, int ok) 343 { 344 struct dpp_authentication *auth = hapd->dpp_auth; 345 346 wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d", 347 MAC2STR(dst), ok); 348 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR 349 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED"); 350 351 if (!hapd->dpp_auth) { 352 wpa_printf(MSG_DEBUG, 353 "DPP: Ignore TX status since there is no ongoing authentication exchange"); 354 return; 355 } 356 357 if (hapd->dpp_auth->remove_on_tx_status) { 358 wpa_printf(MSG_DEBUG, 359 "DPP: Terminate authentication exchange due to an earlier error"); 360 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 361 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, 362 hapd, NULL); 363 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, 364 NULL); 365 hostapd_drv_send_action_cancel_wait(hapd); 366 dpp_auth_deinit(hapd->dpp_auth); 367 hapd->dpp_auth = NULL; 368 return; 369 } 370 371 if (hapd->dpp_auth_ok_on_ack) 372 hostapd_dpp_auth_success(hapd, 1); 373 374 if (!is_broadcast_ether_addr(dst) && !ok) { 375 wpa_printf(MSG_DEBUG, 376 "DPP: Unicast DPP Action frame was not ACKed"); 377 if (auth->waiting_auth_resp) { 378 /* In case of DPP Authentication Request frame, move to 379 * the next channel immediately. */ 380 hostapd_drv_send_action_cancel_wait(hapd); 381 hostapd_dpp_auth_init_next(hapd); 382 return; 383 } 384 if (auth->waiting_auth_conf) { 385 hostapd_dpp_auth_resp_retry(hapd); 386 return; 387 } 388 } 389 390 if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) { 391 /* Allow timeout handling to stop iteration if no response is 392 * received from a peer that has ACKed a request. */ 393 auth->auth_req_ack = 1; 394 } 395 396 if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 && 397 hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) { 398 wpa_printf(MSG_DEBUG, 399 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response", 400 hapd->dpp_auth->curr_freq, 401 hapd->dpp_auth->neg_freq); 402 hostapd_drv_send_action_cancel_wait(hapd); 403 404 if (hapd->dpp_auth->neg_freq != 405 (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) { 406 /* TODO: Listen operation on non-operating channel */ 407 wpa_printf(MSG_INFO, 408 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)", 409 hapd->dpp_auth->neg_freq, hapd->iface->freq); 410 } 411 } 412 413 if (hapd->dpp_auth_ok_on_ack) 414 hapd->dpp_auth_ok_on_ack = 0; 415 } 416 417 418 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx) 419 { 420 struct hostapd_data *hapd = eloop_ctx; 421 struct dpp_authentication *auth = hapd->dpp_auth; 422 unsigned int freq; 423 struct os_reltime now, diff; 424 unsigned int wait_time, diff_ms; 425 426 if (!auth || !auth->waiting_auth_resp) 427 return; 428 429 wait_time = hapd->dpp_resp_wait_time ? 430 hapd->dpp_resp_wait_time : 2000; 431 os_get_reltime(&now); 432 os_reltime_sub(&now, &hapd->dpp_last_init, &diff); 433 diff_ms = diff.sec * 1000 + diff.usec / 1000; 434 wpa_printf(MSG_DEBUG, 435 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u", 436 wait_time, diff_ms); 437 438 if (auth->auth_req_ack && diff_ms >= wait_time) { 439 /* Peer ACK'ed Authentication Request frame, but did not reply 440 * with Authentication Response frame within two seconds. */ 441 wpa_printf(MSG_INFO, 442 "DPP: No response received from responder - stopping initiation attempt"); 443 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED); 444 hostapd_drv_send_action_cancel_wait(hapd); 445 hostapd_dpp_listen_stop(hapd); 446 dpp_auth_deinit(auth); 447 hapd->dpp_auth = NULL; 448 return; 449 } 450 451 if (diff_ms >= wait_time) { 452 /* Authentication Request frame was not ACK'ed and no reply 453 * was receiving within two seconds. */ 454 wpa_printf(MSG_DEBUG, 455 "DPP: Continue Initiator channel iteration"); 456 hostapd_drv_send_action_cancel_wait(hapd); 457 hostapd_dpp_listen_stop(hapd); 458 hostapd_dpp_auth_init_next(hapd); 459 return; 460 } 461 462 /* Driver did not support 2000 ms long wait_time with TX command, so 463 * schedule listen operation to continue waiting for the response. 464 * 465 * DPP listen operations continue until stopped, so simply schedule a 466 * new call to this function at the point when the two second reply 467 * wait has expired. */ 468 wait_time -= diff_ms; 469 470 freq = auth->curr_freq; 471 if (auth->neg_freq > 0) 472 freq = auth->neg_freq; 473 wpa_printf(MSG_DEBUG, 474 "DPP: Continue reply wait on channel %u MHz for %u ms", 475 freq, wait_time); 476 hapd->dpp_in_response_listen = 1; 477 478 if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) { 479 /* TODO: Listen operation on non-operating channel */ 480 wpa_printf(MSG_INFO, 481 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)", 482 freq, hapd->iface->freq); 483 } 484 485 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000, 486 hostapd_dpp_reply_wait_timeout, hapd, NULL); 487 } 488 489 490 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd, 491 struct dpp_authentication *auth) 492 { 493 #ifdef CONFIG_TESTING_OPTIONS 494 if (hapd->dpp_config_obj_override) 495 auth->config_obj_override = 496 os_strdup(hapd->dpp_config_obj_override); 497 if (hapd->dpp_discovery_override) 498 auth->discovery_override = 499 os_strdup(hapd->dpp_discovery_override); 500 if (hapd->dpp_groups_override) 501 auth->groups_override = os_strdup(hapd->dpp_groups_override); 502 auth->ignore_netaccesskey_mismatch = 503 hapd->dpp_ignore_netaccesskey_mismatch; 504 #endif /* CONFIG_TESTING_OPTIONS */ 505 } 506 507 508 static int hostapd_dpp_set_configurator(struct hostapd_data *hapd, 509 struct dpp_authentication *auth, 510 const char *cmd) 511 { 512 const char *pos, *end; 513 struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL; 514 struct dpp_configurator *conf = NULL; 515 u8 ssid[32] = { "test" }; 516 size_t ssid_len = 4; 517 char pass[64] = { }; 518 size_t pass_len = 0; 519 u8 psk[PMK_LEN]; 520 int psk_set = 0; 521 char *group_id = NULL; 522 523 if (!cmd) 524 return 0; 525 526 wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd); 527 pos = os_strstr(cmd, " ssid="); 528 if (pos) { 529 pos += 6; 530 end = os_strchr(pos, ' '); 531 ssid_len = end ? (size_t) (end - pos) : os_strlen(pos); 532 ssid_len /= 2; 533 if (ssid_len > sizeof(ssid) || 534 hexstr2bin(pos, ssid, ssid_len) < 0) 535 goto fail; 536 } 537 538 pos = os_strstr(cmd, " pass="); 539 if (pos) { 540 pos += 6; 541 end = os_strchr(pos, ' '); 542 pass_len = end ? (size_t) (end - pos) : os_strlen(pos); 543 pass_len /= 2; 544 if (pass_len > sizeof(pass) - 1 || pass_len < 8 || 545 hexstr2bin(pos, (u8 *) pass, pass_len) < 0) 546 goto fail; 547 } 548 549 pos = os_strstr(cmd, " psk="); 550 if (pos) { 551 pos += 5; 552 if (hexstr2bin(pos, psk, PMK_LEN) < 0) 553 goto fail; 554 psk_set = 1; 555 } 556 557 pos = os_strstr(cmd, " group_id="); 558 if (pos) { 559 size_t group_id_len; 560 561 pos += 10; 562 end = os_strchr(pos, ' '); 563 group_id_len = end ? (size_t) (end - pos) : os_strlen(pos); 564 group_id = os_malloc(group_id_len + 1); 565 if (!group_id) 566 goto fail; 567 os_memcpy(group_id, pos, group_id_len); 568 group_id[group_id_len] = '\0'; 569 } 570 571 if (os_strstr(cmd, " conf=sta-")) { 572 conf_sta = os_zalloc(sizeof(struct dpp_configuration)); 573 if (!conf_sta) 574 goto fail; 575 os_memcpy(conf_sta->ssid, ssid, ssid_len); 576 conf_sta->ssid_len = ssid_len; 577 if (os_strstr(cmd, " conf=sta-psk") || 578 os_strstr(cmd, " conf=sta-sae") || 579 os_strstr(cmd, " conf=sta-psk-sae")) { 580 if (os_strstr(cmd, " conf=sta-psk-sae")) 581 conf_sta->akm = DPP_AKM_PSK_SAE; 582 else if (os_strstr(cmd, " conf=sta-sae")) 583 conf_sta->akm = DPP_AKM_SAE; 584 else 585 conf_sta->akm = DPP_AKM_PSK; 586 if (psk_set) { 587 os_memcpy(conf_sta->psk, psk, PMK_LEN); 588 } else { 589 conf_sta->passphrase = os_strdup(pass); 590 if (!conf_sta->passphrase) 591 goto fail; 592 } 593 } else if (os_strstr(cmd, " conf=sta-dpp")) { 594 conf_sta->akm = DPP_AKM_DPP; 595 } else { 596 goto fail; 597 } 598 if (os_strstr(cmd, " group_id=")) { 599 conf_sta->group_id = group_id; 600 group_id = NULL; 601 } 602 } 603 604 if (os_strstr(cmd, " conf=ap-")) { 605 conf_ap = os_zalloc(sizeof(struct dpp_configuration)); 606 if (!conf_ap) 607 goto fail; 608 os_memcpy(conf_ap->ssid, ssid, ssid_len); 609 conf_ap->ssid_len = ssid_len; 610 if (os_strstr(cmd, " conf=ap-psk") || 611 os_strstr(cmd, " conf=ap-sae") || 612 os_strstr(cmd, " conf=ap-psk-sae")) { 613 if (os_strstr(cmd, " conf=ap-psk-sae")) 614 conf_ap->akm = DPP_AKM_PSK_SAE; 615 else if (os_strstr(cmd, " conf=ap-sae")) 616 conf_ap->akm = DPP_AKM_SAE; 617 else 618 conf_ap->akm = DPP_AKM_PSK; 619 if (psk_set) { 620 os_memcpy(conf_ap->psk, psk, PMK_LEN); 621 } else if (pass_len > 0) { 622 conf_ap->passphrase = os_strdup(pass); 623 if (!conf_ap->passphrase) 624 goto fail; 625 } else { 626 goto fail; 627 } 628 } else if (os_strstr(cmd, " conf=ap-dpp")) { 629 conf_ap->akm = DPP_AKM_DPP; 630 } else { 631 goto fail; 632 } 633 if (os_strstr(cmd, " group_id=")) { 634 conf_ap->group_id = group_id; 635 group_id = NULL; 636 } 637 } 638 639 pos = os_strstr(cmd, " expiry="); 640 if (pos) { 641 long int val; 642 643 pos += 8; 644 val = strtol(pos, NULL, 0); 645 if (val <= 0) 646 goto fail; 647 if (conf_sta) 648 conf_sta->netaccesskey_expiry = val; 649 if (conf_ap) 650 conf_ap->netaccesskey_expiry = val; 651 } 652 653 pos = os_strstr(cmd, " configurator="); 654 if (pos) { 655 auth->configurator = 1; 656 pos += 14; 657 conf = hostapd_dpp_configurator_get_id(hapd, atoi(pos)); 658 if (!conf) { 659 wpa_printf(MSG_INFO, 660 "DPP: Could not find the specified configurator"); 661 goto fail; 662 } 663 } 664 auth->conf_sta = conf_sta; 665 auth->conf_ap = conf_ap; 666 auth->conf = conf; 667 os_free(group_id); 668 return 0; 669 670 fail: 671 wpa_msg(hapd->msg_ctx, MSG_INFO, 672 "DPP: Failed to set configurator parameters"); 673 dpp_configuration_free(conf_sta); 674 dpp_configuration_free(conf_ap); 675 os_free(group_id); 676 return -1; 677 } 678 679 680 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx) 681 { 682 struct hostapd_data *hapd = eloop_ctx; 683 684 if (!hapd->dpp_auth) 685 return; 686 wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout"); 687 hostapd_dpp_auth_init_next(hapd); 688 } 689 690 691 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd) 692 { 693 struct dpp_authentication *auth = hapd->dpp_auth; 694 const u8 *dst; 695 unsigned int wait_time, max_wait_time, freq, max_tries, used; 696 struct os_reltime now, diff; 697 698 if (!auth) 699 return -1; 700 701 if (auth->freq_idx == 0) 702 os_get_reltime(&hapd->dpp_init_iter_start); 703 704 if (auth->freq_idx >= auth->num_freq) { 705 auth->num_freq_iters++; 706 if (hapd->dpp_init_max_tries) 707 max_tries = hapd->dpp_init_max_tries; 708 else 709 max_tries = 5; 710 if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) { 711 wpa_printf(MSG_INFO, 712 "DPP: No response received from responder - stopping initiation attempt"); 713 wpa_msg(hapd->msg_ctx, MSG_INFO, 714 DPP_EVENT_AUTH_INIT_FAILED); 715 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, 716 hapd, NULL); 717 hostapd_drv_send_action_cancel_wait(hapd); 718 dpp_auth_deinit(hapd->dpp_auth); 719 hapd->dpp_auth = NULL; 720 return -1; 721 } 722 auth->freq_idx = 0; 723 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 724 if (hapd->dpp_init_retry_time) 725 wait_time = hapd->dpp_init_retry_time; 726 else 727 wait_time = 10000; 728 os_get_reltime(&now); 729 os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff); 730 used = diff.sec * 1000 + diff.usec / 1000; 731 if (used > wait_time) 732 wait_time = 0; 733 else 734 wait_time -= used; 735 wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms", 736 wait_time); 737 eloop_register_timeout(wait_time / 1000, 738 (wait_time % 1000) * 1000, 739 hostapd_dpp_init_timeout, hapd, 740 NULL); 741 return 0; 742 } 743 freq = auth->freq[auth->freq_idx++]; 744 auth->curr_freq = freq; 745 746 if (is_zero_ether_addr(auth->peer_bi->mac_addr)) 747 dst = broadcast; 748 else 749 dst = auth->peer_bi->mac_addr; 750 hapd->dpp_auth_ok_on_ack = 0; 751 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 752 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */ 753 max_wait_time = hapd->dpp_resp_wait_time ? 754 hapd->dpp_resp_wait_time : 2000; 755 if (wait_time > max_wait_time) 756 wait_time = max_wait_time; 757 wait_time += 10; /* give the driver some extra time to complete */ 758 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000, 759 hostapd_dpp_reply_wait_timeout, hapd, NULL); 760 wait_time -= 10; 761 if (auth->neg_freq > 0 && freq != auth->neg_freq) { 762 wpa_printf(MSG_DEBUG, 763 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response", 764 freq, auth->neg_freq); 765 } 766 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 767 " freq=%u type=%d", 768 MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ); 769 auth->auth_req_ack = 0; 770 os_get_reltime(&hapd->dpp_last_init); 771 return hostapd_drv_send_action(hapd, freq, wait_time, 772 dst, 773 wpabuf_head(hapd->dpp_auth->req_msg), 774 wpabuf_len(hapd->dpp_auth->req_msg)); 775 } 776 777 778 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd) 779 { 780 const char *pos; 781 struct dpp_bootstrap_info *peer_bi, *own_bi = NULL; 782 u8 allowed_roles = DPP_CAPAB_CONFIGURATOR; 783 unsigned int neg_freq = 0; 784 785 pos = os_strstr(cmd, " peer="); 786 if (!pos) 787 return -1; 788 pos += 6; 789 peer_bi = dpp_bootstrap_get_id(hapd, atoi(pos)); 790 if (!peer_bi) { 791 wpa_printf(MSG_INFO, 792 "DPP: Could not find bootstrapping info for the identified peer"); 793 return -1; 794 } 795 796 pos = os_strstr(cmd, " own="); 797 if (pos) { 798 pos += 5; 799 own_bi = dpp_bootstrap_get_id(hapd, atoi(pos)); 800 if (!own_bi) { 801 wpa_printf(MSG_INFO, 802 "DPP: Could not find bootstrapping info for the identified local entry"); 803 return -1; 804 } 805 806 if (peer_bi->curve != own_bi->curve) { 807 wpa_printf(MSG_INFO, 808 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)", 809 peer_bi->curve->name, own_bi->curve->name); 810 return -1; 811 } 812 } 813 814 pos = os_strstr(cmd, " role="); 815 if (pos) { 816 pos += 6; 817 if (os_strncmp(pos, "configurator", 12) == 0) 818 allowed_roles = DPP_CAPAB_CONFIGURATOR; 819 else if (os_strncmp(pos, "enrollee", 8) == 0) 820 allowed_roles = DPP_CAPAB_ENROLLEE; 821 else if (os_strncmp(pos, "either", 6) == 0) 822 allowed_roles = DPP_CAPAB_CONFIGURATOR | 823 DPP_CAPAB_ENROLLEE; 824 else 825 goto fail; 826 } 827 828 pos = os_strstr(cmd, " neg_freq="); 829 if (pos) 830 neg_freq = atoi(pos + 10); 831 832 if (hapd->dpp_auth) { 833 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 834 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, 835 hapd, NULL); 836 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, 837 NULL); 838 hostapd_drv_send_action_cancel_wait(hapd); 839 dpp_auth_deinit(hapd->dpp_auth); 840 } 841 842 hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi, 843 allowed_roles, neg_freq, 844 hapd->iface->hw_features, 845 hapd->iface->num_hw_features); 846 if (!hapd->dpp_auth) 847 goto fail; 848 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth); 849 if (hostapd_dpp_set_configurator(hapd, hapd->dpp_auth, cmd) < 0) { 850 dpp_auth_deinit(hapd->dpp_auth); 851 hapd->dpp_auth = NULL; 852 goto fail; 853 } 854 855 hapd->dpp_auth->neg_freq = neg_freq; 856 857 if (!is_zero_ether_addr(peer_bi->mac_addr)) 858 os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr, 859 ETH_ALEN); 860 861 return hostapd_dpp_auth_init_next(hapd); 862 fail: 863 return -1; 864 } 865 866 867 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd) 868 { 869 int freq; 870 871 freq = atoi(cmd); 872 if (freq <= 0) 873 return -1; 874 875 if (os_strstr(cmd, " role=configurator")) 876 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR; 877 else if (os_strstr(cmd, " role=enrollee")) 878 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE; 879 else 880 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | 881 DPP_CAPAB_ENROLLEE; 882 hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL; 883 884 if (freq != hapd->iface->freq && hapd->iface->freq > 0) { 885 /* TODO: Listen operation on non-operating channel */ 886 wpa_printf(MSG_INFO, 887 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)", 888 freq, hapd->iface->freq); 889 return -1; 890 } 891 892 return 0; 893 } 894 895 896 void hostapd_dpp_listen_stop(struct hostapd_data *hapd) 897 { 898 /* TODO: Stop listen operation on non-operating channel */ 899 } 900 901 902 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src, 903 const u8 *hdr, const u8 *buf, size_t len, 904 unsigned int freq) 905 { 906 const u8 *r_bootstrap, *i_bootstrap; 907 u16 r_bootstrap_len, i_bootstrap_len; 908 struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL; 909 910 wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR, 911 MAC2STR(src)); 912 913 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 914 &r_bootstrap_len); 915 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { 916 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 917 "Missing or invalid required Responder Bootstrapping Key Hash attribute"); 918 return; 919 } 920 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash", 921 r_bootstrap, r_bootstrap_len); 922 923 i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 924 &i_bootstrap_len); 925 if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) { 926 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 927 "Missing or invalid required Initiator Bootstrapping Key Hash attribute"); 928 return; 929 } 930 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash", 931 i_bootstrap, i_bootstrap_len); 932 933 /* Try to find own and peer bootstrapping key matches based on the 934 * received hash values */ 935 dl_list_for_each(bi, &hapd->iface->interfaces->dpp_bootstrap, 936 struct dpp_bootstrap_info, list) { 937 if (!own_bi && bi->own && 938 os_memcmp(bi->pubkey_hash, r_bootstrap, 939 SHA256_MAC_LEN) == 0) { 940 wpa_printf(MSG_DEBUG, 941 "DPP: Found matching own bootstrapping information"); 942 own_bi = bi; 943 } 944 945 if (!peer_bi && !bi->own && 946 os_memcmp(bi->pubkey_hash, i_bootstrap, 947 SHA256_MAC_LEN) == 0) { 948 wpa_printf(MSG_DEBUG, 949 "DPP: Found matching peer bootstrapping information"); 950 peer_bi = bi; 951 } 952 953 if (own_bi && peer_bi) 954 break; 955 } 956 957 if (!own_bi) { 958 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 959 "No matching own bootstrapping key found - ignore message"); 960 return; 961 } 962 963 if (hapd->dpp_auth) { 964 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 965 "Already in DPP authentication exchange - ignore new one"); 966 return; 967 } 968 969 hapd->dpp_auth_ok_on_ack = 0; 970 hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles, 971 hapd->dpp_qr_mutual, 972 peer_bi, own_bi, freq, hdr, buf, len); 973 if (!hapd->dpp_auth) { 974 wpa_printf(MSG_DEBUG, "DPP: No response generated"); 975 return; 976 } 977 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth); 978 if (hostapd_dpp_set_configurator(hapd, hapd->dpp_auth, 979 hapd->dpp_configurator_params) < 0) { 980 dpp_auth_deinit(hapd->dpp_auth); 981 hapd->dpp_auth = NULL; 982 return; 983 } 984 os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN); 985 986 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 987 " freq=%u type=%d", 988 MAC2STR(src), hapd->dpp_auth->curr_freq, 989 DPP_PA_AUTHENTICATION_RESP); 990 hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0, 991 src, wpabuf_head(hapd->dpp_auth->resp_msg), 992 wpabuf_len(hapd->dpp_auth->resp_msg)); 993 } 994 995 996 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd, 997 struct dpp_authentication *auth) 998 { 999 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED); 1000 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s", 1001 dpp_akm_str(auth->akm)); 1002 if (auth->ssid_len) 1003 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s", 1004 wpa_ssid_txt(auth->ssid, auth->ssid_len)); 1005 if (auth->connector) { 1006 /* TODO: Save the Connector and consider using a command 1007 * to fetch the value instead of sending an event with 1008 * it. The Connector could end up being larger than what 1009 * most clients are ready to receive as an event 1010 * message. */ 1011 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s", 1012 auth->connector); 1013 } else if (auth->passphrase[0]) { 1014 char hex[64 * 2 + 1]; 1015 1016 wpa_snprintf_hex(hex, sizeof(hex), 1017 (const u8 *) auth->passphrase, 1018 os_strlen(auth->passphrase)); 1019 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s", 1020 hex); 1021 } else if (auth->psk_set) { 1022 char hex[PMK_LEN * 2 + 1]; 1023 1024 wpa_snprintf_hex(hex, sizeof(hex), auth->psk, PMK_LEN); 1025 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s", 1026 hex); 1027 } 1028 if (auth->c_sign_key) { 1029 char *hex; 1030 size_t hexlen; 1031 1032 hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1; 1033 hex = os_malloc(hexlen); 1034 if (hex) { 1035 wpa_snprintf_hex(hex, hexlen, 1036 wpabuf_head(auth->c_sign_key), 1037 wpabuf_len(auth->c_sign_key)); 1038 wpa_msg(hapd->msg_ctx, MSG_INFO, 1039 DPP_EVENT_C_SIGN_KEY "%s", hex); 1040 os_free(hex); 1041 } 1042 } 1043 if (auth->net_access_key) { 1044 char *hex; 1045 size_t hexlen; 1046 1047 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1; 1048 hex = os_malloc(hexlen); 1049 if (hex) { 1050 wpa_snprintf_hex(hex, hexlen, 1051 wpabuf_head(auth->net_access_key), 1052 wpabuf_len(auth->net_access_key)); 1053 if (auth->net_access_key_expiry) 1054 wpa_msg(hapd->msg_ctx, MSG_INFO, 1055 DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex, 1056 (unsigned long) 1057 auth->net_access_key_expiry); 1058 else 1059 wpa_msg(hapd->msg_ctx, MSG_INFO, 1060 DPP_EVENT_NET_ACCESS_KEY "%s", hex); 1061 os_free(hex); 1062 } 1063 } 1064 } 1065 1066 1067 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, 1068 enum gas_query_ap_result result, 1069 const struct wpabuf *adv_proto, 1070 const struct wpabuf *resp, u16 status_code) 1071 { 1072 struct hostapd_data *hapd = ctx; 1073 const u8 *pos; 1074 struct dpp_authentication *auth = hapd->dpp_auth; 1075 1076 if (!auth || !auth->auth_success) { 1077 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); 1078 return; 1079 } 1080 if (!resp || status_code != WLAN_STATUS_SUCCESS) { 1081 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed"); 1082 goto fail; 1083 } 1084 1085 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto", 1086 adv_proto); 1087 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)", 1088 resp); 1089 1090 if (wpabuf_len(adv_proto) != 10 || 1091 !(pos = wpabuf_head(adv_proto)) || 1092 pos[0] != WLAN_EID_ADV_PROTO || 1093 pos[1] != 8 || 1094 pos[3] != WLAN_EID_VENDOR_SPECIFIC || 1095 pos[4] != 5 || 1096 WPA_GET_BE24(&pos[5]) != OUI_WFA || 1097 pos[8] != 0x1a || 1098 pos[9] != 1) { 1099 wpa_printf(MSG_DEBUG, 1100 "DPP: Not a DPP Advertisement Protocol ID"); 1101 goto fail; 1102 } 1103 1104 if (dpp_conf_resp_rx(auth, resp) < 0) { 1105 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed"); 1106 goto fail; 1107 } 1108 1109 hostapd_dpp_handle_config_obj(hapd, auth); 1110 dpp_auth_deinit(hapd->dpp_auth); 1111 hapd->dpp_auth = NULL; 1112 return; 1113 1114 fail: 1115 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1116 dpp_auth_deinit(hapd->dpp_auth); 1117 hapd->dpp_auth = NULL; 1118 } 1119 1120 1121 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd) 1122 { 1123 struct dpp_authentication *auth = hapd->dpp_auth; 1124 struct wpabuf *buf, *conf_req; 1125 char json[100]; 1126 int res; 1127 int netrole_ap = 1; 1128 1129 os_snprintf(json, sizeof(json), 1130 "{\"name\":\"Test\"," 1131 "\"wi-fi_tech\":\"infra\"," 1132 "\"netRole\":\"%s\"}", 1133 netrole_ap ? "ap" : "sta"); 1134 wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json); 1135 1136 conf_req = dpp_build_conf_req(auth, json); 1137 if (!conf_req) { 1138 wpa_printf(MSG_DEBUG, 1139 "DPP: No configuration request data available"); 1140 return; 1141 } 1142 1143 buf = gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req)); 1144 if (!buf) { 1145 wpabuf_free(conf_req); 1146 return; 1147 } 1148 1149 /* Advertisement Protocol IE */ 1150 wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO); 1151 wpabuf_put_u8(buf, 8); /* Length */ 1152 wpabuf_put_u8(buf, 0x7f); 1153 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); 1154 wpabuf_put_u8(buf, 5); 1155 wpabuf_put_be24(buf, OUI_WFA); 1156 wpabuf_put_u8(buf, DPP_OUI_TYPE); 1157 wpabuf_put_u8(buf, 0x01); 1158 1159 /* GAS Query */ 1160 wpabuf_put_le16(buf, wpabuf_len(conf_req)); 1161 wpabuf_put_buf(buf, conf_req); 1162 wpabuf_free(conf_req); 1163 1164 wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)", 1165 MAC2STR(auth->peer_mac_addr), auth->curr_freq); 1166 1167 res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq, 1168 buf, hostapd_dpp_gas_resp_cb, hapd); 1169 if (res < 0) { 1170 wpa_msg(hapd->msg_ctx, MSG_DEBUG, 1171 "GAS: Failed to send Query Request"); 1172 wpabuf_free(buf); 1173 } else { 1174 wpa_printf(MSG_DEBUG, 1175 "DPP: GAS query started with dialog token %u", res); 1176 } 1177 } 1178 1179 1180 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator) 1181 { 1182 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded"); 1183 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d", 1184 initiator); 1185 #ifdef CONFIG_TESTING_OPTIONS 1186 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) { 1187 wpa_printf(MSG_INFO, 1188 "DPP: TESTING - stop at Authentication Confirm"); 1189 if (hapd->dpp_auth->configurator) { 1190 /* Prevent GAS response */ 1191 hapd->dpp_auth->auth_success = 0; 1192 } 1193 return; 1194 } 1195 #endif /* CONFIG_TESTING_OPTIONS */ 1196 1197 if (!hapd->dpp_auth->configurator) 1198 hostapd_dpp_start_gas_client(hapd); 1199 } 1200 1201 1202 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src, 1203 const u8 *hdr, const u8 *buf, size_t len, 1204 unsigned int freq) 1205 { 1206 struct dpp_authentication *auth = hapd->dpp_auth; 1207 struct wpabuf *msg; 1208 1209 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR, 1210 MAC2STR(src)); 1211 1212 if (!auth) { 1213 wpa_printf(MSG_DEBUG, 1214 "DPP: No DPP Authentication in progress - drop"); 1215 return; 1216 } 1217 1218 if (!is_zero_ether_addr(auth->peer_mac_addr) && 1219 os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { 1220 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1221 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1222 return; 1223 } 1224 1225 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 1226 1227 if (auth->curr_freq != freq && auth->neg_freq == freq) { 1228 wpa_printf(MSG_DEBUG, 1229 "DPP: Responder accepted request for different negotiation channel"); 1230 auth->curr_freq = freq; 1231 } 1232 1233 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 1234 msg = dpp_auth_resp_rx(auth, hdr, buf, len); 1235 if (!msg) { 1236 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) { 1237 wpa_printf(MSG_DEBUG, "DPP: Wait for full response"); 1238 return; 1239 } 1240 wpa_printf(MSG_DEBUG, "DPP: No confirm generated"); 1241 return; 1242 } 1243 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN); 1244 1245 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1246 " freq=%u type=%d", MAC2STR(src), auth->curr_freq, 1247 DPP_PA_AUTHENTICATION_CONF); 1248 hostapd_drv_send_action(hapd, auth->curr_freq, 0, src, 1249 wpabuf_head(msg), wpabuf_len(msg)); 1250 wpabuf_free(msg); 1251 hapd->dpp_auth_ok_on_ack = 1; 1252 } 1253 1254 1255 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src, 1256 const u8 *hdr, const u8 *buf, size_t len) 1257 { 1258 struct dpp_authentication *auth = hapd->dpp_auth; 1259 1260 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR, 1261 MAC2STR(src)); 1262 1263 if (!auth) { 1264 wpa_printf(MSG_DEBUG, 1265 "DPP: No DPP Authentication in progress - drop"); 1266 return; 1267 } 1268 1269 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { 1270 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1271 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1272 return; 1273 } 1274 1275 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) { 1276 wpa_printf(MSG_DEBUG, "DPP: Authentication failed"); 1277 return; 1278 } 1279 1280 hostapd_dpp_auth_success(hapd, 0); 1281 } 1282 1283 1284 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd, 1285 const u8 *src, unsigned int freq, 1286 u8 trans_id, 1287 enum dpp_status_error status) 1288 { 1289 struct wpabuf *msg; 1290 1291 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, 1292 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector)); 1293 if (!msg) 1294 return; 1295 1296 #ifdef CONFIG_TESTING_OPTIONS 1297 if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) { 1298 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID"); 1299 goto skip_trans_id; 1300 } 1301 if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) { 1302 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID"); 1303 trans_id ^= 0x01; 1304 } 1305 #endif /* CONFIG_TESTING_OPTIONS */ 1306 1307 /* Transaction ID */ 1308 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID); 1309 wpabuf_put_le16(msg, 1); 1310 wpabuf_put_u8(msg, trans_id); 1311 1312 #ifdef CONFIG_TESTING_OPTIONS 1313 skip_trans_id: 1314 if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) { 1315 wpa_printf(MSG_INFO, "DPP: TESTING - no Status"); 1316 goto skip_status; 1317 } 1318 if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) { 1319 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status"); 1320 status = 254; 1321 } 1322 #endif /* CONFIG_TESTING_OPTIONS */ 1323 1324 /* DPP Status */ 1325 wpabuf_put_le16(msg, DPP_ATTR_STATUS); 1326 wpabuf_put_le16(msg, 1); 1327 wpabuf_put_u8(msg, status); 1328 1329 #ifdef CONFIG_TESTING_OPTIONS 1330 skip_status: 1331 if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) { 1332 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector"); 1333 goto skip_connector; 1334 } 1335 if (status == DPP_STATUS_OK && 1336 dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) { 1337 char *connector; 1338 1339 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector"); 1340 connector = dpp_corrupt_connector_signature( 1341 hapd->conf->dpp_connector); 1342 if (!connector) { 1343 wpabuf_free(msg); 1344 return; 1345 } 1346 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 1347 wpabuf_put_le16(msg, os_strlen(connector)); 1348 wpabuf_put_str(msg, connector); 1349 os_free(connector); 1350 goto skip_connector; 1351 } 1352 #endif /* CONFIG_TESTING_OPTIONS */ 1353 1354 /* DPP Connector */ 1355 if (status == DPP_STATUS_OK) { 1356 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 1357 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector)); 1358 wpabuf_put_str(msg, hapd->conf->dpp_connector); 1359 } 1360 1361 #ifdef CONFIG_TESTING_OPTIONS 1362 skip_connector: 1363 #endif /* CONFIG_TESTING_OPTIONS */ 1364 1365 wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR 1366 " status=%d", MAC2STR(src), status); 1367 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1368 " freq=%u type=%d status=%d", MAC2STR(src), freq, 1369 DPP_PA_PEER_DISCOVERY_RESP, status); 1370 hostapd_drv_send_action(hapd, freq, 0, src, 1371 wpabuf_head(msg), wpabuf_len(msg)); 1372 wpabuf_free(msg); 1373 } 1374 1375 1376 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, 1377 const u8 *src, 1378 const u8 *buf, size_t len, 1379 unsigned int freq) 1380 { 1381 const u8 *connector, *trans_id; 1382 u16 connector_len, trans_id_len; 1383 struct os_time now; 1384 struct dpp_introduction intro; 1385 os_time_t expire; 1386 int expiration; 1387 enum dpp_status_error res; 1388 1389 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR, 1390 MAC2STR(src)); 1391 if (!hapd->wpa_auth || 1392 !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) || 1393 !(hapd->conf->wpa & WPA_PROTO_RSN)) { 1394 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use"); 1395 return; 1396 } 1397 1398 if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey || 1399 !hapd->conf->dpp_csign) { 1400 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set"); 1401 return; 1402 } 1403 1404 os_get_time(&now); 1405 1406 if (hapd->conf->dpp_netaccesskey_expiry && 1407 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) { 1408 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired"); 1409 return; 1410 } 1411 1412 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, 1413 &trans_id_len); 1414 if (!trans_id || trans_id_len != 1) { 1415 wpa_printf(MSG_DEBUG, 1416 "DPP: Peer did not include Transaction ID"); 1417 return; 1418 } 1419 1420 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len); 1421 if (!connector) { 1422 wpa_printf(MSG_DEBUG, 1423 "DPP: Peer did not include its Connector"); 1424 return; 1425 } 1426 1427 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector, 1428 wpabuf_head(hapd->conf->dpp_netaccesskey), 1429 wpabuf_len(hapd->conf->dpp_netaccesskey), 1430 wpabuf_head(hapd->conf->dpp_csign), 1431 wpabuf_len(hapd->conf->dpp_csign), 1432 connector, connector_len, &expire); 1433 if (res == 255) { 1434 wpa_printf(MSG_INFO, 1435 "DPP: Network Introduction protocol resulted in internal failure (peer " 1436 MACSTR ")", MAC2STR(src)); 1437 return; 1438 } 1439 if (res != DPP_STATUS_OK) { 1440 wpa_printf(MSG_INFO, 1441 "DPP: Network Introduction protocol resulted in failure (peer " 1442 MACSTR " status %d)", MAC2STR(src), res); 1443 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0], 1444 res); 1445 return; 1446 } 1447 1448 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire) 1449 expire = hapd->conf->dpp_netaccesskey_expiry; 1450 if (expire) 1451 expiration = expire - now.sec; 1452 else 1453 expiration = 0; 1454 1455 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len, 1456 intro.pmkid, expiration, 1457 WPA_KEY_MGMT_DPP) < 0) { 1458 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry"); 1459 return; 1460 } 1461 1462 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0], 1463 DPP_STATUS_OK); 1464 } 1465 1466 1467 static void 1468 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src, 1469 const u8 *buf, size_t len, 1470 unsigned int freq) 1471 { 1472 struct wpabuf *msg; 1473 1474 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR, 1475 MAC2STR(src)); 1476 1477 /* TODO: Support multiple PKEX codes by iterating over all the enabled 1478 * values here */ 1479 1480 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) { 1481 wpa_printf(MSG_DEBUG, 1482 "DPP: No PKEX code configured - ignore request"); 1483 return; 1484 } 1485 1486 if (hapd->dpp_pkex) { 1487 /* TODO: Support parallel operations */ 1488 wpa_printf(MSG_DEBUG, 1489 "DPP: Already in PKEX session - ignore new request"); 1490 return; 1491 } 1492 1493 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx, 1494 hapd->dpp_pkex_bi, 1495 hapd->own_addr, src, 1496 hapd->dpp_pkex_identifier, 1497 hapd->dpp_pkex_code, 1498 buf, len); 1499 if (!hapd->dpp_pkex) { 1500 wpa_printf(MSG_DEBUG, 1501 "DPP: Failed to process the request - ignore it"); 1502 return; 1503 } 1504 1505 msg = hapd->dpp_pkex->exchange_resp; 1506 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1507 " freq=%u type=%d", MAC2STR(src), freq, 1508 DPP_PA_PKEX_EXCHANGE_RESP); 1509 hostapd_drv_send_action(hapd, freq, 0, src, 1510 wpabuf_head(msg), wpabuf_len(msg)); 1511 if (hapd->dpp_pkex->failed) { 1512 wpa_printf(MSG_DEBUG, 1513 "DPP: Terminate PKEX exchange due to an earlier error"); 1514 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t) 1515 hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t; 1516 dpp_pkex_free(hapd->dpp_pkex); 1517 hapd->dpp_pkex = NULL; 1518 } 1519 } 1520 1521 1522 static void 1523 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src, 1524 const u8 *buf, size_t len, unsigned int freq) 1525 { 1526 struct wpabuf *msg; 1527 1528 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR, 1529 MAC2STR(src)); 1530 1531 /* TODO: Support multiple PKEX codes by iterating over all the enabled 1532 * values here */ 1533 1534 if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator || 1535 hapd->dpp_pkex->exchange_done) { 1536 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1537 return; 1538 } 1539 1540 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len); 1541 if (!msg) { 1542 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 1543 return; 1544 } 1545 1546 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR, 1547 MAC2STR(src)); 1548 1549 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1550 " freq=%u type=%d", MAC2STR(src), freq, 1551 DPP_PA_PKEX_COMMIT_REVEAL_REQ); 1552 hostapd_drv_send_action(hapd, freq, 0, src, 1553 wpabuf_head(msg), wpabuf_len(msg)); 1554 wpabuf_free(msg); 1555 } 1556 1557 1558 static void 1559 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src, 1560 const u8 *hdr, const u8 *buf, size_t len, 1561 unsigned int freq) 1562 { 1563 struct wpabuf *msg; 1564 struct dpp_pkex *pkex = hapd->dpp_pkex; 1565 struct dpp_bootstrap_info *bi; 1566 1567 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR, 1568 MAC2STR(src)); 1569 1570 if (!pkex || pkex->initiator || !pkex->exchange_done) { 1571 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1572 return; 1573 } 1574 1575 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len); 1576 if (!msg) { 1577 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request"); 1578 if (hapd->dpp_pkex->failed) { 1579 wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange"); 1580 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t) 1581 hapd->dpp_pkex->own_bi->pkex_t = 1582 hapd->dpp_pkex->t; 1583 dpp_pkex_free(hapd->dpp_pkex); 1584 hapd->dpp_pkex = NULL; 1585 } 1586 return; 1587 } 1588 1589 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to " 1590 MACSTR, MAC2STR(src)); 1591 1592 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1593 " freq=%u type=%d", MAC2STR(src), freq, 1594 DPP_PA_PKEX_COMMIT_REVEAL_RESP); 1595 hostapd_drv_send_action(hapd, freq, 0, src, 1596 wpabuf_head(msg), wpabuf_len(msg)); 1597 wpabuf_free(msg); 1598 1599 bi = os_zalloc(sizeof(*bi)); 1600 if (!bi) 1601 return; 1602 bi->id = hapd_dpp_next_id(hapd); 1603 bi->type = DPP_BOOTSTRAP_PKEX; 1604 os_memcpy(bi->mac_addr, src, ETH_ALEN); 1605 bi->num_freq = 1; 1606 bi->freq[0] = freq; 1607 bi->curve = pkex->own_bi->curve; 1608 bi->pubkey = pkex->peer_bootstrap_key; 1609 pkex->peer_bootstrap_key = NULL; 1610 dpp_pkex_free(pkex); 1611 hapd->dpp_pkex = NULL; 1612 if (dpp_bootstrap_key_hash(bi) < 0) { 1613 dpp_bootstrap_info_free(bi); 1614 return; 1615 } 1616 dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list); 1617 } 1618 1619 1620 static void 1621 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src, 1622 const u8 *hdr, const u8 *buf, size_t len, 1623 unsigned int freq) 1624 { 1625 int res; 1626 struct dpp_bootstrap_info *bi, *own_bi; 1627 struct dpp_pkex *pkex = hapd->dpp_pkex; 1628 char cmd[500]; 1629 1630 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR, 1631 MAC2STR(src)); 1632 1633 if (!pkex || !pkex->initiator || !pkex->exchange_done) { 1634 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1635 return; 1636 } 1637 1638 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len); 1639 if (res < 0) { 1640 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 1641 return; 1642 } 1643 1644 own_bi = pkex->own_bi; 1645 1646 bi = os_zalloc(sizeof(*bi)); 1647 if (!bi) 1648 return; 1649 bi->id = hapd_dpp_next_id(hapd); 1650 bi->type = DPP_BOOTSTRAP_PKEX; 1651 os_memcpy(bi->mac_addr, src, ETH_ALEN); 1652 bi->num_freq = 1; 1653 bi->freq[0] = freq; 1654 bi->curve = own_bi->curve; 1655 bi->pubkey = pkex->peer_bootstrap_key; 1656 pkex->peer_bootstrap_key = NULL; 1657 dpp_pkex_free(pkex); 1658 hapd->dpp_pkex = NULL; 1659 if (dpp_bootstrap_key_hash(bi) < 0) { 1660 dpp_bootstrap_info_free(bi); 1661 return; 1662 } 1663 dl_list_add(&hapd->iface->interfaces->dpp_bootstrap, &bi->list); 1664 1665 os_snprintf(cmd, sizeof(cmd), " peer=%u %s", 1666 bi->id, 1667 hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : ""); 1668 wpa_printf(MSG_DEBUG, 1669 "DPP: Start authentication after PKEX with parameters: %s", 1670 cmd); 1671 if (hostapd_dpp_auth_init(hapd, cmd) < 0) { 1672 wpa_printf(MSG_DEBUG, 1673 "DPP: Authentication initialization failed"); 1674 return; 1675 } 1676 } 1677 1678 1679 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src, 1680 const u8 *buf, size_t len, unsigned int freq) 1681 { 1682 u8 crypto_suite; 1683 enum dpp_public_action_frame_type type; 1684 const u8 *hdr; 1685 unsigned int pkex_t; 1686 1687 if (len < DPP_HDR_LEN) 1688 return; 1689 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE) 1690 return; 1691 hdr = buf; 1692 buf += 4; 1693 len -= 4; 1694 crypto_suite = *buf++; 1695 type = *buf++; 1696 len -= 2; 1697 1698 wpa_printf(MSG_DEBUG, 1699 "DPP: Received DPP Public Action frame crypto suite %u type %d from " 1700 MACSTR " freq=%u", 1701 crypto_suite, type, MAC2STR(src), freq); 1702 if (crypto_suite != 1) { 1703 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u", 1704 crypto_suite); 1705 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 1706 " freq=%u type=%d ignore=unsupported-crypto-suite", 1707 MAC2STR(src), freq, type); 1708 return; 1709 } 1710 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len); 1711 if (dpp_check_attrs(buf, len) < 0) { 1712 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 1713 " freq=%u type=%d ignore=invalid-attributes", 1714 MAC2STR(src), freq, type); 1715 return; 1716 } 1717 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR 1718 " freq=%u type=%d", MAC2STR(src), freq, type); 1719 1720 switch (type) { 1721 case DPP_PA_AUTHENTICATION_REQ: 1722 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq); 1723 break; 1724 case DPP_PA_AUTHENTICATION_RESP: 1725 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq); 1726 break; 1727 case DPP_PA_AUTHENTICATION_CONF: 1728 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len); 1729 break; 1730 case DPP_PA_PEER_DISCOVERY_REQ: 1731 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq); 1732 break; 1733 case DPP_PA_PKEX_EXCHANGE_REQ: 1734 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq); 1735 break; 1736 case DPP_PA_PKEX_EXCHANGE_RESP: 1737 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq); 1738 break; 1739 case DPP_PA_PKEX_COMMIT_REVEAL_REQ: 1740 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len, 1741 freq); 1742 break; 1743 case DPP_PA_PKEX_COMMIT_REVEAL_RESP: 1744 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len, 1745 freq); 1746 break; 1747 default: 1748 wpa_printf(MSG_DEBUG, 1749 "DPP: Ignored unsupported frame subtype %d", type); 1750 break; 1751 } 1752 1753 if (hapd->dpp_pkex) 1754 pkex_t = hapd->dpp_pkex->t; 1755 else if (hapd->dpp_pkex_bi) 1756 pkex_t = hapd->dpp_pkex_bi->pkex_t; 1757 else 1758 pkex_t = 0; 1759 if (pkex_t >= PKEX_COUNTER_T_LIMIT) { 1760 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0"); 1761 hostapd_dpp_pkex_remove(hapd, "*"); 1762 } 1763 } 1764 1765 1766 struct wpabuf * 1767 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa, 1768 const u8 *query, size_t query_len) 1769 { 1770 struct dpp_authentication *auth = hapd->dpp_auth; 1771 struct wpabuf *resp; 1772 1773 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa)); 1774 if (!auth || !auth->auth_success || 1775 os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) { 1776 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); 1777 return NULL; 1778 } 1779 wpa_hexdump(MSG_DEBUG, 1780 "DPP: Received Configuration Request (GAS Query Request)", 1781 query, query_len); 1782 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR, 1783 MAC2STR(sa)); 1784 resp = dpp_conf_req_rx(auth, query, query_len); 1785 if (!resp) 1786 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1787 return resp; 1788 } 1789 1790 1791 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok) 1792 { 1793 if (!hapd->dpp_auth) 1794 return; 1795 1796 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 1797 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 1798 hostapd_drv_send_action_cancel_wait(hapd); 1799 1800 if (ok) 1801 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT); 1802 else 1803 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED); 1804 dpp_auth_deinit(hapd->dpp_auth); 1805 hapd->dpp_auth = NULL; 1806 } 1807 1808 1809 static unsigned int hostapd_dpp_next_configurator_id(struct hostapd_data *hapd) 1810 { 1811 struct dpp_configurator *conf; 1812 unsigned int max_id = 0; 1813 1814 dl_list_for_each(conf, &hapd->iface->interfaces->dpp_configurator, 1815 struct dpp_configurator, list) { 1816 if (conf->id > max_id) 1817 max_id = conf->id; 1818 } 1819 return max_id + 1; 1820 } 1821 1822 1823 int hostapd_dpp_configurator_add(struct hostapd_data *hapd, const char *cmd) 1824 { 1825 char *curve = NULL; 1826 char *key = NULL; 1827 u8 *privkey = NULL; 1828 size_t privkey_len = 0; 1829 int ret = -1; 1830 struct dpp_configurator *conf = NULL; 1831 1832 curve = get_param(cmd, " curve="); 1833 key = get_param(cmd, " key="); 1834 1835 if (key) { 1836 privkey_len = os_strlen(key) / 2; 1837 privkey = os_malloc(privkey_len); 1838 if (!privkey || 1839 hexstr2bin(key, privkey, privkey_len) < 0) 1840 goto fail; 1841 } 1842 1843 conf = dpp_keygen_configurator(curve, privkey, privkey_len); 1844 if (!conf) 1845 goto fail; 1846 1847 conf->id = hostapd_dpp_next_configurator_id(hapd); 1848 dl_list_add(&hapd->iface->interfaces->dpp_configurator, &conf->list); 1849 ret = conf->id; 1850 conf = NULL; 1851 fail: 1852 os_free(curve); 1853 str_clear_free(key); 1854 bin_clear_free(privkey, privkey_len); 1855 dpp_configurator_free(conf); 1856 return ret; 1857 } 1858 1859 1860 static int dpp_configurator_del(struct hapd_interfaces *ifaces, unsigned int id) 1861 { 1862 struct dpp_configurator *conf, *tmp; 1863 int found = 0; 1864 1865 dl_list_for_each_safe(conf, tmp, &ifaces->dpp_configurator, 1866 struct dpp_configurator, list) { 1867 if (id && conf->id != id) 1868 continue; 1869 found = 1; 1870 dl_list_del(&conf->list); 1871 dpp_configurator_free(conf); 1872 } 1873 1874 if (id == 0) 1875 return 0; /* flush succeeds regardless of entries found */ 1876 return found ? 0 : -1; 1877 } 1878 1879 1880 int hostapd_dpp_configurator_remove(struct hostapd_data *hapd, const char *id) 1881 { 1882 unsigned int id_val; 1883 1884 if (os_strcmp(id, "*") == 0) { 1885 id_val = 0; 1886 } else { 1887 id_val = atoi(id); 1888 if (id_val == 0) 1889 return -1; 1890 } 1891 1892 return dpp_configurator_del(hapd->iface->interfaces, id_val); 1893 } 1894 1895 1896 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd) 1897 { 1898 struct dpp_authentication *auth; 1899 int ret = -1; 1900 char *curve = NULL; 1901 1902 auth = os_zalloc(sizeof(*auth)); 1903 if (!auth) 1904 return -1; 1905 1906 curve = get_param(cmd, " curve="); 1907 hostapd_dpp_set_testing_options(hapd, auth); 1908 if (hostapd_dpp_set_configurator(hapd, auth, cmd) == 0 && 1909 dpp_configurator_own_config(auth, curve, 1) == 0) { 1910 hostapd_dpp_handle_config_obj(hapd, auth); 1911 ret = 0; 1912 } 1913 1914 dpp_auth_deinit(auth); 1915 os_free(curve); 1916 1917 return ret; 1918 } 1919 1920 1921 int hostapd_dpp_configurator_get_key(struct hostapd_data *hapd, unsigned int id, 1922 char *buf, size_t buflen) 1923 { 1924 struct dpp_configurator *conf; 1925 1926 conf = hostapd_dpp_configurator_get_id(hapd, id); 1927 if (!conf) 1928 return -1; 1929 1930 return dpp_configurator_get_key(conf, buf, buflen); 1931 } 1932 1933 1934 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd) 1935 { 1936 struct dpp_bootstrap_info *own_bi; 1937 const char *pos, *end; 1938 1939 pos = os_strstr(cmd, " own="); 1940 if (!pos) 1941 return -1; 1942 pos += 5; 1943 own_bi = dpp_bootstrap_get_id(hapd, atoi(pos)); 1944 if (!own_bi) { 1945 wpa_printf(MSG_DEBUG, 1946 "DPP: Identified bootstrap info not found"); 1947 return -1; 1948 } 1949 if (own_bi->type != DPP_BOOTSTRAP_PKEX) { 1950 wpa_printf(MSG_DEBUG, 1951 "DPP: Identified bootstrap info not for PKEX"); 1952 return -1; 1953 } 1954 hapd->dpp_pkex_bi = own_bi; 1955 own_bi->pkex_t = 0; /* clear pending errors on new code */ 1956 1957 os_free(hapd->dpp_pkex_identifier); 1958 hapd->dpp_pkex_identifier = NULL; 1959 pos = os_strstr(cmd, " identifier="); 1960 if (pos) { 1961 pos += 12; 1962 end = os_strchr(pos, ' '); 1963 if (!end) 1964 return -1; 1965 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1); 1966 if (!hapd->dpp_pkex_identifier) 1967 return -1; 1968 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos); 1969 hapd->dpp_pkex_identifier[end - pos] = '\0'; 1970 } 1971 1972 pos = os_strstr(cmd, " code="); 1973 if (!pos) 1974 return -1; 1975 os_free(hapd->dpp_pkex_code); 1976 hapd->dpp_pkex_code = os_strdup(pos + 6); 1977 if (!hapd->dpp_pkex_code) 1978 return -1; 1979 1980 if (os_strstr(cmd, " init=1")) { 1981 struct wpabuf *msg; 1982 1983 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX"); 1984 dpp_pkex_free(hapd->dpp_pkex); 1985 hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi, 1986 hapd->own_addr, 1987 hapd->dpp_pkex_identifier, 1988 hapd->dpp_pkex_code); 1989 if (!hapd->dpp_pkex) 1990 return -1; 1991 1992 msg = hapd->dpp_pkex->exchange_req; 1993 /* TODO: Which channel to use? */ 1994 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR 1995 " freq=%u type=%d", MAC2STR(broadcast), 2437, 1996 DPP_PA_PKEX_EXCHANGE_REQ); 1997 hostapd_drv_send_action(hapd, 2437, 0, broadcast, 1998 wpabuf_head(msg), wpabuf_len(msg)); 1999 } 2000 2001 /* TODO: Support multiple PKEX info entries */ 2002 2003 os_free(hapd->dpp_pkex_auth_cmd); 2004 hapd->dpp_pkex_auth_cmd = os_strdup(cmd); 2005 2006 return 1; 2007 } 2008 2009 2010 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id) 2011 { 2012 unsigned int id_val; 2013 2014 if (os_strcmp(id, "*") == 0) { 2015 id_val = 0; 2016 } else { 2017 id_val = atoi(id); 2018 if (id_val == 0) 2019 return -1; 2020 } 2021 2022 if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code) 2023 return -1; 2024 2025 /* TODO: Support multiple PKEX entries */ 2026 os_free(hapd->dpp_pkex_code); 2027 hapd->dpp_pkex_code = NULL; 2028 os_free(hapd->dpp_pkex_identifier); 2029 hapd->dpp_pkex_identifier = NULL; 2030 os_free(hapd->dpp_pkex_auth_cmd); 2031 hapd->dpp_pkex_auth_cmd = NULL; 2032 hapd->dpp_pkex_bi = NULL; 2033 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */ 2034 dpp_pkex_free(hapd->dpp_pkex); 2035 hapd->dpp_pkex = NULL; 2036 return 0; 2037 } 2038 2039 2040 void hostapd_dpp_stop(struct hostapd_data *hapd) 2041 { 2042 dpp_auth_deinit(hapd->dpp_auth); 2043 hapd->dpp_auth = NULL; 2044 dpp_pkex_free(hapd->dpp_pkex); 2045 hapd->dpp_pkex = NULL; 2046 } 2047 2048 2049 int hostapd_dpp_init(struct hostapd_data *hapd) 2050 { 2051 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE; 2052 hapd->dpp_init_done = 1; 2053 return 0; 2054 } 2055 2056 2057 void hostapd_dpp_deinit(struct hostapd_data *hapd) 2058 { 2059 #ifdef CONFIG_TESTING_OPTIONS 2060 os_free(hapd->dpp_config_obj_override); 2061 hapd->dpp_config_obj_override = NULL; 2062 os_free(hapd->dpp_discovery_override); 2063 hapd->dpp_discovery_override = NULL; 2064 os_free(hapd->dpp_groups_override); 2065 hapd->dpp_groups_override = NULL; 2066 hapd->dpp_ignore_netaccesskey_mismatch = 0; 2067 #endif /* CONFIG_TESTING_OPTIONS */ 2068 if (!hapd->dpp_init_done) 2069 return; 2070 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL); 2071 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL); 2072 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL); 2073 dpp_auth_deinit(hapd->dpp_auth); 2074 hapd->dpp_auth = NULL; 2075 hostapd_dpp_pkex_remove(hapd, "*"); 2076 hapd->dpp_pkex = NULL; 2077 os_free(hapd->dpp_configurator_params); 2078 hapd->dpp_configurator_params = NULL; 2079 } 2080 2081 2082 void hostapd_dpp_init_global(struct hapd_interfaces *ifaces) 2083 { 2084 dl_list_init(&ifaces->dpp_bootstrap); 2085 dl_list_init(&ifaces->dpp_configurator); 2086 ifaces->dpp_init_done = 1; 2087 } 2088 2089 2090 void hostapd_dpp_deinit_global(struct hapd_interfaces *ifaces) 2091 { 2092 if (!ifaces->dpp_init_done) 2093 return; 2094 dpp_bootstrap_del(ifaces, 0); 2095 dpp_configurator_del(ifaces, 0); 2096 } 2097