1 /*
2  * Simultaneous authentication of equals
3  * Copyright (c) 2012-2016, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "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 
sae_suitable_group(int group)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 
sae_set_group(struct sae_data * sae,int group)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 
sae_clear_temp_data(struct sae_data * sae)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 
sae_clear_data(struct sae_data * sae)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 
buf_shift_right(u8 * buf,size_t len,size_t bits)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 
sae_get_rand(struct sae_data * sae)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 
sae_get_rand_and_mask(struct sae_data * sae)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 
sae_pwd_seed_key(const u8 * addr1,const u8 * addr2,u8 * key)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 *
get_rand_1_to_p_1(const u8 * prime,size_t prime_len,size_t prime_bits,int * r_odd)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 
is_quadratic_residue_blind(struct sae_data * sae,const u8 * prime,size_t bits,const u8 * qr,const u8 * qnr,const struct crypto_bignum * y_sqr)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 
sae_test_pwd_seed_ecc(struct sae_data * sae,const u8 * pwd_seed,const u8 * prime,const u8 * qr,const u8 * qnr,u8 * pwd_value)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. */
sae_test_pwd_seed_ffc(struct sae_data * sae,const u8 * pwd_seed,struct crypto_bignum * pwe)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 
get_random_qr_qnr(const u8 * prime,size_t prime_len,const struct crypto_bignum * prime_bn,size_t prime_bits,struct crypto_bignum ** qr,struct crypto_bignum ** qnr)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 
sae_derive_pwe_ecc(struct sae_data * sae,const u8 * addr1,const u8 * addr2,const u8 * password,size_t password_len,const char * identifier)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 
sae_modp_group_require_masking(int group)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 
sae_derive_pwe_ffc(struct sae_data * sae,const u8 * addr1,const u8 * addr2,const u8 * password,size_t password_len,const char * identifier)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 
sae_derive_commit_element_ecc(struct sae_data * sae,struct crypto_bignum * mask)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 
sae_derive_commit_element_ffc(struct sae_data * sae,struct crypto_bignum * mask)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 
sae_derive_commit(struct sae_data * sae)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 
sae_prepare_commit(const u8 * addr1,const u8 * addr2,const u8 * password,size_t password_len,const char * identifier,struct sae_data * sae)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 
sae_derive_k_ecc(struct sae_data * sae,u8 * k)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 
sae_derive_k_ffc(struct sae_data * sae,u8 * k)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 
sae_derive_keys(struct sae_data * sae,const u8 * k)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 
sae_process_commit(struct sae_data * sae)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 
sae_write_commit(struct sae_data * sae,struct wpabuf * buf,const struct wpabuf * token,const char * identifier)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 
sae_group_allowed(struct sae_data * sae,int * allowed_groups,u16 group)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 
sae_is_password_id_elem(const u8 * pos,const u8 * end)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 
sae_parse_commit_token(struct sae_data * sae,const u8 ** pos,const u8 * end,const u8 ** token,size_t * token_len)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 
sae_parse_commit_scalar(struct sae_data * sae,const u8 ** pos,const u8 * end)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 
sae_parse_commit_element_ecc(struct sae_data * sae,const u8 ** pos,const u8 * end)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 
sae_parse_commit_element_ffc(struct sae_data * sae,const u8 ** pos,const u8 * end)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 
sae_parse_commit_element(struct sae_data * sae,const u8 ** pos,const u8 * end)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 
sae_parse_password_identifier(struct sae_data * sae,const u8 * pos,const u8 * end)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 
sae_parse_commit(struct sae_data * sae,const u8 * data,size_t len,const u8 ** token,size_t * token_len,int * allowed_groups)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 
sae_cn_confirm(struct sae_data * sae,const u8 * sc,const struct crypto_bignum * scalar1,const u8 * element1,size_t element1_len,const struct crypto_bignum * scalar2,const u8 * element2,size_t element2_len,u8 * confirm)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 
sae_cn_confirm_ecc(struct sae_data * sae,const u8 * sc,const struct crypto_bignum * scalar1,const struct crypto_ec_point * element1,const struct crypto_bignum * scalar2,const struct crypto_ec_point * element2,u8 * confirm)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 
sae_cn_confirm_ffc(struct sae_data * sae,const u8 * sc,const struct crypto_bignum * scalar1,const struct crypto_bignum * element1,const struct crypto_bignum * scalar2,const struct crypto_bignum * element2,u8 * confirm)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 
sae_write_confirm(struct sae_data * sae,struct wpabuf * buf)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 
sae_check_confirm(struct sae_data * sae,const u8 * data,size_t len)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 
sae_state_txt(enum sae_state state)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