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