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 crypto_ec_key_deinit(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 = crypto_ec_key_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 struct crypto_ec_key *pi = NULL; 675 size_t secret_len; 676 const u8 *addr[2]; 677 size_t len[2]; 678 u8 *unwrapped = NULL; 679 size_t unwrapped_len = 0; 680 const u8 *wrapped_data, *i_proto, *i_nonce, *i_capab, *i_bootstrap, 681 *channel; 682 u16 wrapped_data_len, i_proto_len, i_nonce_len, i_capab_len, 683 i_bootstrap_len, channel_len; 684 struct dpp_authentication *auth = NULL; 685 #ifdef CONFIG_DPP2 686 const u8 *version; 687 u16 version_len; 688 #endif /* CONFIG_DPP2 */ 689 690 #ifdef CONFIG_TESTING_OPTIONS 691 if (dpp_test == DPP_TEST_STOP_AT_AUTH_REQ) { 692 wpa_printf(MSG_INFO, 693 "DPP: TESTING - stop at Authentication Request"); 694 return NULL; 695 } 696 #endif /* CONFIG_TESTING_OPTIONS */ 697 698 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA, 699 &wrapped_data_len); 700 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) { 701 wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL 702 "Missing or invalid required Wrapped Data attribute"); 703 return NULL; 704 } 705 wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped Data", 706 wrapped_data, wrapped_data_len); 707 attr_len = wrapped_data - 4 - attr_start; 708 709 auth = dpp_alloc_auth(dpp, msg_ctx); 710 if (!auth) 711 goto fail; 712 if (peer_bi && peer_bi->configurator_params && 713 dpp_set_configurator(auth, peer_bi->configurator_params) < 0) 714 goto fail; 715 auth->peer_bi = peer_bi; 716 auth->own_bi = own_bi; 717 auth->curve = own_bi->curve; 718 auth->curr_freq = freq; 719 720 auth->peer_version = 1; /* default to the first version */ 721 #ifdef CONFIG_DPP2 722 version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION, 723 &version_len); 724 if (version && DPP_VERSION > 1) { 725 if (version_len < 1 || version[0] == 0) { 726 dpp_auth_fail(auth, 727 "Invalid Protocol Version attribute"); 728 goto fail; 729 } 730 auth->peer_version = version[0]; 731 wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u", 732 auth->peer_version); 733 } 734 #endif /* CONFIG_DPP2 */ 735 736 channel = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CHANNEL, 737 &channel_len); 738 if (channel) { 739 int neg_freq; 740 741 if (channel_len < 2) { 742 dpp_auth_fail(auth, "Too short Channel attribute"); 743 goto fail; 744 } 745 746 neg_freq = ieee80211_chan_to_freq(NULL, channel[0], channel[1]); 747 wpa_printf(MSG_DEBUG, 748 "DPP: Initiator requested different channel for negotiation: op_class=%u channel=%u --> freq=%d", 749 channel[0], channel[1], neg_freq); 750 if (neg_freq < 0) { 751 dpp_auth_fail(auth, 752 "Unsupported Channel attribute value"); 753 goto fail; 754 } 755 756 if (auth->curr_freq != (unsigned int) neg_freq) { 757 wpa_printf(MSG_DEBUG, 758 "DPP: Changing negotiation channel from %u MHz to %u MHz", 759 freq, neg_freq); 760 auth->curr_freq = neg_freq; 761 } 762 } 763 764 i_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_I_PROTOCOL_KEY, 765 &i_proto_len); 766 if (!i_proto) { 767 dpp_auth_fail(auth, 768 "Missing required Initiator Protocol Key attribute"); 769 goto fail; 770 } 771 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Protocol Key", 772 i_proto, i_proto_len); 773 774 /* M = bR * PI */ 775 pi = dpp_set_pubkey_point(own_bi->pubkey, i_proto, i_proto_len); 776 if (!pi) { 777 dpp_auth_fail(auth, "Invalid Initiator Protocol Key"); 778 goto fail; 779 } 780 dpp_debug_print_key("Peer (Initiator) Protocol Key", pi); 781 782 if (dpp_ecdh(own_bi->pubkey, pi, auth->Mx, &secret_len) < 0) 783 goto fail; 784 auth->secret_len = secret_len; 785 786 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)", 787 auth->Mx, auth->secret_len); 788 auth->Mx_len = auth->secret_len; 789 790 if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1, 791 auth->curve->hash_len) < 0) 792 goto fail; 793 794 addr[0] = hdr; 795 len[0] = DPP_HDR_LEN; 796 addr[1] = attr_start; 797 len[1] = attr_len; 798 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 799 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 800 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 801 wrapped_data, wrapped_data_len); 802 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 803 unwrapped = os_malloc(unwrapped_len); 804 if (!unwrapped) 805 goto fail; 806 if (aes_siv_decrypt(auth->k1, auth->curve->hash_len, 807 wrapped_data, wrapped_data_len, 808 2, addr, len, unwrapped) < 0) { 809 dpp_auth_fail(auth, "AES-SIV decryption failed"); 810 goto fail; 811 } 812 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 813 unwrapped, unwrapped_len); 814 815 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 816 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 817 goto fail; 818 } 819 820 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE, 821 &i_nonce_len); 822 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) { 823 dpp_auth_fail(auth, "Missing or invalid I-nonce"); 824 goto fail; 825 } 826 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len); 827 os_memcpy(auth->i_nonce, i_nonce, i_nonce_len); 828 829 i_capab = dpp_get_attr(unwrapped, unwrapped_len, 830 DPP_ATTR_I_CAPABILITIES, 831 &i_capab_len); 832 if (!i_capab || i_capab_len < 1) { 833 dpp_auth_fail(auth, "Missing or invalid I-capabilities"); 834 goto fail; 835 } 836 auth->i_capab = i_capab[0]; 837 wpa_printf(MSG_DEBUG, "DPP: I-capabilities: 0x%02x", auth->i_capab); 838 839 bin_clear_free(unwrapped, unwrapped_len); 840 unwrapped = NULL; 841 842 switch (auth->i_capab & DPP_CAPAB_ROLE_MASK) { 843 case DPP_CAPAB_ENROLLEE: 844 if (!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR)) { 845 wpa_printf(MSG_DEBUG, 846 "DPP: Local policy does not allow Configurator role"); 847 goto not_compatible; 848 } 849 wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator"); 850 auth->configurator = 1; 851 break; 852 case DPP_CAPAB_CONFIGURATOR: 853 if (!(dpp_allowed_roles & DPP_CAPAB_ENROLLEE)) { 854 wpa_printf(MSG_DEBUG, 855 "DPP: Local policy does not allow Enrollee role"); 856 goto not_compatible; 857 } 858 wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee"); 859 auth->configurator = 0; 860 break; 861 case DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE: 862 if (dpp_allowed_roles & DPP_CAPAB_ENROLLEE) { 863 wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee"); 864 auth->configurator = 0; 865 } else if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) { 866 wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator"); 867 auth->configurator = 1; 868 } else { 869 wpa_printf(MSG_DEBUG, 870 "DPP: Local policy does not allow Configurator/Enrollee role"); 871 goto not_compatible; 872 } 873 break; 874 default: 875 wpa_printf(MSG_DEBUG, "DPP: Unexpected role in I-capabilities"); 876 wpa_msg(auth->msg_ctx, MSG_INFO, 877 DPP_EVENT_FAIL "Invalid role in I-capabilities 0x%02x", 878 auth->i_capab & DPP_CAPAB_ROLE_MASK); 879 goto fail; 880 } 881 882 auth->peer_protocol_key = pi; 883 pi = NULL; 884 if (qr_mutual && !peer_bi && own_bi->type == DPP_BOOTSTRAP_QR_CODE) { 885 char hex[SHA256_MAC_LEN * 2 + 1]; 886 887 wpa_printf(MSG_DEBUG, 888 "DPP: Mutual authentication required with QR Codes, but peer info is not yet available - request more time"); 889 if (dpp_auth_build_resp_status(auth, 890 DPP_STATUS_RESPONSE_PENDING) < 0) 891 goto fail; 892 i_bootstrap = dpp_get_attr(attr_start, attr_len, 893 DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 894 &i_bootstrap_len); 895 if (i_bootstrap && i_bootstrap_len == SHA256_MAC_LEN) { 896 auth->response_pending = 1; 897 os_memcpy(auth->waiting_pubkey_hash, 898 i_bootstrap, i_bootstrap_len); 899 wpa_snprintf_hex(hex, sizeof(hex), i_bootstrap, 900 i_bootstrap_len); 901 } else { 902 hex[0] = '\0'; 903 } 904 905 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_SCAN_PEER_QR_CODE 906 "%s", hex); 907 return auth; 908 } 909 if (dpp_auth_build_resp_ok(auth) < 0) 910 goto fail; 911 912 return auth; 913 914 not_compatible: 915 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE 916 "i-capab=0x%02x", auth->i_capab); 917 if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) 918 auth->configurator = 1; 919 else 920 auth->configurator = 0; 921 auth->peer_protocol_key = pi; 922 pi = NULL; 923 if (dpp_auth_build_resp_status(auth, DPP_STATUS_NOT_COMPATIBLE) < 0) 924 goto fail; 925 926 auth->remove_on_tx_status = 1; 927 return auth; 928 fail: 929 bin_clear_free(unwrapped, unwrapped_len); 930 crypto_ec_key_deinit(pi); 931 dpp_auth_deinit(auth); 932 return NULL; 933 } 934 935 936 int dpp_notify_new_qr_code(struct dpp_authentication *auth, 937 struct dpp_bootstrap_info *peer_bi) 938 { 939 if (!auth || !auth->response_pending || 940 os_memcmp(auth->waiting_pubkey_hash, peer_bi->pubkey_hash, 941 SHA256_MAC_LEN) != 0) 942 return 0; 943 944 wpa_printf(MSG_DEBUG, 945 "DPP: New scanned QR Code has matching public key that was needed to continue DPP Authentication exchange with " 946 MACSTR, MAC2STR(auth->peer_mac_addr)); 947 auth->peer_bi = peer_bi; 948 949 if (dpp_auth_build_resp_ok(auth) < 0) 950 return -1; 951 952 return 1; 953 } 954 955 956 static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth, 957 enum dpp_status_error status) 958 { 959 struct wpabuf *msg; 960 u8 i_auth[4 + DPP_MAX_HASH_LEN]; 961 size_t i_auth_len; 962 u8 r_nonce[4 + DPP_MAX_NONCE_LEN]; 963 size_t r_nonce_len; 964 const u8 *addr[2]; 965 size_t len[2], attr_len; 966 u8 *wrapped_i_auth; 967 u8 *wrapped_r_nonce; 968 u8 *attr_start, *attr_end; 969 const u8 *r_pubkey_hash, *i_pubkey_hash; 970 #ifdef CONFIG_TESTING_OPTIONS 971 u8 test_hash[SHA256_MAC_LEN]; 972 #endif /* CONFIG_TESTING_OPTIONS */ 973 974 wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation"); 975 976 i_auth_len = 4 + auth->curve->hash_len; 977 r_nonce_len = 4 + auth->curve->nonce_len; 978 /* Build DPP Authentication Confirmation frame attributes */ 979 attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) + 980 4 + i_auth_len + r_nonce_len + AES_BLOCK_SIZE; 981 #ifdef CONFIG_TESTING_OPTIONS 982 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) 983 attr_len += 5; 984 #endif /* CONFIG_TESTING_OPTIONS */ 985 msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len); 986 if (!msg) 987 goto fail; 988 989 attr_start = wpabuf_put(msg, 0); 990 991 r_pubkey_hash = auth->peer_bi->pubkey_hash; 992 if (auth->own_bi) 993 i_pubkey_hash = auth->own_bi->pubkey_hash; 994 else 995 i_pubkey_hash = NULL; 996 997 #ifdef CONFIG_TESTING_OPTIONS 998 if (dpp_test == DPP_TEST_NO_STATUS_AUTH_CONF) { 999 wpa_printf(MSG_INFO, "DPP: TESTING - no Status"); 1000 goto skip_status; 1001 } else if (dpp_test == DPP_TEST_INVALID_STATUS_AUTH_CONF) { 1002 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status"); 1003 status = 254; 1004 } 1005 #endif /* CONFIG_TESTING_OPTIONS */ 1006 1007 /* DPP Status */ 1008 dpp_build_attr_status(msg, status); 1009 1010 #ifdef CONFIG_TESTING_OPTIONS 1011 skip_status: 1012 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1013 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash"); 1014 r_pubkey_hash = NULL; 1015 } else if (dpp_test == 1016 DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1017 wpa_printf(MSG_INFO, 1018 "DPP: TESTING - invalid R-Bootstrap Key Hash"); 1019 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN); 1020 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1021 r_pubkey_hash = test_hash; 1022 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1023 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash"); 1024 i_pubkey_hash = NULL; 1025 } else if (dpp_test == 1026 DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_CONF) { 1027 wpa_printf(MSG_INFO, 1028 "DPP: TESTING - invalid I-Bootstrap Key Hash"); 1029 if (i_pubkey_hash) 1030 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN); 1031 else 1032 os_memset(test_hash, 0, SHA256_MAC_LEN); 1033 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1034 i_pubkey_hash = test_hash; 1035 } 1036 #endif /* CONFIG_TESTING_OPTIONS */ 1037 1038 /* Responder Bootstrapping Key Hash */ 1039 dpp_build_attr_r_bootstrap_key_hash(msg, r_pubkey_hash); 1040 1041 /* Initiator Bootstrapping Key Hash (mutual authentication) */ 1042 dpp_build_attr_i_bootstrap_key_hash(msg, i_pubkey_hash); 1043 1044 #ifdef CONFIG_TESTING_OPTIONS 1045 if (dpp_test == DPP_TEST_NO_WRAPPED_DATA_AUTH_CONF) 1046 goto skip_wrapped_data; 1047 if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF) 1048 i_auth_len = 0; 1049 #endif /* CONFIG_TESTING_OPTIONS */ 1050 1051 attr_end = wpabuf_put(msg, 0); 1052 1053 /* OUI, OUI type, Crypto Suite, DPP frame type */ 1054 addr[0] = wpabuf_head_u8(msg) + 2; 1055 len[0] = 3 + 1 + 1 + 1; 1056 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1057 1058 /* Attributes before Wrapped Data */ 1059 addr[1] = attr_start; 1060 len[1] = attr_end - attr_start; 1061 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1062 1063 if (status == DPP_STATUS_OK) { 1064 /* I-auth wrapped with ke */ 1065 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA); 1066 wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE); 1067 wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE); 1068 1069 #ifdef CONFIG_TESTING_OPTIONS 1070 if (dpp_test == DPP_TEST_NO_I_AUTH_AUTH_CONF) 1071 goto skip_i_auth; 1072 #endif /* CONFIG_TESTING_OPTIONS */ 1073 1074 /* I-auth = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1075 * 1) */ 1076 WPA_PUT_LE16(i_auth, DPP_ATTR_I_AUTH_TAG); 1077 WPA_PUT_LE16(&i_auth[2], auth->curve->hash_len); 1078 if (dpp_gen_i_auth(auth, i_auth + 4) < 0) 1079 goto fail; 1080 1081 #ifdef CONFIG_TESTING_OPTIONS 1082 if (dpp_test == DPP_TEST_I_AUTH_MISMATCH_AUTH_CONF) { 1083 wpa_printf(MSG_INFO, "DPP: TESTING - I-auth mismatch"); 1084 i_auth[4 + auth->curve->hash_len / 2] ^= 0x01; 1085 } 1086 skip_i_auth: 1087 #endif /* CONFIG_TESTING_OPTIONS */ 1088 if (aes_siv_encrypt(auth->ke, auth->curve->hash_len, 1089 i_auth, i_auth_len, 1090 2, addr, len, wrapped_i_auth) < 0) 1091 goto fail; 1092 wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke", 1093 wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE); 1094 } else { 1095 /* R-nonce wrapped with k2 */ 1096 wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA); 1097 wpabuf_put_le16(msg, r_nonce_len + AES_BLOCK_SIZE); 1098 wrapped_r_nonce = wpabuf_put(msg, r_nonce_len + AES_BLOCK_SIZE); 1099 1100 WPA_PUT_LE16(r_nonce, DPP_ATTR_R_NONCE); 1101 WPA_PUT_LE16(&r_nonce[2], auth->curve->nonce_len); 1102 os_memcpy(r_nonce + 4, auth->r_nonce, auth->curve->nonce_len); 1103 1104 if (aes_siv_encrypt(auth->k2, auth->curve->hash_len, 1105 r_nonce, r_nonce_len, 1106 2, addr, len, wrapped_r_nonce) < 0) 1107 goto fail; 1108 wpa_hexdump(MSG_DEBUG, "DPP: {R-nonce}k2", 1109 wrapped_r_nonce, r_nonce_len + AES_BLOCK_SIZE); 1110 } 1111 1112 #ifdef CONFIG_TESTING_OPTIONS 1113 if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF) { 1114 wpa_printf(MSG_INFO, "DPP: TESTING - attr after Wrapped Data"); 1115 dpp_build_attr_status(msg, DPP_STATUS_OK); 1116 } 1117 skip_wrapped_data: 1118 #endif /* CONFIG_TESTING_OPTIONS */ 1119 1120 wpa_hexdump_buf(MSG_DEBUG, 1121 "DPP: Authentication Confirmation frame attributes", 1122 msg); 1123 if (status == DPP_STATUS_OK) 1124 dpp_auth_success(auth); 1125 1126 return msg; 1127 1128 fail: 1129 wpabuf_free(msg); 1130 return NULL; 1131 } 1132 1133 1134 static int dpp_autogen_bootstrap_key(struct dpp_authentication *auth) 1135 { 1136 struct dpp_bootstrap_info *bi; 1137 1138 if (auth->own_bi) 1139 return 0; /* already generated */ 1140 1141 bi = os_zalloc(sizeof(*bi)); 1142 if (!bi) 1143 return -1; 1144 bi->type = DPP_BOOTSTRAP_QR_CODE; 1145 if (dpp_keygen(bi, auth->peer_bi->curve->name, NULL, 0) < 0 || 1146 dpp_gen_uri(bi) < 0) 1147 goto fail; 1148 wpa_printf(MSG_DEBUG, 1149 "DPP: Auto-generated own bootstrapping key info: URI %s", 1150 bi->uri); 1151 1152 auth->tmp_own_bi = auth->own_bi = bi; 1153 1154 return 0; 1155 fail: 1156 dpp_bootstrap_info_free(bi); 1157 return -1; 1158 } 1159 1160 1161 struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx, 1162 struct dpp_bootstrap_info *peer_bi, 1163 struct dpp_bootstrap_info *own_bi, 1164 u8 dpp_allowed_roles, 1165 unsigned int neg_freq, 1166 struct hostapd_hw_modes *own_modes, 1167 u16 num_modes) 1168 { 1169 struct dpp_authentication *auth; 1170 size_t nonce_len; 1171 size_t secret_len; 1172 struct wpabuf *pi = NULL; 1173 const u8 *r_pubkey_hash, *i_pubkey_hash; 1174 #ifdef CONFIG_TESTING_OPTIONS 1175 u8 test_hash[SHA256_MAC_LEN]; 1176 #endif /* CONFIG_TESTING_OPTIONS */ 1177 1178 auth = dpp_alloc_auth(dpp, msg_ctx); 1179 if (!auth) 1180 return NULL; 1181 if (peer_bi->configurator_params && 1182 dpp_set_configurator(auth, peer_bi->configurator_params) < 0) 1183 goto fail; 1184 auth->initiator = 1; 1185 auth->waiting_auth_resp = 1; 1186 auth->allowed_roles = dpp_allowed_roles; 1187 auth->configurator = !!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR); 1188 auth->peer_bi = peer_bi; 1189 auth->own_bi = own_bi; 1190 auth->curve = peer_bi->curve; 1191 1192 if (dpp_autogen_bootstrap_key(auth) < 0 || 1193 dpp_prepare_channel_list(auth, neg_freq, own_modes, num_modes) < 0) 1194 goto fail; 1195 1196 #ifdef CONFIG_TESTING_OPTIONS 1197 if (dpp_nonce_override_len > 0) { 1198 wpa_printf(MSG_INFO, "DPP: TESTING - override I-nonce"); 1199 nonce_len = dpp_nonce_override_len; 1200 os_memcpy(auth->i_nonce, dpp_nonce_override, nonce_len); 1201 } else { 1202 nonce_len = auth->curve->nonce_len; 1203 if (random_get_bytes(auth->i_nonce, nonce_len)) { 1204 wpa_printf(MSG_ERROR, 1205 "DPP: Failed to generate I-nonce"); 1206 goto fail; 1207 } 1208 } 1209 #else /* CONFIG_TESTING_OPTIONS */ 1210 nonce_len = auth->curve->nonce_len; 1211 if (random_get_bytes(auth->i_nonce, nonce_len)) { 1212 wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce"); 1213 goto fail; 1214 } 1215 #endif /* CONFIG_TESTING_OPTIONS */ 1216 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len); 1217 1218 #ifdef CONFIG_TESTING_OPTIONS 1219 if (dpp_protocol_key_override_len) { 1220 const struct dpp_curve_params *tmp_curve; 1221 1222 wpa_printf(MSG_INFO, 1223 "DPP: TESTING - override protocol key"); 1224 auth->own_protocol_key = dpp_set_keypair( 1225 &tmp_curve, dpp_protocol_key_override, 1226 dpp_protocol_key_override_len); 1227 } else { 1228 auth->own_protocol_key = dpp_gen_keypair(auth->curve); 1229 } 1230 #else /* CONFIG_TESTING_OPTIONS */ 1231 auth->own_protocol_key = dpp_gen_keypair(auth->curve); 1232 #endif /* CONFIG_TESTING_OPTIONS */ 1233 if (!auth->own_protocol_key) 1234 goto fail; 1235 1236 pi = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); 1237 if (!pi) 1238 goto fail; 1239 1240 /* ECDH: M = pI * BR */ 1241 if (dpp_ecdh(auth->own_protocol_key, auth->peer_bi->pubkey, 1242 auth->Mx, &secret_len) < 0) 1243 goto fail; 1244 auth->secret_len = secret_len; 1245 1246 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)", 1247 auth->Mx, auth->secret_len); 1248 auth->Mx_len = auth->secret_len; 1249 1250 if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1, 1251 auth->curve->hash_len) < 0) 1252 goto fail; 1253 1254 r_pubkey_hash = auth->peer_bi->pubkey_hash; 1255 i_pubkey_hash = auth->own_bi->pubkey_hash; 1256 1257 #ifdef CONFIG_TESTING_OPTIONS 1258 if (dpp_test == DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1259 wpa_printf(MSG_INFO, "DPP: TESTING - no R-Bootstrap Key Hash"); 1260 r_pubkey_hash = NULL; 1261 } else if (dpp_test == DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1262 wpa_printf(MSG_INFO, 1263 "DPP: TESTING - invalid R-Bootstrap Key Hash"); 1264 os_memcpy(test_hash, r_pubkey_hash, SHA256_MAC_LEN); 1265 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1266 r_pubkey_hash = test_hash; 1267 } else if (dpp_test == DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1268 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Bootstrap Key Hash"); 1269 i_pubkey_hash = NULL; 1270 } else if (dpp_test == DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_REQ) { 1271 wpa_printf(MSG_INFO, 1272 "DPP: TESTING - invalid I-Bootstrap Key Hash"); 1273 os_memcpy(test_hash, i_pubkey_hash, SHA256_MAC_LEN); 1274 test_hash[SHA256_MAC_LEN - 1] ^= 0x01; 1275 i_pubkey_hash = test_hash; 1276 } else if (dpp_test == DPP_TEST_NO_I_PROTO_KEY_AUTH_REQ) { 1277 wpa_printf(MSG_INFO, "DPP: TESTING - no I-Proto Key"); 1278 wpabuf_free(pi); 1279 pi = NULL; 1280 } else if (dpp_test == DPP_TEST_INVALID_I_PROTO_KEY_AUTH_REQ) { 1281 wpa_printf(MSG_INFO, "DPP: TESTING - invalid I-Proto Key"); 1282 wpabuf_free(pi); 1283 pi = wpabuf_alloc(2 * auth->curve->prime_len); 1284 if (!pi || dpp_test_gen_invalid_key(pi, auth->curve) < 0) 1285 goto fail; 1286 } 1287 #endif /* CONFIG_TESTING_OPTIONS */ 1288 1289 if (neg_freq && auth->num_freq == 1 && auth->freq[0] == neg_freq) 1290 neg_freq = 0; 1291 auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash, 1292 i_pubkey_hash, neg_freq); 1293 if (!auth->req_msg) 1294 goto fail; 1295 1296 out: 1297 wpabuf_free(pi); 1298 return auth; 1299 fail: 1300 dpp_auth_deinit(auth); 1301 auth = NULL; 1302 goto out; 1303 } 1304 static void 1305 dpp_auth_resp_rx_status(struct dpp_authentication *auth, const u8 *hdr, 1306 const u8 *attr_start, size_t attr_len, 1307 const u8 *wrapped_data, u16 wrapped_data_len, 1308 enum dpp_status_error status) 1309 { 1310 const u8 *addr[2]; 1311 size_t len[2]; 1312 u8 *unwrapped = NULL; 1313 size_t unwrapped_len = 0; 1314 const u8 *i_nonce, *r_capab; 1315 u16 i_nonce_len, r_capab_len; 1316 1317 if (status == DPP_STATUS_NOT_COMPATIBLE) { 1318 wpa_printf(MSG_DEBUG, 1319 "DPP: Responder reported incompatible roles"); 1320 } else if (status == DPP_STATUS_RESPONSE_PENDING) { 1321 wpa_printf(MSG_DEBUG, 1322 "DPP: Responder reported more time needed"); 1323 } else { 1324 wpa_printf(MSG_DEBUG, 1325 "DPP: Responder reported failure (status %d)", 1326 status); 1327 dpp_auth_fail(auth, "Responder reported failure"); 1328 return; 1329 } 1330 1331 addr[0] = hdr; 1332 len[0] = DPP_HDR_LEN; 1333 addr[1] = attr_start; 1334 len[1] = attr_len; 1335 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1336 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1337 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1338 wrapped_data, wrapped_data_len); 1339 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1340 unwrapped = os_malloc(unwrapped_len); 1341 if (!unwrapped) 1342 goto fail; 1343 if (aes_siv_decrypt(auth->k1, auth->curve->hash_len, 1344 wrapped_data, wrapped_data_len, 1345 2, addr, len, unwrapped) < 0) { 1346 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1347 goto fail; 1348 } 1349 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1350 unwrapped, unwrapped_len); 1351 1352 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1353 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1354 goto fail; 1355 } 1356 1357 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE, 1358 &i_nonce_len); 1359 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) { 1360 dpp_auth_fail(auth, "Missing or invalid I-nonce"); 1361 goto fail; 1362 } 1363 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len); 1364 if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) { 1365 dpp_auth_fail(auth, "I-nonce mismatch"); 1366 goto fail; 1367 } 1368 1369 r_capab = dpp_get_attr(unwrapped, unwrapped_len, 1370 DPP_ATTR_R_CAPABILITIES, 1371 &r_capab_len); 1372 if (!r_capab || r_capab_len < 1) { 1373 dpp_auth_fail(auth, "Missing or invalid R-capabilities"); 1374 goto fail; 1375 } 1376 auth->r_capab = r_capab[0]; 1377 wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab); 1378 if (status == DPP_STATUS_NOT_COMPATIBLE) { 1379 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_NOT_COMPATIBLE 1380 "r-capab=0x%02x", auth->r_capab); 1381 } else if (status == DPP_STATUS_RESPONSE_PENDING) { 1382 u8 role = auth->r_capab & DPP_CAPAB_ROLE_MASK; 1383 1384 if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) || 1385 (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) { 1386 wpa_msg(auth->msg_ctx, MSG_INFO, 1387 DPP_EVENT_FAIL "Unexpected role in R-capabilities 0x%02x", 1388 role); 1389 } else { 1390 wpa_printf(MSG_DEBUG, 1391 "DPP: Continue waiting for full DPP Authentication Response"); 1392 wpa_msg(auth->msg_ctx, MSG_INFO, 1393 DPP_EVENT_RESPONSE_PENDING "%s", 1394 auth->tmp_own_bi ? auth->tmp_own_bi->uri : ""); 1395 } 1396 } 1397 fail: 1398 bin_clear_free(unwrapped, unwrapped_len); 1399 } 1400 1401 1402 struct wpabuf * 1403 dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, 1404 const u8 *attr_start, size_t attr_len) 1405 { 1406 struct crypto_ec_key *pr; 1407 size_t secret_len; 1408 const u8 *addr[2]; 1409 size_t len[2]; 1410 u8 *unwrapped = NULL, *unwrapped2 = NULL; 1411 size_t unwrapped_len = 0, unwrapped2_len = 0; 1412 const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto, 1413 *r_nonce, *i_nonce, *r_capab, *wrapped2, *r_auth; 1414 u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len, 1415 r_proto_len, r_nonce_len, i_nonce_len, r_capab_len, 1416 wrapped2_len, r_auth_len; 1417 u8 r_auth2[DPP_MAX_HASH_LEN]; 1418 u8 role; 1419 #ifdef CONFIG_DPP2 1420 const u8 *version; 1421 u16 version_len; 1422 #endif /* CONFIG_DPP2 */ 1423 1424 #ifdef CONFIG_TESTING_OPTIONS 1425 if (dpp_test == DPP_TEST_STOP_AT_AUTH_RESP) { 1426 wpa_printf(MSG_INFO, 1427 "DPP: TESTING - stop at Authentication Response"); 1428 return NULL; 1429 } 1430 #endif /* CONFIG_TESTING_OPTIONS */ 1431 1432 if (!auth->initiator || !auth->peer_bi || auth->reconfig) { 1433 dpp_auth_fail(auth, "Unexpected Authentication Response"); 1434 return NULL; 1435 } 1436 1437 auth->waiting_auth_resp = 0; 1438 1439 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA, 1440 &wrapped_data_len); 1441 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) { 1442 dpp_auth_fail(auth, 1443 "Missing or invalid required Wrapped Data attribute"); 1444 return NULL; 1445 } 1446 wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data", 1447 wrapped_data, wrapped_data_len); 1448 1449 attr_len = wrapped_data - 4 - attr_start; 1450 1451 r_bootstrap = dpp_get_attr(attr_start, attr_len, 1452 DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 1453 &r_bootstrap_len); 1454 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { 1455 dpp_auth_fail(auth, 1456 "Missing or invalid required Responder Bootstrapping Key Hash attribute"); 1457 return NULL; 1458 } 1459 wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash", 1460 r_bootstrap, r_bootstrap_len); 1461 if (os_memcmp(r_bootstrap, auth->peer_bi->pubkey_hash, 1462 SHA256_MAC_LEN) != 0) { 1463 dpp_auth_fail(auth, 1464 "Unexpected Responder Bootstrapping Key Hash value"); 1465 wpa_hexdump(MSG_DEBUG, 1466 "DPP: Expected Responder Bootstrapping Key Hash", 1467 auth->peer_bi->pubkey_hash, SHA256_MAC_LEN); 1468 return NULL; 1469 } 1470 1471 i_bootstrap = dpp_get_attr(attr_start, attr_len, 1472 DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 1473 &i_bootstrap_len); 1474 if (i_bootstrap) { 1475 if (i_bootstrap_len != SHA256_MAC_LEN) { 1476 dpp_auth_fail(auth, 1477 "Invalid Initiator Bootstrapping Key Hash attribute"); 1478 return NULL; 1479 } 1480 wpa_hexdump(MSG_MSGDUMP, 1481 "DPP: Initiator Bootstrapping Key Hash", 1482 i_bootstrap, i_bootstrap_len); 1483 if (!auth->own_bi || 1484 os_memcmp(i_bootstrap, auth->own_bi->pubkey_hash, 1485 SHA256_MAC_LEN) != 0) { 1486 dpp_auth_fail(auth, 1487 "Initiator Bootstrapping Key Hash attribute did not match"); 1488 return NULL; 1489 } 1490 } else if (auth->own_bi && auth->own_bi->type == DPP_BOOTSTRAP_PKEX) { 1491 /* PKEX bootstrapping mandates use of mutual authentication */ 1492 dpp_auth_fail(auth, 1493 "Missing Initiator Bootstrapping Key Hash attribute"); 1494 return NULL; 1495 } else if (auth->own_bi && 1496 auth->own_bi->type == DPP_BOOTSTRAP_NFC_URI && 1497 auth->own_bi->nfc_negotiated) { 1498 /* NFC negotiated connection handover bootstrapping mandates 1499 * use of mutual authentication */ 1500 dpp_auth_fail(auth, 1501 "Missing Initiator Bootstrapping Key Hash attribute"); 1502 return NULL; 1503 } 1504 1505 auth->peer_version = 1; /* default to the first version */ 1506 #ifdef CONFIG_DPP2 1507 version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION, 1508 &version_len); 1509 if (version && DPP_VERSION > 1) { 1510 if (version_len < 1 || version[0] == 0) { 1511 dpp_auth_fail(auth, 1512 "Invalid Protocol Version attribute"); 1513 return NULL; 1514 } 1515 auth->peer_version = version[0]; 1516 wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u", 1517 auth->peer_version); 1518 } 1519 #endif /* CONFIG_DPP2 */ 1520 1521 status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS, 1522 &status_len); 1523 if (!status || status_len < 1) { 1524 dpp_auth_fail(auth, 1525 "Missing or invalid required DPP Status attribute"); 1526 return NULL; 1527 } 1528 wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]); 1529 auth->auth_resp_status = status[0]; 1530 if (status[0] != DPP_STATUS_OK) { 1531 dpp_auth_resp_rx_status(auth, hdr, attr_start, 1532 attr_len, wrapped_data, 1533 wrapped_data_len, status[0]); 1534 return NULL; 1535 } 1536 1537 if (!i_bootstrap && auth->own_bi) { 1538 wpa_printf(MSG_DEBUG, 1539 "DPP: Responder decided not to use mutual authentication"); 1540 auth->own_bi = NULL; 1541 } 1542 1543 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_DIRECTION "mutual=%d", 1544 auth->own_bi != NULL); 1545 1546 r_proto = dpp_get_attr(attr_start, attr_len, DPP_ATTR_R_PROTOCOL_KEY, 1547 &r_proto_len); 1548 if (!r_proto) { 1549 dpp_auth_fail(auth, 1550 "Missing required Responder Protocol Key attribute"); 1551 return NULL; 1552 } 1553 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Protocol Key", 1554 r_proto, r_proto_len); 1555 1556 /* N = pI * PR */ 1557 pr = dpp_set_pubkey_point(auth->own_protocol_key, r_proto, r_proto_len); 1558 if (!pr) { 1559 dpp_auth_fail(auth, "Invalid Responder Protocol Key"); 1560 return NULL; 1561 } 1562 dpp_debug_print_key("Peer (Responder) Protocol Key", pr); 1563 1564 if (dpp_ecdh(auth->own_protocol_key, pr, auth->Nx, &secret_len) < 0) { 1565 dpp_auth_fail(auth, "Failed to derive ECDH shared secret"); 1566 goto fail; 1567 } 1568 crypto_ec_key_deinit(auth->peer_protocol_key); 1569 auth->peer_protocol_key = pr; 1570 pr = NULL; 1571 1572 wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (N.x)", 1573 auth->Nx, auth->secret_len); 1574 auth->Nx_len = auth->secret_len; 1575 1576 if (dpp_derive_k2(auth->Nx, auth->secret_len, auth->k2, 1577 auth->curve->hash_len) < 0) 1578 goto fail; 1579 1580 addr[0] = hdr; 1581 len[0] = DPP_HDR_LEN; 1582 addr[1] = attr_start; 1583 len[1] = attr_len; 1584 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1585 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1586 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1587 wrapped_data, wrapped_data_len); 1588 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1589 unwrapped = os_malloc(unwrapped_len); 1590 if (!unwrapped) 1591 goto fail; 1592 if (aes_siv_decrypt(auth->k2, auth->curve->hash_len, 1593 wrapped_data, wrapped_data_len, 1594 2, addr, len, unwrapped) < 0) { 1595 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1596 goto fail; 1597 } 1598 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1599 unwrapped, unwrapped_len); 1600 1601 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1602 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1603 goto fail; 1604 } 1605 1606 r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE, 1607 &r_nonce_len); 1608 if (!r_nonce || r_nonce_len != auth->curve->nonce_len) { 1609 dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce"); 1610 goto fail; 1611 } 1612 wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", r_nonce, r_nonce_len); 1613 os_memcpy(auth->r_nonce, r_nonce, r_nonce_len); 1614 1615 i_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_NONCE, 1616 &i_nonce_len); 1617 if (!i_nonce || i_nonce_len != auth->curve->nonce_len) { 1618 dpp_auth_fail(auth, "Missing or invalid I-nonce"); 1619 goto fail; 1620 } 1621 wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", i_nonce, i_nonce_len); 1622 if (os_memcmp(auth->i_nonce, i_nonce, i_nonce_len) != 0) { 1623 dpp_auth_fail(auth, "I-nonce mismatch"); 1624 goto fail; 1625 } 1626 1627 if (auth->own_bi) { 1628 /* Mutual authentication */ 1629 if (dpp_auth_derive_l_initiator(auth) < 0) 1630 goto fail; 1631 } 1632 1633 r_capab = dpp_get_attr(unwrapped, unwrapped_len, 1634 DPP_ATTR_R_CAPABILITIES, 1635 &r_capab_len); 1636 if (!r_capab || r_capab_len < 1) { 1637 dpp_auth_fail(auth, "Missing or invalid R-capabilities"); 1638 goto fail; 1639 } 1640 auth->r_capab = r_capab[0]; 1641 wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab); 1642 role = auth->r_capab & DPP_CAPAB_ROLE_MASK; 1643 if ((auth->allowed_roles == 1644 (DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) && 1645 (role == DPP_CAPAB_CONFIGURATOR || role == DPP_CAPAB_ENROLLEE)) { 1646 /* Peer selected its role, so move from "either role" to the 1647 * role that is compatible with peer's selection. */ 1648 auth->configurator = role == DPP_CAPAB_ENROLLEE; 1649 wpa_printf(MSG_DEBUG, "DPP: Acting as %s", 1650 auth->configurator ? "Configurator" : "Enrollee"); 1651 } else if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) || 1652 (!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) { 1653 wpa_printf(MSG_DEBUG, "DPP: Incompatible role selection"); 1654 wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL 1655 "Unexpected role in R-capabilities 0x%02x", 1656 role); 1657 if (role != DPP_CAPAB_ENROLLEE && 1658 role != DPP_CAPAB_CONFIGURATOR) 1659 goto fail; 1660 bin_clear_free(unwrapped, unwrapped_len); 1661 auth->remove_on_tx_status = 1; 1662 return dpp_auth_build_conf(auth, DPP_STATUS_NOT_COMPATIBLE); 1663 } 1664 1665 wrapped2 = dpp_get_attr(unwrapped, unwrapped_len, 1666 DPP_ATTR_WRAPPED_DATA, &wrapped2_len); 1667 if (!wrapped2 || wrapped2_len < AES_BLOCK_SIZE) { 1668 dpp_auth_fail(auth, 1669 "Missing or invalid Secondary Wrapped Data"); 1670 goto fail; 1671 } 1672 1673 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1674 wrapped2, wrapped2_len); 1675 1676 if (dpp_derive_bk_ke(auth) < 0) 1677 goto fail; 1678 1679 unwrapped2_len = wrapped2_len - AES_BLOCK_SIZE; 1680 unwrapped2 = os_malloc(unwrapped2_len); 1681 if (!unwrapped2) 1682 goto fail; 1683 if (aes_siv_decrypt(auth->ke, auth->curve->hash_len, 1684 wrapped2, wrapped2_len, 1685 0, NULL, NULL, unwrapped2) < 0) { 1686 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1687 goto fail; 1688 } 1689 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1690 unwrapped2, unwrapped2_len); 1691 1692 if (dpp_check_attrs(unwrapped2, unwrapped2_len) < 0) { 1693 dpp_auth_fail(auth, 1694 "Invalid attribute in secondary unwrapped data"); 1695 goto fail; 1696 } 1697 1698 r_auth = dpp_get_attr(unwrapped2, unwrapped2_len, DPP_ATTR_R_AUTH_TAG, 1699 &r_auth_len); 1700 if (!r_auth || r_auth_len != auth->curve->hash_len) { 1701 dpp_auth_fail(auth, 1702 "Missing or invalid Responder Authenticating Tag"); 1703 goto fail; 1704 } 1705 wpa_hexdump(MSG_DEBUG, "DPP: Received Responder Authenticating Tag", 1706 r_auth, r_auth_len); 1707 /* R-auth' = H(I-nonce | R-nonce | PI.x | PR.x | [BI.x |] BR.x | 0) */ 1708 if (dpp_gen_r_auth(auth, r_auth2) < 0) 1709 goto fail; 1710 wpa_hexdump(MSG_DEBUG, "DPP: Calculated Responder Authenticating Tag", 1711 r_auth2, r_auth_len); 1712 if (os_memcmp(r_auth, r_auth2, r_auth_len) != 0) { 1713 dpp_auth_fail(auth, "Mismatching Responder Authenticating Tag"); 1714 bin_clear_free(unwrapped, unwrapped_len); 1715 bin_clear_free(unwrapped2, unwrapped2_len); 1716 auth->remove_on_tx_status = 1; 1717 return dpp_auth_build_conf(auth, DPP_STATUS_AUTH_FAILURE); 1718 } 1719 1720 bin_clear_free(unwrapped, unwrapped_len); 1721 bin_clear_free(unwrapped2, unwrapped2_len); 1722 1723 #ifdef CONFIG_TESTING_OPTIONS 1724 if (dpp_test == DPP_TEST_AUTH_RESP_IN_PLACE_OF_CONF) { 1725 wpa_printf(MSG_INFO, 1726 "DPP: TESTING - Authentication Response in place of Confirm"); 1727 if (dpp_auth_build_resp_ok(auth) < 0) 1728 return NULL; 1729 return wpabuf_dup(auth->resp_msg); 1730 } 1731 #endif /* CONFIG_TESTING_OPTIONS */ 1732 1733 return dpp_auth_build_conf(auth, DPP_STATUS_OK); 1734 1735 fail: 1736 bin_clear_free(unwrapped, unwrapped_len); 1737 bin_clear_free(unwrapped2, unwrapped2_len); 1738 crypto_ec_key_deinit(pr); 1739 return NULL; 1740 } 1741 1742 1743 static int dpp_auth_conf_rx_failure(struct dpp_authentication *auth, 1744 const u8 *hdr, 1745 const u8 *attr_start, size_t attr_len, 1746 const u8 *wrapped_data, 1747 u16 wrapped_data_len, 1748 enum dpp_status_error status) 1749 { 1750 const u8 *addr[2]; 1751 size_t len[2]; 1752 u8 *unwrapped = NULL; 1753 size_t unwrapped_len = 0; 1754 const u8 *r_nonce; 1755 u16 r_nonce_len; 1756 1757 /* Authentication Confirm failure cases are expected to include 1758 * {R-nonce}k2 in the Wrapped Data attribute. */ 1759 1760 addr[0] = hdr; 1761 len[0] = DPP_HDR_LEN; 1762 addr[1] = attr_start; 1763 len[1] = attr_len; 1764 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1765 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1766 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1767 wrapped_data, wrapped_data_len); 1768 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1769 unwrapped = os_malloc(unwrapped_len); 1770 if (!unwrapped) { 1771 dpp_auth_fail(auth, "Authentication failed"); 1772 goto fail; 1773 } 1774 if (aes_siv_decrypt(auth->k2, auth->curve->hash_len, 1775 wrapped_data, wrapped_data_len, 1776 2, addr, len, unwrapped) < 0) { 1777 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1778 goto fail; 1779 } 1780 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1781 unwrapped, unwrapped_len); 1782 1783 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1784 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1785 goto fail; 1786 } 1787 1788 r_nonce = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_NONCE, 1789 &r_nonce_len); 1790 if (!r_nonce || r_nonce_len != auth->curve->nonce_len) { 1791 dpp_auth_fail(auth, "DPP: Missing or invalid R-nonce"); 1792 goto fail; 1793 } 1794 if (os_memcmp(r_nonce, auth->r_nonce, r_nonce_len) != 0) { 1795 wpa_hexdump(MSG_DEBUG, "DPP: Received R-nonce", 1796 r_nonce, r_nonce_len); 1797 wpa_hexdump(MSG_DEBUG, "DPP: Expected R-nonce", 1798 auth->r_nonce, r_nonce_len); 1799 dpp_auth_fail(auth, "R-nonce mismatch"); 1800 goto fail; 1801 } 1802 1803 if (status == DPP_STATUS_NOT_COMPATIBLE) 1804 dpp_auth_fail(auth, "Peer reported incompatible R-capab role"); 1805 else if (status == DPP_STATUS_AUTH_FAILURE) 1806 dpp_auth_fail(auth, "Peer reported authentication failure)"); 1807 1808 fail: 1809 bin_clear_free(unwrapped, unwrapped_len); 1810 return -1; 1811 } 1812 1813 1814 int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr, 1815 const u8 *attr_start, size_t attr_len) 1816 { 1817 const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth; 1818 u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len, 1819 i_auth_len; 1820 const u8 *addr[2]; 1821 size_t len[2]; 1822 u8 *unwrapped = NULL; 1823 size_t unwrapped_len = 0; 1824 u8 i_auth2[DPP_MAX_HASH_LEN]; 1825 1826 #ifdef CONFIG_TESTING_OPTIONS 1827 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) { 1828 wpa_printf(MSG_INFO, 1829 "DPP: TESTING - stop at Authentication Confirm"); 1830 return -1; 1831 } 1832 #endif /* CONFIG_TESTING_OPTIONS */ 1833 1834 if (auth->initiator || !auth->own_bi || !auth->waiting_auth_conf || 1835 auth->reconfig) { 1836 wpa_printf(MSG_DEBUG, 1837 "DPP: initiator=%d own_bi=%d waiting_auth_conf=%d", 1838 auth->initiator, !!auth->own_bi, 1839 auth->waiting_auth_conf); 1840 dpp_auth_fail(auth, "Unexpected Authentication Confirm"); 1841 return -1; 1842 } 1843 1844 auth->waiting_auth_conf = 0; 1845 1846 wrapped_data = dpp_get_attr(attr_start, attr_len, DPP_ATTR_WRAPPED_DATA, 1847 &wrapped_data_len); 1848 if (!wrapped_data || wrapped_data_len < AES_BLOCK_SIZE) { 1849 dpp_auth_fail(auth, 1850 "Missing or invalid required Wrapped Data attribute"); 1851 return -1; 1852 } 1853 wpa_hexdump(MSG_DEBUG, "DPP: Wrapped data", 1854 wrapped_data, wrapped_data_len); 1855 1856 attr_len = wrapped_data - 4 - attr_start; 1857 1858 r_bootstrap = dpp_get_attr(attr_start, attr_len, 1859 DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 1860 &r_bootstrap_len); 1861 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { 1862 dpp_auth_fail(auth, 1863 "Missing or invalid required Responder Bootstrapping Key Hash attribute"); 1864 return -1; 1865 } 1866 wpa_hexdump(MSG_DEBUG, "DPP: Responder Bootstrapping Key Hash", 1867 r_bootstrap, r_bootstrap_len); 1868 if (os_memcmp(r_bootstrap, auth->own_bi->pubkey_hash, 1869 SHA256_MAC_LEN) != 0) { 1870 wpa_hexdump(MSG_DEBUG, 1871 "DPP: Expected Responder Bootstrapping Key Hash", 1872 auth->peer_bi->pubkey_hash, SHA256_MAC_LEN); 1873 dpp_auth_fail(auth, 1874 "Responder Bootstrapping Key Hash mismatch"); 1875 return -1; 1876 } 1877 1878 i_bootstrap = dpp_get_attr(attr_start, attr_len, 1879 DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 1880 &i_bootstrap_len); 1881 if (i_bootstrap) { 1882 if (i_bootstrap_len != SHA256_MAC_LEN) { 1883 dpp_auth_fail(auth, 1884 "Invalid Initiator Bootstrapping Key Hash attribute"); 1885 return -1; 1886 } 1887 wpa_hexdump(MSG_MSGDUMP, 1888 "DPP: Initiator Bootstrapping Key Hash", 1889 i_bootstrap, i_bootstrap_len); 1890 if (!auth->peer_bi || 1891 os_memcmp(i_bootstrap, auth->peer_bi->pubkey_hash, 1892 SHA256_MAC_LEN) != 0) { 1893 dpp_auth_fail(auth, 1894 "Initiator Bootstrapping Key Hash mismatch"); 1895 return -1; 1896 } 1897 } else if (auth->peer_bi) { 1898 /* Mutual authentication and peer did not include its 1899 * Bootstrapping Key Hash attribute. */ 1900 dpp_auth_fail(auth, 1901 "Missing Initiator Bootstrapping Key Hash attribute"); 1902 return -1; 1903 } 1904 1905 status = dpp_get_attr(attr_start, attr_len, DPP_ATTR_STATUS, 1906 &status_len); 1907 if (!status || status_len < 1) { 1908 dpp_auth_fail(auth, 1909 "Missing or invalid required DPP Status attribute"); 1910 return -1; 1911 } 1912 wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]); 1913 if (status[0] == DPP_STATUS_NOT_COMPATIBLE || 1914 status[0] == DPP_STATUS_AUTH_FAILURE) 1915 return dpp_auth_conf_rx_failure(auth, hdr, attr_start, 1916 attr_len, wrapped_data, 1917 wrapped_data_len, status[0]); 1918 1919 if (status[0] != DPP_STATUS_OK) { 1920 dpp_auth_fail(auth, "Authentication failed"); 1921 return -1; 1922 } 1923 1924 addr[0] = hdr; 1925 len[0] = DPP_HDR_LEN; 1926 addr[1] = attr_start; 1927 len[1] = attr_len; 1928 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]); 1929 wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]); 1930 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext", 1931 wrapped_data, wrapped_data_len); 1932 unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE; 1933 unwrapped = os_malloc(unwrapped_len); 1934 if (!unwrapped) 1935 return -1; 1936 if (aes_siv_decrypt(auth->ke, auth->curve->hash_len, 1937 wrapped_data, wrapped_data_len, 1938 2, addr, len, unwrapped) < 0) { 1939 dpp_auth_fail(auth, "AES-SIV decryption failed"); 1940 goto fail; 1941 } 1942 wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", 1943 unwrapped, unwrapped_len); 1944 1945 if (dpp_check_attrs(unwrapped, unwrapped_len) < 0) { 1946 dpp_auth_fail(auth, "Invalid attribute in unwrapped data"); 1947 goto fail; 1948 } 1949 1950 i_auth = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG, 1951 &i_auth_len); 1952 if (!i_auth || i_auth_len != auth->curve->hash_len) { 1953 dpp_auth_fail(auth, 1954 "Missing or invalid Initiator Authenticating Tag"); 1955 goto fail; 1956 } 1957 wpa_hexdump(MSG_DEBUG, "DPP: Received Initiator Authenticating Tag", 1958 i_auth, i_auth_len); 1959 /* I-auth' = H(R-nonce | I-nonce | PR.x | PI.x | BR.x | [BI.x |] 1) */ 1960 if (dpp_gen_i_auth(auth, i_auth2) < 0) 1961 goto fail; 1962 wpa_hexdump(MSG_DEBUG, "DPP: Calculated Initiator Authenticating Tag", 1963 i_auth2, i_auth_len); 1964 if (os_memcmp(i_auth, i_auth2, i_auth_len) != 0) { 1965 dpp_auth_fail(auth, "Mismatching Initiator Authenticating Tag"); 1966 goto fail; 1967 } 1968 1969 bin_clear_free(unwrapped, unwrapped_len); 1970 dpp_auth_success(auth); 1971 return 0; 1972 fail: 1973 bin_clear_free(unwrapped, unwrapped_len); 1974 return -1; 1975 } 1976