1 /* 2 * Simultaneous authentication of equals 3 * Copyright (c) 2012-2016, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "crypto/crypto.h" 13 #include "crypto/sha256.h" 14 #include "crypto/random.h" 15 #include "crypto/dh_groups.h" 16 #include "ieee802_11_defs.h" 17 #include "sae.h" 18 19 20 int sae_set_group(struct sae_data *sae, int group) 21 { 22 struct sae_temporary_data *tmp; 23 24 sae_clear_data(sae); 25 tmp = sae->tmp = os_zalloc(sizeof(*tmp)); 26 if (tmp == NULL) 27 return -1; 28 29 /* First, check if this is an ECC group */ 30 tmp->ec = crypto_ec_init(group); 31 if (tmp->ec) { 32 wpa_printf(MSG_DEBUG, "SAE: Selecting supported ECC group %d", 33 group); 34 sae->group = group; 35 tmp->prime_len = crypto_ec_prime_len(tmp->ec); 36 tmp->prime = crypto_ec_get_prime(tmp->ec); 37 tmp->order = crypto_ec_get_order(tmp->ec); 38 return 0; 39 } 40 41 /* Not an ECC group, check FFC */ 42 tmp->dh = dh_groups_get(group); 43 if (tmp->dh) { 44 wpa_printf(MSG_DEBUG, "SAE: Selecting supported FFC group %d", 45 group); 46 sae->group = group; 47 tmp->prime_len = tmp->dh->prime_len; 48 if (tmp->prime_len > SAE_MAX_PRIME_LEN) { 49 sae_clear_data(sae); 50 return -1; 51 } 52 53 tmp->prime_buf = crypto_bignum_init_set(tmp->dh->prime, 54 tmp->prime_len); 55 if (tmp->prime_buf == NULL) { 56 sae_clear_data(sae); 57 return -1; 58 } 59 tmp->prime = tmp->prime_buf; 60 61 tmp->order_buf = crypto_bignum_init_set(tmp->dh->order, 62 tmp->dh->order_len); 63 if (tmp->order_buf == NULL) { 64 sae_clear_data(sae); 65 return -1; 66 } 67 tmp->order = tmp->order_buf; 68 69 return 0; 70 } 71 72 /* Unsupported group */ 73 wpa_printf(MSG_DEBUG, 74 "SAE: Group %d not supported by the crypto library", group); 75 return -1; 76 } 77 78 79 void sae_clear_temp_data(struct sae_data *sae) 80 { 81 struct sae_temporary_data *tmp; 82 if (sae == NULL || sae->tmp == NULL) 83 return; 84 tmp = sae->tmp; 85 crypto_ec_deinit(tmp->ec); 86 crypto_bignum_deinit(tmp->prime_buf, 0); 87 crypto_bignum_deinit(tmp->order_buf, 0); 88 crypto_bignum_deinit(tmp->sae_rand, 1); 89 crypto_bignum_deinit(tmp->pwe_ffc, 1); 90 crypto_bignum_deinit(tmp->own_commit_scalar, 0); 91 crypto_bignum_deinit(tmp->own_commit_element_ffc, 0); 92 crypto_bignum_deinit(tmp->peer_commit_element_ffc, 0); 93 crypto_ec_point_deinit(tmp->pwe_ecc, 1); 94 crypto_ec_point_deinit(tmp->own_commit_element_ecc, 0); 95 crypto_ec_point_deinit(tmp->peer_commit_element_ecc, 0); 96 wpabuf_free(tmp->anti_clogging_token); 97 os_free(tmp->pw_id); 98 bin_clear_free(tmp, sizeof(*tmp)); 99 sae->tmp = NULL; 100 } 101 102 103 void sae_clear_data(struct sae_data *sae) 104 { 105 if (sae == NULL) 106 return; 107 sae_clear_temp_data(sae); 108 crypto_bignum_deinit(sae->peer_commit_scalar, 0); 109 os_memset(sae, 0, sizeof(*sae)); 110 } 111 112 113 static void buf_shift_right(u8 *buf, size_t len, size_t bits) 114 { 115 size_t i; 116 for (i = len - 1; i > 0; i--) 117 buf[i] = (buf[i - 1] << (8 - bits)) | (buf[i] >> bits); 118 buf[0] >>= bits; 119 } 120 121 122 static struct crypto_bignum * sae_get_rand(struct sae_data *sae) 123 { 124 u8 val[SAE_MAX_PRIME_LEN]; 125 int iter = 0; 126 struct crypto_bignum *bn = NULL; 127 int order_len_bits = crypto_bignum_bits(sae->tmp->order); 128 size_t order_len = (order_len_bits + 7) / 8; 129 130 if (order_len > sizeof(val)) 131 return NULL; 132 133 for (;;) { 134 if (iter++ > 100 || random_get_bytes(val, order_len) < 0) 135 return NULL; 136 if (order_len_bits % 8) 137 buf_shift_right(val, order_len, 8 - order_len_bits % 8); 138 bn = crypto_bignum_init_set(val, order_len); 139 if (bn == NULL) 140 return NULL; 141 if (crypto_bignum_is_zero(bn) || 142 crypto_bignum_is_one(bn) || 143 crypto_bignum_cmp(bn, sae->tmp->order) >= 0) { 144 crypto_bignum_deinit(bn, 0); 145 continue; 146 } 147 break; 148 } 149 150 os_memset(val, 0, order_len); 151 return bn; 152 } 153 154 155 static struct crypto_bignum * sae_get_rand_and_mask(struct sae_data *sae) 156 { 157 crypto_bignum_deinit(sae->tmp->sae_rand, 1); 158 sae->tmp->sae_rand = sae_get_rand(sae); 159 if (sae->tmp->sae_rand == NULL) 160 return NULL; 161 return sae_get_rand(sae); 162 } 163 164 165 static void sae_pwd_seed_key(const u8 *addr1, const u8 *addr2, u8 *key) 166 { 167 wpa_printf(MSG_DEBUG, "SAE: PWE derivation - addr1=" MACSTR 168 " addr2=" MACSTR, MAC2STR(addr1), MAC2STR(addr2)); 169 if (os_memcmp(addr1, addr2, ETH_ALEN) > 0) { 170 os_memcpy(key, addr1, ETH_ALEN); 171 os_memcpy(key + ETH_ALEN, addr2, ETH_ALEN); 172 } else { 173 os_memcpy(key, addr2, ETH_ALEN); 174 os_memcpy(key + ETH_ALEN, addr1, ETH_ALEN); 175 } 176 } 177 178 179 static struct crypto_bignum * 180 get_rand_1_to_p_1(const u8 *prime, size_t prime_len, size_t prime_bits, 181 int *r_odd) 182 { 183 for (;;) { 184 struct crypto_bignum *r; 185 u8 tmp[SAE_MAX_ECC_PRIME_LEN]; 186 187 if (random_get_bytes(tmp, prime_len) < 0) 188 break; 189 if (prime_bits % 8) 190 buf_shift_right(tmp, prime_len, 8 - prime_bits % 8); 191 if (os_memcmp(tmp, prime, prime_len) >= 0) 192 continue; 193 r = crypto_bignum_init_set(tmp, prime_len); 194 if (!r) 195 break; 196 if (crypto_bignum_is_zero(r)) { 197 crypto_bignum_deinit(r, 0); 198 continue; 199 } 200 201 *r_odd = tmp[prime_len - 1] & 0x01; 202 return r; 203 } 204 205 return NULL; 206 } 207 208 209 static int is_quadratic_residue_blind(struct sae_data *sae, 210 const u8 *prime, size_t bits, 211 const struct crypto_bignum *qr, 212 const struct crypto_bignum *qnr, 213 const struct crypto_bignum *y_sqr) 214 { 215 struct crypto_bignum *r, *num; 216 int r_odd, check, res = -1; 217 218 /* 219 * Use the blinding technique to mask y_sqr while determining 220 * whether it is a quadratic residue modulo p to avoid leaking 221 * timing information while determining the Legendre symbol. 222 * 223 * v = y_sqr 224 * r = a random number between 1 and p-1, inclusive 225 * num = (v * r * r) modulo p 226 */ 227 r = get_rand_1_to_p_1(prime, sae->tmp->prime_len, bits, &r_odd); 228 if (!r) 229 return -1; 230 231 num = crypto_bignum_init(); 232 if (!num || 233 crypto_bignum_mulmod(y_sqr, r, sae->tmp->prime, num) < 0 || 234 crypto_bignum_mulmod(num, r, sae->tmp->prime, num) < 0) 235 goto fail; 236 237 if (r_odd) { 238 /* 239 * num = (num * qr) module p 240 * LGR(num, p) = 1 ==> quadratic residue 241 */ 242 if (crypto_bignum_mulmod(num, qr, sae->tmp->prime, num) < 0) 243 goto fail; 244 check = 1; 245 } else { 246 /* 247 * num = (num * qnr) module p 248 * LGR(num, p) = -1 ==> quadratic residue 249 */ 250 if (crypto_bignum_mulmod(num, qnr, sae->tmp->prime, num) < 0) 251 goto fail; 252 check = -1; 253 } 254 255 res = crypto_bignum_legendre(num, sae->tmp->prime); 256 if (res == -2) { 257 res = -1; 258 goto fail; 259 } 260 res = res == check; 261 fail: 262 crypto_bignum_deinit(num, 1); 263 crypto_bignum_deinit(r, 1); 264 return res; 265 } 266 267 268 static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed, 269 const u8 *prime, 270 const struct crypto_bignum *qr, 271 const struct crypto_bignum *qnr, 272 struct crypto_bignum **ret_x_cand) 273 { 274 u8 pwd_value[SAE_MAX_ECC_PRIME_LEN]; 275 struct crypto_bignum *y_sqr, *x_cand; 276 int res; 277 size_t bits; 278 279 *ret_x_cand = NULL; 280 281 wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN); 282 283 /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */ 284 bits = crypto_ec_prime_len_bits(sae->tmp->ec); 285 if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking", 286 prime, sae->tmp->prime_len, pwd_value, bits) < 0) 287 return -1; 288 if (bits % 8) 289 buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8); 290 wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", 291 pwd_value, sae->tmp->prime_len); 292 293 if (os_memcmp(pwd_value, prime, sae->tmp->prime_len) >= 0) 294 return 0; 295 296 x_cand = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len); 297 if (!x_cand) 298 return -1; 299 y_sqr = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x_cand); 300 if (!y_sqr) { 301 crypto_bignum_deinit(x_cand, 1); 302 return -1; 303 } 304 305 res = is_quadratic_residue_blind(sae, prime, bits, qr, qnr, y_sqr); 306 crypto_bignum_deinit(y_sqr, 1); 307 if (res <= 0) { 308 crypto_bignum_deinit(x_cand, 1); 309 return res; 310 } 311 312 *ret_x_cand = x_cand; 313 return 1; 314 } 315 316 317 static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed, 318 struct crypto_bignum *pwe) 319 { 320 u8 pwd_value[SAE_MAX_PRIME_LEN]; 321 size_t bits = sae->tmp->prime_len * 8; 322 u8 exp[1]; 323 struct crypto_bignum *a, *b; 324 int res; 325 326 wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN); 327 328 /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */ 329 if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking", 330 sae->tmp->dh->prime, sae->tmp->prime_len, pwd_value, 331 bits) < 0) 332 return -1; 333 wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value, 334 sae->tmp->prime_len); 335 336 if (os_memcmp(pwd_value, sae->tmp->dh->prime, sae->tmp->prime_len) >= 0) 337 { 338 wpa_printf(MSG_DEBUG, "SAE: pwd-value >= p"); 339 return 0; 340 } 341 342 /* PWE = pwd-value^((p-1)/r) modulo p */ 343 344 a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len); 345 346 if (sae->tmp->dh->safe_prime) { 347 /* 348 * r = (p-1)/2 for the group used here, so this becomes: 349 * PWE = pwd-value^2 modulo p 350 */ 351 exp[0] = 2; 352 b = crypto_bignum_init_set(exp, sizeof(exp)); 353 } else { 354 /* Calculate exponent: (p-1)/r */ 355 exp[0] = 1; 356 b = crypto_bignum_init_set(exp, sizeof(exp)); 357 if (b == NULL || 358 crypto_bignum_sub(sae->tmp->prime, b, b) < 0 || 359 crypto_bignum_div(b, sae->tmp->order, b) < 0) { 360 crypto_bignum_deinit(b, 0); 361 b = NULL; 362 } 363 } 364 365 if (a == NULL || b == NULL) 366 res = -1; 367 else 368 res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe); 369 370 crypto_bignum_deinit(a, 0); 371 crypto_bignum_deinit(b, 0); 372 373 if (res < 0) { 374 wpa_printf(MSG_DEBUG, "SAE: Failed to calculate PWE"); 375 return -1; 376 } 377 378 /* if (PWE > 1) --> found */ 379 if (crypto_bignum_is_zero(pwe) || crypto_bignum_is_one(pwe)) { 380 wpa_printf(MSG_DEBUG, "SAE: PWE <= 1"); 381 return 0; 382 } 383 384 wpa_printf(MSG_DEBUG, "SAE: PWE found"); 385 return 1; 386 } 387 388 389 static int get_random_qr_qnr(const u8 *prime, size_t prime_len, 390 const struct crypto_bignum *prime_bn, 391 size_t prime_bits, struct crypto_bignum **qr, 392 struct crypto_bignum **qnr) 393 { 394 *qr = NULL; 395 *qnr = NULL; 396 397 while (!(*qr) || !(*qnr)) { 398 u8 tmp[SAE_MAX_ECC_PRIME_LEN]; 399 struct crypto_bignum *q; 400 int res; 401 402 if (random_get_bytes(tmp, prime_len) < 0) 403 break; 404 if (prime_bits % 8) 405 buf_shift_right(tmp, prime_len, 8 - prime_bits % 8); 406 if (os_memcmp(tmp, prime, prime_len) >= 0) 407 continue; 408 q = crypto_bignum_init_set(tmp, prime_len); 409 if (!q) 410 break; 411 res = crypto_bignum_legendre(q, prime_bn); 412 413 if (res == 1 && !(*qr)) 414 *qr = q; 415 else if (res == -1 && !(*qnr)) 416 *qnr = q; 417 else 418 crypto_bignum_deinit(q, 0); 419 } 420 421 return (*qr && *qnr) ? 0 : -1; 422 } 423 424 425 static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1, 426 const u8 *addr2, const u8 *password, 427 size_t password_len, const char *identifier) 428 { 429 u8 counter, k = 40; 430 u8 addrs[2 * ETH_ALEN]; 431 const u8 *addr[3]; 432 size_t len[3]; 433 size_t num_elem; 434 u8 dummy_password[32]; 435 size_t dummy_password_len; 436 int pwd_seed_odd = 0; 437 u8 prime[SAE_MAX_ECC_PRIME_LEN]; 438 size_t prime_len; 439 struct crypto_bignum *x = NULL, *qr, *qnr; 440 size_t bits; 441 int res; 442 443 dummy_password_len = password_len; 444 if (dummy_password_len > sizeof(dummy_password)) 445 dummy_password_len = sizeof(dummy_password); 446 if (random_get_bytes(dummy_password, dummy_password_len) < 0) 447 return -1; 448 449 prime_len = sae->tmp->prime_len; 450 if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime), 451 prime_len) < 0) 452 return -1; 453 bits = crypto_ec_prime_len_bits(sae->tmp->ec); 454 455 /* 456 * Create a random quadratic residue (qr) and quadratic non-residue 457 * (qnr) modulo p for blinding purposes during the loop. 458 */ 459 if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits, 460 &qr, &qnr) < 0) 461 return -1; 462 463 wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password", 464 password, password_len); 465 if (identifier) 466 wpa_printf(MSG_DEBUG, "SAE: password identifier: %s", 467 identifier); 468 469 /* 470 * H(salt, ikm) = HMAC-SHA256(salt, ikm) 471 * base = password [|| identifier] 472 * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC), 473 * base || counter) 474 */ 475 sae_pwd_seed_key(addr1, addr2, addrs); 476 477 addr[0] = password; 478 len[0] = password_len; 479 num_elem = 1; 480 if (identifier) { 481 addr[num_elem] = (const u8 *) identifier; 482 len[num_elem] = os_strlen(identifier); 483 num_elem++; 484 } 485 addr[num_elem] = &counter; 486 len[num_elem] = sizeof(counter); 487 num_elem++; 488 489 /* 490 * Continue for at least k iterations to protect against side-channel 491 * attacks that attempt to determine the number of iterations required 492 * in the loop. 493 */ 494 for (counter = 1; counter <= k || !x; counter++) { 495 u8 pwd_seed[SHA256_MAC_LEN]; 496 struct crypto_bignum *x_cand; 497 498 if (counter > 200) { 499 /* This should not happen in practice */ 500 wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE"); 501 break; 502 } 503 504 wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter); 505 if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem, 506 addr, len, pwd_seed) < 0) 507 break; 508 509 res = sae_test_pwd_seed_ecc(sae, pwd_seed, 510 prime, qr, qnr, &x_cand); 511 if (res < 0) 512 goto fail; 513 if (res > 0 && !x) { 514 wpa_printf(MSG_DEBUG, 515 "SAE: Selected pwd-seed with counter %u", 516 counter); 517 x = x_cand; 518 pwd_seed_odd = pwd_seed[SHA256_MAC_LEN - 1] & 0x01; 519 os_memset(pwd_seed, 0, sizeof(pwd_seed)); 520 521 /* 522 * Use a dummy password for the following rounds, if 523 * any. 524 */ 525 addr[0] = dummy_password; 526 len[0] = dummy_password_len; 527 } else if (res > 0) { 528 crypto_bignum_deinit(x_cand, 1); 529 } 530 } 531 532 if (!x) { 533 wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE"); 534 res = -1; 535 goto fail; 536 } 537 538 if (!sae->tmp->pwe_ecc) 539 sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec); 540 if (!sae->tmp->pwe_ecc) 541 res = -1; 542 else 543 res = crypto_ec_point_solve_y_coord(sae->tmp->ec, 544 sae->tmp->pwe_ecc, x, 545 pwd_seed_odd); 546 crypto_bignum_deinit(x, 1); 547 if (res < 0) { 548 /* 549 * This should not happen since we already checked that there 550 * is a result. 551 */ 552 wpa_printf(MSG_DEBUG, "SAE: Could not solve y"); 553 } 554 555 fail: 556 crypto_bignum_deinit(qr, 0); 557 crypto_bignum_deinit(qnr, 0); 558 559 return res; 560 } 561 562 563 static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1, 564 const u8 *addr2, const u8 *password, 565 size_t password_len, const char *identifier) 566 { 567 u8 counter; 568 u8 addrs[2 * ETH_ALEN]; 569 const u8 *addr[3]; 570 size_t len[3]; 571 size_t num_elem; 572 int found = 0; 573 574 if (sae->tmp->pwe_ffc == NULL) { 575 sae->tmp->pwe_ffc = crypto_bignum_init(); 576 if (sae->tmp->pwe_ffc == NULL) 577 return -1; 578 } 579 580 wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password", 581 password, password_len); 582 583 /* 584 * H(salt, ikm) = HMAC-SHA256(salt, ikm) 585 * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC), 586 * password [|| identifier] || counter) 587 */ 588 sae_pwd_seed_key(addr1, addr2, addrs); 589 590 addr[0] = password; 591 len[0] = password_len; 592 num_elem = 1; 593 if (identifier) { 594 addr[num_elem] = (const u8 *) identifier; 595 len[num_elem] = os_strlen(identifier); 596 num_elem++; 597 } 598 addr[num_elem] = &counter; 599 len[num_elem] = sizeof(counter); 600 num_elem++; 601 602 for (counter = 1; !found; counter++) { 603 u8 pwd_seed[SHA256_MAC_LEN]; 604 int res; 605 606 if (counter > 200) { 607 /* This should not happen in practice */ 608 wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE"); 609 break; 610 } 611 612 wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter); 613 if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem, 614 addr, len, pwd_seed) < 0) 615 break; 616 res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc); 617 if (res < 0) 618 break; 619 if (res > 0) { 620 wpa_printf(MSG_DEBUG, "SAE: Use this PWE"); 621 found = 1; 622 } 623 } 624 625 return found ? 0 : -1; 626 } 627 628 629 static int sae_derive_commit_element_ecc(struct sae_data *sae, 630 struct crypto_bignum *mask) 631 { 632 /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */ 633 if (!sae->tmp->own_commit_element_ecc) { 634 sae->tmp->own_commit_element_ecc = 635 crypto_ec_point_init(sae->tmp->ec); 636 if (!sae->tmp->own_commit_element_ecc) 637 return -1; 638 } 639 640 if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc, mask, 641 sae->tmp->own_commit_element_ecc) < 0 || 642 crypto_ec_point_invert(sae->tmp->ec, 643 sae->tmp->own_commit_element_ecc) < 0) { 644 wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element"); 645 return -1; 646 } 647 648 return 0; 649 } 650 651 652 static int sae_derive_commit_element_ffc(struct sae_data *sae, 653 struct crypto_bignum *mask) 654 { 655 /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */ 656 if (!sae->tmp->own_commit_element_ffc) { 657 sae->tmp->own_commit_element_ffc = crypto_bignum_init(); 658 if (!sae->tmp->own_commit_element_ffc) 659 return -1; 660 } 661 662 if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, mask, sae->tmp->prime, 663 sae->tmp->own_commit_element_ffc) < 0 || 664 crypto_bignum_inverse(sae->tmp->own_commit_element_ffc, 665 sae->tmp->prime, 666 sae->tmp->own_commit_element_ffc) < 0) { 667 wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element"); 668 return -1; 669 } 670 671 return 0; 672 } 673 674 675 static int sae_derive_commit(struct sae_data *sae) 676 { 677 struct crypto_bignum *mask; 678 int ret = -1; 679 unsigned int counter = 0; 680 681 do { 682 counter++; 683 if (counter > 100) { 684 /* 685 * This cannot really happen in practice if the random 686 * number generator is working. Anyway, to avoid even a 687 * theoretical infinite loop, break out after 100 688 * attemps. 689 */ 690 return -1; 691 } 692 693 mask = sae_get_rand_and_mask(sae); 694 if (mask == NULL) { 695 wpa_printf(MSG_DEBUG, "SAE: Could not get rand/mask"); 696 return -1; 697 } 698 699 /* commit-scalar = (rand + mask) modulo r */ 700 if (!sae->tmp->own_commit_scalar) { 701 sae->tmp->own_commit_scalar = crypto_bignum_init(); 702 if (!sae->tmp->own_commit_scalar) 703 goto fail; 704 } 705 crypto_bignum_add(sae->tmp->sae_rand, mask, 706 sae->tmp->own_commit_scalar); 707 crypto_bignum_mod(sae->tmp->own_commit_scalar, sae->tmp->order, 708 sae->tmp->own_commit_scalar); 709 } while (crypto_bignum_is_zero(sae->tmp->own_commit_scalar) || 710 crypto_bignum_is_one(sae->tmp->own_commit_scalar)); 711 712 if ((sae->tmp->ec && sae_derive_commit_element_ecc(sae, mask) < 0) || 713 (sae->tmp->dh && sae_derive_commit_element_ffc(sae, mask) < 0)) 714 goto fail; 715 716 ret = 0; 717 fail: 718 crypto_bignum_deinit(mask, 1); 719 return ret; 720 } 721 722 723 int sae_prepare_commit(const u8 *addr1, const u8 *addr2, 724 const u8 *password, size_t password_len, 725 const char *identifier, struct sae_data *sae) 726 { 727 if (sae->tmp == NULL || 728 (sae->tmp->ec && sae_derive_pwe_ecc(sae, addr1, addr2, password, 729 password_len, 730 identifier) < 0) || 731 (sae->tmp->dh && sae_derive_pwe_ffc(sae, addr1, addr2, password, 732 password_len, 733 identifier) < 0) || 734 sae_derive_commit(sae) < 0) 735 return -1; 736 return 0; 737 } 738 739 740 static int sae_derive_k_ecc(struct sae_data *sae, u8 *k) 741 { 742 struct crypto_ec_point *K; 743 int ret = -1; 744 745 K = crypto_ec_point_init(sae->tmp->ec); 746 if (K == NULL) 747 goto fail; 748 749 /* 750 * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE), 751 * PEER-COMMIT-ELEMENT))) 752 * If K is identity element (point-at-infinity), reject 753 * k = F(K) (= x coordinate) 754 */ 755 756 if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc, 757 sae->peer_commit_scalar, K) < 0 || 758 crypto_ec_point_add(sae->tmp->ec, K, 759 sae->tmp->peer_commit_element_ecc, K) < 0 || 760 crypto_ec_point_mul(sae->tmp->ec, K, sae->tmp->sae_rand, K) < 0 || 761 crypto_ec_point_is_at_infinity(sae->tmp->ec, K) || 762 crypto_ec_point_to_bin(sae->tmp->ec, K, k, NULL) < 0) { 763 wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k"); 764 goto fail; 765 } 766 767 wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len); 768 769 ret = 0; 770 fail: 771 crypto_ec_point_deinit(K, 1); 772 return ret; 773 } 774 775 776 static int sae_derive_k_ffc(struct sae_data *sae, u8 *k) 777 { 778 struct crypto_bignum *K; 779 int ret = -1; 780 781 K = crypto_bignum_init(); 782 if (K == NULL) 783 goto fail; 784 785 /* 786 * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE), 787 * PEER-COMMIT-ELEMENT))) 788 * If K is identity element (one), reject. 789 * k = F(K) (= x coordinate) 790 */ 791 792 if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, sae->peer_commit_scalar, 793 sae->tmp->prime, K) < 0 || 794 crypto_bignum_mulmod(K, sae->tmp->peer_commit_element_ffc, 795 sae->tmp->prime, K) < 0 || 796 crypto_bignum_exptmod(K, sae->tmp->sae_rand, sae->tmp->prime, K) < 0 797 || 798 crypto_bignum_is_one(K) || 799 crypto_bignum_to_bin(K, k, SAE_MAX_PRIME_LEN, sae->tmp->prime_len) < 800 0) { 801 wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k"); 802 goto fail; 803 } 804 805 wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len); 806 807 ret = 0; 808 fail: 809 crypto_bignum_deinit(K, 1); 810 return ret; 811 } 812 813 814 static int sae_derive_keys(struct sae_data *sae, const u8 *k) 815 { 816 u8 null_key[SAE_KEYSEED_KEY_LEN], val[SAE_MAX_PRIME_LEN]; 817 u8 keyseed[SHA256_MAC_LEN]; 818 u8 keys[SAE_KCK_LEN + SAE_PMK_LEN]; 819 struct crypto_bignum *tmp; 820 int ret = -1; 821 822 tmp = crypto_bignum_init(); 823 if (tmp == NULL) 824 goto fail; 825 826 /* keyseed = H(<0>32, k) 827 * KCK || PMK = KDF-512(keyseed, "SAE KCK and PMK", 828 * (commit-scalar + peer-commit-scalar) modulo r) 829 * PMKID = L((commit-scalar + peer-commit-scalar) modulo r, 0, 128) 830 */ 831 832 os_memset(null_key, 0, sizeof(null_key)); 833 hmac_sha256(null_key, sizeof(null_key), k, sae->tmp->prime_len, 834 keyseed); 835 wpa_hexdump_key(MSG_DEBUG, "SAE: keyseed", keyseed, sizeof(keyseed)); 836 837 crypto_bignum_add(sae->tmp->own_commit_scalar, sae->peer_commit_scalar, 838 tmp); 839 crypto_bignum_mod(tmp, sae->tmp->order, tmp); 840 crypto_bignum_to_bin(tmp, val, sizeof(val), sae->tmp->prime_len); 841 wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN); 842 if (sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK", 843 val, sae->tmp->prime_len, keys, sizeof(keys)) < 0) 844 goto fail; 845 os_memset(keyseed, 0, sizeof(keyseed)); 846 os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN); 847 os_memcpy(sae->pmk, keys + SAE_KCK_LEN, SAE_PMK_LEN); 848 os_memcpy(sae->pmkid, val, SAE_PMKID_LEN); 849 os_memset(keys, 0, sizeof(keys)); 850 wpa_hexdump_key(MSG_DEBUG, "SAE: KCK", sae->tmp->kck, SAE_KCK_LEN); 851 wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, SAE_PMK_LEN); 852 853 ret = 0; 854 fail: 855 crypto_bignum_deinit(tmp, 0); 856 return ret; 857 } 858 859 860 int sae_process_commit(struct sae_data *sae) 861 { 862 u8 k[SAE_MAX_PRIME_LEN]; 863 if (sae->tmp == NULL || 864 (sae->tmp->ec && sae_derive_k_ecc(sae, k) < 0) || 865 (sae->tmp->dh && sae_derive_k_ffc(sae, k) < 0) || 866 sae_derive_keys(sae, k) < 0) 867 return -1; 868 return 0; 869 } 870 871 872 void sae_write_commit(struct sae_data *sae, struct wpabuf *buf, 873 const struct wpabuf *token, const char *identifier) 874 { 875 u8 *pos; 876 877 if (sae->tmp == NULL) 878 return; 879 880 wpabuf_put_le16(buf, sae->group); /* Finite Cyclic Group */ 881 if (token) { 882 wpabuf_put_buf(buf, token); 883 wpa_hexdump(MSG_DEBUG, "SAE: Anti-clogging token", 884 wpabuf_head(token), wpabuf_len(token)); 885 } 886 pos = wpabuf_put(buf, sae->tmp->prime_len); 887 crypto_bignum_to_bin(sae->tmp->own_commit_scalar, pos, 888 sae->tmp->prime_len, sae->tmp->prime_len); 889 wpa_hexdump(MSG_DEBUG, "SAE: own commit-scalar", 890 pos, sae->tmp->prime_len); 891 if (sae->tmp->ec) { 892 pos = wpabuf_put(buf, 2 * sae->tmp->prime_len); 893 crypto_ec_point_to_bin(sae->tmp->ec, 894 sae->tmp->own_commit_element_ecc, 895 pos, pos + sae->tmp->prime_len); 896 wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(x)", 897 pos, sae->tmp->prime_len); 898 wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(y)", 899 pos + sae->tmp->prime_len, sae->tmp->prime_len); 900 } else { 901 pos = wpabuf_put(buf, sae->tmp->prime_len); 902 crypto_bignum_to_bin(sae->tmp->own_commit_element_ffc, pos, 903 sae->tmp->prime_len, sae->tmp->prime_len); 904 wpa_hexdump(MSG_DEBUG, "SAE: own commit-element", 905 pos, sae->tmp->prime_len); 906 } 907 908 if (identifier) { 909 /* Password Identifier element */ 910 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); 911 wpabuf_put_u8(buf, 1 + os_strlen(identifier)); 912 wpabuf_put_u8(buf, WLAN_EID_EXT_PASSWORD_IDENTIFIER); 913 wpabuf_put_str(buf, identifier); 914 wpa_printf(MSG_DEBUG, "SAE: own Password Identifier: %s", 915 identifier); 916 } 917 } 918 919 920 u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group) 921 { 922 if (allowed_groups) { 923 int i; 924 for (i = 0; allowed_groups[i] > 0; i++) { 925 if (allowed_groups[i] == group) 926 break; 927 } 928 if (allowed_groups[i] != group) { 929 wpa_printf(MSG_DEBUG, "SAE: Proposed group %u not " 930 "enabled in the current configuration", 931 group); 932 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED; 933 } 934 } 935 936 if (sae->state == SAE_COMMITTED && group != sae->group) { 937 wpa_printf(MSG_DEBUG, "SAE: Do not allow group to be changed"); 938 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED; 939 } 940 941 if (group != sae->group && sae_set_group(sae, group) < 0) { 942 wpa_printf(MSG_DEBUG, "SAE: Unsupported Finite Cyclic Group %u", 943 group); 944 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED; 945 } 946 947 if (sae->tmp == NULL) { 948 wpa_printf(MSG_DEBUG, "SAE: Group information not yet initialized"); 949 return WLAN_STATUS_UNSPECIFIED_FAILURE; 950 } 951 952 if (sae->tmp->dh && !allowed_groups) { 953 wpa_printf(MSG_DEBUG, "SAE: Do not allow FFC group %u without " 954 "explicit configuration enabling it", group); 955 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED; 956 } 957 958 return WLAN_STATUS_SUCCESS; 959 } 960 961 962 static int sae_is_password_id_elem(const u8 *pos, const u8 *end) 963 { 964 return end - pos >= 3 && 965 pos[0] == WLAN_EID_EXTENSION && 966 pos[1] >= 1 && 967 end - pos - 2 >= pos[1] && 968 pos[2] == WLAN_EID_EXT_PASSWORD_IDENTIFIER; 969 } 970 971 972 static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos, 973 const u8 *end, const u8 **token, 974 size_t *token_len) 975 { 976 size_t scalar_elem_len, tlen; 977 const u8 *elem; 978 979 if (token) 980 *token = NULL; 981 if (token_len) 982 *token_len = 0; 983 984 scalar_elem_len = (sae->tmp->ec ? 3 : 2) * sae->tmp->prime_len; 985 if (scalar_elem_len >= (size_t) (end - *pos)) 986 return; /* No extra data beyond peer scalar and element */ 987 988 /* It is a bit difficult to parse this now that there is an 989 * optional variable length Anti-Clogging Token field and 990 * optional variable length Password Identifier element in the 991 * frame. We are sending out fixed length Anti-Clogging Token 992 * fields, so use that length as a requirement for the received 993 * token and check for the presence of possible Password 994 * Identifier element based on the element header information. 995 */ 996 tlen = end - (*pos + scalar_elem_len); 997 998 if (tlen < SHA256_MAC_LEN) { 999 wpa_printf(MSG_DEBUG, 1000 "SAE: Too short optional data (%u octets) to include our Anti-Clogging Token", 1001 (unsigned int) tlen); 1002 return; 1003 } 1004 1005 elem = *pos + scalar_elem_len; 1006 if (sae_is_password_id_elem(elem, end)) { 1007 /* Password Identifier element takes out all available 1008 * extra octets, so there can be no Anti-Clogging token in 1009 * this frame. */ 1010 return; 1011 } 1012 1013 elem += SHA256_MAC_LEN; 1014 if (sae_is_password_id_elem(elem, end)) { 1015 /* Password Identifier element is included in the end, so 1016 * remove its length from the Anti-Clogging token field. */ 1017 tlen -= 2 + elem[1]; 1018 } 1019 1020 wpa_hexdump(MSG_DEBUG, "SAE: Anti-Clogging Token", *pos, tlen); 1021 if (token) 1022 *token = *pos; 1023 if (token_len) 1024 *token_len = tlen; 1025 *pos += tlen; 1026 } 1027 1028 1029 static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos, 1030 const u8 *end) 1031 { 1032 struct crypto_bignum *peer_scalar; 1033 1034 if (sae->tmp->prime_len > end - *pos) { 1035 wpa_printf(MSG_DEBUG, "SAE: Not enough data for scalar"); 1036 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1037 } 1038 1039 peer_scalar = crypto_bignum_init_set(*pos, sae->tmp->prime_len); 1040 if (peer_scalar == NULL) 1041 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1042 1043 /* 1044 * IEEE Std 802.11-2012, 11.3.8.6.1: If there is a protocol instance for 1045 * the peer and it is in Authenticated state, the new Commit Message 1046 * shall be dropped if the peer-scalar is identical to the one used in 1047 * the existing protocol instance. 1048 */ 1049 if (sae->state == SAE_ACCEPTED && sae->peer_commit_scalar && 1050 crypto_bignum_cmp(sae->peer_commit_scalar, peer_scalar) == 0) { 1051 wpa_printf(MSG_DEBUG, "SAE: Do not accept re-use of previous " 1052 "peer-commit-scalar"); 1053 crypto_bignum_deinit(peer_scalar, 0); 1054 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1055 } 1056 1057 /* 1 < scalar < r */ 1058 if (crypto_bignum_is_zero(peer_scalar) || 1059 crypto_bignum_is_one(peer_scalar) || 1060 crypto_bignum_cmp(peer_scalar, sae->tmp->order) >= 0) { 1061 wpa_printf(MSG_DEBUG, "SAE: Invalid peer scalar"); 1062 crypto_bignum_deinit(peer_scalar, 0); 1063 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1064 } 1065 1066 1067 crypto_bignum_deinit(sae->peer_commit_scalar, 0); 1068 sae->peer_commit_scalar = peer_scalar; 1069 wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-scalar", 1070 *pos, sae->tmp->prime_len); 1071 *pos += sae->tmp->prime_len; 1072 1073 return WLAN_STATUS_SUCCESS; 1074 } 1075 1076 1077 static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 **pos, 1078 const u8 *end) 1079 { 1080 u8 prime[SAE_MAX_ECC_PRIME_LEN]; 1081 1082 if (2 * sae->tmp->prime_len > end - *pos) { 1083 wpa_printf(MSG_DEBUG, "SAE: Not enough data for " 1084 "commit-element"); 1085 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1086 } 1087 1088 if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime), 1089 sae->tmp->prime_len) < 0) 1090 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1091 1092 /* element x and y coordinates < p */ 1093 if (os_memcmp(*pos, prime, sae->tmp->prime_len) >= 0 || 1094 os_memcmp(*pos + sae->tmp->prime_len, prime, 1095 sae->tmp->prime_len) >= 0) { 1096 wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer " 1097 "element"); 1098 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1099 } 1100 1101 wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(x)", 1102 *pos, sae->tmp->prime_len); 1103 wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(y)", 1104 *pos + sae->tmp->prime_len, sae->tmp->prime_len); 1105 1106 crypto_ec_point_deinit(sae->tmp->peer_commit_element_ecc, 0); 1107 sae->tmp->peer_commit_element_ecc = 1108 crypto_ec_point_from_bin(sae->tmp->ec, *pos); 1109 if (sae->tmp->peer_commit_element_ecc == NULL) 1110 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1111 1112 if (!crypto_ec_point_is_on_curve(sae->tmp->ec, 1113 sae->tmp->peer_commit_element_ecc)) { 1114 wpa_printf(MSG_DEBUG, "SAE: Peer element is not on curve"); 1115 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1116 } 1117 1118 *pos += 2 * sae->tmp->prime_len; 1119 1120 return WLAN_STATUS_SUCCESS; 1121 } 1122 1123 1124 static u16 sae_parse_commit_element_ffc(struct sae_data *sae, const u8 **pos, 1125 const u8 *end) 1126 { 1127 struct crypto_bignum *res, *one; 1128 const u8 one_bin[1] = { 0x01 }; 1129 1130 if (sae->tmp->prime_len > end - *pos) { 1131 wpa_printf(MSG_DEBUG, "SAE: Not enough data for " 1132 "commit-element"); 1133 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1134 } 1135 wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element", *pos, 1136 sae->tmp->prime_len); 1137 1138 crypto_bignum_deinit(sae->tmp->peer_commit_element_ffc, 0); 1139 sae->tmp->peer_commit_element_ffc = 1140 crypto_bignum_init_set(*pos, sae->tmp->prime_len); 1141 if (sae->tmp->peer_commit_element_ffc == NULL) 1142 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1143 /* 1 < element < p - 1 */ 1144 res = crypto_bignum_init(); 1145 one = crypto_bignum_init_set(one_bin, sizeof(one_bin)); 1146 if (!res || !one || 1147 crypto_bignum_sub(sae->tmp->prime, one, res) || 1148 crypto_bignum_is_zero(sae->tmp->peer_commit_element_ffc) || 1149 crypto_bignum_is_one(sae->tmp->peer_commit_element_ffc) || 1150 crypto_bignum_cmp(sae->tmp->peer_commit_element_ffc, res) >= 0) { 1151 crypto_bignum_deinit(res, 0); 1152 crypto_bignum_deinit(one, 0); 1153 wpa_printf(MSG_DEBUG, "SAE: Invalid peer element"); 1154 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1155 } 1156 crypto_bignum_deinit(one, 0); 1157 1158 /* scalar-op(r, ELEMENT) = 1 modulo p */ 1159 if (crypto_bignum_exptmod(sae->tmp->peer_commit_element_ffc, 1160 sae->tmp->order, sae->tmp->prime, res) < 0 || 1161 !crypto_bignum_is_one(res)) { 1162 wpa_printf(MSG_DEBUG, "SAE: Invalid peer element (scalar-op)"); 1163 crypto_bignum_deinit(res, 0); 1164 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1165 } 1166 crypto_bignum_deinit(res, 0); 1167 1168 *pos += sae->tmp->prime_len; 1169 1170 return WLAN_STATUS_SUCCESS; 1171 } 1172 1173 1174 static u16 sae_parse_commit_element(struct sae_data *sae, const u8 **pos, 1175 const u8 *end) 1176 { 1177 if (sae->tmp->dh) 1178 return sae_parse_commit_element_ffc(sae, pos, end); 1179 return sae_parse_commit_element_ecc(sae, pos, end); 1180 } 1181 1182 1183 static int sae_parse_password_identifier(struct sae_data *sae, 1184 const u8 *pos, const u8 *end) 1185 { 1186 wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame", 1187 pos, end - pos); 1188 if (!sae_is_password_id_elem(pos, end)) { 1189 if (sae->tmp->pw_id) { 1190 wpa_printf(MSG_DEBUG, 1191 "SAE: No Password Identifier included, but expected one (%s)", 1192 sae->tmp->pw_id); 1193 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER; 1194 } 1195 os_free(sae->tmp->pw_id); 1196 sae->tmp->pw_id = NULL; 1197 return WLAN_STATUS_SUCCESS; /* No Password Identifier */ 1198 } 1199 1200 if (sae->tmp->pw_id && 1201 (pos[1] - 1 != (int) os_strlen(sae->tmp->pw_id) || 1202 os_memcmp(sae->tmp->pw_id, pos + 3, pos[1] - 1) != 0)) { 1203 wpa_printf(MSG_DEBUG, 1204 "SAE: The included Password Identifier does not match the expected one (%s)", 1205 sae->tmp->pw_id); 1206 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER; 1207 } 1208 1209 os_free(sae->tmp->pw_id); 1210 sae->tmp->pw_id = os_malloc(pos[1]); 1211 if (!sae->tmp->pw_id) 1212 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1213 os_memcpy(sae->tmp->pw_id, pos + 3, pos[1] - 1); 1214 sae->tmp->pw_id[pos[1] - 1] = '\0'; 1215 wpa_hexdump_ascii(MSG_DEBUG, "SAE: Received Password Identifier", 1216 sae->tmp->pw_id, pos[1] - 1); 1217 return WLAN_STATUS_SUCCESS; 1218 } 1219 1220 1221 u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len, 1222 const u8 **token, size_t *token_len, int *allowed_groups) 1223 { 1224 const u8 *pos = data, *end = data + len; 1225 u16 res; 1226 1227 /* Check Finite Cyclic Group */ 1228 if (end - pos < 2) 1229 return WLAN_STATUS_UNSPECIFIED_FAILURE; 1230 res = sae_group_allowed(sae, allowed_groups, WPA_GET_LE16(pos)); 1231 if (res != WLAN_STATUS_SUCCESS) 1232 return res; 1233 pos += 2; 1234 1235 /* Optional Anti-Clogging Token */ 1236 sae_parse_commit_token(sae, &pos, end, token, token_len); 1237 1238 /* commit-scalar */ 1239 res = sae_parse_commit_scalar(sae, &pos, end); 1240 if (res != WLAN_STATUS_SUCCESS) 1241 return res; 1242 1243 /* commit-element */ 1244 res = sae_parse_commit_element(sae, &pos, end); 1245 if (res != WLAN_STATUS_SUCCESS) 1246 return res; 1247 1248 /* Optional Password Identifier element */ 1249 res = sae_parse_password_identifier(sae, pos, end); 1250 if (res != WLAN_STATUS_SUCCESS) 1251 return res; 1252 1253 /* 1254 * Check whether peer-commit-scalar and PEER-COMMIT-ELEMENT are same as 1255 * the values we sent which would be evidence of a reflection attack. 1256 */ 1257 if (!sae->tmp->own_commit_scalar || 1258 crypto_bignum_cmp(sae->tmp->own_commit_scalar, 1259 sae->peer_commit_scalar) != 0 || 1260 (sae->tmp->dh && 1261 (!sae->tmp->own_commit_element_ffc || 1262 crypto_bignum_cmp(sae->tmp->own_commit_element_ffc, 1263 sae->tmp->peer_commit_element_ffc) != 0)) || 1264 (sae->tmp->ec && 1265 (!sae->tmp->own_commit_element_ecc || 1266 crypto_ec_point_cmp(sae->tmp->ec, 1267 sae->tmp->own_commit_element_ecc, 1268 sae->tmp->peer_commit_element_ecc) != 0))) 1269 return WLAN_STATUS_SUCCESS; /* scalars/elements are different */ 1270 1271 /* 1272 * This is a reflection attack - return special value to trigger caller 1273 * to silently discard the frame instead of replying with a specific 1274 * status code. 1275 */ 1276 return SAE_SILENTLY_DISCARD; 1277 } 1278 1279 1280 static void sae_cn_confirm(struct sae_data *sae, const u8 *sc, 1281 const struct crypto_bignum *scalar1, 1282 const u8 *element1, size_t element1_len, 1283 const struct crypto_bignum *scalar2, 1284 const u8 *element2, size_t element2_len, 1285 u8 *confirm) 1286 { 1287 const u8 *addr[5]; 1288 size_t len[5]; 1289 u8 scalar_b1[SAE_MAX_PRIME_LEN], scalar_b2[SAE_MAX_PRIME_LEN]; 1290 1291 /* Confirm 1292 * CN(key, X, Y, Z, ...) = 1293 * HMAC-SHA256(key, D2OS(X) || D2OS(Y) || D2OS(Z) | ...) 1294 * confirm = CN(KCK, send-confirm, commit-scalar, COMMIT-ELEMENT, 1295 * peer-commit-scalar, PEER-COMMIT-ELEMENT) 1296 * verifier = CN(KCK, peer-send-confirm, peer-commit-scalar, 1297 * PEER-COMMIT-ELEMENT, commit-scalar, COMMIT-ELEMENT) 1298 */ 1299 addr[0] = sc; 1300 len[0] = 2; 1301 crypto_bignum_to_bin(scalar1, scalar_b1, sizeof(scalar_b1), 1302 sae->tmp->prime_len); 1303 addr[1] = scalar_b1; 1304 len[1] = sae->tmp->prime_len; 1305 addr[2] = element1; 1306 len[2] = element1_len; 1307 crypto_bignum_to_bin(scalar2, scalar_b2, sizeof(scalar_b2), 1308 sae->tmp->prime_len); 1309 addr[3] = scalar_b2; 1310 len[3] = sae->tmp->prime_len; 1311 addr[4] = element2; 1312 len[4] = element2_len; 1313 hmac_sha256_vector(sae->tmp->kck, sizeof(sae->tmp->kck), 5, addr, len, 1314 confirm); 1315 } 1316 1317 1318 static void sae_cn_confirm_ecc(struct sae_data *sae, const u8 *sc, 1319 const struct crypto_bignum *scalar1, 1320 const struct crypto_ec_point *element1, 1321 const struct crypto_bignum *scalar2, 1322 const struct crypto_ec_point *element2, 1323 u8 *confirm) 1324 { 1325 u8 element_b1[2 * SAE_MAX_ECC_PRIME_LEN]; 1326 u8 element_b2[2 * SAE_MAX_ECC_PRIME_LEN]; 1327 1328 crypto_ec_point_to_bin(sae->tmp->ec, element1, element_b1, 1329 element_b1 + sae->tmp->prime_len); 1330 crypto_ec_point_to_bin(sae->tmp->ec, element2, element_b2, 1331 element_b2 + sae->tmp->prime_len); 1332 1333 sae_cn_confirm(sae, sc, scalar1, element_b1, 2 * sae->tmp->prime_len, 1334 scalar2, element_b2, 2 * sae->tmp->prime_len, confirm); 1335 } 1336 1337 1338 static void sae_cn_confirm_ffc(struct sae_data *sae, const u8 *sc, 1339 const struct crypto_bignum *scalar1, 1340 const struct crypto_bignum *element1, 1341 const struct crypto_bignum *scalar2, 1342 const struct crypto_bignum *element2, 1343 u8 *confirm) 1344 { 1345 u8 element_b1[SAE_MAX_PRIME_LEN]; 1346 u8 element_b2[SAE_MAX_PRIME_LEN]; 1347 1348 crypto_bignum_to_bin(element1, element_b1, sizeof(element_b1), 1349 sae->tmp->prime_len); 1350 crypto_bignum_to_bin(element2, element_b2, sizeof(element_b2), 1351 sae->tmp->prime_len); 1352 1353 sae_cn_confirm(sae, sc, scalar1, element_b1, sae->tmp->prime_len, 1354 scalar2, element_b2, sae->tmp->prime_len, confirm); 1355 } 1356 1357 1358 void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf) 1359 { 1360 const u8 *sc; 1361 1362 if (sae->tmp == NULL) 1363 return; 1364 1365 /* Send-Confirm */ 1366 sc = wpabuf_put(buf, 0); 1367 wpabuf_put_le16(buf, sae->send_confirm); 1368 if (sae->send_confirm < 0xffff) 1369 sae->send_confirm++; 1370 1371 if (sae->tmp->ec) 1372 sae_cn_confirm_ecc(sae, sc, sae->tmp->own_commit_scalar, 1373 sae->tmp->own_commit_element_ecc, 1374 sae->peer_commit_scalar, 1375 sae->tmp->peer_commit_element_ecc, 1376 wpabuf_put(buf, SHA256_MAC_LEN)); 1377 else 1378 sae_cn_confirm_ffc(sae, sc, sae->tmp->own_commit_scalar, 1379 sae->tmp->own_commit_element_ffc, 1380 sae->peer_commit_scalar, 1381 sae->tmp->peer_commit_element_ffc, 1382 wpabuf_put(buf, SHA256_MAC_LEN)); 1383 } 1384 1385 1386 int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len) 1387 { 1388 u8 verifier[SHA256_MAC_LEN]; 1389 1390 if (len < 2 + SHA256_MAC_LEN) { 1391 wpa_printf(MSG_DEBUG, "SAE: Too short confirm message"); 1392 return -1; 1393 } 1394 1395 wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data)); 1396 1397 if (sae->tmp == NULL) { 1398 wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available"); 1399 return -1; 1400 } 1401 1402 if (sae->tmp->ec) 1403 sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar, 1404 sae->tmp->peer_commit_element_ecc, 1405 sae->tmp->own_commit_scalar, 1406 sae->tmp->own_commit_element_ecc, 1407 verifier); 1408 else 1409 sae_cn_confirm_ffc(sae, data, sae->peer_commit_scalar, 1410 sae->tmp->peer_commit_element_ffc, 1411 sae->tmp->own_commit_scalar, 1412 sae->tmp->own_commit_element_ffc, 1413 verifier); 1414 1415 if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) { 1416 wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch"); 1417 wpa_hexdump(MSG_DEBUG, "SAE: Received confirm", 1418 data + 2, SHA256_MAC_LEN); 1419 wpa_hexdump(MSG_DEBUG, "SAE: Calculated verifier", 1420 verifier, SHA256_MAC_LEN); 1421 return -1; 1422 } 1423 1424 return 0; 1425 } 1426 1427 1428 const char * sae_state_txt(enum sae_state state) 1429 { 1430 switch (state) { 1431 case SAE_NOTHING: 1432 return "Nothing"; 1433 case SAE_COMMITTED: 1434 return "Committed"; 1435 case SAE_CONFIRMED: 1436 return "Confirmed"; 1437 case SAE_ACCEPTED: 1438 return "Accepted"; 1439 } 1440 return "?"; 1441 } 1442