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