Home | History | Annotate | Line # | 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 "common/defs.h"
     13 #include "common/wpa_common.h"
     14 #include "utils/const_time.h"
     15 #include "crypto/crypto.h"
     16 #include "crypto/sha256.h"
     17 #include "crypto/sha384.h"
     18 #include "crypto/sha512.h"
     19 #include "crypto/random.h"
     20 #include "crypto/dh_groups.h"
     21 #include "ieee802_11_defs.h"
     22 #include "dragonfly.h"
     23 #include "sae.h"
     24 
     25 
     26 int sae_set_group(struct sae_data *sae, int group)
     27 {
     28 	struct sae_temporary_data *tmp;
     29 
     30 #ifdef CONFIG_TESTING_OPTIONS
     31 	/* Allow all groups for testing purposes in non-production builds. */
     32 #else /* CONFIG_TESTING_OPTIONS */
     33 	if (!dragonfly_suitable_group(group, 0)) {
     34 		wpa_printf(MSG_DEBUG, "SAE: Reject unsuitable group %d", group);
     35 		return -1;
     36 	}
     37 #endif /* CONFIG_TESTING_OPTIONS */
     38 
     39 	sae_clear_data(sae);
     40 	tmp = sae->tmp = os_zalloc(sizeof(*tmp));
     41 	if (tmp == NULL)
     42 		return -1;
     43 
     44 	/* First, check if this is an ECC group */
     45 	tmp->ec = crypto_ec_init(group);
     46 	if (tmp->ec) {
     47 		wpa_printf(MSG_DEBUG, "SAE: Selecting supported ECC group %d",
     48 			   group);
     49 		sae->group = group;
     50 		tmp->prime_len = crypto_ec_prime_len(tmp->ec);
     51 		tmp->prime = crypto_ec_get_prime(tmp->ec);
     52 		tmp->order_len = crypto_ec_order_len(tmp->ec);
     53 		tmp->order = crypto_ec_get_order(tmp->ec);
     54 		return 0;
     55 	}
     56 
     57 	/* Not an ECC group, check FFC */
     58 	tmp->dh = dh_groups_get(group);
     59 	if (tmp->dh) {
     60 		wpa_printf(MSG_DEBUG, "SAE: Selecting supported FFC group %d",
     61 			   group);
     62 		sae->group = group;
     63 		tmp->prime_len = tmp->dh->prime_len;
     64 		if (tmp->prime_len > SAE_MAX_PRIME_LEN) {
     65 			sae_clear_data(sae);
     66 			return -1;
     67 		}
     68 
     69 		tmp->prime_buf = crypto_bignum_init_set(tmp->dh->prime,
     70 							tmp->prime_len);
     71 		if (tmp->prime_buf == NULL) {
     72 			sae_clear_data(sae);
     73 			return -1;
     74 		}
     75 		tmp->prime = tmp->prime_buf;
     76 
     77 		tmp->order_len = tmp->dh->order_len;
     78 		tmp->order_buf = crypto_bignum_init_set(tmp->dh->order,
     79 							tmp->dh->order_len);
     80 		if (tmp->order_buf == NULL) {
     81 			sae_clear_data(sae);
     82 			return -1;
     83 		}
     84 		tmp->order = tmp->order_buf;
     85 
     86 		return 0;
     87 	}
     88 
     89 	/* Unsupported group */
     90 	wpa_printf(MSG_DEBUG,
     91 		   "SAE: Group %d not supported by the crypto library", group);
     92 	return -1;
     93 }
     94 
     95 
     96 void sae_clear_temp_data(struct sae_data *sae)
     97 {
     98 	struct sae_temporary_data *tmp;
     99 	if (sae == NULL || sae->tmp == NULL)
    100 		return;
    101 	tmp = sae->tmp;
    102 	crypto_ec_deinit(tmp->ec);
    103 	crypto_bignum_deinit(tmp->prime_buf, 0);
    104 	crypto_bignum_deinit(tmp->order_buf, 0);
    105 	crypto_bignum_deinit(tmp->sae_rand, 1);
    106 	crypto_bignum_deinit(tmp->pwe_ffc, 1);
    107 	crypto_bignum_deinit(tmp->own_commit_scalar, 0);
    108 	crypto_bignum_deinit(tmp->own_commit_element_ffc, 0);
    109 	crypto_bignum_deinit(tmp->peer_commit_element_ffc, 0);
    110 	crypto_ec_point_deinit(tmp->pwe_ecc, 1);
    111 	crypto_ec_point_deinit(tmp->own_commit_element_ecc, 0);
    112 	crypto_ec_point_deinit(tmp->peer_commit_element_ecc, 0);
    113 	wpabuf_free(tmp->anti_clogging_token);
    114 	wpabuf_free(tmp->own_rejected_groups);
    115 	wpabuf_free(tmp->peer_rejected_groups);
    116 	os_free(tmp->pw_id);
    117 	bin_clear_free(tmp, sizeof(*tmp));
    118 	sae->tmp = NULL;
    119 }
    120 
    121 
    122 void sae_clear_data(struct sae_data *sae)
    123 {
    124 	if (sae == NULL)
    125 		return;
    126 	sae_clear_temp_data(sae);
    127 	crypto_bignum_deinit(sae->peer_commit_scalar, 0);
    128 	crypto_bignum_deinit(sae->peer_commit_scalar_accepted, 0);
    129 	os_memset(sae, 0, sizeof(*sae));
    130 }
    131 
    132 
    133 static void sae_pwd_seed_key(const u8 *addr1, const u8 *addr2, u8 *key)
    134 {
    135 	wpa_printf(MSG_DEBUG, "SAE: PWE derivation - addr1=" MACSTR
    136 		   " addr2=" MACSTR, MAC2STR(addr1), MAC2STR(addr2));
    137 	if (os_memcmp(addr1, addr2, ETH_ALEN) > 0) {
    138 		os_memcpy(key, addr1, ETH_ALEN);
    139 		os_memcpy(key + ETH_ALEN, addr2, ETH_ALEN);
    140 	} else {
    141 		os_memcpy(key, addr2, ETH_ALEN);
    142 		os_memcpy(key + ETH_ALEN, addr1, ETH_ALEN);
    143 	}
    144 }
    145 
    146 
    147 static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed,
    148 				 const u8 *prime, const u8 *qr, const u8 *qnr,
    149 				 u8 *pwd_value)
    150 {
    151 	struct crypto_bignum *y_sqr, *x_cand;
    152 	int res;
    153 	size_t bits;
    154 	int cmp_prime;
    155 	unsigned int in_range;
    156 
    157 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
    158 
    159 	/* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
    160 	bits = crypto_ec_prime_len_bits(sae->tmp->ec);
    161 	if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
    162 			    prime, sae->tmp->prime_len, pwd_value, bits) < 0)
    163 		return -1;
    164 	if (bits % 8)
    165 		buf_shift_right(pwd_value, sae->tmp->prime_len, 8 - bits % 8);
    166 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
    167 			pwd_value, sae->tmp->prime_len);
    168 
    169 	cmp_prime = const_time_memcmp(pwd_value, prime, sae->tmp->prime_len);
    170 	/* Create a const_time mask for selection based on prf result
    171 	 * being smaller than prime. */
    172 	in_range = const_time_fill_msb((unsigned int) cmp_prime);
    173 	/* The algorithm description would skip the next steps if
    174 	 * cmp_prime >= 0 (return 0 here), but go through them regardless to
    175 	 * minimize externally observable differences in behavior. */
    176 
    177 	x_cand = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
    178 	if (!x_cand)
    179 		return -1;
    180 	y_sqr = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x_cand);
    181 	crypto_bignum_deinit(x_cand, 1);
    182 	if (!y_sqr)
    183 		return -1;
    184 
    185 	res = dragonfly_is_quadratic_residue_blind(sae->tmp->ec, qr, qnr,
    186 						   y_sqr);
    187 	crypto_bignum_deinit(y_sqr, 1);
    188 	if (res < 0)
    189 		return res;
    190 	return const_time_select_int(in_range, res, 0);
    191 }
    192 
    193 
    194 /* Returns -1 on fatal failure, 0 if PWE cannot be derived from the provided
    195  * pwd-seed, or 1 if a valid PWE was derived from pwd-seed. */
    196 static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed,
    197 				 struct crypto_bignum *pwe)
    198 {
    199 	u8 pwd_value[SAE_MAX_PRIME_LEN];
    200 	size_t bits = sae->tmp->prime_len * 8;
    201 	u8 exp[1];
    202 	struct crypto_bignum *a, *b = NULL;
    203 	int res, is_val;
    204 	u8 pwd_value_valid;
    205 
    206 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
    207 
    208 	/* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
    209 	if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
    210 			    sae->tmp->dh->prime, sae->tmp->prime_len, pwd_value,
    211 			    bits) < 0)
    212 		return -1;
    213 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value,
    214 			sae->tmp->prime_len);
    215 
    216 	/* Check whether pwd-value < p */
    217 	res = const_time_memcmp(pwd_value, sae->tmp->dh->prime,
    218 				sae->tmp->prime_len);
    219 	/* pwd-value >= p is invalid, so res is < 0 for the valid cases and
    220 	 * the negative sign can be used to fill the mask for constant time
    221 	 * selection */
    222 	pwd_value_valid = const_time_fill_msb(res);
    223 
    224 	/* If pwd-value >= p, force pwd-value to be < p and perform the
    225 	 * calculations anyway to hide timing difference. The derived PWE will
    226 	 * be ignored in that case. */
    227 	pwd_value[0] = const_time_select_u8(pwd_value_valid, pwd_value[0], 0);
    228 
    229 	/* PWE = pwd-value^((p-1)/r) modulo p */
    230 
    231 	res = -1;
    232 	a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
    233 	if (!a)
    234 		goto fail;
    235 
    236 	/* This is an optimization based on the used group that does not depend
    237 	 * on the password in any way, so it is fine to use separate branches
    238 	 * for this step without constant time operations. */
    239 	if (sae->tmp->dh->safe_prime) {
    240 		/*
    241 		 * r = (p-1)/2 for the group used here, so this becomes:
    242 		 * PWE = pwd-value^2 modulo p
    243 		 */
    244 		exp[0] = 2;
    245 		b = crypto_bignum_init_set(exp, sizeof(exp));
    246 	} else {
    247 		/* Calculate exponent: (p-1)/r */
    248 		exp[0] = 1;
    249 		b = crypto_bignum_init_set(exp, sizeof(exp));
    250 		if (b == NULL ||
    251 		    crypto_bignum_sub(sae->tmp->prime, b, b) < 0 ||
    252 		    crypto_bignum_div(b, sae->tmp->order, b) < 0)
    253 			goto fail;
    254 	}
    255 
    256 	if (!b)
    257 		goto fail;
    258 
    259 	res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
    260 	if (res < 0)
    261 		goto fail;
    262 
    263 	/* There were no fatal errors in calculations, so determine the return
    264 	 * value using constant time operations. We get here for number of
    265 	 * invalid cases which are cleared here after having performed all the
    266 	 * computation. PWE is valid if pwd-value was less than prime and
    267 	 * PWE > 1. Start with pwd-value check first and then use constant time
    268 	 * operations to clear res to 0 if PWE is 0 or 1.
    269 	 */
    270 	res = const_time_select_u8(pwd_value_valid, 1, 0);
    271 	is_val = crypto_bignum_is_zero(pwe);
    272 	res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
    273 	is_val = crypto_bignum_is_one(pwe);
    274 	res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
    275 
    276 fail:
    277 	crypto_bignum_deinit(a, 1);
    278 	crypto_bignum_deinit(b, 1);
    279 	return res;
    280 }
    281 
    282 
    283 static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
    284 			      const u8 *addr2, const u8 *password,
    285 			      size_t password_len)
    286 {
    287 	u8 counter, k;
    288 	u8 addrs[2 * ETH_ALEN];
    289 	const u8 *addr[2];
    290 	size_t len[2];
    291 	u8 *stub_password, *tmp_password;
    292 	int pwd_seed_odd = 0;
    293 	u8 prime[SAE_MAX_ECC_PRIME_LEN];
    294 	size_t prime_len;
    295 	struct crypto_bignum *x = NULL, *y = NULL, *qr = NULL, *qnr = NULL;
    296 	u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
    297 	u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
    298 	u8 qr_bin[SAE_MAX_ECC_PRIME_LEN];
    299 	u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN];
    300 	u8 x_y[2 * SAE_MAX_ECC_PRIME_LEN];
    301 	int res = -1;
    302 	u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
    303 		       * mask */
    304 	unsigned int is_eq;
    305 
    306 	os_memset(x_bin, 0, sizeof(x_bin));
    307 
    308 	stub_password = os_malloc(password_len);
    309 	tmp_password = os_malloc(password_len);
    310 	if (!stub_password || !tmp_password ||
    311 	    random_get_bytes(stub_password, password_len) < 0)
    312 		goto fail;
    313 
    314 	prime_len = sae->tmp->prime_len;
    315 	if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
    316 				 prime_len) < 0)
    317 		goto fail;
    318 
    319 	/*
    320 	 * Create a random quadratic residue (qr) and quadratic non-residue
    321 	 * (qnr) modulo p for blinding purposes during the loop.
    322 	 */
    323 	if (dragonfly_get_random_qr_qnr(sae->tmp->prime, &qr, &qnr) < 0 ||
    324 	    crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), prime_len) < 0 ||
    325 	    crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin), prime_len) < 0)
    326 		goto fail;
    327 
    328 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
    329 			      password, password_len);
    330 
    331 	/*
    332 	 * H(salt, ikm) = HMAC-SHA256(salt, ikm)
    333 	 * base = password
    334 	 * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
    335 	 *              base || counter)
    336 	 */
    337 	sae_pwd_seed_key(addr1, addr2, addrs);
    338 
    339 	addr[0] = tmp_password;
    340 	len[0] = password_len;
    341 	addr[1] = &counter;
    342 	len[1] = sizeof(counter);
    343 
    344 	/*
    345 	 * Continue for at least k iterations to protect against side-channel
    346 	 * attacks that attempt to determine the number of iterations required
    347 	 * in the loop.
    348 	 */
    349 	k = dragonfly_min_pwe_loop_iter(sae->group);
    350 
    351 	for (counter = 1; counter <= k || !found; counter++) {
    352 		u8 pwd_seed[SHA256_MAC_LEN];
    353 
    354 		if (counter > 200) {
    355 			/* This should not happen in practice */
    356 			wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE");
    357 			break;
    358 		}
    359 
    360 		wpa_printf(MSG_DEBUG, "SAE: counter = %03u", counter);
    361 		const_time_select_bin(found, stub_password, password,
    362 				      password_len, tmp_password);
    363 		if (hmac_sha256_vector(addrs, sizeof(addrs), 2,
    364 				       addr, len, pwd_seed) < 0)
    365 			break;
    366 
    367 		res = sae_test_pwd_seed_ecc(sae, pwd_seed,
    368 					    prime, qr_bin, qnr_bin, x_cand_bin);
    369 		const_time_select_bin(found, x_bin, x_cand_bin, prime_len,
    370 				      x_bin);
    371 		pwd_seed_odd = const_time_select_u8(
    372 			found, pwd_seed_odd,
    373 			pwd_seed[SHA256_MAC_LEN - 1] & 0x01);
    374 		os_memset(pwd_seed, 0, sizeof(pwd_seed));
    375 		if (res < 0)
    376 			goto fail;
    377 		/* Need to minimize differences in handling res == 0 and 1 here
    378 		 * to avoid differences in timing and instruction cache access,
    379 		 * so use const_time_select_*() to make local copies of the
    380 		 * values based on whether this loop iteration was the one that
    381 		 * found the pwd-seed/x. */
    382 
    383 		/* found is 0 or 0xff here and res is 0 or 1. Bitwise OR of them
    384 		 * (with res converted to 0/0xff) handles this in constant time.
    385 		 */
    386 		found |= res * 0xff;
    387 		wpa_printf(MSG_DEBUG, "SAE: pwd-seed result %d found=0x%02x",
    388 			   res, found);
    389 	}
    390 
    391 	if (!found) {
    392 		wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
    393 		res = -1;
    394 		goto fail;
    395 	}
    396 
    397 	x = crypto_bignum_init_set(x_bin, prime_len);
    398 	if (!x) {
    399 		res = -1;
    400 		goto fail;
    401 	}
    402 
    403 	/* y = sqrt(x^3 + ax + b) mod p
    404 	 * if LSB(save) == LSB(y): PWE = (x, y)
    405 	 * else: PWE = (x, p - y)
    406 	 *
    407 	 * Calculate y and the two possible values for PWE and after that,
    408 	 * use constant time selection to copy the correct alternative.
    409 	 */
    410 	y = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x);
    411 	if (!y ||
    412 	    dragonfly_sqrt(sae->tmp->ec, y, y) < 0 ||
    413 	    crypto_bignum_to_bin(y, x_y, SAE_MAX_ECC_PRIME_LEN,
    414 				 prime_len) < 0 ||
    415 	    crypto_bignum_sub(sae->tmp->prime, y, y) < 0 ||
    416 	    crypto_bignum_to_bin(y, x_y + SAE_MAX_ECC_PRIME_LEN,
    417 				 SAE_MAX_ECC_PRIME_LEN, prime_len) < 0) {
    418 		wpa_printf(MSG_DEBUG, "SAE: Could not solve y");
    419 		goto fail;
    420 	}
    421 
    422 	is_eq = const_time_eq(pwd_seed_odd, x_y[prime_len - 1] & 0x01);
    423 	const_time_select_bin(is_eq, x_y, x_y + SAE_MAX_ECC_PRIME_LEN,
    424 			      prime_len, x_y + prime_len);
    425 	os_memcpy(x_y, x_bin, prime_len);
    426 	wpa_hexdump_key(MSG_DEBUG, "SAE: PWE", x_y, 2 * prime_len);
    427 	crypto_ec_point_deinit(sae->tmp->pwe_ecc, 1);
    428 	sae->tmp->pwe_ecc = crypto_ec_point_from_bin(sae->tmp->ec, x_y);
    429 	if (!sae->tmp->pwe_ecc) {
    430 		wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
    431 		res = -1;
    432 	}
    433 
    434 fail:
    435 	forced_memzero(x_y, sizeof(x_y));
    436 	crypto_bignum_deinit(qr, 0);
    437 	crypto_bignum_deinit(qnr, 0);
    438 	crypto_bignum_deinit(y, 1);
    439 	os_free(stub_password);
    440 	bin_clear_free(tmp_password, password_len);
    441 	crypto_bignum_deinit(x, 1);
    442 	os_memset(x_bin, 0, sizeof(x_bin));
    443 	os_memset(x_cand_bin, 0, sizeof(x_cand_bin));
    444 
    445 	return res;
    446 }
    447 
    448 
    449 static int sae_modp_group_require_masking(int group)
    450 {
    451 	/* Groups for which pwd-value is likely to be >= p frequently */
    452 	return group == 22 || group == 23 || group == 24;
    453 }
    454 
    455 
    456 static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
    457 			      const u8 *addr2, const u8 *password,
    458 			      size_t password_len)
    459 {
    460 	u8 counter, k, sel_counter = 0;
    461 	u8 addrs[2 * ETH_ALEN];
    462 	const u8 *addr[2];
    463 	size_t len[2];
    464 	u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
    465 		       * mask */
    466 	u8 mask;
    467 	struct crypto_bignum *pwe;
    468 	size_t prime_len = sae->tmp->prime_len;
    469 	u8 *pwe_buf;
    470 
    471 	crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
    472 	sae->tmp->pwe_ffc = NULL;
    473 
    474 	/* Allocate a buffer to maintain selected and candidate PWE for constant
    475 	 * time selection. */
    476 	pwe_buf = os_zalloc(prime_len * 2);
    477 	pwe = crypto_bignum_init();
    478 	if (!pwe_buf || !pwe)
    479 		goto fail;
    480 
    481 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
    482 			      password, password_len);
    483 
    484 	/*
    485 	 * H(salt, ikm) = HMAC-SHA256(salt, ikm)
    486 	 * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
    487 	 *              password || counter)
    488 	 */
    489 	sae_pwd_seed_key(addr1, addr2, addrs);
    490 
    491 	addr[0] = password;
    492 	len[0] = password_len;
    493 	addr[1] = &counter;
    494 	len[1] = sizeof(counter);
    495 
    496 	k = dragonfly_min_pwe_loop_iter(sae->group);
    497 
    498 	for (counter = 1; counter <= k || !found; counter++) {
    499 		u8 pwd_seed[SHA256_MAC_LEN];
    500 		int res;
    501 
    502 		if (counter > 200) {
    503 			/* This should not happen in practice */
    504 			wpa_printf(MSG_DEBUG, "SAE: Failed to derive PWE");
    505 			break;
    506 		}
    507 
    508 		wpa_printf(MSG_DEBUG, "SAE: counter = %02u", counter);
    509 		if (hmac_sha256_vector(addrs, sizeof(addrs), 2,
    510 				       addr, len, pwd_seed) < 0)
    511 			break;
    512 		res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
    513 		/* res is -1 for fatal failure, 0 if a valid PWE was not found,
    514 		 * or 1 if a valid PWE was found. */
    515 		if (res < 0)
    516 			break;
    517 		/* Store the candidate PWE into the second half of pwe_buf and
    518 		 * the selected PWE in the beginning of pwe_buf using constant
    519 		 * time selection. */
    520 		if (crypto_bignum_to_bin(pwe, pwe_buf + prime_len, prime_len,
    521 					 prime_len) < 0)
    522 			break;
    523 		const_time_select_bin(found, pwe_buf, pwe_buf + prime_len,
    524 				      prime_len, pwe_buf);
    525 		sel_counter = const_time_select_u8(found, sel_counter, counter);
    526 		mask = const_time_eq_u8(res, 1);
    527 		found = const_time_select_u8(found, found, mask);
    528 	}
    529 
    530 	if (!found)
    531 		goto fail;
    532 
    533 	wpa_printf(MSG_DEBUG, "SAE: Use PWE from counter = %02u", sel_counter);
    534 	sae->tmp->pwe_ffc = crypto_bignum_init_set(pwe_buf, prime_len);
    535 fail:
    536 	crypto_bignum_deinit(pwe, 1);
    537 	bin_clear_free(pwe_buf, prime_len * 2);
    538 	return sae->tmp->pwe_ffc ? 0 : -1;
    539 }
    540 
    541 
    542 static int hkdf_extract(size_t hash_len, const u8 *salt, size_t salt_len,
    543 			size_t num_elem, const u8 *addr[], const size_t len[],
    544 			u8 *prk)
    545 {
    546 	if (hash_len == 32)
    547 		return hmac_sha256_vector(salt, salt_len, num_elem, addr, len,
    548 					  prk);
    549 #ifdef CONFIG_SHA384
    550 	if (hash_len == 48)
    551 		return hmac_sha384_vector(salt, salt_len, num_elem, addr, len,
    552 					  prk);
    553 #endif /* CONFIG_SHA384 */
    554 #ifdef CONFIG_SHA512
    555 	if (hash_len == 64)
    556 		return hmac_sha512_vector(salt, salt_len, num_elem, addr, len,
    557 					  prk);
    558 #endif /* CONFIG_SHA512 */
    559 	return -1;
    560 }
    561 
    562 
    563 static int hkdf_expand(size_t hash_len, const u8 *prk, size_t prk_len,
    564 		       const char *info, u8 *okm, size_t okm_len)
    565 {
    566 	size_t info_len = os_strlen(info);
    567 
    568 	if (hash_len == 32)
    569 		return hmac_sha256_kdf(prk, prk_len, NULL,
    570 				       (const u8 *) info, info_len,
    571 				       okm, okm_len);
    572 #ifdef CONFIG_SHA384
    573 	if (hash_len == 48)
    574 		return hmac_sha384_kdf(prk, prk_len, NULL,
    575 				       (const u8 *) info, info_len,
    576 				       okm, okm_len);
    577 #endif /* CONFIG_SHA384 */
    578 #ifdef CONFIG_SHA512
    579 	if (hash_len == 64)
    580 		return hmac_sha512_kdf(prk, prk_len, NULL,
    581 				       (const u8 *) info, info_len,
    582 				       okm, okm_len);
    583 #endif /* CONFIG_SHA512 */
    584 	return -1;
    585 }
    586 
    587 
    588 static int sswu_curve_param(int group, int *z)
    589 {
    590 	switch (group) {
    591 	case 19:
    592 		*z = -10;
    593 		return 0;
    594 	case 20:
    595 		*z = -12;
    596 		return 0;
    597 	case 21:
    598 		*z = -4;
    599 		return 0;
    600 	case 25:
    601 	case 29:
    602 		*z = -5;
    603 		return 0;
    604 	case 26:
    605 		*z = 31;
    606 		return 0;
    607 	case 28:
    608 		*z = -2;
    609 		return 0;
    610 	case 30:
    611 		*z = 7;
    612 		return 0;
    613 	default:
    614 		return -1;
    615 	}
    616 }
    617 
    618 
    619 static void debug_print_bignum(const char *title, const struct crypto_bignum *a,
    620 			       size_t prime_len)
    621 {
    622 	u8 *bin;
    623 
    624 	bin = os_malloc(prime_len);
    625 	if (bin && crypto_bignum_to_bin(a, bin, prime_len, prime_len) >= 0)
    626 		wpa_hexdump_key(MSG_DEBUG, title, bin, prime_len);
    627 	else
    628 		wpa_printf(MSG_DEBUG, "Could not print bignum (%s)", title);
    629 	bin_clear_free(bin, prime_len);
    630 }
    631 
    632 
    633 static struct crypto_ec_point * sswu(struct crypto_ec *ec, int group,
    634 				     const struct crypto_bignum *u)
    635 {
    636 	int z_int;
    637 	const struct crypto_bignum *a, *b, *prime;
    638 	struct crypto_bignum *u2, *t1, *t2, *z, *t, *zero, *one, *two, *three,
    639 		*x1a, *x1b, *y = NULL;
    640 	struct crypto_bignum *x1 = NULL, *x2, *gx1, *gx2, *v = NULL;
    641 	unsigned int m_is_zero, is_qr, is_eq;
    642 	size_t prime_len;
    643 	u8 bin[SAE_MAX_ECC_PRIME_LEN];
    644 	u8 bin1[SAE_MAX_ECC_PRIME_LEN];
    645 	u8 bin2[SAE_MAX_ECC_PRIME_LEN];
    646 	u8 x_y[2 * SAE_MAX_ECC_PRIME_LEN];
    647 	struct crypto_ec_point *p = NULL;
    648 
    649 	if (sswu_curve_param(group, &z_int) < 0)
    650 		return NULL;
    651 
    652 	prime = crypto_ec_get_prime(ec);
    653 	prime_len = crypto_ec_prime_len(ec);
    654 	a = crypto_ec_get_a(ec);
    655 	b = crypto_ec_get_b(ec);
    656 
    657 	u2 = crypto_bignum_init();
    658 	t1 = crypto_bignum_init();
    659 	t2 = crypto_bignum_init();
    660 	z = crypto_bignum_init_uint(abs(z_int));
    661 	t = crypto_bignum_init();
    662 	zero = crypto_bignum_init_uint(0);
    663 	one = crypto_bignum_init_uint(1);
    664 	two = crypto_bignum_init_uint(2);
    665 	three = crypto_bignum_init_uint(3);
    666 	x1a = crypto_bignum_init();
    667 	x1b = crypto_bignum_init();
    668 	x2 = crypto_bignum_init();
    669 	gx1 = crypto_bignum_init();
    670 	gx2 = crypto_bignum_init();
    671 	if (!u2 || !t1 || !t2 || !z || !t || !zero || !one || !two || !three ||
    672 	    !x1a || !x1b || !x2 || !gx1 || !gx2)
    673 		goto fail;
    674 
    675 	if (z_int < 0 && crypto_bignum_sub(prime, z, z) < 0)
    676 		goto fail;
    677 
    678 	/* m = z^2 * u^4 + z * u^2 */
    679 	/* --> tmp = z * u^2, m = tmp^2 + tmp */
    680 
    681 	/* u2 = u^2
    682 	 * t1 = z * u2
    683 	 * t2 = t1^2
    684 	 * m = t1 = t1 + t2 */
    685 	if (crypto_bignum_sqrmod(u, prime, u2) < 0 ||
    686 	    crypto_bignum_mulmod(z, u2, prime, t1) < 0 ||
    687 	    crypto_bignum_sqrmod(t1, prime, t2) < 0 ||
    688 	    crypto_bignum_addmod(t1, t2, prime, t1) < 0)
    689 		goto fail;
    690 	debug_print_bignum("SSWU: m", t1, prime_len);
    691 
    692 	/* l = CEQ(m, 0)
    693 	 * t = CSEL(l, 0, inverse(m); where inverse(x) is calculated as
    694 	 * x^(p-2) modulo p which will handle m == 0 case correctly */
    695 	/* TODO: Make sure crypto_bignum_is_zero() is constant time */
    696 	m_is_zero = const_time_eq(crypto_bignum_is_zero(t1), 1);
    697 	/* t = m^(p-2) modulo p */
    698 	if (crypto_bignum_sub(prime, two, t2) < 0 ||
    699 	    crypto_bignum_exptmod(t1, t2, prime, t) < 0)
    700 		goto fail;
    701 	debug_print_bignum("SSWU: t", t, prime_len);
    702 
    703 	/* b / (z * a) */
    704 	if (crypto_bignum_mulmod(z, a, prime, t1) < 0 ||
    705 	    crypto_bignum_inverse(t1, prime, t1) < 0 ||
    706 	    crypto_bignum_mulmod(b, t1, prime, x1a) < 0)
    707 		goto fail;
    708 	debug_print_bignum("SSWU: x1a = b / (z * a)", x1a, prime_len);
    709 
    710 	/* (-b/a) * (1 + t) */
    711 	if (crypto_bignum_sub(prime, b, t1) < 0 ||
    712 	    crypto_bignum_inverse(a, prime, t2) < 0 ||
    713 	    crypto_bignum_mulmod(t1, t2, prime, t1) < 0 ||
    714 	    crypto_bignum_addmod(one, t, prime, t2) < 0 ||
    715 	    crypto_bignum_mulmod(t1, t2, prime, x1b) < 0)
    716 		goto fail;
    717 	debug_print_bignum("SSWU: x1b = (-b/a) * (1 + t)", x1b, prime_len);
    718 
    719 	/* x1 = CSEL(CEQ(m, 0), x1a, x1b) */
    720 	if (crypto_bignum_to_bin(x1a, bin1, sizeof(bin1), prime_len) < 0 ||
    721 	    crypto_bignum_to_bin(x1b, bin2, sizeof(bin2), prime_len) < 0)
    722 		goto fail;
    723 	const_time_select_bin(m_is_zero, bin1, bin2, prime_len, bin);
    724 	x1 = crypto_bignum_init_set(bin, prime_len);
    725 	if (!x1)
    726 		goto fail;
    727 	debug_print_bignum("SSWU: x1 = CSEL(l, x1a, x1b)", x1, prime_len);
    728 
    729 	/* gx1 = x1^3 + a * x1 + b */
    730 	if (crypto_bignum_exptmod(x1, three, prime, t1) < 0 ||
    731 	    crypto_bignum_mulmod(a, x1, prime, t2) < 0 ||
    732 	    crypto_bignum_addmod(t1, t2, prime, t1) < 0 ||
    733 	    crypto_bignum_addmod(t1, b, prime, gx1) < 0)
    734 		goto fail;
    735 	debug_print_bignum("SSWU: gx1 = x1^3 + a * x1 + b", gx1, prime_len);
    736 
    737 	/* x2 = z * u^2 * x1 */
    738 	if (crypto_bignum_mulmod(z, u2, prime, t1) < 0 ||
    739 	    crypto_bignum_mulmod(t1, x1, prime, x2) < 0)
    740 		goto fail;
    741 	debug_print_bignum("SSWU: x2 = z * u^2 * x1", x2, prime_len);
    742 
    743 	/* gx2 = x2^3 + a * x2 + b */
    744 	if (crypto_bignum_exptmod(x2, three, prime, t1) < 0 ||
    745 	    crypto_bignum_mulmod(a, x2, prime, t2) < 0 ||
    746 	    crypto_bignum_addmod(t1, t2, prime, t1) < 0 ||
    747 	    crypto_bignum_addmod(t1, b, prime, gx2) < 0)
    748 		goto fail;
    749 	debug_print_bignum("SSWU: gx2 = x2^3 + a * x2 + b", gx2, prime_len);
    750 
    751 	/* l = gx1 is a quadratic residue modulo p
    752 	 * --> gx1^((p-1)/2) modulo p is zero or one */
    753 	if (crypto_bignum_sub(prime, one, t1) < 0 ||
    754 	    crypto_bignum_rshift(t1, 1, t1) < 0 ||
    755 	    crypto_bignum_exptmod(gx1, t1, prime, t1) < 0)
    756 		goto fail;
    757 	debug_print_bignum("SSWU: gx1^((p-1)/2) modulo p", t1, prime_len);
    758 	is_qr = const_time_eq(crypto_bignum_is_zero(t1) |
    759 			      crypto_bignum_is_one(t1), 1);
    760 
    761 	/* v = CSEL(l, gx1, gx2) */
    762 	if (crypto_bignum_to_bin(gx1, bin1, sizeof(bin1), prime_len) < 0 ||
    763 	    crypto_bignum_to_bin(gx2, bin2, sizeof(bin2), prime_len) < 0)
    764 		goto fail;
    765 	const_time_select_bin(is_qr, bin1, bin2, prime_len, bin);
    766 	v = crypto_bignum_init_set(bin, prime_len);
    767 	if (!v)
    768 		goto fail;
    769 	debug_print_bignum("SSWU: v = CSEL(l, gx1, gx2)", v, prime_len);
    770 
    771 	/* x = CSEL(l, x1, x2) */
    772 	if (crypto_bignum_to_bin(x1, bin1, sizeof(bin1), prime_len) < 0 ||
    773 	    crypto_bignum_to_bin(x2, bin2, sizeof(bin2), prime_len) < 0)
    774 		goto fail;
    775 	const_time_select_bin(is_qr, bin1, bin2, prime_len, x_y);
    776 	wpa_hexdump_key(MSG_DEBUG, "SSWU: x = CSEL(l, x1, x2)", x_y, prime_len);
    777 
    778 	/* y = sqrt(v) */
    779 	y = crypto_bignum_init();
    780 	if (!y || dragonfly_sqrt(ec, v, y) < 0)
    781 		goto fail;
    782 	debug_print_bignum("SSWU: y = sqrt(v)", y, prime_len);
    783 
    784 	/* l = CEQ(LSB(u), LSB(y)) */
    785 	if (crypto_bignum_to_bin(u, bin1, sizeof(bin1), prime_len) < 0 ||
    786 	    crypto_bignum_to_bin(y, bin2, sizeof(bin2), prime_len) < 0)
    787 		goto fail;
    788 	is_eq = const_time_eq(bin1[prime_len - 1] & 0x01,
    789 			      bin2[prime_len - 1] & 0x01);
    790 
    791 	/* P = CSEL(l, (x,y), (x, p-y)) */
    792 	if (crypto_bignum_sub(prime, y, t1) < 0)
    793 		goto fail;
    794 	debug_print_bignum("SSWU: p - y", t1, prime_len);
    795 	if (crypto_bignum_to_bin(y, bin1, sizeof(bin1), prime_len) < 0 ||
    796 	    crypto_bignum_to_bin(t1, bin2, sizeof(bin2), prime_len) < 0)
    797 		goto fail;
    798 	const_time_select_bin(is_eq, bin1, bin2, prime_len, &x_y[prime_len]);
    799 
    800 	/* output P */
    801 	wpa_hexdump_key(MSG_DEBUG, "SSWU: P.x", x_y, prime_len);
    802 	wpa_hexdump_key(MSG_DEBUG, "SSWU: P.y", &x_y[prime_len], prime_len);
    803 	p = crypto_ec_point_from_bin(ec, x_y);
    804 
    805 fail:
    806 	crypto_bignum_deinit(u2, 1);
    807 	crypto_bignum_deinit(t1, 1);
    808 	crypto_bignum_deinit(t2, 1);
    809 	crypto_bignum_deinit(z, 0);
    810 	crypto_bignum_deinit(t, 1);
    811 	crypto_bignum_deinit(x1a, 1);
    812 	crypto_bignum_deinit(x1b, 1);
    813 	crypto_bignum_deinit(x1, 1);
    814 	crypto_bignum_deinit(x2, 1);
    815 	crypto_bignum_deinit(gx1, 1);
    816 	crypto_bignum_deinit(gx2, 1);
    817 	crypto_bignum_deinit(y, 1);
    818 	crypto_bignum_deinit(v, 1);
    819 	crypto_bignum_deinit(zero, 0);
    820 	crypto_bignum_deinit(one, 0);
    821 	crypto_bignum_deinit(two, 0);
    822 	crypto_bignum_deinit(three, 0);
    823 	forced_memzero(bin, sizeof(bin));
    824 	forced_memzero(bin1, sizeof(bin1));
    825 	forced_memzero(bin2, sizeof(bin2));
    826 	forced_memzero(x_y, sizeof(x_y));
    827 	return p;
    828 }
    829 
    830 
    831 static int sae_pwd_seed(size_t hash_len, const u8 *ssid, size_t ssid_len,
    832 			const u8 *password, size_t password_len,
    833 			const char *identifier, u8 *pwd_seed)
    834 {
    835 	const u8 *addr[2];
    836 	size_t len[2];
    837 	size_t num_elem;
    838 
    839 	/* pwd-seed = HKDF-Extract(ssid, password [ || identifier ]) */
    840 	addr[0] = password;
    841 	len[0] = password_len;
    842 	num_elem = 1;
    843 	wpa_hexdump_ascii(MSG_DEBUG, "SAE: SSID", ssid, ssid_len);
    844 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
    845 			      password, password_len);
    846 	if (identifier) {
    847 		wpa_printf(MSG_DEBUG, "SAE: password identifier: %s",
    848 			   identifier);
    849 		addr[num_elem] = (const u8 *) identifier;
    850 		len[num_elem] = os_strlen(identifier);
    851 		num_elem++;
    852 	}
    853 	if (hkdf_extract(hash_len, ssid, ssid_len, num_elem, addr, len,
    854 			 pwd_seed) < 0)
    855 		return -1;
    856 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, hash_len);
    857 	return 0;
    858 }
    859 
    860 
    861 size_t sae_ecc_prime_len_2_hash_len(size_t prime_len)
    862 {
    863 	if (prime_len <= 256 / 8)
    864 		return 32;
    865 	if (prime_len <= 384 / 8)
    866 		return 48;
    867 	return 64;
    868 }
    869 
    870 
    871 static struct crypto_ec_point *
    872 sae_derive_pt_ecc(struct crypto_ec *ec, int group,
    873 		  const u8 *ssid, size_t ssid_len,
    874 		  const u8 *password, size_t password_len,
    875 		  const char *identifier)
    876 {
    877 	u8 pwd_seed[64];
    878 	u8 pwd_value[SAE_MAX_ECC_PRIME_LEN * 2];
    879 	size_t pwd_value_len, hash_len, prime_len;
    880 	const struct crypto_bignum *prime;
    881 	struct crypto_bignum *bn = NULL;
    882 	struct crypto_ec_point *p1 = NULL, *p2 = NULL, *pt = NULL;
    883 
    884 	prime = crypto_ec_get_prime(ec);
    885 	prime_len = crypto_ec_prime_len(ec);
    886 	if (prime_len > SAE_MAX_ECC_PRIME_LEN)
    887 		goto fail;
    888 	hash_len = sae_ecc_prime_len_2_hash_len(prime_len);
    889 
    890 	/* len = olen(p) + ceil(olen(p)/2) */
    891 	pwd_value_len = prime_len + (prime_len + 1) / 2;
    892 
    893 	if (sae_pwd_seed(hash_len, ssid, ssid_len, password, password_len,
    894 			 identifier, pwd_seed) < 0)
    895 		goto fail;
    896 
    897 	/* pwd-value = HKDF-Expand(pwd-seed, "SAE Hash to Element u1 P1", len)
    898 	 */
    899 	if (hkdf_expand(hash_len, pwd_seed, hash_len,
    900 			"SAE Hash to Element u1 P1", pwd_value, pwd_value_len) <
    901 	    0)
    902 		goto fail;
    903 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value (u1 P1)",
    904 			pwd_value, pwd_value_len);
    905 
    906 	/* u1 = pwd-value modulo p */
    907 	bn = crypto_bignum_init_set(pwd_value, pwd_value_len);
    908 	if (!bn || crypto_bignum_mod(bn, prime, bn) < 0 ||
    909 	    crypto_bignum_to_bin(bn, pwd_value, sizeof(pwd_value),
    910 				 prime_len) < 0)
    911 		goto fail;
    912 	wpa_hexdump_key(MSG_DEBUG, "SAE: u1", pwd_value, prime_len);
    913 
    914 	/* P1 = SSWU(u1) */
    915 	p1 = sswu(ec, group, bn);
    916 	if (!p1)
    917 		goto fail;
    918 
    919 	/* pwd-value = HKDF-Expand(pwd-seed, "SAE Hash to Element u2 P2", len)
    920 	 */
    921 	if (hkdf_expand(hash_len, pwd_seed, hash_len,
    922 			"SAE Hash to Element u2 P2", pwd_value,
    923 			pwd_value_len) < 0)
    924 		goto fail;
    925 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value (u2 P2)",
    926 			pwd_value, pwd_value_len);
    927 
    928 	/* u2 = pwd-value modulo p */
    929 	crypto_bignum_deinit(bn, 1);
    930 	bn = crypto_bignum_init_set(pwd_value, pwd_value_len);
    931 	if (!bn || crypto_bignum_mod(bn, prime, bn) < 0 ||
    932 	    crypto_bignum_to_bin(bn, pwd_value, sizeof(pwd_value),
    933 				 prime_len) < 0)
    934 		goto fail;
    935 	wpa_hexdump_key(MSG_DEBUG, "SAE: u2", pwd_value, prime_len);
    936 
    937 	/* P2 = SSWU(u2) */
    938 	p2 = sswu(ec, group, bn);
    939 	if (!p2)
    940 		goto fail;
    941 
    942 	/* PT = elem-op(P1, P2) */
    943 	pt = crypto_ec_point_init(ec);
    944 	if (!pt)
    945 		goto fail;
    946 	if (crypto_ec_point_add(ec, p1, p2, pt) < 0) {
    947 		crypto_ec_point_deinit(pt, 1);
    948 		pt = NULL;
    949 	}
    950 
    951 fail:
    952 	forced_memzero(pwd_seed, sizeof(pwd_seed));
    953 	forced_memzero(pwd_value, sizeof(pwd_value));
    954 	crypto_bignum_deinit(bn, 1);
    955 	crypto_ec_point_deinit(p1, 1);
    956 	crypto_ec_point_deinit(p2, 1);
    957 	return pt;
    958 }
    959 
    960 
    961 size_t sae_ffc_prime_len_2_hash_len(size_t prime_len)
    962 {
    963 	if (prime_len <= 2048 / 8)
    964 		return 32;
    965 	if (prime_len <= 3072 / 8)
    966 		return 48;
    967 	return 64;
    968 }
    969 
    970 
    971 static struct crypto_bignum *
    972 sae_derive_pt_ffc(const struct dh_group *dh, int group,
    973 		  const u8 *ssid, size_t ssid_len,
    974 		  const u8 *password, size_t password_len,
    975 		  const char *identifier)
    976 {
    977 	size_t hash_len, prime_len, pwd_value_len;
    978 	struct crypto_bignum *prime, *order;
    979 	struct crypto_bignum *one = NULL, *two = NULL, *bn = NULL, *tmp = NULL,
    980 		*pt = NULL;
    981 	u8 pwd_seed[64];
    982 	u8 pwd_value[SAE_MAX_PRIME_LEN + SAE_MAX_PRIME_LEN / 2];
    983 
    984 	prime = crypto_bignum_init_set(dh->prime, dh->prime_len);
    985 	order = crypto_bignum_init_set(dh->order, dh->order_len);
    986 	if (!prime || !order)
    987 		goto fail;
    988 	prime_len = dh->prime_len;
    989 	if (prime_len > SAE_MAX_PRIME_LEN)
    990 		goto fail;
    991 	hash_len = sae_ffc_prime_len_2_hash_len(prime_len);
    992 
    993 	/* len = olen(p) + ceil(olen(p)/2) */
    994 	pwd_value_len = prime_len + (prime_len + 1) / 2;
    995 	if (pwd_value_len > sizeof(pwd_value))
    996 		goto fail;
    997 
    998 	if (sae_pwd_seed(hash_len, ssid, ssid_len, password, password_len,
    999 			 identifier, pwd_seed) < 0)
   1000 		goto fail;
   1001 
   1002 	/* pwd-value = HKDF-Expand(pwd-seed, "SAE Hash to Element", len) */
   1003 	if (hkdf_expand(hash_len, pwd_seed, hash_len,
   1004 			"SAE Hash to Element", pwd_value, pwd_value_len) < 0)
   1005 		goto fail;
   1006 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
   1007 			pwd_value, pwd_value_len);
   1008 
   1009 	/* pwd-value = (pwd-value modulo (p-2)) + 2 */
   1010 	bn = crypto_bignum_init_set(pwd_value, pwd_value_len);
   1011 	one = crypto_bignum_init_uint(1);
   1012 	two = crypto_bignum_init_uint(2);
   1013 	tmp = crypto_bignum_init();
   1014 	if (!bn || !one || !two || !tmp ||
   1015 	    crypto_bignum_sub(prime, two, tmp) < 0 ||
   1016 	    crypto_bignum_mod(bn, tmp, bn) < 0 ||
   1017 	    crypto_bignum_add(bn, two, bn) < 0 ||
   1018 	    crypto_bignum_to_bin(bn, pwd_value, sizeof(pwd_value),
   1019 				 prime_len) < 0)
   1020 		goto fail;
   1021 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value(reduced)",
   1022 			pwd_value, prime_len);
   1023 
   1024 	/* PT = pwd-value^((p-1)/q) modulo p */
   1025 	pt = crypto_bignum_init();
   1026 	if (!pt ||
   1027 	    crypto_bignum_sub(prime, one, tmp) < 0 ||
   1028 	    crypto_bignum_div(tmp, order, tmp) < 0 ||
   1029 	    crypto_bignum_exptmod(bn, tmp, prime, pt) < 0) {
   1030 		crypto_bignum_deinit(pt, 1);
   1031 		pt = NULL;
   1032 		goto fail;
   1033 	}
   1034 	debug_print_bignum("SAE: PT", pt, prime_len);
   1035 
   1036 fail:
   1037 	forced_memzero(pwd_seed, sizeof(pwd_seed));
   1038 	forced_memzero(pwd_value, sizeof(pwd_value));
   1039 	crypto_bignum_deinit(bn, 1);
   1040 	crypto_bignum_deinit(tmp, 1);
   1041 	crypto_bignum_deinit(one, 0);
   1042 	crypto_bignum_deinit(two, 0);
   1043 	crypto_bignum_deinit(prime, 0);
   1044 	crypto_bignum_deinit(order, 0);
   1045 	return pt;
   1046 }
   1047 
   1048 
   1049 static struct sae_pt *
   1050 sae_derive_pt_group(int group, const u8 *ssid, size_t ssid_len,
   1051 		    const u8 *password, size_t password_len,
   1052 		    const char *identifier)
   1053 {
   1054 	struct sae_pt *pt;
   1055 
   1056 	wpa_printf(MSG_DEBUG, "SAE: Derive PT - group %d", group);
   1057 
   1058 	if (ssid_len > 32)
   1059 		return NULL;
   1060 
   1061 	pt = os_zalloc(sizeof(*pt));
   1062 	if (!pt)
   1063 		return NULL;
   1064 
   1065 #ifdef CONFIG_SAE_PK
   1066 	os_memcpy(pt->ssid, ssid, ssid_len);
   1067 	pt->ssid_len = ssid_len;
   1068 #endif /* CONFIG_SAE_PK */
   1069 	pt->group = group;
   1070 	pt->ec = crypto_ec_init(group);
   1071 	if (pt->ec) {
   1072 		pt->ecc_pt = sae_derive_pt_ecc(pt->ec, group, ssid, ssid_len,
   1073 					       password, password_len,
   1074 					       identifier);
   1075 		if (!pt->ecc_pt) {
   1076 			wpa_printf(MSG_DEBUG, "SAE: Failed to derive PT");
   1077 			goto fail;
   1078 		}
   1079 
   1080 		return pt;
   1081 	}
   1082 
   1083 	pt->dh = dh_groups_get(group);
   1084 	if (!pt->dh) {
   1085 		wpa_printf(MSG_DEBUG, "SAE: Unsupported group %d", group);
   1086 		goto fail;
   1087 	}
   1088 
   1089 	pt->ffc_pt = sae_derive_pt_ffc(pt->dh, group, ssid, ssid_len,
   1090 				       password, password_len, identifier);
   1091 	if (!pt->ffc_pt) {
   1092 		wpa_printf(MSG_DEBUG, "SAE: Failed to derive PT");
   1093 		goto fail;
   1094 	}
   1095 
   1096 	return pt;
   1097 fail:
   1098 	sae_deinit_pt(pt);
   1099 	return NULL;
   1100 }
   1101 
   1102 
   1103 struct sae_pt * sae_derive_pt(int *groups, const u8 *ssid, size_t ssid_len,
   1104 			      const u8 *password, size_t password_len,
   1105 			      const char *identifier)
   1106 {
   1107 	struct sae_pt *pt = NULL, *last = NULL, *tmp;
   1108 	int default_groups[] = { 19, 0 };
   1109 	int i;
   1110 
   1111 	if (!groups)
   1112 		groups = default_groups;
   1113 	for (i = 0; groups[i] > 0; i++) {
   1114 		tmp = sae_derive_pt_group(groups[i], ssid, ssid_len, password,
   1115 					  password_len, identifier);
   1116 		if (!tmp)
   1117 			continue;
   1118 
   1119 		if (last)
   1120 			last->next = tmp;
   1121 		else
   1122 			pt = tmp;
   1123 		last = tmp;
   1124 	}
   1125 
   1126 	return pt;
   1127 }
   1128 
   1129 
   1130 static void sae_max_min_addr(const u8 *addr[], size_t len[],
   1131 			     const u8 *addr1, const u8 *addr2)
   1132 {
   1133 	len[0] = ETH_ALEN;
   1134 	len[1] = ETH_ALEN;
   1135 	if (os_memcmp(addr1, addr2, ETH_ALEN) > 0) {
   1136 		addr[0] = addr1;
   1137 		addr[1] = addr2;
   1138 	} else {
   1139 		addr[0] = addr2;
   1140 		addr[1] = addr1;
   1141 	}
   1142 }
   1143 
   1144 
   1145 struct crypto_ec_point *
   1146 sae_derive_pwe_from_pt_ecc(const struct sae_pt *pt,
   1147 			   const u8 *addr1, const u8 *addr2)
   1148 {
   1149 	u8 bin[SAE_MAX_ECC_PRIME_LEN * 2];
   1150 	size_t prime_len;
   1151 	const u8 *addr[2];
   1152 	size_t len[2];
   1153 	u8 salt[64], hash[64];
   1154 	size_t hash_len;
   1155 	const struct crypto_bignum *order;
   1156 	struct crypto_bignum *tmp = NULL, *val = NULL, *one = NULL;
   1157 	struct crypto_ec_point *pwe = NULL;
   1158 
   1159 	wpa_printf(MSG_DEBUG, "SAE: Derive PWE from PT");
   1160 	prime_len = crypto_ec_prime_len(pt->ec);
   1161 	if (crypto_ec_point_to_bin(pt->ec, pt->ecc_pt,
   1162 				   bin, bin + prime_len) < 0)
   1163 		return NULL;
   1164 	wpa_hexdump_key(MSG_DEBUG, "SAE: PT.x", bin, prime_len);
   1165 	wpa_hexdump_key(MSG_DEBUG, "SAE: PT.y", bin + prime_len, prime_len);
   1166 
   1167 	sae_max_min_addr(addr, len, addr1, addr2);
   1168 
   1169 	/* val = H(0^n,
   1170 	 *         MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC)) */
   1171 	wpa_printf(MSG_DEBUG, "SAE: val = H(0^n, MAX(addrs) || MIN(addrs))");
   1172 	hash_len = sae_ecc_prime_len_2_hash_len(prime_len);
   1173 	os_memset(salt, 0, hash_len);
   1174 	if (hkdf_extract(hash_len, salt, hash_len, 2, addr, len, hash) < 0)
   1175 		goto fail;
   1176 	wpa_hexdump(MSG_DEBUG, "SAE: val", hash, hash_len);
   1177 
   1178 	/* val = val modulo (q - 1) + 1 */
   1179 	order = crypto_ec_get_order(pt->ec);
   1180 	tmp = crypto_bignum_init();
   1181 	val = crypto_bignum_init_set(hash, hash_len);
   1182 	one = crypto_bignum_init_uint(1);
   1183 	if (!tmp || !val || !one ||
   1184 	    crypto_bignum_sub(order, one, tmp) < 0 ||
   1185 	    crypto_bignum_mod(val, tmp, val) < 0 ||
   1186 	    crypto_bignum_add(val, one, val) < 0)
   1187 		goto fail;
   1188 	debug_print_bignum("SAE: val(reduced to 1..q-1)", val, prime_len);
   1189 
   1190 	/* PWE = scalar-op(val, PT) */
   1191 	pwe = crypto_ec_point_init(pt->ec);
   1192 	if (!pwe ||
   1193 	    crypto_ec_point_mul(pt->ec, pt->ecc_pt, val, pwe) < 0 ||
   1194 	    crypto_ec_point_to_bin(pt->ec, pwe, bin, bin + prime_len) < 0) {
   1195 		crypto_ec_point_deinit(pwe, 1);
   1196 		pwe = NULL;
   1197 		goto fail;
   1198 	}
   1199 	wpa_hexdump_key(MSG_DEBUG, "SAE: PWE.x", bin, prime_len);
   1200 	wpa_hexdump_key(MSG_DEBUG, "SAE: PWE.y", bin + prime_len, prime_len);
   1201 
   1202 fail:
   1203 	crypto_bignum_deinit(tmp, 1);
   1204 	crypto_bignum_deinit(val, 1);
   1205 	crypto_bignum_deinit(one, 0);
   1206 	return pwe;
   1207 }
   1208 
   1209 
   1210 struct crypto_bignum *
   1211 sae_derive_pwe_from_pt_ffc(const struct sae_pt *pt,
   1212 			   const u8 *addr1, const u8 *addr2)
   1213 {
   1214 	size_t prime_len;
   1215 	const u8 *addr[2];
   1216 	size_t len[2];
   1217 	u8 salt[64], hash[64];
   1218 	size_t hash_len;
   1219 	struct crypto_bignum *tmp = NULL, *val = NULL, *one = NULL;
   1220 	struct crypto_bignum *pwe = NULL, *order = NULL, *prime = NULL;
   1221 
   1222 	wpa_printf(MSG_DEBUG, "SAE: Derive PWE from PT");
   1223 	prime = crypto_bignum_init_set(pt->dh->prime, pt->dh->prime_len);
   1224 	order = crypto_bignum_init_set(pt->dh->order, pt->dh->order_len);
   1225 	if (!prime || !order)
   1226 		goto fail;
   1227 	prime_len = pt->dh->prime_len;
   1228 
   1229 	sae_max_min_addr(addr, len, addr1, addr2);
   1230 
   1231 	/* val = H(0^n,
   1232 	 *         MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC)) */
   1233 	wpa_printf(MSG_DEBUG, "SAE: val = H(0^n, MAX(addrs) || MIN(addrs))");
   1234 	hash_len = sae_ffc_prime_len_2_hash_len(prime_len);
   1235 	os_memset(salt, 0, hash_len);
   1236 	if (hkdf_extract(hash_len, salt, hash_len, 2, addr, len, hash) < 0)
   1237 		goto fail;
   1238 	wpa_hexdump(MSG_DEBUG, "SAE: val", hash, hash_len);
   1239 
   1240 	/* val = val modulo (q - 1) + 1 */
   1241 	tmp = crypto_bignum_init();
   1242 	val = crypto_bignum_init_set(hash, hash_len);
   1243 	one = crypto_bignum_init_uint(1);
   1244 	if (!tmp || !val || !one ||
   1245 	    crypto_bignum_sub(order, one, tmp) < 0 ||
   1246 	    crypto_bignum_mod(val, tmp, val) < 0 ||
   1247 	    crypto_bignum_add(val, one, val) < 0)
   1248 		goto fail;
   1249 	debug_print_bignum("SAE: val(reduced to 1..q-1)", val, prime_len);
   1250 
   1251 	/* PWE = scalar-op(val, PT) */
   1252 	pwe = crypto_bignum_init();
   1253 	if (!pwe || crypto_bignum_exptmod(pt->ffc_pt, val, prime, pwe) < 0) {
   1254 		crypto_bignum_deinit(pwe, 1);
   1255 		pwe = NULL;
   1256 		goto fail;
   1257 	}
   1258 	debug_print_bignum("SAE: PWE", pwe, prime_len);
   1259 
   1260 fail:
   1261 	crypto_bignum_deinit(tmp, 1);
   1262 	crypto_bignum_deinit(val, 1);
   1263 	crypto_bignum_deinit(one, 0);
   1264 	crypto_bignum_deinit(prime, 0);
   1265 	crypto_bignum_deinit(order, 0);
   1266 	return pwe;
   1267 }
   1268 
   1269 
   1270 void sae_deinit_pt(struct sae_pt *pt)
   1271 {
   1272 	struct sae_pt *prev;
   1273 
   1274 	while (pt) {
   1275 		crypto_ec_point_deinit(pt->ecc_pt, 1);
   1276 		crypto_bignum_deinit(pt->ffc_pt, 1);
   1277 		crypto_ec_deinit(pt->ec);
   1278 		prev = pt;
   1279 		pt = pt->next;
   1280 		os_free(prev);
   1281 	}
   1282 }
   1283 
   1284 
   1285 static int sae_derive_commit_element_ecc(struct sae_data *sae,
   1286 					 struct crypto_bignum *mask)
   1287 {
   1288 	/* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */
   1289 	if (!sae->tmp->own_commit_element_ecc) {
   1290 		sae->tmp->own_commit_element_ecc =
   1291 			crypto_ec_point_init(sae->tmp->ec);
   1292 		if (!sae->tmp->own_commit_element_ecc)
   1293 			return -1;
   1294 	}
   1295 
   1296 	if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc, mask,
   1297 				sae->tmp->own_commit_element_ecc) < 0 ||
   1298 	    crypto_ec_point_invert(sae->tmp->ec,
   1299 				   sae->tmp->own_commit_element_ecc) < 0) {
   1300 		wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element");
   1301 		return -1;
   1302 	}
   1303 
   1304 	return 0;
   1305 }
   1306 
   1307 
   1308 static int sae_derive_commit_element_ffc(struct sae_data *sae,
   1309 					 struct crypto_bignum *mask)
   1310 {
   1311 	/* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */
   1312 	if (!sae->tmp->own_commit_element_ffc) {
   1313 		sae->tmp->own_commit_element_ffc = crypto_bignum_init();
   1314 		if (!sae->tmp->own_commit_element_ffc)
   1315 			return -1;
   1316 	}
   1317 
   1318 	if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, mask, sae->tmp->prime,
   1319 				  sae->tmp->own_commit_element_ffc) < 0 ||
   1320 	    crypto_bignum_inverse(sae->tmp->own_commit_element_ffc,
   1321 				  sae->tmp->prime,
   1322 				  sae->tmp->own_commit_element_ffc) < 0) {
   1323 		wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element");
   1324 		return -1;
   1325 	}
   1326 
   1327 	return 0;
   1328 }
   1329 
   1330 
   1331 static int sae_derive_commit(struct sae_data *sae)
   1332 {
   1333 	struct crypto_bignum *mask;
   1334 	int ret;
   1335 
   1336 	mask = crypto_bignum_init();
   1337 	if (!sae->tmp->sae_rand)
   1338 		sae->tmp->sae_rand = crypto_bignum_init();
   1339 	if (!sae->tmp->own_commit_scalar)
   1340 		sae->tmp->own_commit_scalar = crypto_bignum_init();
   1341 	ret = !mask || !sae->tmp->sae_rand || !sae->tmp->own_commit_scalar ||
   1342 		dragonfly_generate_scalar(sae->tmp->order, sae->tmp->sae_rand,
   1343 					  mask,
   1344 					  sae->tmp->own_commit_scalar) < 0 ||
   1345 		(sae->tmp->ec &&
   1346 		 sae_derive_commit_element_ecc(sae, mask) < 0) ||
   1347 		(sae->tmp->dh &&
   1348 		 sae_derive_commit_element_ffc(sae, mask) < 0);
   1349 	crypto_bignum_deinit(mask, 1);
   1350 	return ret ? -1 : 0;
   1351 }
   1352 
   1353 
   1354 int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
   1355 		       const u8 *password, size_t password_len,
   1356 		       struct sae_data *sae)
   1357 {
   1358 	if (sae->tmp == NULL ||
   1359 	    (sae->tmp->ec && sae_derive_pwe_ecc(sae, addr1, addr2, password,
   1360 						password_len) < 0) ||
   1361 	    (sae->tmp->dh && sae_derive_pwe_ffc(sae, addr1, addr2, password,
   1362 						password_len) < 0))
   1363 		return -1;
   1364 
   1365 	sae->h2e = 0;
   1366 	sae->pk = 0;
   1367 	return sae_derive_commit(sae);
   1368 }
   1369 
   1370 
   1371 int sae_prepare_commit_pt(struct sae_data *sae, const struct sae_pt *pt,
   1372 			  const u8 *addr1, const u8 *addr2,
   1373 			  int *rejected_groups, const struct sae_pk *pk)
   1374 {
   1375 	if (!sae->tmp)
   1376 		return -1;
   1377 
   1378 	while (pt) {
   1379 		if (pt->group == sae->group)
   1380 			break;
   1381 		pt = pt->next;
   1382 	}
   1383 	if (!pt) {
   1384 		wpa_printf(MSG_INFO, "SAE: Could not find PT for group %u",
   1385 			   sae->group);
   1386 		return -1;
   1387 	}
   1388 
   1389 #ifdef CONFIG_SAE_PK
   1390 	os_memcpy(sae->tmp->ssid, pt->ssid, pt->ssid_len);
   1391 	sae->tmp->ssid_len = pt->ssid_len;
   1392 	sae->tmp->ap_pk = pk;
   1393 #endif /* CONFIG_SAE_PK */
   1394 	sae->tmp->own_addr_higher = os_memcmp(addr1, addr2, ETH_ALEN) > 0;
   1395 	wpabuf_free(sae->tmp->own_rejected_groups);
   1396 	sae->tmp->own_rejected_groups = NULL;
   1397 	if (rejected_groups) {
   1398 		int count, i;
   1399 		struct wpabuf *groups;
   1400 
   1401 		count = int_array_len(rejected_groups);
   1402 		groups = wpabuf_alloc(count * 2);
   1403 		if (!groups)
   1404 			return -1;
   1405 		for (i = 0; i < count; i++)
   1406 			wpabuf_put_le16(groups, rejected_groups[i]);
   1407 		sae->tmp->own_rejected_groups = groups;
   1408 	}
   1409 
   1410 	if (pt->ec) {
   1411 		crypto_ec_point_deinit(sae->tmp->pwe_ecc, 1);
   1412 		sae->tmp->pwe_ecc = sae_derive_pwe_from_pt_ecc(pt, addr1,
   1413 							       addr2);
   1414 		if (!sae->tmp->pwe_ecc)
   1415 			return -1;
   1416 	}
   1417 
   1418 	if (pt->dh) {
   1419 		crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
   1420 		sae->tmp->pwe_ffc = sae_derive_pwe_from_pt_ffc(pt, addr1,
   1421 							       addr2);
   1422 		if (!sae->tmp->pwe_ffc)
   1423 			return -1;
   1424 	}
   1425 
   1426 	sae->h2e = 1;
   1427 	return sae_derive_commit(sae);
   1428 }
   1429 
   1430 
   1431 static int sae_derive_k_ecc(struct sae_data *sae, u8 *k)
   1432 {
   1433 	struct crypto_ec_point *K;
   1434 	int ret = -1;
   1435 
   1436 	K = crypto_ec_point_init(sae->tmp->ec);
   1437 	if (K == NULL)
   1438 		goto fail;
   1439 
   1440 	/*
   1441 	 * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE),
   1442 	 *                                        PEER-COMMIT-ELEMENT)))
   1443 	 * If K is identity element (point-at-infinity), reject
   1444 	 * k = F(K) (= x coordinate)
   1445 	 */
   1446 
   1447 	if (crypto_ec_point_mul(sae->tmp->ec, sae->tmp->pwe_ecc,
   1448 				sae->peer_commit_scalar, K) < 0 ||
   1449 	    crypto_ec_point_add(sae->tmp->ec, K,
   1450 				sae->tmp->peer_commit_element_ecc, K) < 0 ||
   1451 	    crypto_ec_point_mul(sae->tmp->ec, K, sae->tmp->sae_rand, K) < 0 ||
   1452 	    crypto_ec_point_is_at_infinity(sae->tmp->ec, K) ||
   1453 	    crypto_ec_point_to_bin(sae->tmp->ec, K, k, NULL) < 0) {
   1454 		wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k");
   1455 		goto fail;
   1456 	}
   1457 
   1458 	wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len);
   1459 
   1460 	ret = 0;
   1461 fail:
   1462 	crypto_ec_point_deinit(K, 1);
   1463 	return ret;
   1464 }
   1465 
   1466 
   1467 static int sae_derive_k_ffc(struct sae_data *sae, u8 *k)
   1468 {
   1469 	struct crypto_bignum *K;
   1470 	int ret = -1;
   1471 
   1472 	K = crypto_bignum_init();
   1473 	if (K == NULL)
   1474 		goto fail;
   1475 
   1476 	/*
   1477 	 * K = scalar-op(rand, (elem-op(scalar-op(peer-commit-scalar, PWE),
   1478 	 *                                        PEER-COMMIT-ELEMENT)))
   1479 	 * If K is identity element (one), reject.
   1480 	 * k = F(K) (= x coordinate)
   1481 	 */
   1482 
   1483 	if (crypto_bignum_exptmod(sae->tmp->pwe_ffc, sae->peer_commit_scalar,
   1484 				  sae->tmp->prime, K) < 0 ||
   1485 	    crypto_bignum_mulmod(K, sae->tmp->peer_commit_element_ffc,
   1486 				 sae->tmp->prime, K) < 0 ||
   1487 	    crypto_bignum_exptmod(K, sae->tmp->sae_rand, sae->tmp->prime, K) < 0
   1488 	    ||
   1489 	    crypto_bignum_is_one(K) ||
   1490 	    crypto_bignum_to_bin(K, k, SAE_MAX_PRIME_LEN, sae->tmp->prime_len) <
   1491 	    0) {
   1492 		wpa_printf(MSG_DEBUG, "SAE: Failed to calculate K and k");
   1493 		goto fail;
   1494 	}
   1495 
   1496 	wpa_hexdump_key(MSG_DEBUG, "SAE: k", k, sae->tmp->prime_len);
   1497 
   1498 	ret = 0;
   1499 fail:
   1500 	crypto_bignum_deinit(K, 1);
   1501 	return ret;
   1502 }
   1503 
   1504 
   1505 static int sae_kdf_hash(size_t hash_len, const u8 *k, const char *label,
   1506 			const u8 *context, size_t context_len,
   1507 			u8 *out, size_t out_len)
   1508 {
   1509 	if (hash_len == 32)
   1510 		return sha256_prf(k, hash_len, label,
   1511 				  context, context_len, out, out_len);
   1512 #ifdef CONFIG_SHA384
   1513 	if (hash_len == 48)
   1514 		return sha384_prf(k, hash_len, label,
   1515 				  context, context_len, out, out_len);
   1516 #endif /* CONFIG_SHA384 */
   1517 #ifdef CONFIG_SHA512
   1518 	if (hash_len == 64)
   1519 		return sha512_prf(k, hash_len, label,
   1520 				  context, context_len, out, out_len);
   1521 #endif /* CONFIG_SHA512 */
   1522 	return -1;
   1523 }
   1524 
   1525 
   1526 static int sae_derive_keys(struct sae_data *sae, const u8 *k)
   1527 {
   1528 	u8 zero[SAE_MAX_HASH_LEN], val[SAE_MAX_PRIME_LEN];
   1529 	const u8 *salt;
   1530 	struct wpabuf *rejected_groups = NULL;
   1531 	u8 keyseed[SAE_MAX_HASH_LEN];
   1532 	u8 keys[2 * SAE_MAX_HASH_LEN + SAE_PMK_LEN_MAX];
   1533 	struct crypto_bignum *tmp;
   1534 	int ret = -1;
   1535 	size_t hash_len, salt_len, prime_len = sae->tmp->prime_len;
   1536 	size_t pmk_len;
   1537 	const u8 *addr[1];
   1538 	size_t len[1];
   1539 
   1540 	tmp = crypto_bignum_init();
   1541 	if (tmp == NULL)
   1542 		goto fail;
   1543 
   1544 	/* keyseed = H(salt, k)
   1545 	 * KCK || PMK = KDF-Hash-Length(keyseed, "SAE KCK and PMK",
   1546 	 *                      (commit-scalar + peer-commit-scalar) modulo r)
   1547 	 * PMKID = L((commit-scalar + peer-commit-scalar) modulo r, 0, 128)
   1548 	 *
   1549 	 * When SAE-PK is used,
   1550 	 * KCK || PMK || KEK = KDF-Hash-Length(keyseed, "SAE-PK keys", context)
   1551 	 */
   1552 	if (!sae->h2e)
   1553 		hash_len = SHA256_MAC_LEN;
   1554 	else if (sae->tmp->dh)
   1555 		hash_len = sae_ffc_prime_len_2_hash_len(prime_len);
   1556 	else
   1557 		hash_len = sae_ecc_prime_len_2_hash_len(prime_len);
   1558 	if (wpa_key_mgmt_sae_ext_key(sae->akmp))
   1559 		pmk_len = hash_len;
   1560 	else
   1561 		pmk_len = SAE_PMK_LEN;
   1562 	wpa_printf(MSG_DEBUG, "SAE: Derive keys - H2E=%d AKMP=0x%x = %08x (%s)",
   1563 		   sae->h2e, sae->akmp,
   1564 		   wpa_akm_to_suite(sae->akmp),
   1565 		   wpa_key_mgmt_txt(sae->akmp, WPA_PROTO_RSN));
   1566 	if (sae->h2e && (sae->tmp->own_rejected_groups ||
   1567 			 sae->tmp->peer_rejected_groups)) {
   1568 		struct wpabuf *own, *peer;
   1569 
   1570 		own = sae->tmp->own_rejected_groups;
   1571 		peer = sae->tmp->peer_rejected_groups;
   1572 		salt_len = 0;
   1573 		if (own)
   1574 			salt_len += wpabuf_len(own);
   1575 		if (peer)
   1576 			salt_len += wpabuf_len(peer);
   1577 		rejected_groups = wpabuf_alloc(salt_len);
   1578 		if (!rejected_groups)
   1579 			goto fail;
   1580 		if (sae->tmp->own_addr_higher) {
   1581 			if (own)
   1582 				wpabuf_put_buf(rejected_groups, own);
   1583 			if (peer)
   1584 				wpabuf_put_buf(rejected_groups, peer);
   1585 		} else {
   1586 			if (peer)
   1587 				wpabuf_put_buf(rejected_groups, peer);
   1588 			if (own)
   1589 				wpabuf_put_buf(rejected_groups, own);
   1590 		}
   1591 		salt = wpabuf_head(rejected_groups);
   1592 		salt_len = wpabuf_len(rejected_groups);
   1593 	} else {
   1594 		os_memset(zero, 0, hash_len);
   1595 		salt = zero;
   1596 		salt_len = hash_len;
   1597 	}
   1598 	wpa_hexdump(MSG_DEBUG, "SAE: salt for keyseed derivation",
   1599 		    salt, salt_len);
   1600 	addr[0] = k;
   1601 	len[0] = prime_len;
   1602 	if (hkdf_extract(hash_len, salt, salt_len, 1, addr, len, keyseed) < 0)
   1603 		goto fail;
   1604 	wpa_hexdump_key(MSG_DEBUG, "SAE: keyseed", keyseed, hash_len);
   1605 
   1606 	if (crypto_bignum_add(sae->tmp->own_commit_scalar,
   1607 			      sae->peer_commit_scalar, tmp) < 0 ||
   1608 	    crypto_bignum_mod(tmp, sae->tmp->order, tmp) < 0)
   1609 		goto fail;
   1610 	/* IEEE Std 802.11-2016 is not exactly clear on the encoding of the bit
   1611 	 * string that is needed for KCK, PMK, and PMKID derivation, but it
   1612 	 * seems to make most sense to encode the
   1613 	 * (commit-scalar + peer-commit-scalar) mod r part as a bit string by
   1614 	 * zero padding it from left to the length of the order (in full
   1615 	 * octets). */
   1616 	if (crypto_bignum_to_bin(tmp, val, sizeof(val),
   1617 				 sae->tmp->order_len) < 0)
   1618 		goto fail;
   1619 	wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
   1620 
   1621 #ifdef CONFIG_SAE_PK
   1622 	if (sae->pk) {
   1623 		if (sae_kdf_hash(hash_len, keyseed, "SAE-PK keys",
   1624 				 val, sae->tmp->order_len,
   1625 				 keys, 2 * hash_len + pmk_len) < 0)
   1626 			goto fail;
   1627 	} else {
   1628 		if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
   1629 				 val, sae->tmp->order_len,
   1630 				 keys, hash_len + pmk_len) < 0)
   1631 			goto fail;
   1632 	}
   1633 #else /* CONFIG_SAE_PK */
   1634 	if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
   1635 			 val, sae->tmp->order_len,
   1636 			 keys, hash_len + pmk_len) < 0)
   1637 		goto fail;
   1638 #endif /* !CONFIG_SAE_PK */
   1639 
   1640 	forced_memzero(keyseed, sizeof(keyseed));
   1641 	os_memcpy(sae->tmp->kck, keys, hash_len);
   1642 	sae->tmp->kck_len = hash_len;
   1643 	os_memcpy(sae->pmk, keys + hash_len, pmk_len);
   1644 	sae->pmk_len = pmk_len;
   1645 	os_memcpy(sae->pmkid, val, SAE_PMKID_LEN);
   1646 #ifdef CONFIG_SAE_PK
   1647 	if (sae->pk) {
   1648 		os_memcpy(sae->tmp->kek, keys + hash_len + SAE_PMK_LEN,
   1649 			  hash_len);
   1650 		sae->tmp->kek_len = hash_len;
   1651 		wpa_hexdump_key(MSG_DEBUG, "SAE: KEK for SAE-PK",
   1652 				sae->tmp->kek, sae->tmp->kek_len);
   1653 	}
   1654 #endif /* CONFIG_SAE_PK */
   1655 	forced_memzero(keys, sizeof(keys));
   1656 	wpa_hexdump_key(MSG_DEBUG, "SAE: KCK",
   1657 			sae->tmp->kck, sae->tmp->kck_len);
   1658 	wpa_hexdump_key(MSG_DEBUG, "SAE: PMK", sae->pmk, sae->pmk_len);
   1659 
   1660 	ret = 0;
   1661 fail:
   1662 	wpabuf_free(rejected_groups);
   1663 	crypto_bignum_deinit(tmp, 0);
   1664 	return ret;
   1665 }
   1666 
   1667 
   1668 int sae_process_commit(struct sae_data *sae)
   1669 {
   1670 	u8 k[SAE_MAX_PRIME_LEN];
   1671 	if (sae->tmp == NULL ||
   1672 	    (sae->tmp->ec && sae_derive_k_ecc(sae, k) < 0) ||
   1673 	    (sae->tmp->dh && sae_derive_k_ffc(sae, k) < 0) ||
   1674 	    sae_derive_keys(sae, k) < 0)
   1675 		return -1;
   1676 	return 0;
   1677 }
   1678 
   1679 
   1680 int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
   1681 		     const struct wpabuf *token, const char *identifier)
   1682 {
   1683 	u8 *pos;
   1684 
   1685 	if (sae->tmp == NULL)
   1686 		return -1;
   1687 
   1688 	wpabuf_put_le16(buf, sae->group); /* Finite Cyclic Group */
   1689 	if (!sae->h2e && token) {
   1690 		wpabuf_put_buf(buf, token);
   1691 		wpa_hexdump(MSG_DEBUG, "SAE: Anti-clogging token",
   1692 			    wpabuf_head(token), wpabuf_len(token));
   1693 	}
   1694 	pos = wpabuf_put(buf, sae->tmp->prime_len);
   1695 	if (crypto_bignum_to_bin(sae->tmp->own_commit_scalar, pos,
   1696 				 sae->tmp->prime_len, sae->tmp->prime_len) < 0)
   1697 		return -1;
   1698 	wpa_hexdump(MSG_DEBUG, "SAE: own commit-scalar",
   1699 		    pos, sae->tmp->prime_len);
   1700 	if (sae->tmp->ec) {
   1701 		pos = wpabuf_put(buf, 2 * sae->tmp->prime_len);
   1702 		if (crypto_ec_point_to_bin(sae->tmp->ec,
   1703 					   sae->tmp->own_commit_element_ecc,
   1704 					   pos, pos + sae->tmp->prime_len) < 0)
   1705 			return -1;
   1706 		wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(x)",
   1707 			    pos, sae->tmp->prime_len);
   1708 		wpa_hexdump(MSG_DEBUG, "SAE: own commit-element(y)",
   1709 			    pos + sae->tmp->prime_len, sae->tmp->prime_len);
   1710 	} else {
   1711 		pos = wpabuf_put(buf, sae->tmp->prime_len);
   1712 		if (crypto_bignum_to_bin(sae->tmp->own_commit_element_ffc, pos,
   1713 					 sae->tmp->prime_len,
   1714 					 sae->tmp->prime_len) < 0)
   1715 			return -1;
   1716 		wpa_hexdump(MSG_DEBUG, "SAE: own commit-element",
   1717 			    pos, sae->tmp->prime_len);
   1718 	}
   1719 
   1720 	if (identifier) {
   1721 		/* Password Identifier element */
   1722 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
   1723 		wpabuf_put_u8(buf, 1 + os_strlen(identifier));
   1724 		wpabuf_put_u8(buf, WLAN_EID_EXT_PASSWORD_IDENTIFIER);
   1725 		wpabuf_put_str(buf, identifier);
   1726 		wpa_printf(MSG_DEBUG, "SAE: own Password Identifier: %s",
   1727 			   identifier);
   1728 	}
   1729 
   1730 	if (sae->h2e && sae->tmp->own_rejected_groups) {
   1731 		wpa_hexdump_buf(MSG_DEBUG, "SAE: own Rejected Groups",
   1732 				sae->tmp->own_rejected_groups);
   1733 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
   1734 		wpabuf_put_u8(buf,
   1735 			      1 + wpabuf_len(sae->tmp->own_rejected_groups));
   1736 		wpabuf_put_u8(buf, WLAN_EID_EXT_REJECTED_GROUPS);
   1737 		wpabuf_put_buf(buf, sae->tmp->own_rejected_groups);
   1738 	}
   1739 
   1740 	if (sae->h2e && token) {
   1741 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
   1742 		wpabuf_put_u8(buf, 1 + wpabuf_len(token));
   1743 		wpabuf_put_u8(buf, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN);
   1744 		wpabuf_put_buf(buf, token);
   1745 		wpa_hexdump_buf(MSG_DEBUG,
   1746 				"SAE: Anti-clogging token (in container)",
   1747 				token);
   1748 	}
   1749 
   1750 	if (wpa_key_mgmt_sae_ext_key(sae->akmp)) {
   1751 		u32 suite = wpa_akm_to_suite(sae->akmp);
   1752 
   1753 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
   1754 		wpabuf_put_u8(buf, 1 + RSN_SELECTOR_LEN);
   1755 		wpabuf_put_u8(buf, WLAN_EID_EXT_AKM_SUITE_SELECTOR);
   1756 		RSN_SELECTOR_PUT(wpabuf_put(buf, RSN_SELECTOR_LEN), suite);
   1757 		wpa_printf(MSG_DEBUG, "SAE: AKM Suite Selector: %08x", suite);
   1758 		sae->own_akm_suite_selector = suite;
   1759 	}
   1760 
   1761 	return 0;
   1762 }
   1763 
   1764 
   1765 u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group)
   1766 {
   1767 	if (allowed_groups) {
   1768 		int i;
   1769 		for (i = 0; allowed_groups[i] > 0; i++) {
   1770 			if (allowed_groups[i] == group)
   1771 				break;
   1772 		}
   1773 		if (allowed_groups[i] != group) {
   1774 			wpa_printf(MSG_DEBUG, "SAE: Proposed group %u not "
   1775 				   "enabled in the current configuration",
   1776 				   group);
   1777 			return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
   1778 		}
   1779 	}
   1780 
   1781 	if (sae->state == SAE_COMMITTED && group != sae->group) {
   1782 		wpa_printf(MSG_DEBUG, "SAE: Do not allow group to be changed");
   1783 		return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
   1784 	}
   1785 
   1786 	if (group != sae->group && sae_set_group(sae, group) < 0) {
   1787 		wpa_printf(MSG_DEBUG, "SAE: Unsupported Finite Cyclic Group %u",
   1788 			   group);
   1789 		return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
   1790 	}
   1791 
   1792 	if (sae->tmp == NULL) {
   1793 		wpa_printf(MSG_DEBUG, "SAE: Group information not yet initialized");
   1794 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1795 	}
   1796 
   1797 	if (sae->tmp->dh && !allowed_groups) {
   1798 		wpa_printf(MSG_DEBUG, "SAE: Do not allow FFC group %u without "
   1799 			   "explicit configuration enabling it", group);
   1800 		return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
   1801 	}
   1802 
   1803 	return WLAN_STATUS_SUCCESS;
   1804 }
   1805 
   1806 
   1807 static int sae_is_password_id_elem(const u8 *pos, const u8 *end)
   1808 {
   1809 	return end - pos >= 3 &&
   1810 		pos[0] == WLAN_EID_EXTENSION &&
   1811 		pos[1] >= 1 &&
   1812 		end - pos - 2 >= pos[1] &&
   1813 		pos[2] == WLAN_EID_EXT_PASSWORD_IDENTIFIER;
   1814 }
   1815 
   1816 
   1817 static int sae_is_rejected_groups_elem(const u8 *pos, const u8 *end)
   1818 {
   1819 	return end - pos >= 3 &&
   1820 		pos[0] == WLAN_EID_EXTENSION &&
   1821 		pos[1] >= 2 &&
   1822 		end - pos - 2 >= pos[1] &&
   1823 		pos[2] == WLAN_EID_EXT_REJECTED_GROUPS;
   1824 }
   1825 
   1826 
   1827 static int sae_is_token_container_elem(const u8 *pos, const u8 *end)
   1828 {
   1829 	return end - pos >= 3 &&
   1830 		pos[0] == WLAN_EID_EXTENSION &&
   1831 		pos[1] >= 1 &&
   1832 		end - pos - 2 >= pos[1] &&
   1833 		pos[2] == WLAN_EID_EXT_ANTI_CLOGGING_TOKEN;
   1834 }
   1835 
   1836 
   1837 static int sae_is_akm_suite_selector_elem(const u8 *pos, const u8 *end)
   1838 {
   1839 	return end - pos >= 2 + 1 + RSN_SELECTOR_LEN &&
   1840 		pos[0] == WLAN_EID_EXTENSION &&
   1841 		pos[1] >= 1 + RSN_SELECTOR_LEN &&
   1842 		end - pos - 2 >= pos[1] &&
   1843 		pos[2] == WLAN_EID_EXT_AKM_SUITE_SELECTOR;
   1844 }
   1845 
   1846 
   1847 static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
   1848 				   const u8 *end, const u8 **token,
   1849 				   size_t *token_len, int h2e)
   1850 {
   1851 	size_t scalar_elem_len, tlen;
   1852 
   1853 	if (token)
   1854 		*token = NULL;
   1855 	if (token_len)
   1856 		*token_len = 0;
   1857 
   1858 	if (h2e)
   1859 		return; /* No Anti-Clogging Token field outside container IE */
   1860 
   1861 	scalar_elem_len = (sae->tmp->ec ? 3 : 2) * sae->tmp->prime_len;
   1862 	if (scalar_elem_len >= (size_t) (end - *pos))
   1863 		return; /* No extra data beyond peer scalar and element */
   1864 
   1865 	tlen = end - (*pos + scalar_elem_len);
   1866 
   1867 	if (tlen < SHA256_MAC_LEN) {
   1868 		wpa_printf(MSG_DEBUG,
   1869 			   "SAE: Too short optional data (%u octets) to include our Anti-Clogging Token",
   1870 			   (unsigned int) tlen);
   1871 		return;
   1872 	}
   1873 
   1874 	wpa_hexdump(MSG_DEBUG, "SAE: Anti-Clogging Token", *pos, tlen);
   1875 	if (token)
   1876 		*token = *pos;
   1877 	if (token_len)
   1878 		*token_len = tlen;
   1879 	*pos += tlen;
   1880 }
   1881 
   1882 
   1883 static void sae_parse_token_container(struct sae_data *sae,
   1884 				      const u8 *pos, const u8 *end,
   1885 				      const u8 **token, size_t *token_len)
   1886 {
   1887 	wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
   1888 		    pos, end - pos);
   1889 	if (!sae_is_token_container_elem(pos, end))
   1890 		return;
   1891 	*token = pos + 3;
   1892 	*token_len = pos[1] - 1;
   1893 	wpa_hexdump(MSG_DEBUG, "SAE: Anti-Clogging Token (in container)",
   1894 		    *token, *token_len);
   1895 }
   1896 
   1897 
   1898 static u16 sae_parse_commit_scalar(struct sae_data *sae, const u8 **pos,
   1899 				   const u8 *end)
   1900 {
   1901 	struct crypto_bignum *peer_scalar;
   1902 
   1903 	if (sae->tmp->prime_len > end - *pos) {
   1904 		wpa_printf(MSG_DEBUG, "SAE: Not enough data for scalar");
   1905 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1906 	}
   1907 
   1908 	peer_scalar = crypto_bignum_init_set(*pos, sae->tmp->prime_len);
   1909 	if (peer_scalar == NULL)
   1910 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1911 
   1912 	/*
   1913 	 * IEEE Std 802.11-2012, 11.3.8.6.1: If there is a protocol instance for
   1914 	 * the peer and it is in Authenticated state, the new Commit Message
   1915 	 * shall be dropped if the peer-scalar is identical to the one used in
   1916 	 * the existing protocol instance.
   1917 	 */
   1918 	if (sae->state == SAE_ACCEPTED && sae->peer_commit_scalar_accepted &&
   1919 	    crypto_bignum_cmp(sae->peer_commit_scalar_accepted,
   1920 			      peer_scalar) == 0) {
   1921 		wpa_printf(MSG_DEBUG, "SAE: Do not accept re-use of previous "
   1922 			   "peer-commit-scalar");
   1923 		crypto_bignum_deinit(peer_scalar, 0);
   1924 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1925 	}
   1926 
   1927 	/* 1 < scalar < r */
   1928 	if (crypto_bignum_is_zero(peer_scalar) ||
   1929 	    crypto_bignum_is_one(peer_scalar) ||
   1930 	    crypto_bignum_cmp(peer_scalar, sae->tmp->order) >= 0) {
   1931 		wpa_printf(MSG_DEBUG, "SAE: Invalid peer scalar");
   1932 		crypto_bignum_deinit(peer_scalar, 0);
   1933 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1934 	}
   1935 
   1936 
   1937 	crypto_bignum_deinit(sae->peer_commit_scalar, 0);
   1938 	sae->peer_commit_scalar = peer_scalar;
   1939 	wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-scalar",
   1940 		    *pos, sae->tmp->prime_len);
   1941 	*pos += sae->tmp->prime_len;
   1942 
   1943 	return WLAN_STATUS_SUCCESS;
   1944 }
   1945 
   1946 
   1947 static u16 sae_parse_commit_element_ecc(struct sae_data *sae, const u8 **pos,
   1948 					const u8 *end)
   1949 {
   1950 	u8 prime[SAE_MAX_ECC_PRIME_LEN];
   1951 
   1952 	if (2 * sae->tmp->prime_len > end - *pos) {
   1953 		wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
   1954 			   "commit-element");
   1955 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1956 	}
   1957 
   1958 	if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
   1959 				 sae->tmp->prime_len) < 0)
   1960 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1961 
   1962 	/* element x and y coordinates < p */
   1963 	if (os_memcmp(*pos, prime, sae->tmp->prime_len) >= 0 ||
   1964 	    os_memcmp(*pos + sae->tmp->prime_len, prime,
   1965 		      sae->tmp->prime_len) >= 0) {
   1966 		wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer "
   1967 			   "element");
   1968 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1969 	}
   1970 
   1971 	wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(x)",
   1972 		    *pos, sae->tmp->prime_len);
   1973 	wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element(y)",
   1974 		    *pos + sae->tmp->prime_len, sae->tmp->prime_len);
   1975 
   1976 	crypto_ec_point_deinit(sae->tmp->peer_commit_element_ecc, 0);
   1977 	sae->tmp->peer_commit_element_ecc =
   1978 		crypto_ec_point_from_bin(sae->tmp->ec, *pos);
   1979 	if (!sae->tmp->peer_commit_element_ecc) {
   1980 		wpa_printf(MSG_DEBUG, "SAE: Peer element is not a valid point");
   1981 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1982 	}
   1983 
   1984 	if (!crypto_ec_point_is_on_curve(sae->tmp->ec,
   1985 					 sae->tmp->peer_commit_element_ecc)) {
   1986 		wpa_printf(MSG_DEBUG, "SAE: Peer element is not on curve");
   1987 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   1988 	}
   1989 
   1990 	*pos += 2 * sae->tmp->prime_len;
   1991 
   1992 	return WLAN_STATUS_SUCCESS;
   1993 }
   1994 
   1995 
   1996 static u16 sae_parse_commit_element_ffc(struct sae_data *sae, const u8 **pos,
   1997 					const u8 *end)
   1998 {
   1999 	struct crypto_bignum *res, *one;
   2000 	const u8 one_bin[1] = { 0x01 };
   2001 
   2002 	if (sae->tmp->prime_len > end - *pos) {
   2003 		wpa_printf(MSG_DEBUG, "SAE: Not enough data for "
   2004 			   "commit-element");
   2005 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2006 	}
   2007 	wpa_hexdump(MSG_DEBUG, "SAE: Peer commit-element", *pos,
   2008 		    sae->tmp->prime_len);
   2009 
   2010 	crypto_bignum_deinit(sae->tmp->peer_commit_element_ffc, 0);
   2011 	sae->tmp->peer_commit_element_ffc =
   2012 		crypto_bignum_init_set(*pos, sae->tmp->prime_len);
   2013 	if (sae->tmp->peer_commit_element_ffc == NULL)
   2014 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2015 	/* 1 < element < p - 1 */
   2016 	res = crypto_bignum_init();
   2017 	one = crypto_bignum_init_set(one_bin, sizeof(one_bin));
   2018 	if (!res || !one ||
   2019 	    crypto_bignum_sub(sae->tmp->prime, one, res) ||
   2020 	    crypto_bignum_is_zero(sae->tmp->peer_commit_element_ffc) ||
   2021 	    crypto_bignum_is_one(sae->tmp->peer_commit_element_ffc) ||
   2022 	    crypto_bignum_cmp(sae->tmp->peer_commit_element_ffc, res) >= 0) {
   2023 		crypto_bignum_deinit(res, 0);
   2024 		crypto_bignum_deinit(one, 0);
   2025 		wpa_printf(MSG_DEBUG, "SAE: Invalid peer element");
   2026 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2027 	}
   2028 	crypto_bignum_deinit(one, 0);
   2029 
   2030 	/* scalar-op(r, ELEMENT) = 1 modulo p */
   2031 	if (crypto_bignum_exptmod(sae->tmp->peer_commit_element_ffc,
   2032 				  sae->tmp->order, sae->tmp->prime, res) < 0 ||
   2033 	    !crypto_bignum_is_one(res)) {
   2034 		wpa_printf(MSG_DEBUG, "SAE: Invalid peer element (scalar-op)");
   2035 		crypto_bignum_deinit(res, 0);
   2036 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2037 	}
   2038 	crypto_bignum_deinit(res, 0);
   2039 
   2040 	*pos += sae->tmp->prime_len;
   2041 
   2042 	return WLAN_STATUS_SUCCESS;
   2043 }
   2044 
   2045 
   2046 static u16 sae_parse_commit_element(struct sae_data *sae, const u8 **pos,
   2047 				    const u8 *end)
   2048 {
   2049 	if (sae->tmp->dh)
   2050 		return sae_parse_commit_element_ffc(sae, pos, end);
   2051 	return sae_parse_commit_element_ecc(sae, pos, end);
   2052 }
   2053 
   2054 
   2055 static int sae_parse_password_identifier(struct sae_data *sae,
   2056 					 const u8 **pos, const u8 *end)
   2057 {
   2058 	const u8 *epos;
   2059 	u8 len;
   2060 
   2061 	wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
   2062 		    *pos, end - *pos);
   2063 	if (!sae_is_password_id_elem(*pos, end)) {
   2064 		if (sae->tmp->pw_id) {
   2065 			wpa_printf(MSG_DEBUG,
   2066 				   "SAE: No Password Identifier included, but expected one (%s)",
   2067 				   sae->tmp->pw_id);
   2068 			return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
   2069 		}
   2070 		os_free(sae->tmp->pw_id);
   2071 		sae->tmp->pw_id = NULL;
   2072 		return WLAN_STATUS_SUCCESS; /* No Password Identifier */
   2073 	}
   2074 
   2075 	epos = *pos;
   2076 	epos++; /* skip IE type */
   2077 	len = *epos++; /* IE length */
   2078 	if (len > end - epos || len < 1)
   2079 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2080 	epos++; /* skip ext ID */
   2081 	len--;
   2082 
   2083 	if (sae->tmp->pw_id &&
   2084 	    (len != os_strlen(sae->tmp->pw_id) ||
   2085 	     os_memcmp(sae->tmp->pw_id, epos, len) != 0)) {
   2086 		wpa_printf(MSG_DEBUG,
   2087 			   "SAE: The included Password Identifier does not match the expected one (%s)",
   2088 			   sae->tmp->pw_id);
   2089 		return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
   2090 	}
   2091 
   2092 	os_free(sae->tmp->pw_id);
   2093 	sae->tmp->pw_id = os_malloc(len + 1);
   2094 	if (!sae->tmp->pw_id)
   2095 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2096 	os_memcpy(sae->tmp->pw_id, epos, len);
   2097 	sae->tmp->pw_id[len] = '\0';
   2098 	wpa_hexdump_ascii(MSG_DEBUG, "SAE: Received Password Identifier",
   2099 			  sae->tmp->pw_id, len);
   2100 	*pos = epos + len;
   2101 	return WLAN_STATUS_SUCCESS;
   2102 }
   2103 
   2104 
   2105 static int sae_parse_rejected_groups(struct sae_data *sae,
   2106 				     const u8 **pos, const u8 *end)
   2107 {
   2108 	const u8 *epos;
   2109 	u8 len;
   2110 
   2111 	wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
   2112 		    *pos, end - *pos);
   2113 	if (!sae_is_rejected_groups_elem(*pos, end)) {
   2114 		wpabuf_free(sae->tmp->peer_rejected_groups);
   2115 		sae->tmp->peer_rejected_groups = NULL;
   2116 		return WLAN_STATUS_SUCCESS;
   2117 	}
   2118 
   2119 	epos = *pos;
   2120 	epos++; /* skip IE type */
   2121 	len = *epos++; /* IE length */
   2122 	if (len > end - epos || len < 1)
   2123 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2124 	epos++; /* skip ext ID */
   2125 	len--;
   2126 	if (len & 1) {
   2127 		wpa_printf(MSG_DEBUG,
   2128 			   "SAE: Invalid length of the Rejected Groups element payload: %u",
   2129 			   len);
   2130 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2131 	}
   2132 
   2133 	wpabuf_free(sae->tmp->peer_rejected_groups);
   2134 	sae->tmp->peer_rejected_groups = wpabuf_alloc(len);
   2135 	if (!sae->tmp->peer_rejected_groups)
   2136 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2137 	wpabuf_put_data(sae->tmp->peer_rejected_groups, epos, len);
   2138 	wpa_hexdump_buf(MSG_DEBUG, "SAE: Received Rejected Groups list",
   2139 			sae->tmp->peer_rejected_groups);
   2140 	*pos = epos + len;
   2141 	return WLAN_STATUS_SUCCESS;
   2142 }
   2143 
   2144 
   2145 static int sae_parse_akm_suite_selector(struct sae_data *sae,
   2146 					const u8 **pos, const u8 *end)
   2147 {
   2148 	const u8 *epos;
   2149 	u8 len;
   2150 
   2151 	wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
   2152 		    *pos, end - *pos);
   2153 	if (!sae_is_akm_suite_selector_elem(*pos, end))
   2154 		return WLAN_STATUS_SUCCESS;
   2155 
   2156 	epos = *pos;
   2157 	epos++; /* skip IE type */
   2158 	len = *epos++; /* IE length */
   2159 	if (len > end - epos || len < 1)
   2160 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2161 	epos++; /* skip ext ID */
   2162 	len--;
   2163 
   2164 	if (len < RSN_SELECTOR_LEN)
   2165 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2166 	sae->peer_akm_suite_selector = RSN_SELECTOR_GET(epos);
   2167 	wpa_printf(MSG_DEBUG, "SAE: Received AKM Suite Selector: %08x",
   2168 		   sae->peer_akm_suite_selector);
   2169 	*pos = epos + len;
   2170 	return WLAN_STATUS_SUCCESS;
   2171 }
   2172 
   2173 
   2174 u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
   2175 		     const u8 **token, size_t *token_len, int *allowed_groups,
   2176 		     int h2e, int *ie_offset)
   2177 {
   2178 	const u8 *pos = data, *end = data + len;
   2179 	u16 res;
   2180 
   2181 	/* Check Finite Cyclic Group */
   2182 	if (end - pos < 2)
   2183 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2184 	res = sae_group_allowed(sae, allowed_groups, WPA_GET_LE16(pos));
   2185 	if (res != WLAN_STATUS_SUCCESS)
   2186 		return res;
   2187 	pos += 2;
   2188 
   2189 	/* Optional Anti-Clogging Token */
   2190 	sae_parse_commit_token(sae, &pos, end, token, token_len, h2e);
   2191 
   2192 	/* commit-scalar */
   2193 	res = sae_parse_commit_scalar(sae, &pos, end);
   2194 	if (res != WLAN_STATUS_SUCCESS)
   2195 		return res;
   2196 
   2197 	/* commit-element */
   2198 	res = sae_parse_commit_element(sae, &pos, end);
   2199 	if (res != WLAN_STATUS_SUCCESS)
   2200 		return res;
   2201 
   2202 	if (ie_offset)
   2203 		*ie_offset = pos - data;
   2204 
   2205 	/* Optional Password Identifier element */
   2206 	res = sae_parse_password_identifier(sae, &pos, end);
   2207 	if (res != WLAN_STATUS_SUCCESS)
   2208 		return res;
   2209 
   2210 	/* Conditional Rejected Groups element */
   2211 	if (h2e) {
   2212 		res = sae_parse_rejected_groups(sae, &pos, end);
   2213 		if (res != WLAN_STATUS_SUCCESS)
   2214 			return res;
   2215 	} else {
   2216 		wpabuf_free(sae->tmp->peer_rejected_groups);
   2217 		sae->tmp->peer_rejected_groups = NULL;
   2218 	}
   2219 
   2220 	/* Optional Anti-Clogging Token Container element */
   2221 	if (h2e)
   2222 		sae_parse_token_container(sae, pos, end, token, token_len);
   2223 
   2224 	/* Conditional AKM Suite Selector element */
   2225 	if (h2e) {
   2226 		res = sae_parse_akm_suite_selector(sae, &pos, end);
   2227 		if (res != WLAN_STATUS_SUCCESS)
   2228 			return res;
   2229 	}
   2230 
   2231 	if (sae->own_akm_suite_selector &&
   2232 	    sae->own_akm_suite_selector != sae->peer_akm_suite_selector) {
   2233 		wpa_printf(MSG_DEBUG,
   2234 			   "SAE: AKM suite selector mismatch: own=%08x peer=%08x",
   2235 			   sae->own_akm_suite_selector,
   2236 			   sae->peer_akm_suite_selector);
   2237 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
   2238 	}
   2239 
   2240 	if (!sae->akmp) {
   2241 		if (sae->peer_akm_suite_selector ==
   2242 		    RSN_AUTH_KEY_MGMT_SAE_EXT_KEY)
   2243 			sae->akmp = WPA_KEY_MGMT_SAE_EXT_KEY;
   2244 		else if (sae->peer_akm_suite_selector ==
   2245 		    RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY)
   2246 			sae->akmp = WPA_KEY_MGMT_FT_SAE_EXT_KEY;
   2247 	}
   2248 
   2249 	/*
   2250 	 * Check whether peer-commit-scalar and PEER-COMMIT-ELEMENT are same as
   2251 	 * the values we sent which would be evidence of a reflection attack.
   2252 	 */
   2253 	if (!sae->tmp->own_commit_scalar ||
   2254 	    crypto_bignum_cmp(sae->tmp->own_commit_scalar,
   2255 			      sae->peer_commit_scalar) != 0 ||
   2256 	    (sae->tmp->dh &&
   2257 	     (!sae->tmp->own_commit_element_ffc ||
   2258 	      crypto_bignum_cmp(sae->tmp->own_commit_element_ffc,
   2259 				sae->tmp->peer_commit_element_ffc) != 0)) ||
   2260 	    (sae->tmp->ec &&
   2261 	     (!sae->tmp->own_commit_element_ecc ||
   2262 	      crypto_ec_point_cmp(sae->tmp->ec,
   2263 				  sae->tmp->own_commit_element_ecc,
   2264 				  sae->tmp->peer_commit_element_ecc) != 0)))
   2265 		return WLAN_STATUS_SUCCESS; /* scalars/elements are different */
   2266 
   2267 	/*
   2268 	 * This is a reflection attack - return special value to trigger caller
   2269 	 * to silently discard the frame instead of replying with a specific
   2270 	 * status code.
   2271 	 */
   2272 	return SAE_SILENTLY_DISCARD;
   2273 }
   2274 
   2275 
   2276 static int sae_cn_confirm(struct sae_data *sae, const u8 *sc,
   2277 			  const struct crypto_bignum *scalar1,
   2278 			  const u8 *element1, size_t element1_len,
   2279 			  const struct crypto_bignum *scalar2,
   2280 			  const u8 *element2, size_t element2_len,
   2281 			  u8 *confirm)
   2282 {
   2283 	const u8 *addr[5];
   2284 	size_t len[5];
   2285 	u8 scalar_b1[SAE_MAX_PRIME_LEN], scalar_b2[SAE_MAX_PRIME_LEN];
   2286 
   2287 	/* Confirm
   2288 	 * CN(key, X, Y, Z, ...) =
   2289 	 *    HMAC-SHA256(key, D2OS(X) || D2OS(Y) || D2OS(Z) | ...)
   2290 	 * confirm = CN(KCK, send-confirm, commit-scalar, COMMIT-ELEMENT,
   2291 	 *              peer-commit-scalar, PEER-COMMIT-ELEMENT)
   2292 	 * verifier = CN(KCK, peer-send-confirm, peer-commit-scalar,
   2293 	 *               PEER-COMMIT-ELEMENT, commit-scalar, COMMIT-ELEMENT)
   2294 	 */
   2295 	if (crypto_bignum_to_bin(scalar1, scalar_b1, sizeof(scalar_b1),
   2296 				 sae->tmp->prime_len) < 0 ||
   2297 	    crypto_bignum_to_bin(scalar2, scalar_b2, sizeof(scalar_b2),
   2298 				 sae->tmp->prime_len) < 0)
   2299 		return -1;
   2300 	addr[0] = sc;
   2301 	len[0] = 2;
   2302 	addr[1] = scalar_b1;
   2303 	len[1] = sae->tmp->prime_len;
   2304 	addr[2] = element1;
   2305 	len[2] = element1_len;
   2306 	addr[3] = scalar_b2;
   2307 	len[3] = sae->tmp->prime_len;
   2308 	addr[4] = element2;
   2309 	len[4] = element2_len;
   2310 	return hkdf_extract(sae->tmp->kck_len, sae->tmp->kck, sae->tmp->kck_len,
   2311 			    5, addr, len, confirm);
   2312 }
   2313 
   2314 
   2315 static int sae_cn_confirm_ecc(struct sae_data *sae, const u8 *sc,
   2316 			      const struct crypto_bignum *scalar1,
   2317 			      const struct crypto_ec_point *element1,
   2318 			      const struct crypto_bignum *scalar2,
   2319 			      const struct crypto_ec_point *element2,
   2320 			      u8 *confirm)
   2321 {
   2322 	u8 element_b1[2 * SAE_MAX_ECC_PRIME_LEN];
   2323 	u8 element_b2[2 * SAE_MAX_ECC_PRIME_LEN];
   2324 
   2325 	if (crypto_ec_point_to_bin(sae->tmp->ec, element1, element_b1,
   2326 				   element_b1 + sae->tmp->prime_len) < 0 ||
   2327 	    crypto_ec_point_to_bin(sae->tmp->ec, element2, element_b2,
   2328 				   element_b2 + sae->tmp->prime_len) < 0 ||
   2329 	    sae_cn_confirm(sae, sc, scalar1, element_b1,
   2330 			   2 * sae->tmp->prime_len,
   2331 			   scalar2, element_b2, 2 * sae->tmp->prime_len,
   2332 			   confirm) < 0)
   2333 		return -1;
   2334 	return 0;
   2335 }
   2336 
   2337 
   2338 static int sae_cn_confirm_ffc(struct sae_data *sae, const u8 *sc,
   2339 			      const struct crypto_bignum *scalar1,
   2340 			      const struct crypto_bignum *element1,
   2341 			      const struct crypto_bignum *scalar2,
   2342 			      const struct crypto_bignum *element2,
   2343 			      u8 *confirm)
   2344 {
   2345 	u8 element_b1[SAE_MAX_PRIME_LEN];
   2346 	u8 element_b2[SAE_MAX_PRIME_LEN];
   2347 
   2348 	if (crypto_bignum_to_bin(element1, element_b1, sizeof(element_b1),
   2349 				 sae->tmp->prime_len) < 0 ||
   2350 	    crypto_bignum_to_bin(element2, element_b2, sizeof(element_b2),
   2351 				 sae->tmp->prime_len) < 0 ||
   2352 	    sae_cn_confirm(sae, sc, scalar1, element_b1, sae->tmp->prime_len,
   2353 			   scalar2, element_b2, sae->tmp->prime_len,
   2354 			   confirm) < 0)
   2355 		return -1;
   2356 	return 0;
   2357 }
   2358 
   2359 
   2360 int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf)
   2361 {
   2362 	const u8 *sc;
   2363 	size_t hash_len;
   2364 	int res;
   2365 
   2366 	if (sae->tmp == NULL)
   2367 		return -1;
   2368 
   2369 	hash_len = sae->tmp->kck_len;
   2370 
   2371 	/* Send-Confirm */
   2372 	if (sae->send_confirm < 0xffff)
   2373 		sae->send_confirm++;
   2374 	sc = wpabuf_put(buf, 0);
   2375 	wpabuf_put_le16(buf, sae->send_confirm);
   2376 
   2377 	if (sae->tmp->ec)
   2378 		res = sae_cn_confirm_ecc(sae, sc, sae->tmp->own_commit_scalar,
   2379 					 sae->tmp->own_commit_element_ecc,
   2380 					 sae->peer_commit_scalar,
   2381 					 sae->tmp->peer_commit_element_ecc,
   2382 					 wpabuf_put(buf, hash_len));
   2383 	else
   2384 		res = sae_cn_confirm_ffc(sae, sc, sae->tmp->own_commit_scalar,
   2385 					 sae->tmp->own_commit_element_ffc,
   2386 					 sae->peer_commit_scalar,
   2387 					 sae->tmp->peer_commit_element_ffc,
   2388 					 wpabuf_put(buf, hash_len));
   2389 	if (res)
   2390 		return res;
   2391 
   2392 #ifdef CONFIG_SAE_PK
   2393 	if (sae_write_confirm_pk(sae, buf) < 0)
   2394 		return -1;
   2395 #endif /* CONFIG_SAE_PK */
   2396 
   2397 	return 0;
   2398 }
   2399 
   2400 
   2401 int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len,
   2402 		      int *ie_offset)
   2403 {
   2404 	u8 verifier[SAE_MAX_HASH_LEN];
   2405 	size_t hash_len;
   2406 
   2407 	if (!sae->tmp)
   2408 		return -1;
   2409 
   2410 	hash_len = sae->tmp->kck_len;
   2411 	if (len < 2 + hash_len) {
   2412 		wpa_printf(MSG_DEBUG, "SAE: Too short confirm message");
   2413 		return -1;
   2414 	}
   2415 
   2416 	wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data));
   2417 
   2418 	if (!sae->peer_commit_scalar || !sae->tmp->own_commit_scalar) {
   2419 		wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available");
   2420 		return -1;
   2421 	}
   2422 
   2423 	if (sae->tmp->ec) {
   2424 		if (!sae->tmp->peer_commit_element_ecc ||
   2425 		    !sae->tmp->own_commit_element_ecc ||
   2426 		    sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar,
   2427 				       sae->tmp->peer_commit_element_ecc,
   2428 				       sae->tmp->own_commit_scalar,
   2429 				       sae->tmp->own_commit_element_ecc,
   2430 				       verifier) < 0)
   2431 			return -1;
   2432 	} else {
   2433 		if (!sae->tmp->peer_commit_element_ffc ||
   2434 		    !sae->tmp->own_commit_element_ffc ||
   2435 		    sae_cn_confirm_ffc(sae, data, sae->peer_commit_scalar,
   2436 				       sae->tmp->peer_commit_element_ffc,
   2437 				       sae->tmp->own_commit_scalar,
   2438 				       sae->tmp->own_commit_element_ffc,
   2439 				       verifier) < 0)
   2440 			return -1;
   2441 	}
   2442 
   2443 	if (os_memcmp_const(verifier, data + 2, hash_len) != 0) {
   2444 		wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch");
   2445 		wpa_hexdump(MSG_DEBUG, "SAE: Received confirm",
   2446 			    data + 2, hash_len);
   2447 		wpa_hexdump(MSG_DEBUG, "SAE: Calculated verifier",
   2448 			    verifier, hash_len);
   2449 		return -1;
   2450 	}
   2451 
   2452 #ifdef CONFIG_SAE_PK
   2453 	if (sae_check_confirm_pk(sae, data + 2 + hash_len,
   2454 				 len - 2 - hash_len) < 0)
   2455 		return -1;
   2456 #endif /* CONFIG_SAE_PK */
   2457 
   2458 	/* 2 bytes are for send-confirm, then the hash, followed by IEs */
   2459 	if (ie_offset)
   2460 		*ie_offset = 2 + hash_len;
   2461 
   2462 	return 0;
   2463 }
   2464 
   2465 
   2466 const char * sae_state_txt(enum sae_state state)
   2467 {
   2468 	switch (state) {
   2469 	case SAE_NOTHING:
   2470 		return "Nothing";
   2471 	case SAE_COMMITTED:
   2472 		return "Committed";
   2473 	case SAE_CONFIRMED:
   2474 		return "Confirmed";
   2475 	case SAE_ACCEPTED:
   2476 		return "Accepted";
   2477 	}
   2478 	return "?";
   2479 }
   2480