1 From f8f20717f87eff1f025f48ed585c7684debacf72 Mon Sep 17 00:00:00 2001
2 From: Jouni Malinen <jouni@codeaurora.org>
3 Date: Sat, 2 Mar 2019 12:45:33 +0200
4 Subject: [PATCH 08/14] SAE: Use const_time selection for PWE in FFC
6 This is an initial step towards making the FFC case use strictly
7 constant time operations similarly to the ECC case.
8 sae_test_pwd_seed_ffc() does not yet have constant time behavior,
11 This is related to CVE-2019-9494.
13 Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
15 src/common/sae.c | 53 +++++++++++++++++++++++++++++++++++------------------
16 1 file changed, 35 insertions(+), 18 deletions(-)
18 --- a/src/common/sae.c
19 +++ b/src/common/sae.c
20 @@ -589,17 +589,28 @@ static int sae_derive_pwe_ffc(struct sae
21 const u8 *addr2, const u8 *password,
22 size_t password_len, const char *identifier)
25 + u8 counter, k, sel_counter = 0;
26 u8 addrs[2 * ETH_ALEN];
31 - struct crypto_bignum *pwe = NULL;
32 + u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
35 + struct crypto_bignum *pwe;
36 + size_t prime_len = sae->tmp->prime_len * 8;
39 crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
40 sae->tmp->pwe_ffc = NULL;
42 + /* Allocate a buffer to maintain selected and candidate PWE for constant
43 + * time selection. */
44 + pwe_buf = os_zalloc(prime_len * 2);
45 + pwe = crypto_bignum_init();
46 + if (!pwe_buf || !pwe)
49 wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
50 password, password_len);
52 @@ -638,27 +649,33 @@ static int sae_derive_pwe_ffc(struct sae
53 if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
54 addr, len, pwd_seed) < 0)
57 - pwe = crypto_bignum_init();
61 res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
62 + /* res is -1 for fatal failure, 0 if a valid PWE was not found,
63 + * or 1 if a valid PWE was found. */
68 - if (!sae->tmp->pwe_ffc) {
69 - wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
70 - sae->tmp->pwe_ffc = pwe;
74 + /* Store the candidate PWE into the second half of pwe_buf and
75 + * the selected PWE in the beginning of pwe_buf using constant
76 + * time selection. */
77 + if (crypto_bignum_to_bin(pwe, pwe_buf + prime_len, prime_len,
80 + const_time_select_bin(found, pwe_buf, pwe_buf + prime_len,
81 + prime_len, pwe_buf);
82 + sel_counter = const_time_select_u8(found, sel_counter, counter);
83 + mask = const_time_eq_u8(res, 1);
84 + found = const_time_select_u8(found, found, mask);
87 - crypto_bignum_deinit(pwe, 1);
91 - return found ? 0 : -1;
92 + wpa_printf(MSG_DEBUG, "SAE: Use PWE from counter = %02u", sel_counter);
93 + sae->tmp->pwe_ffc = crypto_bignum_init_set(pwe_buf, prime_len);
95 + crypto_bignum_deinit(pwe, 1);
96 + bin_clear_free(pwe_buf, prime_len * 2);
97 + return sae->tmp->pwe_ffc ? 0 : -1;