1 /* 2 * DPP authentication exchange 3 * Copyright (c) 2017, Qualcomm Atheros, Inc. 4 * Copyright (c) 2018-2020, The Linux Foundation 5 * 6 * This software may be distributed under the terms of the BSD license. 7 * See README for more details. 8 */ 9 10 #include "utils/includes.h" 11 12 #include "utils/common.h" 13 #include "common/ieee802_11_common.h" 14 #include "common/wpa_ctrl.h" 15 #include "crypto/aes.h" 16 #include "crypto/aes_siv.h" 17 #include "crypto/random.h" 18 #include "dpp.h" 19 #include "dpp_i.h" 20 21 22 #ifdef CONFIG_TESTING_OPTIONS 23 u8 dpp_protocol_key_override[600]; 24 size_t dpp_protocol_key_override_len = 0; 25 u8 dpp_nonce_override[DPP_MAX_NONCE_LEN]; 26 size_t dpp_nonce_override_len = 0; 27 #endif /* CONFIG_TESTING_OPTIONS */ 28 29 30 static void dpp_build_attr_i_bootstrap_key_hash(struct wpabuf *msg, 31 const u8 *hash) 32 { 33 if (hash) { 34 wpa_printf(MSG_DEBUG, "DPP: I-Bootstrap Key Hash"); 35 wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH); 36 wpabuf_put_le16(msg, SHA256_MAC_LEN); 37 wpabuf_put_data(msg, hash, SHA256_MAC_LEN); 38 } 39 } 40 41 42 static void dpp_auth_success(struct dpp_authentication *auth) 43 { 44 wpa_printf(MSG_DEBUG, 45 "DPP: Authentication success - clear temporary keys"); 46 os_memset(auth->Mx, 0, sizeof(auth->Mx)); 47 auth->Mx_len = 0; 48 os_memset(auth->Nx, 0, sizeof(auth->Nx)); 49 auth->Nx_len = 0; 50 os_memset(auth->Lx, 0, sizeof(auth->Lx)); 51 auth->Lx_len = 0; 52 os_memset(auth->k1, 0, sizeof(auth->k1)); 53 os_memset(auth->k2, 0, sizeof(auth->k2)); 54 55 auth->auth_success = 1; 56 } 57 58 59 static struct wpabuf * dpp_auth_build_req(struct dpp_authentication *auth, 60 const struct wpabuf *pi, 61 size_t nonce_len, 62 const u8 *r_pubkey_hash, 63 const u8 *i_pubkey_hash, 64 unsigned int neg_freq) 65 { 66 struct wpabuf *msg; 67 u8 clear[4 + DPP_MAX_NONCE_LEN + 4 + 1]; 68 u8 wrapped_data[4 + DPP_MAX_NONCE_LEN + 4 + 1 + AES_BLOCK_SIZE]; 69 u8 *pos; 70 const u8 *addr[2]; 71 size_t len[2], siv_len, attr_len; 72 u8 *attr_start, *attr_end; 73 74 /* Build DPP Authentication Request frame attributes */ 75 attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + (pi ? wpabuf_len(pi) : 0) + 76 4 + sizeof(wrapped_data); 77 if (neg_freq > 0) 78 attr_len += 4 + 2; 79 #ifdef CONFIG_DPP2 80 attr_len += 5; 81 #endif /* CONFIG_DPP2 */ 82 #ifdef CONFIG_TESTING_OPTIONS 83 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ) 84 attr_len += 5; 85 #endif /* CONFIG_TESTING_OPTIONS */ 86 msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ, attr_len); 87 if (!msg) 88 return NULL; 89 90 attr_start = wpabuf_put(msg, 0); 91 92 /* Responder Bootstrapping Key Hash */ 93 dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash); 94 95 /* Initiator Bootstrapping Key Hash */ 96 dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash); 97 98 /* Initiator Protocol Key */ 99 if (pi) { 100 wpabuf_put_le16(msg, DPP_ATTR_I_PROTOCOL_KEY); 101 wpabuf_put_le16(msg, wpabuf_len(pi)); 102 wpabuf_put_buf(msg, pi); 103 } 104 105 /* Channel */ 106 if (neg_freq > 0) { 107 u8 op_class, channel; 108 109 if (ieee80211_freq_to_channel_ext(neg_freq, 0, 0, &op_class, 110 &channel) == 111 NUM_HOSTAPD_MODES) { 112 wpa_printf(MSG_INFO, 113 "DPP: Unsupported negotiation frequency request: %d", 114 neg_freq); 115 wpabuf_free(msg); 116 return NULL; 117 } 118 wpabuf_put_le16(msg, DPP_ATTR_CHANNEL); 119 wpabuf_put_le16(msg, 2); 120 wpabuf_put_u8(msg, op_class); 121 wpabuf_put_u8(msg, channel); 122 } 123 124 #ifdef CONFIG_DPP2 125 /* Protocol Version */ 126 if (DPP_VERSION > 1) { 127 wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); 128 wpabuf_put_le16(msg, 1); 129 wpabuf_put_u8(msg, DPP_VERSION); 130 } 131 #endif /* CONFIG_DPP2 */ 132 133 #ifdef CONFIG_TESTING_OPTIONS 134 if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_REQ) { 135 wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data"); 136 goto skip_wrapped_data; 137 } 138 #endif /* CONFIG_TESTING_OPTIONS */ 139 140 /* Wrapped data ({I-nonce, I-capabilities}k1) */ 141 pos = clear; 142 143 #ifdef CONFIG_TESTING_OPTIONS 144 if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_REQ) { 145 wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce"); 146 goto skip_i_nonce; 147 } 148 if (dpp_test == DPP_TEST_INVALID_I_NONCE_AUTH_REQ) { 149 wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-nonce"); 150 WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE); 151 pos += 2; 152 WPA_PUT_LE16(pos, nonce_len - 1); 153 pos += 2; 154 os_memcpy(pos, auth->i_nonce, nonce_len - 1); 155 pos += nonce_len - 1; 156 goto skip_i_nonce; 157 } 158 #endif /* CONFIG_TESTING_OPTIONS */ 159 160 /* I-nonce */ 161 WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE); 162 pos += 2; 163 WPA_PUT_LE16(pos, nonce_len); 164 pos += 2; 165 os_memcpy(pos, auth->i_nonce, nonce_len); 166 pos += nonce_len; 167 168 #ifdef CONFIG_TESTING_OPTIONS 169 skip_i_nonce: 170 if (dpp_test == DPP_TEST_NO_I_CAPAB_AUTH_REQ) { 171 wpa_printf(MSG_INFO, "DPP: TESTING - no I-capab"); 172 goto skip_i_capab; 173 } 174 #endif /* CONFIG_TESTING_OPTIONS */ 175 176 /* I-capabilities */ 177 WPA_PUT_LE16(pos, DPP_ATTR_I_CAPABILITIES); 178 pos += 2; 179 WPA_PUT_LE16(pos, 1); 180 pos += 2; 181 auth->i_capab = auth->allowed_roles; 182 *pos++ = auth->i_capab; 183 #ifdef CONFIG_TESTING_OPTIONS 184 if (dpp_test == DPP_TEST_ZERO_I_CAPAB) { 185 wpa_printf(MSG_INFO, "DPP: TESTING - zero I-capabilities"); 186 pos[-1] = 0; 187 } 188 skip_i_capab: 189 #endif /* CONFIG_TESTING_OPTIONS */ 190 191 attr_end = wpabuf_put(msg, 0); 192 193 /* OUI, OUI type, Crypto Suite, DPP frame type */ 194 addr[0] = wpabuf_head_u8(msg) + 2; 195 len[0] = 3 + 1 + 1 + 1; 196 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 197 198 /* Attributes before Wrapped Data */ 199 addr[1] = attr_start; 200 len[1] = attr_end - attr_start; 201 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 202 203 siv_len = pos - clear; 204 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len); 205 if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len, 206 2, addr, len, wrapped_data) < 0) { 207 wpabuf_free(msg); 208 return NULL; 209 } 210 siv_len += AES_BLOCK_SIZE; 211 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 212 wrapped_data, siv_len); 213 214 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA); 215 wpabuf_put_le16(msg, siv_len); 216 wpabuf_put_data(msg, wrapped_data, siv_len); 217 218 #ifdef CONFIG_TESTING_OPTIONS 219 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ) { 220 wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data"); 221 dpp_build_attr_status(msg, DPP_STATUS_OK); 222 } 223 skip_wrapped_data: 224 #endif /* CONFIG_TESTING_OPTIONS */ 225 226 wpa_hexdump_buf(MSG_DEBUG, 227 "DPP: Authentication Request frame attributes", msg); 228 229 return msg; 230 } 231 232 233 static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth, 234 enum dpp_status_error status, 235 const struct wpabuf *pr, 236 size_t nonce_len, 237 const u8 *r_pubkey_hash, 238 const u8 *i_pubkey_hash, 239 const u8 *r_nonce, const u8 *i_nonce, 240 const u8 *wrapped_r_auth, 241 size_t wrapped_r_auth_len, 242 const u8 *siv_key) 243 { 244 struct wpabuf *msg; 245 #define DPP_AUTH_RESP_CLEAR_LEN 2 * (4 + DPP_MAX_NONCE_LEN) + 4 + 1 + \ 246 4 + 4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE 247 u8 clear[DPP_AUTH_RESP_CLEAR_LEN]; 248 u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN + AES_BLOCK_SIZE]; 249 const u8 *addr[2]; 250 size_t len[2], siv_len, attr_len; 251 u8 *attr_start, *attr_end, *pos; 252 253 auth->waiting_auth_conf = 1; 254 auth->auth_resp_status = status; 255 auth->auth_resp_tries = 0; 256 257 /* Build DPP Authentication Response frame attributes */ 258 attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) + 259 4 + (pr ? wpabuf_len(pr) : 0) + 4 + sizeof(wrapped_data); 260 #ifdef CONFIG_DPP2 261 attr_len += 5; 262 #endif /* CONFIG_DPP2 */ 263 #ifdef CONFIG_TESTING_OPTIONS 264 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) 265 attr_len += 5; 266 #endif /* CONFIG_TESTING_OPTIONS */ 267 msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len); 268 if (!msg) 269 return NULL; 270 271 attr_start = wpabuf_put(msg, 0); 272 273 /* DPP Status */ 274 if (status != 255) 275 dpp_build_attr_status(msg, status); 276 277 /* Responder Bootstrapping Key Hash */ 278 dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash); 279 280 /* Initiator Bootstrapping Key Hash (mutual authentication) */ 281 dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash); 282 283 /* Responder Protocol Key */ 284 if (pr) { 285 wpabuf_put_le16(msg, DPP_ATTR_R_PROTOCOL_KEY); 286 wpabuf_put_le16(msg, wpabuf_len(pr)); 287 wpabuf_put_buf(msg, pr); 288 } 289 290 #ifdef CONFIG_DPP2 291 /* Protocol Version */ 292 if (auth->peer_version >= 2) { 293 wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION); 294 wpabuf_put_le16(msg, 1); 295 wpabuf_put_u8(msg, DPP_VERSION); 296 } 297 #endif /* CONFIG_DPP2 */ 298 299 attr_end = wpabuf_put(msg, 0); 300 301 #ifdef CONFIG_TESTING_OPTIONS 302 if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_RESP) { 303 wpa_printf(MSG_INFO, "DPP: TESTING - no Wrapped Data"); 304 goto skip_wrapped_data; 305 } 306 #endif /* CONFIG_TESTING_OPTIONS */ 307 308 /* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */ 309 pos = clear; 310 311 if (r_nonce) { 312 /* R-nonce */ 313 WPA_PUT_LE16(pos, DPP_ATTR_R_NONCE); 314 pos += 2; 315 WPA_PUT_LE16(pos, nonce_len); 316 pos += 2; 317 os_memcpy(pos, r_nonce, nonce_len); 318 pos += nonce_len; 319 } 320 321 if (i_nonce) { 322 /* I-nonce */ 323 WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE); 324 pos += 2; 325 WPA_PUT_LE16(pos, nonce_len); 326 pos += 2; 327 os_memcpy(pos, i_nonce, nonce_len); 328 #ifdef CONFIG_TESTING_OPTIONS 329 if (dpp_test == DPP_TEST_I_NONCE_MISMATCH_AUTH_RESP) { 330 wpa_printf(MSG_INFO, "DPP: TESTING - I-nonce mismatch"); 331 pos[nonce_len / 2] ^= 0x01; 332 } 333 #endif /* CONFIG_TESTING_OPTIONS */ 334 pos += nonce_len; 335 } 336 337 #ifdef CONFIG_TESTING_OPTIONS 338 if (dpp_test == DPP_TEST_NO_R_CAPAB_AUTH_RESP) { 339 wpa_printf(MSG_INFO, "DPP: TESTING - no R-capab"); 340 goto skip_r_capab; 341 } 342 #endif /* CONFIG_TESTING_OPTIONS */ 343 344 /* R-capabilities */ 345 WPA_PUT_LE16(pos, DPP_ATTR_R_CAPABILITIES); 346 pos += 2; 347 WPA_PUT_LE16(pos, 1); 348 pos += 2; 349 auth->r_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR : 350 DPP_CAPAB_ENROLLEE; 351 *pos++ = auth->r_capab; 352 #ifdef CONFIG_TESTING_OPTIONS 353 if (dpp_test == DPP_TEST_ZERO_R_CAPAB) { 354 wpa_printf(MSG_INFO, "DPP: TESTING - zero R-capabilities"); 355 pos[-1] = 0; 356 } else if (dpp_test == DPP_TEST_INCOMPATIBLE_R_CAPAB_AUTH_RESP) { 357 wpa_printf(MSG_INFO, 358 "DPP: TESTING - incompatible R-capabilities"); 359 if ((auth->i_capab & DPP_CAPAB_ROLE_MASK) == 360 (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) 361 pos[-1] = 0; 362 else 363 pos[-1] = auth->configurator ? DPP_CAPAB_ENROLLEE : 364 DPP_CAPAB_CONFIGURATOR; 365 } 366 skip_r_capab: 367 #endif /* CONFIG_TESTING_OPTIONS */ 368 369 if (wrapped_r_auth) { 370 /* {R-auth}ke */ 371 WPA_PUT_LE16(pos, DPP_ATTR_WRAPPED_DATA); 372 pos += 2; 373 WPA_PUT_LE16(pos, wrapped_r_auth_len); 374 pos += 2; 375 os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len); 376 pos += wrapped_r_auth_len; 377 } 378 379 /* OUI, OUI type, Crypto Suite, DPP frame type */ 380 addr[0] = wpabuf_head_u8(msg) + 2; 381 len[0] = 3 + 1 + 1 + 1; 382 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 383 384 /* Attributes before Wrapped Data */ 385 addr[1] = attr_start; 386 len[1] = attr_end - attr_start; 387 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 388 389 siv_len = pos - clear; 390 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len); 391 if (aes_siv_encrypt(siv_key, auth->curve->hash_len, clear, siv_len, 392 2, addr, len, wrapped_data) < 0) { 393 wpabuf_free(msg); 394 return NULL; 395 } 396 siv_len += AES_BLOCK_SIZE; 397 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 398 wrapped_data, siv_len); 399 400 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA); 401 wpabuf_put_le16(msg, siv_len); 402 wpabuf_put_data(msg, wrapped_data, siv_len); 403 404 #ifdef CONFIG_TESTING_OPTIONS 405 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP) { 406 wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data"); 407 dpp_build_attr_status(msg, DPP_STATUS_OK); 408 } 409 skip_wrapped_data: 410 #endif /* CONFIG_TESTING_OPTIONS */ 411 412 wpa_hexdump_buf(MSG_DEBUG, 413 "DPP: Authentication Response frame attributes", msg); 414 return msg; 415 } 416 417 418 static int dpp_auth_build_resp_ok(struct dpp_authentication *auth) 419 { 420 size_t nonce_len; 421 size_t secret_len; 422 struct wpabuf *msg, *pr = NULL; 423 u8 r_auth[4 + DPP_MAX_HASH_LEN]; 424 u8 wrapped_r_auth[4 + DPP_MAX_HASH_LEN + AES_BLOCK_SIZE], *w_r_auth; 425 size_t wrapped_r_auth_len; 426 int ret = -1; 427 const u8 *r_pubkey_hash, *i_pubkey_hash, *r_nonce, *i_nonce; 428 enum dpp_status_error status = DPP_STATUS_OK; 429 #ifdef CONFIG_TESTING_OPTIONS 430 u8 test_hash[SHA256_MAC_LEN]; 431 #endif /* CONFIG_TESTING_OPTIONS */ 432 433 wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response"); 434 if (!auth->own_bi) 435 return -1; 436 437 #ifdef CONFIG_TESTING_OPTIONS 438 if (dpp_nonce_override_len > 0) { 439 wpa_printf(MSG_INFO, "DPP: TESTING - override R-nonce"); 440 nonce_len = dpp_nonce_override_len; 441 os_memcpy(auth->r_nonce, dpp_nonce_override, nonce_len); 442 } else { 443 nonce_len = auth->curve->nonce_len; 444 if (random_get_bytes(auth->r_nonce, nonce_len)) { 445 wpa_printf(MSG_ERROR, 446 "DPP: Failed to generate R-nonce"); 447 goto fail; 448 } 449 } 450 #else /* CONFIG_TESTING_OPTIONS */ 451 nonce_len = auth->curve->nonce_len; 452 if (random_get_bytes(auth->r_nonce, nonce_len)) { 453 wpa_printf(MSG_ERROR, "DPP: Failed to generate R-nonce"); 454 goto fail; 455 } 456 #endif /* CONFIG_TESTING_OPTIONS */ 457 wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", auth->r_nonce, nonce_len); 458 459 EVP_PKEY_free(auth->own_protocol_key); 460 #ifdef CONFIG_TESTING_OPTIONS 461 if (dpp_protocol_key_override_len) { 462 const struct dpp_curve_params *tmp_curve; 463 464 wpa_printf(MSG_INFO, 465 "DPP: TESTING - override protocol key"); 466 auth->own_protocol_key = dpp_set_keypair( 467 &tmp_curve, dpp_protocol_key_override, 468 dpp_protocol_key_override_len); 469 } else { 470 auth->own_protocol_key = dpp_gen_keypair(auth->curve); 471 } 472 #else /* CONFIG_TESTING_OPTIONS */ 473 auth->own_protocol_key = dpp_gen_keypair(auth->curve); 474 #endif /* CONFIG_TESTING_OPTIONS */ 475 if (!auth->own_protocol_key) 476 goto fail; 477 478 pr = dpp_get_pubkey_point(auth->own_protocol_key, 0); 479 if (!pr) 480 goto fail; 481 482 /* ECDH: N = pR * PI */ 483 if (dpp_ecdh(auth->own_protocol_key, auth->peer_protocol_key, 484 auth->Nx, &secret_len) < 0) 485 goto fail; 486 487 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)", 488 auth->Nx, auth->secret_len); 489 auth->Nx_len = auth->secret_len; 490 491 if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2, 492 auth->curve->hash_len) < 0) 493 goto fail; 494 495 if (auth->own_bi && auth->peer_bi) { 496 /* Mutual authentication */ 497 if (dpp_auth_derive_l_responder(auth) < 0) 498 goto fail; 499 } 500 501 if (dpp_derive_bk_ke(auth) < 0) 502 goto fail; 503 504 /* R-auth = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */ 505 WPA_PUT_LE16(r_auth, DPP_ATTR_R_AUTH_TAG); 506 WPA_PUT_LE16(&r_auth[2], auth->curve->hash_len); 507 if (dpp_gen_r_auth(auth, r_auth + 4) < 0) 508 goto fail; 509 #ifdef CONFIG_TESTING_OPTIONS 510 if (dpp_test == DPP_TEST_R_AUTH_MISMATCH_AUTH_RESP) { 511 wpa_printf(MSG_INFO, "DPP: TESTING - R-auth mismatch"); 512 r_auth[4 + auth->curve->hash_len / 2] ^= 0x01; 513 } 514 #endif /* CONFIG_TESTING_OPTIONS */ 515 if (aes_siv_encrypt(auth->ke, auth->curve->hash_len, 516 r_auth, 4 + auth->curve->hash_len, 517 0, NULL, NULL, wrapped_r_auth) < 0) 518 goto fail; 519 wrapped_r_auth_len = 4 + auth->curve->hash_len + AES_BLOCK_SIZE; 520 wpa_hexdump(MSG_DEBUG, "DPP: {R-auth}ke", 521 wrapped_r_auth, wrapped_r_auth_len); 522 w_r_auth = wrapped_r_auth; 523 524 r_pubkey_hash = auth->own_bi->pubkey_hash; 525 if (auth->peer_bi) 526 i_pubkey_hash = auth->peer_bi->pubkey_hash; 527 else 528 i_pubkey_hash = NULL; 529 530 i_nonce = auth->i_nonce; 531 r_nonce = auth->r_nonce; 532 533 #ifdef CONFIG_TESTING_OPTIONS 534 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 535 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash"); 536 r_pubkey_hash = NULL; 537 } else if (dpp_test == 538 DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 539 wpa_printf(MSG_INFO, 540 "DPP: TESTING - invalid R-Bootstrap Key Hash"); 541 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN); 542 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 543 r_pubkey_hash = test_hash; 544 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 545 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash"); 546 i_pubkey_hash = NULL; 547 } else if (dpp_test == 548 DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 549 wpa_printf(MSG_INFO, 550 "DPP: TESTING - invalid I-Bootstrap Key Hash"); 551 if (i_pubkey_hash) 552 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN); 553 else 554 os_memset(test_hash, 0, SHA256_MAC_LEN); 555 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 556 i_pubkey_hash = test_hash; 557 } else if (dpp_test == DPP_TEST_NO_R_PROTO_KEY_AUTH_RESP) { 558 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Proto Key"); 559 wpabuf_free(pr); 560 pr = NULL; 561 } else if (dpp_test == DPP_TEST_INVALID_R_PROTO_KEY_AUTH_RESP) { 562 wpa_printf(MSG_INFO, "DPP: TESTING - invalid R-Proto Key"); 563 wpabuf_free(pr); 564 pr = wpabuf_alloc(2 * auth->curve->prime_len); 565 if (!pr || dpp_test_gen_invalid_key(pr, auth->curve) < 0) 566 goto fail; 567 } else if (dpp_test == DPP_TEST_NO_R_AUTH_AUTH_RESP) { 568 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Auth"); 569 w_r_auth = NULL; 570 wrapped_r_auth_len = 0; 571 } else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) { 572 wpa_printf(MSG_INFO, "DPP: TESTING - no Status"); 573 status = 255; 574 } else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_RESP) { 575 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status"); 576 status = 254; 577 } else if (dpp_test == DPP_TEST_NO_R_NONCE_AUTH_RESP) { 578 wpa_printf(MSG_INFO, "DPP: TESTING - no R-nonce"); 579 r_nonce = NULL; 580 } else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) { 581 wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce"); 582 i_nonce = NULL; 583 } 584 #endif /* CONFIG_TESTING_OPTIONS */ 585 586 msg = dpp_auth_build_resp(auth, status, pr, nonce_len, 587 r_pubkey_hash, i_pubkey_hash, 588 r_nonce, i_nonce, 589 w_r_auth, wrapped_r_auth_len, 590 auth->k2); 591 if (!msg) 592 goto fail; 593 wpabuf_free(auth->resp_msg); 594 auth->resp_msg = msg; 595 ret = 0; 596 fail: 597 wpabuf_free(pr); 598 return ret; 599 } 600 601 602 static int dpp_auth_build_resp_status(struct dpp_authentication *auth, 603 enum dpp_status_error status) 604 { 605 struct wpabuf *msg; 606 const u8 *r_pubkey_hash, *i_pubkey_hash, *i_nonce; 607 #ifdef CONFIG_TESTING_OPTIONS 608 u8 test_hash[SHA256_MAC_LEN]; 609 #endif /* CONFIG_TESTING_OPTIONS */ 610 611 if (!auth->own_bi) 612 return -1; 613 wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response"); 614 615 r_pubkey_hash = auth->own_bi->pubkey_hash; 616 if (auth->peer_bi) 617 i_pubkey_hash = auth->peer_bi->pubkey_hash; 618 else 619 i_pubkey_hash = NULL; 620 621 i_nonce = auth->i_nonce; 622 623 #ifdef CONFIG_TESTING_OPTIONS 624 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 625 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash"); 626 r_pubkey_hash = NULL; 627 } else if (dpp_test == 628 DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 629 wpa_printf(MSG_INFO, 630 "DPP: TESTING - invalid R-Bootstrap Key Hash"); 631 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN); 632 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 633 r_pubkey_hash = test_hash; 634 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 635 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash"); 636 i_pubkey_hash = NULL; 637 } else if (dpp_test == 638 DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP) { 639 wpa_printf(MSG_INFO, 640 "DPP: TESTING - invalid I-Bootstrap Key Hash"); 641 if (i_pubkey_hash) 642 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN); 643 else 644 os_memset(test_hash, 0, SHA256_MAC_LEN); 645 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 646 i_pubkey_hash = test_hash; 647 } else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) { 648 wpa_printf(MSG_INFO, "DPP: TESTING - no Status"); 649 status = 255; 650 } else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) { 651 wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce"); 652 i_nonce = NULL; 653 } 654 #endif /* CONFIG_TESTING_OPTIONS */ 655 656 msg = dpp_auth_build_resp(auth, status, NULL, auth->curve->nonce_len, 657 r_pubkey_hash, i_pubkey_hash, 658 NULL, i_nonce, NULL, 0, auth->k1); 659 if (!msg) 660 return -1; 661 wpabuf_free(auth->resp_msg); 662 auth->resp_msg = msg; 663 return 0; 664 } 665 666 667 struct dpp_authentication * 668 dpp_auth_req_rx(struct dpp_global *dpp, void *msg_ctx, u8 dpp_allowed_roles, 669 int qr_mutual, struct dpp_bootstrap_info *peer_bi, 670 struct dpp_bootstrap_info *own_bi, 671 unsigned int freq, const u8 *hdr, const u8 *attr_start, 672 size_t attr_len) 673 { 674 EVP_PKEY *pi = NULL; 675 EVP_PKEY_CTX *ctx = NULL; 676 size_t secret_len; 677 const u8 *addr[2]; 678 size_t len[2]; 679 u8 *unwrapped = NULL; 680 size_t unwrapped_len = 0; 681 const u8 *wrapped_data, *i_proto, *i_nonce, *i_capab, *i_bootstrap, 682 *channel; 683 u16 wrapped_data_len, i_proto_len, i_nonce_len, i_capab_len, 684 i_bootstrap_len, channel_len; 685 struct dpp_authentication *auth = NULL; 686 #ifdef CONFIG_DPP2 687 const u8 *version; 688 u16 version_len; 689 #endif /* CONFIG_DPP2 */ 690 691 #ifdef CONFIG_TESTING_OPTIONS 692 if (dpp_test == DPP_TEST_STOP_AT_AUTH_REQ) { 693 wpa_printf(MSG_INFO, 694 "DPP: TESTING - stop at Authentication Request"); 695 return NULL; 696 } 697 #endif /* CONFIG_TESTING_OPTIONS */ 698 699 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA, 700 &wrapped_data_len); 701 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) { 702 wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL 703 "Missing or invalid required Wrapped Data attribute"); 704 return NULL; 705 } 706 wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped Data", 707 wrapped_data, wrapped_data_len); 708 attr_len = wrapped_data - 4 - attr_start; 709 710 auth = dpp_alloc_auth(dpp, msg_ctx); 711 if (!auth) 712 goto fail; 713 if (peer_bi && peer_bi->configurator_params && 714 dpp_set_configurator(auth, peer_bi->configurator_params) < 0) 715 goto fail; 716 auth->peer_bi = peer_bi; 717 auth->own_bi = own_bi; 718 auth->curve = own_bi->curve; 719 auth->curr_freq = freq; 720 721 auth->peer_version = 1; /* default to the first version */ 722 #ifdef CONFIG_DPP2 723 version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION, 724 &version_len); 725 if (version && DPP_VERSION > 1) { 726 if (version_len < 1 || version[0] == 0) { 727 dpp_auth_fail(auth, 728 "Invalid Protocol Version attribute"); 729 goto fail; 730 } 731 auth->peer_version = version[0]; 732 wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u", 733 auth->peer_version); 734 } 735 #endif /* CONFIG_DPP2 */ 736 737 channel = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CHANNEL, 738 &channel_len); 739 if (channel) { 740 int neg_freq; 741 742 if (channel_len < 2) { 743 dpp_auth_fail(auth, "Too short Channel attribute"); 744 goto fail; 745 } 746 747 neg_freq = ieee80211_chan_to_freq(NULL, channel[0], channel[1]); 748 wpa_printf(MSG_DEBUG, 749 "DPP: Initiator requested different channel for negotiation: op_class=%u channel=%u --> freq=%d", 750 channel[0], channel[1], neg_freq); 751 if (neg_freq < 0) { 752 dpp_auth_fail(auth, 753 "Unsupported Channel attribute value"); 754 goto fail; 755 } 756 757 if (auth->curr_freq != (unsigned int) neg_freq) { 758 wpa_printf(MSG_DEBUG, 759 "DPP: Changing negotiation channel from %u MHz to %u MHz", 760 freq, neg_freq); 761 auth->curr_freq = neg_freq; 762 } 763 } 764 765 i_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_I_PROTOCOL_KEY, 766 &i_proto_len); 767 if (!i_proto) { 768 dpp_auth_fail(auth, 769 "Missing required Initiator Protocol Key attribute"); 770 goto fail; 771 } 772 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Protocol Key", 773 i_proto, i_proto_len); 774 775 /* M = bR * PI */ 776 pi = dpp_set_pubkey_point(own_bi->pubkey, i_proto, i_proto_len); 777 if (!pi) { 778 dpp_auth_fail(auth, "Invalid Initiator Protocol Key"); 779 goto fail; 780 } 781 dpp_debug_print_key("Peer (Initiator) Protocol Key", pi); 782 783 if (dpp_ecdh(own_bi->pubkey, pi, auth->Mx, &secret_len) < 0) 784 goto fail; 785 auth->secret_len = secret_len; 786 787 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)", 788 auth->Mx, auth->secret_len); 789 auth->Mx_len = auth->secret_len; 790 791 if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1, 792 auth->curve->hash_len) < 0) 793 goto fail; 794 795 addr[0] = hdr; 796 len[0] = DPP_HDR_LEN; 797 addr[1] = attr_start; 798 len[1] = attr_len; 799 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 800 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 801 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 802 wrapped_data, wrapped_data_len); 803 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 804 unwrapped = os_malloc(unwrapped_len); 805 if (!unwrapped) 806 goto fail; 807 if (aes_siv_decrypt(auth->k1, auth->curve->hash_len, 808 wrapped_data, wrapped_data_len, 809 2, addr, len, unwrapped) < 0) { 810 dpp_auth_fail(auth, "AES-SIV decryption failed"); 811 goto fail; 812 } 813 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 814 unwrapped, unwrapped_len); 815 816 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 817 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 818 goto fail; 819 } 820 821 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE, 822 &i_nonce_len); 823 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) { 824 dpp_auth_fail(auth, "Missing or invalid I-nonce"); 825 goto fail; 826 } 827 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len); 828 os_memcpy(auth->i_nonce, i_nonce, i_nonce_len); 829 830 i_capab = dpp_get_attr(unwrapped, unwrapped_len, 831 DPP_ATTR_I_CAPABILITIES, 832 &i_capab_len); 833 if (!i_capab || i_capab_len < 1) { 834 dpp_auth_fail(auth, "Missing or invalid I-capabilities"); 835 goto fail; 836 } 837 auth->i_capab = i_capab[0]; 838 wpa_printf(MSG_DEBUG, "DPP: I-capabilities: 0x%02x", auth->i_capab); 839 840 bin_clear_free(unwrapped, unwrapped_len); 841 unwrapped = NULL; 842 843 switch (auth->i_capab & DPP_CAPAB_ROLE_MASK) { 844 case DPP_CAPAB_ENROLLEE: 845 if (!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)) { 846 wpa_printf(MSG_DEBUG, 847 "DPP: Local policy does not allow Configurator role"); 848 goto not_compatible; 849 } 850 wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator"); 851 auth->configurator = 1; 852 break; 853 case DPP_CAPAB_CONFIGURATOR: 854 if (!(dpp_allowed_roles & DPP_CAPAB_ENROLLEE)) { 855 wpa_printf(MSG_DEBUG, 856 "DPP: Local policy does not allow Enrollee role"); 857 goto not_compatible; 858 } 859 wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee"); 860 auth->configurator = 0; 861 break; 862 case DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE: 863 if (dpp_allowed_roles & DPP_CAPAB_ENROLLEE) { 864 wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee"); 865 auth->configurator = 0; 866 } else if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) { 867 wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator"); 868 auth->configurator = 1; 869 } else { 870 wpa_printf(MSG_DEBUG, 871 "DPP: Local policy does not allow Configurator/Enrollee role"); 872 goto not_compatible; 873 } 874 break; 875 default: 876 wpa_printf(MSG_DEBUG, "DPP: Unexpected role in I-capabilities"); 877 wpa_msg(auth->msg_ctx, MSG_INFO, 878 DPP_EVENT_FAIL "Invalid role in I-capabilities 0x%02x", 879 auth->i_capab & DPP_CAPAB_ROLE_MASK); 880 goto fail; 881 } 882 883 auth->peer_protocol_key = pi; 884 pi = NULL; 885 if (qr_mutual && !peer_bi && own_bi->type == DPP_BOOTSTRAP_QR_CODE) { 886 char hex[SHA256_MAC_LEN * 2 + 1]; 887 888 wpa_printf(MSG_DEBUG, 889 "DPP: Mutual authentication required with QR Codes, but peer info is not yet available - request more time"); 890 if (dpp_auth_build_resp_status(auth, 891 DPP_STATUS_RESPONSE_PENDING) < 0) 892 goto fail; 893 i_bootstrap = dpp_get_attr(attr_start, attr_len, 894 DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 895 &i_bootstrap_len); 896 if (i_bootstrap && i_bootstrap_len == SHA256_MAC_LEN) { 897 auth->response_pending = 1; 898 os_memcpy(auth->waiting_pubkey_hash, 899 i_bootstrap, i_bootstrap_len); 900 wpa_snprintf_hex(hex, sizeof(hex), i_bootstrap, 901 i_bootstrap_len); 902 } else { 903 hex[0] = '\0'; 904 } 905 906 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_SCAN_PEER_QR_CODE 907 "%s", hex); 908 return auth; 909 } 910 if (dpp_auth_build_resp_ok(auth) < 0) 911 goto fail; 912 913 return auth; 914 915 not_compatible: 916 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE 917 "i-capab=0x%02x", auth->i_capab); 918 if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) 919 auth->configurator = 1; 920 else 921 auth->configurator = 0; 922 auth->peer_protocol_key = pi; 923 pi = NULL; 924 if (dpp_auth_build_resp_status(auth, DPP_STATUS_NOT_COMPATIBLE) < 0) 925 goto fail; 926 927 auth->remove_on_tx_status = 1; 928 return auth; 929 fail: 930 bin_clear_free(unwrapped, unwrapped_len); 931 EVP_PKEY_free(pi); 932 EVP_PKEY_CTX_free(ctx); 933 dpp_auth_deinit(auth); 934 return NULL; 935 } 936 937 938 int dpp_notify_new_qr_code(struct dpp_authentication *auth, 939 struct dpp_bootstrap_info *peer_bi) 940 { 941 if (!auth || !auth->response_pending || 942 os_memcmp(auth->waiting_pubkey_hash, peer_bi->pubkey_hash, 943 SHA256_MAC_LEN) != 0) 944 return 0; 945 946 wpa_printf(MSG_DEBUG, 947 "DPP: New scanned QR Code has matching public key that was needed to continue DPP Authentication exchange with " 948 MACSTR, MAC2STR(auth->peer_mac_addr)); 949 auth->peer_bi = peer_bi; 950 951 if (dpp_auth_build_resp_ok(auth) < 0) 952 return -1; 953 954 return 1; 955 } 956 957 958 static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth, 959 enum dpp_status_error status) 960 { 961 struct wpabuf *msg; 962 u8 i_auth[4 + DPP_MAX_HASH_LEN]; 963 size_t i_auth_len; 964 u8 r_nonce[4 + DPP_MAX_NONCE_LEN]; 965 size_t r_nonce_len; 966 const u8 *addr[2]; 967 size_t len[2], attr_len; 968 u8 *wrapped_i_auth; 969 u8 *wrapped_r_nonce; 970 u8 *attr_start, *attr_end; 971 const u8 *r_pubkey_hash, *i_pubkey_hash; 972 #ifdef CONFIG_TESTING_OPTIONS 973 u8 test_hash[SHA256_MAC_LEN]; 974 #endif /* CONFIG_TESTING_OPTIONS */ 975 976 wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation"); 977 978 i_auth_len = 4 + auth->curve->hash_len; 979 r_nonce_len = 4 + auth->curve->nonce_len; 980 /* Build DPP Authentication Confirmation frame attributes */ 981 attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) + 982 4 + i_auth_len + r_nonce_len + AES_BLOCK_SIZE; 983 #ifdef CONFIG_TESTING_OPTIONS 984 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) 985 attr_len += 5; 986 #endif /* CONFIG_TESTING_OPTIONS */ 987 msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len); 988 if (!msg) 989 goto fail; 990 991 attr_start = wpabuf_put(msg, 0); 992 993 r_pubkey_hash = auth->peer_bi->pubkey_hash; 994 if (auth->own_bi) 995 i_pubkey_hash = auth->own_bi->pubkey_hash; 996 else 997 i_pubkey_hash = NULL; 998 999 #ifdef CONFIG_TESTING_OPTIONS 1000 if (dpp_test == DPP_TEST_NO_STATUS_AUTH_CONF) { 1001 wpa_printf(MSG_INFO, "DPP: TESTING - no Status"); 1002 goto skip_status; 1003 } else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_CONF) { 1004 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status"); 1005 status = 254; 1006 } 1007 #endif /* CONFIG_TESTING_OPTIONS */ 1008 1009 /* DPP Status */ 1010 dpp_build_attr_status(msg, status); 1011 1012 #ifdef CONFIG_TESTING_OPTIONS 1013 skip_status: 1014 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1015 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash"); 1016 r_pubkey_hash = NULL; 1017 } else if (dpp_test == 1018 DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1019 wpa_printf(MSG_INFO, 1020 "DPP: TESTING - invalid R-Bootstrap Key Hash"); 1021 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN); 1022 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1023 r_pubkey_hash = test_hash; 1024 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1025 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash"); 1026 i_pubkey_hash = NULL; 1027 } else if (dpp_test == 1028 DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1029 wpa_printf(MSG_INFO, 1030 "DPP: TESTING - invalid I-Bootstrap Key Hash"); 1031 if (i_pubkey_hash) 1032 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN); 1033 else 1034 os_memset(test_hash, 0, SHA256_MAC_LEN); 1035 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1036 i_pubkey_hash = test_hash; 1037 } 1038 #endif /* CONFIG_TESTING_OPTIONS */ 1039 1040 /* Responder Bootstrapping Key Hash */ 1041 dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash); 1042 1043 /* Initiator Bootstrapping Key Hash (mutual authentication) */ 1044 dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash); 1045 1046 #ifdef CONFIG_TESTING_OPTIONS 1047 if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_CONF) 1048 goto skip_wrapped_data; 1049 if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF) 1050 i_auth_len = 0; 1051 #endif /* CONFIG_TESTING_OPTIONS */ 1052 1053 attr_end = wpabuf_put(msg, 0); 1054 1055 /* OUI, OUI type, Crypto Suite, DPP frame type */ 1056 addr[0] = wpabuf_head_u8(msg) + 2; 1057 len[0] = 3 + 1 + 1 + 1; 1058 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1059 1060 /* Attributes before Wrapped Data */ 1061 addr[1] = attr_start; 1062 len[1] = attr_end - attr_start; 1063 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1064 1065 if (status == DPP_STATUS_OK) { 1066 /* I-auth wrapped with ke */ 1067 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA); 1068 wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE); 1069 wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE); 1070 1071 #ifdef CONFIG_TESTING_OPTIONS 1072 if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF) 1073 goto skip_i_auth; 1074 #endif /* CONFIG_TESTING_OPTIONS */ 1075 1076 /* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1077 * 1) */ 1078 WPA_PUT_LE16(i_auth, DPP_ATTR_I_AUTH_TAG); 1079 WPA_PUT_LE16(&i_auth[2], auth->curve->hash_len); 1080 if (dpp_gen_i_auth(auth, i_auth + 4) < 0) 1081 goto fail; 1082 1083 #ifdef CONFIG_TESTING_OPTIONS 1084 if (dpp_test == DPP_TEST_I_AUTH_MISMATCH_AUTH_CONF) { 1085 wpa_printf(MSG_INFO, "DPP: TESTING - I-auth mismatch"); 1086 i_auth[4 + auth->curve->hash_len / 2] ^= 0x01; 1087 } 1088 skip_i_auth: 1089 #endif /* CONFIG_TESTING_OPTIONS */ 1090 if (aes_siv_encrypt(auth->ke, auth->curve->hash_len, 1091 i_auth, i_auth_len, 1092 2, addr, len, wrapped_i_auth) < 0) 1093 goto fail; 1094 wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke", 1095 wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE); 1096 } else { 1097 /* R-nonce wrapped with k2 */ 1098 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA); 1099 wpabuf_put_le16(msg, r_nonce_len + AES_BLOCK_SIZE); 1100 wrapped_r_nonce = wpabuf_put(msg, r_nonce_len + AES_BLOCK_SIZE); 1101 1102 WPA_PUT_LE16(r_nonce, DPP_ATTR_R_NONCE); 1103 WPA_PUT_LE16(&r_nonce[2], auth->curve->nonce_len); 1104 os_memcpy(r_nonce + 4, auth->r_nonce, auth->curve->nonce_len); 1105 1106 if (aes_siv_encrypt(auth->k2, auth->curve->hash_len, 1107 r_nonce, r_nonce_len, 1108 2, addr, len, wrapped_r_nonce) < 0) 1109 goto fail; 1110 wpa_hexdump(MSG_DEBUG, "DPP: {R-nonce}k2", 1111 wrapped_r_nonce, r_nonce_len + AES_BLOCK_SIZE); 1112 } 1113 1114 #ifdef CONFIG_TESTING_OPTIONS 1115 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) { 1116 wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data"); 1117 dpp_build_attr_status(msg, DPP_STATUS_OK); 1118 } 1119 skip_wrapped_data: 1120 #endif /* CONFIG_TESTING_OPTIONS */ 1121 1122 wpa_hexdump_buf(MSG_DEBUG, 1123 "DPP: Authentication Confirmation frame attributes", 1124 msg); 1125 if (status == DPP_STATUS_OK) 1126 dpp_auth_success(auth); 1127 1128 return msg; 1129 1130 fail: 1131 wpabuf_free(msg); 1132 return NULL; 1133 } 1134 1135 1136 static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth) 1137 { 1138 struct dpp_bootstrap_info *bi; 1139 1140 if (auth->own_bi) 1141 return 0; /* already generated */ 1142 1143 bi = os_zalloc(sizeof(*bi)); 1144 if (!bi) 1145 return -1; 1146 bi->type = DPP_BOOTSTRAP_QR_CODE; 1147 if (dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0) < 0 || 1148 dpp_gen_uri(bi) < 0) 1149 goto fail; 1150 wpa_printf(MSG_DEBUG, 1151 "DPP: Auto-generated own bootstrapping key info: URI %s", 1152 bi->uri); 1153 1154 auth->tmp_own_bi = auth->own_bi = bi; 1155 1156 return 0; 1157 fail: 1158 dpp_bootstrap_info_free(bi); 1159 return -1; 1160 } 1161 1162 1163 struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx, 1164 struct dpp_bootstrap_info *peer_bi, 1165 struct dpp_bootstrap_info *own_bi, 1166 u8 dpp_allowed_roles, 1167 unsigned int neg_freq, 1168 struct hostapd_hw_modes *own_modes, 1169 u16 num_modes) 1170 { 1171 struct dpp_authentication *auth; 1172 size_t nonce_len; 1173 size_t secret_len; 1174 struct wpabuf *pi = NULL; 1175 const u8 *r_pubkey_hash, *i_pubkey_hash; 1176 #ifdef CONFIG_TESTING_OPTIONS 1177 u8 test_hash[SHA256_MAC_LEN]; 1178 #endif /* CONFIG_TESTING_OPTIONS */ 1179 1180 auth = dpp_alloc_auth(dpp, msg_ctx); 1181 if (!auth) 1182 return NULL; 1183 if (peer_bi->configurator_params && 1184 dpp_set_configurator(auth, peer_bi->configurator_params) < 0) 1185 goto fail; 1186 auth->initiator = 1; 1187 auth->waiting_auth_resp = 1; 1188 auth->allowed_roles = dpp_allowed_roles; 1189 auth->configurator = !!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR); 1190 auth->peer_bi = peer_bi; 1191 auth->own_bi = own_bi; 1192 auth->curve = peer_bi->curve; 1193 1194 if (dpp_autogen_bootstrap_key(auth) < 0 || 1195 dpp_prepare_channel_list(auth, neg_freq, own_modes, num_modes) < 0) 1196 goto fail; 1197 1198 #ifdef CONFIG_TESTING_OPTIONS 1199 if (dpp_nonce_override_len > 0) { 1200 wpa_printf(MSG_INFO, "DPP: TESTING - override I-nonce"); 1201 nonce_len = dpp_nonce_override_len; 1202 os_memcpy(auth->i_nonce, dpp_nonce_override, nonce_len); 1203 } else { 1204 nonce_len = auth->curve->nonce_len; 1205 if (random_get_bytes(auth->i_nonce, nonce_len)) { 1206 wpa_printf(MSG_ERROR, 1207 "DPP: Failed to generate I-nonce"); 1208 goto fail; 1209 } 1210 } 1211 #else /* CONFIG_TESTING_OPTIONS */ 1212 nonce_len = auth->curve->nonce_len; 1213 if (random_get_bytes(auth->i_nonce, nonce_len)) { 1214 wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce"); 1215 goto fail; 1216 } 1217 #endif /* CONFIG_TESTING_OPTIONS */ 1218 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len); 1219 1220 #ifdef CONFIG_TESTING_OPTIONS 1221 if (dpp_protocol_key_override_len) { 1222 const struct dpp_curve_params *tmp_curve; 1223 1224 wpa_printf(MSG_INFO, 1225 "DPP: TESTING - override protocol key"); 1226 auth->own_protocol_key = dpp_set_keypair( 1227 &tmp_curve, dpp_protocol_key_override, 1228 dpp_protocol_key_override_len); 1229 } else { 1230 auth->own_protocol_key = dpp_gen_keypair(auth->curve); 1231 } 1232 #else /* CONFIG_TESTING_OPTIONS */ 1233 auth->own_protocol_key = dpp_gen_keypair(auth->curve); 1234 #endif /* CONFIG_TESTING_OPTIONS */ 1235 if (!auth->own_protocol_key) 1236 goto fail; 1237 1238 pi = dpp_get_pubkey_point(auth->own_protocol_key, 0); 1239 if (!pi) 1240 goto fail; 1241 1242 /* ECDH: M = pI * BR */ 1243 if (dpp_ecdh(auth->own_protocol_key, auth->peer_bi->pubkey, 1244 auth->Mx, &secret_len) < 0) 1245 goto fail; 1246 auth->secret_len = secret_len; 1247 1248 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)", 1249 auth->Mx, auth->secret_len); 1250 auth->Mx_len = auth->secret_len; 1251 1252 if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1, 1253 auth->curve->hash_len) < 0) 1254 goto fail; 1255 1256 r_pubkey_hash = auth->peer_bi->pubkey_hash; 1257 i_pubkey_hash = auth->own_bi->pubkey_hash; 1258 1259 #ifdef CONFIG_TESTING_OPTIONS 1260 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1261 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash"); 1262 r_pubkey_hash = NULL; 1263 } else if (dpp_test == DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1264 wpa_printf(MSG_INFO, 1265 "DPP: TESTING - invalid R-Bootstrap Key Hash"); 1266 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN); 1267 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1268 r_pubkey_hash = test_hash; 1269 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1270 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash"); 1271 i_pubkey_hash = NULL; 1272 } else if (dpp_test == DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1273 wpa_printf(MSG_INFO, 1274 "DPP: TESTING - invalid I-Bootstrap Key Hash"); 1275 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN); 1276 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1277 i_pubkey_hash = test_hash; 1278 } else if (dpp_test == DPP_TEST_NO_I_PROTO_KEY_AUTH_REQ) { 1279 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Proto Key"); 1280 wpabuf_free(pi); 1281 pi = NULL; 1282 } else if (dpp_test == DPP_TEST_INVALID_I_PROTO_KEY_AUTH_REQ) { 1283 wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-Proto Key"); 1284 wpabuf_free(pi); 1285 pi = wpabuf_alloc(2 * auth->curve->prime_len); 1286 if (!pi || dpp_test_gen_invalid_key(pi, auth->curve) < 0) 1287 goto fail; 1288 } 1289 #endif /* CONFIG_TESTING_OPTIONS */ 1290 1291 if (neg_freq && auth->num_freq == 1 && auth->freq[0] == neg_freq) 1292 neg_freq = 0; 1293 auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash, 1294 i_pubkey_hash, neg_freq); 1295 if (!auth->req_msg) 1296 goto fail; 1297 1298 out: 1299 wpabuf_free(pi); 1300 return auth; 1301 fail: 1302 dpp_auth_deinit(auth); 1303 auth = NULL; 1304 goto out; 1305 } 1306 static void 1307 dpp_auth_resp_rx_status(struct dpp_authentication *auth, const u8 *hdr, 1308 const u8 *attr_start, size_t attr_len, 1309 const u8 *wrapped_data, u16 wrapped_data_len, 1310 enum dpp_status_error status) 1311 { 1312 const u8 *addr[2]; 1313 size_t len[2]; 1314 u8 *unwrapped = NULL; 1315 size_t unwrapped_len = 0; 1316 const u8 *i_nonce, *r_capab; 1317 u16 i_nonce_len, r_capab_len; 1318 1319 if (status == DPP_STATUS_NOT_COMPATIBLE) { 1320 wpa_printf(MSG_DEBUG, 1321 "DPP: Responder reported incompatible roles"); 1322 } else if (status == DPP_STATUS_RESPONSE_PENDING) { 1323 wpa_printf(MSG_DEBUG, 1324 "DPP: Responder reported more time needed"); 1325 } else { 1326 wpa_printf(MSG_DEBUG, 1327 "DPP: Responder reported failure (status %d)", 1328 status); 1329 dpp_auth_fail(auth, "Responder reported failure"); 1330 return; 1331 } 1332 1333 addr[0] = hdr; 1334 len[0] = DPP_HDR_LEN; 1335 addr[1] = attr_start; 1336 len[1] = attr_len; 1337 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1338 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1339 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1340 wrapped_data, wrapped_data_len); 1341 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1342 unwrapped = os_malloc(unwrapped_len); 1343 if (!unwrapped) 1344 goto fail; 1345 if (aes_siv_decrypt(auth->k1, auth->curve->hash_len, 1346 wrapped_data, wrapped_data_len, 1347 2, addr, len, unwrapped) < 0) { 1348 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1349 goto fail; 1350 } 1351 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1352 unwrapped, unwrapped_len); 1353 1354 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1355 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1356 goto fail; 1357 } 1358 1359 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE, 1360 &i_nonce_len); 1361 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) { 1362 dpp_auth_fail(auth, "Missing or invalid I-nonce"); 1363 goto fail; 1364 } 1365 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len); 1366 if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) { 1367 dpp_auth_fail(auth, "I-nonce mismatch"); 1368 goto fail; 1369 } 1370 1371 r_capab = dpp_get_attr(unwrapped, unwrapped_len, 1372 DPP_ATTR_R_CAPABILITIES, 1373 &r_capab_len); 1374 if (!r_capab || r_capab_len < 1) { 1375 dpp_auth_fail(auth, "Missing or invalid R-capabilities"); 1376 goto fail; 1377 } 1378 auth->r_capab = r_capab[0]; 1379 wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab); 1380 if (status == DPP_STATUS_NOT_COMPATIBLE) { 1381 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE 1382 "r-capab=0x%02x", auth->r_capab); 1383 } else if (status == DPP_STATUS_RESPONSE_PENDING) { 1384 u8 role = auth->r_capab & DPP_CAPAB_ROLE_MASK; 1385 1386 if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) || 1387 (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) { 1388 wpa_msg(auth->msg_ctx, MSG_INFO, 1389 DPP_EVENT_FAIL "Unexpected role in R-capabilities 0x%02x", 1390 role); 1391 } else { 1392 wpa_printf(MSG_DEBUG, 1393 "DPP: Continue waiting for full DPP Authentication Response"); 1394 wpa_msg(auth->msg_ctx, MSG_INFO, 1395 DPP_EVENT_RESPONSE_PENDING "%s", 1396 auth->tmp_own_bi ? auth->tmp_own_bi->uri : ""); 1397 } 1398 } 1399 fail: 1400 bin_clear_free(unwrapped, unwrapped_len); 1401 } 1402 1403 1404 struct wpabuf * 1405 dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, 1406 const u8 *attr_start, size_t attr_len) 1407 { 1408 EVP_PKEY *pr; 1409 size_t secret_len; 1410 const u8 *addr[2]; 1411 size_t len[2]; 1412 u8 *unwrapped = NULL, *unwrapped2 = NULL; 1413 size_t unwrapped_len = 0, unwrapped2_len = 0; 1414 const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto, 1415 *r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth; 1416 u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len, 1417 r_proto_len, r_nonce_len, i_nonce_len, r_capab_len, 1418 wrapped2_len, r_auth_len; 1419 u8 r_auth2[DPP_MAX_HASH_LEN]; 1420 u8 role; 1421 #ifdef CONFIG_DPP2 1422 const u8 *version; 1423 u16 version_len; 1424 #endif /* CONFIG_DPP2 */ 1425 1426 #ifdef CONFIG_TESTING_OPTIONS 1427 if (dpp_test == DPP_TEST_STOP_AT_AUTH_RESP) { 1428 wpa_printf(MSG_INFO, 1429 "DPP: TESTING - stop at Authentication Response"); 1430 return NULL; 1431 } 1432 #endif /* CONFIG_TESTING_OPTIONS */ 1433 1434 if (!auth->initiator || !auth->peer_bi || auth->reconfig) { 1435 dpp_auth_fail(auth, "Unexpected Authentication Response"); 1436 return NULL; 1437 } 1438 1439 auth->waiting_auth_resp = 0; 1440 1441 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA, 1442 &wrapped_data_len); 1443 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) { 1444 dpp_auth_fail(auth, 1445 "Missing or invalid required Wrapped Data attribute"); 1446 return NULL; 1447 } 1448 wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data", 1449 wrapped_data, wrapped_data_len); 1450 1451 attr_len = wrapped_data - 4 - attr_start; 1452 1453 r_bootstrap = dpp_get_attr(attr_start, attr_len, 1454 DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 1455 &r_bootstrap_len); 1456 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { 1457 dpp_auth_fail(auth, 1458 "Missing or invalid required Responder Bootstrapping Key Hash attribute"); 1459 return NULL; 1460 } 1461 wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash", 1462 r_bootstrap, r_bootstrap_len); 1463 if (os_memcmp(r_bootstrap, auth->peer_bi->pubkey_hash, 1464 SHA256_MAC_LEN) != 0) { 1465 dpp_auth_fail(auth, 1466 "Unexpected Responder Bootstrapping Key Hash value"); 1467 wpa_hexdump(MSG_DEBUG, 1468 "DPP: Expected Responder Bootstrapping Key Hash", 1469 auth->peer_bi->pubkey_hash, SHA256_MAC_LEN); 1470 return NULL; 1471 } 1472 1473 i_bootstrap = dpp_get_attr(attr_start, attr_len, 1474 DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 1475 &i_bootstrap_len); 1476 if (i_bootstrap) { 1477 if (i_bootstrap_len != SHA256_MAC_LEN) { 1478 dpp_auth_fail(auth, 1479 "Invalid Initiator Bootstrapping Key Hash attribute"); 1480 return NULL; 1481 } 1482 wpa_hexdump(MSG_MSGDUMP, 1483 "DPP: Initiator Bootstrapping Key Hash", 1484 i_bootstrap, i_bootstrap_len); 1485 if (!auth->own_bi || 1486 os_memcmp(i_bootstrap, auth->own_bi->pubkey_hash, 1487 SHA256_MAC_LEN) != 0) { 1488 dpp_auth_fail(auth, 1489 "Initiator Bootstrapping Key Hash attribute did not match"); 1490 return NULL; 1491 } 1492 } else if (auth->own_bi && auth->own_bi->type == DPP_BOOTSTRAP_PKEX) { 1493 /* PKEX bootstrapping mandates use of mutual authentication */ 1494 dpp_auth_fail(auth, 1495 "Missing Initiator Bootstrapping Key Hash attribute"); 1496 return NULL; 1497 } else if (auth->own_bi && 1498 auth->own_bi->type == DPP_BOOTSTRAP_NFC_URI && 1499 auth->own_bi->nfc_negotiated) { 1500 /* NFC negotiated connection handover bootstrapping mandates 1501 * use of mutual authentication */ 1502 dpp_auth_fail(auth, 1503 "Missing Initiator Bootstrapping Key Hash attribute"); 1504 return NULL; 1505 } 1506 1507 auth->peer_version = 1; /* default to the first version */ 1508 #ifdef CONFIG_DPP2 1509 version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION, 1510 &version_len); 1511 if (version && DPP_VERSION > 1) { 1512 if (version_len < 1 || version[0] == 0) { 1513 dpp_auth_fail(auth, 1514 "Invalid Protocol Version attribute"); 1515 return NULL; 1516 } 1517 auth->peer_version = version[0]; 1518 wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u", 1519 auth->peer_version); 1520 } 1521 #endif /* CONFIG_DPP2 */ 1522 1523 status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS, 1524 &status_len); 1525 if (!status || status_len < 1) { 1526 dpp_auth_fail(auth, 1527 "Missing or invalid required DPP Status attribute"); 1528 return NULL; 1529 } 1530 wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]); 1531 auth->auth_resp_status = status[0]; 1532 if (status[0] != DPP_STATUS_OK) { 1533 dpp_auth_resp_rx_status(auth, hdr, attr_start, 1534 attr_len, wrapped_data, 1535 wrapped_data_len, status[0]); 1536 return NULL; 1537 } 1538 1539 if (!i_bootstrap && auth->own_bi) { 1540 wpa_printf(MSG_DEBUG, 1541 "DPP: Responder decided not to use mutual authentication"); 1542 auth->own_bi = NULL; 1543 } 1544 1545 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_DIRECTION "mutual=%d", 1546 auth->own_bi != NULL); 1547 1548 r_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_R_PROTOCOL_KEY, 1549 &r_proto_len); 1550 if (!r_proto) { 1551 dpp_auth_fail(auth, 1552 "Missing required Responder Protocol Key attribute"); 1553 return NULL; 1554 } 1555 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Protocol Key", 1556 r_proto, r_proto_len); 1557 1558 /* N = pI * PR */ 1559 pr = dpp_set_pubkey_point(auth->own_protocol_key, r_proto, r_proto_len); 1560 if (!pr) { 1561 dpp_auth_fail(auth, "Invalid Responder Protocol Key"); 1562 return NULL; 1563 } 1564 dpp_debug_print_key("Peer (Responder) Protocol Key", pr); 1565 1566 if (dpp_ecdh(auth->own_protocol_key, pr, auth->Nx, &secret_len) < 0) { 1567 dpp_auth_fail(auth, "Failed to derive ECDH shared secret"); 1568 goto fail; 1569 } 1570 EVP_PKEY_free(auth->peer_protocol_key); 1571 auth->peer_protocol_key = pr; 1572 pr = NULL; 1573 1574 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)", 1575 auth->Nx, auth->secret_len); 1576 auth->Nx_len = auth->secret_len; 1577 1578 if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2, 1579 auth->curve->hash_len) < 0) 1580 goto fail; 1581 1582 addr[0] = hdr; 1583 len[0] = DPP_HDR_LEN; 1584 addr[1] = attr_start; 1585 len[1] = attr_len; 1586 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1587 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1588 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1589 wrapped_data, wrapped_data_len); 1590 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1591 unwrapped = os_malloc(unwrapped_len); 1592 if (!unwrapped) 1593 goto fail; 1594 if (aes_siv_decrypt(auth->k2, auth->curve->hash_len, 1595 wrapped_data, wrapped_data_len, 1596 2, addr, len, unwrapped) < 0) { 1597 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1598 goto fail; 1599 } 1600 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1601 unwrapped, unwrapped_len); 1602 1603 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1604 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1605 goto fail; 1606 } 1607 1608 r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE, 1609 &r_nonce_len); 1610 if (!r_nonce || r_nonce_len != auth->curve->nonce_len) { 1611 dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce"); 1612 goto fail; 1613 } 1614 wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", r_nonce, r_nonce_len); 1615 os_memcpy(auth->r_nonce, r_nonce, r_nonce_len); 1616 1617 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE, 1618 &i_nonce_len); 1619 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) { 1620 dpp_auth_fail(auth, "Missing or invalid I-nonce"); 1621 goto fail; 1622 } 1623 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len); 1624 if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) { 1625 dpp_auth_fail(auth, "I-nonce mismatch"); 1626 goto fail; 1627 } 1628 1629 if (auth->own_bi) { 1630 /* Mutual authentication */ 1631 if (dpp_auth_derive_l_initiator(auth) < 0) 1632 goto fail; 1633 } 1634 1635 r_capab = dpp_get_attr(unwrapped, unwrapped_len, 1636 DPP_ATTR_R_CAPABILITIES, 1637 &r_capab_len); 1638 if (!r_capab || r_capab_len < 1) { 1639 dpp_auth_fail(auth, "Missing or invalid R-capabilities"); 1640 goto fail; 1641 } 1642 auth->r_capab = r_capab[0]; 1643 wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab); 1644 role = auth->r_capab & DPP_CAPAB_ROLE_MASK; 1645 if ((auth->allowed_roles == 1646 (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) && 1647 (role == DPP_CAPAB_CONFIGURATOR || role == DPP_CAPAB_ENROLLEE)) { 1648 /* Peer selected its role, so move from "either role" to the 1649 * role that is compatible with peer's selection. */ 1650 auth->configurator = role == DPP_CAPAB_ENROLLEE; 1651 wpa_printf(MSG_DEBUG, "DPP: Acting as %s", 1652 auth->configurator ? "Configurator" : "Enrollee"); 1653 } else if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) || 1654 (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) { 1655 wpa_printf(MSG_DEBUG, "DPP: Incompatible role selection"); 1656 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 1657 "Unexpected role in R-capabilities 0x%02x", 1658 role); 1659 if (role != DPP_CAPAB_ENROLLEE && 1660 role != DPP_CAPAB_CONFIGURATOR) 1661 goto fail; 1662 bin_clear_free(unwrapped, unwrapped_len); 1663 auth->remove_on_tx_status = 1; 1664 return dpp_auth_build_conf(auth, DPP_STATUS_NOT_COMPATIBLE); 1665 } 1666 1667 wrapped2 = dpp_get_attr(unwrapped, unwrapped_len, 1668 DPP_ATTR_WRAPPED_DATA, &wrapped2_len); 1669 if (!wrapped2 || wrapped2_len < AES_BLOCK_SIZE) { 1670 dpp_auth_fail(auth, 1671 "Missing or invalid Secondary Wrapped Data"); 1672 goto fail; 1673 } 1674 1675 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1676 wrapped2, wrapped2_len); 1677 1678 if (dpp_derive_bk_ke(auth) < 0) 1679 goto fail; 1680 1681 unwrapped2_len = wrapped2_len - AES_BLOCK_SIZE; 1682 unwrapped2 = os_malloc(unwrapped2_len); 1683 if (!unwrapped2) 1684 goto fail; 1685 if (aes_siv_decrypt(auth->ke, auth->curve->hash_len, 1686 wrapped2, wrapped2_len, 1687 0, NULL, NULL, unwrapped2) < 0) { 1688 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1689 goto fail; 1690 } 1691 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1692 unwrapped2, unwrapped2_len); 1693 1694 if (dpp_check_attrs(unwrapped2, unwrapped2_len) < 0) { 1695 dpp_auth_fail(auth, 1696 "Invalid attribute in secondary unwrapped data"); 1697 goto fail; 1698 } 1699 1700 r_auth = dpp_get_attr(unwrapped2, unwrapped2_len, DPP_ATTR_R_AUTH_TAG, 1701 &r_auth_len); 1702 if (!r_auth || r_auth_len != auth->curve->hash_len) { 1703 dpp_auth_fail(auth, 1704 "Missing or invalid Responder Authenticating Tag"); 1705 goto fail; 1706 } 1707 wpa_hexdump(MSG_DEBUG, "DPP: Received Responder Authenticating Tag", 1708 r_auth, r_auth_len); 1709 /* R-auth' = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */ 1710 if (dpp_gen_r_auth(auth, r_auth2) < 0) 1711 goto fail; 1712 wpa_hexdump(MSG_DEBUG, "DPP: Calculated Responder Authenticating Tag", 1713 r_auth2, r_auth_len); 1714 if (os_memcmp(r_auth, r_auth2, r_auth_len) != 0) { 1715 dpp_auth_fail(auth, "Mismatching Responder Authenticating Tag"); 1716 bin_clear_free(unwrapped, unwrapped_len); 1717 bin_clear_free(unwrapped2, unwrapped2_len); 1718 auth->remove_on_tx_status = 1; 1719 return dpp_auth_build_conf(auth, DPP_STATUS_AUTH_FAILURE); 1720 } 1721 1722 bin_clear_free(unwrapped, unwrapped_len); 1723 bin_clear_free(unwrapped2, unwrapped2_len); 1724 1725 #ifdef CONFIG_TESTING_OPTIONS 1726 if (dpp_test == DPP_TEST_AUTH_RESP_IN_PLACE_OF_CONF) { 1727 wpa_printf(MSG_INFO, 1728 "DPP: TESTING - Authentication Response in place of Confirm"); 1729 if (dpp_auth_build_resp_ok(auth) < 0) 1730 return NULL; 1731 return wpabuf_dup(auth->resp_msg); 1732 } 1733 #endif /* CONFIG_TESTING_OPTIONS */ 1734 1735 return dpp_auth_build_conf(auth, DPP_STATUS_OK); 1736 1737 fail: 1738 bin_clear_free(unwrapped, unwrapped_len); 1739 bin_clear_free(unwrapped2, unwrapped2_len); 1740 EVP_PKEY_free(pr); 1741 return NULL; 1742 } 1743 1744 1745 static int dpp_auth_conf_rx_failure(struct dpp_authentication *auth, 1746 const u8 *hdr, 1747 const u8 *attr_start, size_t attr_len, 1748 const u8 *wrapped_data, 1749 u16 wrapped_data_len, 1750 enum dpp_status_error status) 1751 { 1752 const u8 *addr[2]; 1753 size_t len[2]; 1754 u8 *unwrapped = NULL; 1755 size_t unwrapped_len = 0; 1756 const u8 *r_nonce; 1757 u16 r_nonce_len; 1758 1759 /* Authentication Confirm failure cases are expected to include 1760 * {R-nonce}k2 in the Wrapped Data attribute. */ 1761 1762 addr[0] = hdr; 1763 len[0] = DPP_HDR_LEN; 1764 addr[1] = attr_start; 1765 len[1] = attr_len; 1766 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1767 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1768 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1769 wrapped_data, wrapped_data_len); 1770 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1771 unwrapped = os_malloc(unwrapped_len); 1772 if (!unwrapped) { 1773 dpp_auth_fail(auth, "Authentication failed"); 1774 goto fail; 1775 } 1776 if (aes_siv_decrypt(auth->k2, auth->curve->hash_len, 1777 wrapped_data, wrapped_data_len, 1778 2, addr, len, unwrapped) < 0) { 1779 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1780 goto fail; 1781 } 1782 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1783 unwrapped, unwrapped_len); 1784 1785 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1786 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1787 goto fail; 1788 } 1789 1790 r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE, 1791 &r_nonce_len); 1792 if (!r_nonce || r_nonce_len != auth->curve->nonce_len) { 1793 dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce"); 1794 goto fail; 1795 } 1796 if (os_memcmp(r_nonce, auth->r_nonce, r_nonce_len) != 0) { 1797 wpa_hexdump(MSG_DEBUG, "DPP: Received R-nonce", 1798 r_nonce, r_nonce_len); 1799 wpa_hexdump(MSG_DEBUG, "DPP: Expected R-nonce", 1800 auth->r_nonce, r_nonce_len); 1801 dpp_auth_fail(auth, "R-nonce mismatch"); 1802 goto fail; 1803 } 1804 1805 if (status == DPP_STATUS_NOT_COMPATIBLE) 1806 dpp_auth_fail(auth, "Peer reported incompatible R-capab role"); 1807 else if (status == DPP_STATUS_AUTH_FAILURE) 1808 dpp_auth_fail(auth, "Peer reported authentication failure)"); 1809 1810 fail: 1811 bin_clear_free(unwrapped, unwrapped_len); 1812 return -1; 1813 } 1814 1815 1816 int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr, 1817 const u8 *attr_start, size_t attr_len) 1818 { 1819 const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth; 1820 u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len, 1821 i_auth_len; 1822 const u8 *addr[2]; 1823 size_t len[2]; 1824 u8 *unwrapped = NULL; 1825 size_t unwrapped_len = 0; 1826 u8 i_auth2[DPP_MAX_HASH_LEN]; 1827 1828 #ifdef CONFIG_TESTING_OPTIONS 1829 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) { 1830 wpa_printf(MSG_INFO, 1831 "DPP: TESTING - stop at Authentication Confirm"); 1832 return -1; 1833 } 1834 #endif /* CONFIG_TESTING_OPTIONS */ 1835 1836 if (auth->initiator || !auth->own_bi || !auth->waiting_auth_conf || 1837 auth->reconfig) { 1838 wpa_printf(MSG_DEBUG, 1839 "DPP: initiator=%d own_bi=%d waiting_auth_conf=%d", 1840 auth->initiator, !!auth->own_bi, 1841 auth->waiting_auth_conf); 1842 dpp_auth_fail(auth, "Unexpected Authentication Confirm"); 1843 return -1; 1844 } 1845 1846 auth->waiting_auth_conf = 0; 1847 1848 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA, 1849 &wrapped_data_len); 1850 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) { 1851 dpp_auth_fail(auth, 1852 "Missing or invalid required Wrapped Data attribute"); 1853 return -1; 1854 } 1855 wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data", 1856 wrapped_data, wrapped_data_len); 1857 1858 attr_len = wrapped_data - 4 - attr_start; 1859 1860 r_bootstrap = dpp_get_attr(attr_start, attr_len, 1861 DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 1862 &r_bootstrap_len); 1863 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { 1864 dpp_auth_fail(auth, 1865 "Missing or invalid required Responder Bootstrapping Key Hash attribute"); 1866 return -1; 1867 } 1868 wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash", 1869 r_bootstrap, r_bootstrap_len); 1870 if (os_memcmp(r_bootstrap, auth->own_bi->pubkey_hash, 1871 SHA256_MAC_LEN) != 0) { 1872 wpa_hexdump(MSG_DEBUG, 1873 "DPP: Expected Responder Bootstrapping Key Hash", 1874 auth->peer_bi->pubkey_hash, SHA256_MAC_LEN); 1875 dpp_auth_fail(auth, 1876 "Responder Bootstrapping Key Hash mismatch"); 1877 return -1; 1878 } 1879 1880 i_bootstrap = dpp_get_attr(attr_start, attr_len, 1881 DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 1882 &i_bootstrap_len); 1883 if (i_bootstrap) { 1884 if (i_bootstrap_len != SHA256_MAC_LEN) { 1885 dpp_auth_fail(auth, 1886 "Invalid Initiator Bootstrapping Key Hash attribute"); 1887 return -1; 1888 } 1889 wpa_hexdump(MSG_MSGDUMP, 1890 "DPP: Initiator Bootstrapping Key Hash", 1891 i_bootstrap, i_bootstrap_len); 1892 if (!auth->peer_bi || 1893 os_memcmp(i_bootstrap, auth->peer_bi->pubkey_hash, 1894 SHA256_MAC_LEN) != 0) { 1895 dpp_auth_fail(auth, 1896 "Initiator Bootstrapping Key Hash mismatch"); 1897 return -1; 1898 } 1899 } else if (auth->peer_bi) { 1900 /* Mutual authentication and peer did not include its 1901 * Bootstrapping Key Hash attribute. */ 1902 dpp_auth_fail(auth, 1903 "Missing Initiator Bootstrapping Key Hash attribute"); 1904 return -1; 1905 } 1906 1907 status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS, 1908 &status_len); 1909 if (!status || status_len < 1) { 1910 dpp_auth_fail(auth, 1911 "Missing or invalid required DPP Status attribute"); 1912 return -1; 1913 } 1914 wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]); 1915 if (status[0] == DPP_STATUS_NOT_COMPATIBLE || 1916 status[0] == DPP_STATUS_AUTH_FAILURE) 1917 return dpp_auth_conf_rx_failure(auth, hdr, attr_start, 1918 attr_len, wrapped_data, 1919 wrapped_data_len, status[0]); 1920 1921 if (status[0] != DPP_STATUS_OK) { 1922 dpp_auth_fail(auth, "Authentication failed"); 1923 return -1; 1924 } 1925 1926 addr[0] = hdr; 1927 len[0] = DPP_HDR_LEN; 1928 addr[1] = attr_start; 1929 len[1] = attr_len; 1930 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1931 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1932 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1933 wrapped_data, wrapped_data_len); 1934 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1935 unwrapped = os_malloc(unwrapped_len); 1936 if (!unwrapped) 1937 return -1; 1938 if (aes_siv_decrypt(auth->ke, auth->curve->hash_len, 1939 wrapped_data, wrapped_data_len, 1940 2, addr, len, unwrapped) < 0) { 1941 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1942 goto fail; 1943 } 1944 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1945 unwrapped, unwrapped_len); 1946 1947 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1948 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1949 goto fail; 1950 } 1951 1952 i_auth = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG, 1953 &i_auth_len); 1954 if (!i_auth || i_auth_len != auth->curve->hash_len) { 1955 dpp_auth_fail(auth, 1956 "Missing or invalid Initiator Authenticating Tag"); 1957 goto fail; 1958 } 1959 wpa_hexdump(MSG_DEBUG, "DPP: Received Initiator Authenticating Tag", 1960 i_auth, i_auth_len); 1961 /* I-auth' = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */ 1962 if (dpp_gen_i_auth(auth, i_auth2) < 0) 1963 goto fail; 1964 wpa_hexdump(MSG_DEBUG, "DPP: Calculated Initiator Authenticating Tag", 1965 i_auth2, i_auth_len); 1966 if (os_memcmp(i_auth, i_auth2, i_auth_len) != 0) { 1967 dpp_auth_fail(auth, "Mismatching Initiator Authenticating Tag"); 1968 goto fail; 1969 } 1970 1971 bin_clear_free(unwrapped, unwrapped_len); 1972 dpp_auth_success(auth); 1973 return 0; 1974 fail: 1975 bin_clear_free(unwrapped, unwrapped_len); 1976 return -1; 1977 } 1978