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