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