apm821xx: remove unnecessary kernel padding
[openwrt/openwrt.git] / package / network / services / hostapd / patches / 061-0008-SAE-Use-const_time-selection-for-PWE-in-FFC.patch
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
5
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,
9 though.
10
11 This is related to CVE-2019-9494.
12
13 Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
14 ---
15 src/common/sae.c | 53 +++++++++++++++++++++++++++++++++++------------------
16 1 file changed, 35 insertions(+), 18 deletions(-)
17
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)
23 {
24 - u8 counter, k;
25 + u8 counter, k, sel_counter = 0;
26 u8 addrs[2 * ETH_ALEN];
27 const u8 *addr[3];
28 size_t len[3];
29 size_t num_elem;
30 - int found = 0;
31 - struct crypto_bignum *pwe = NULL;
32 + u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
33 + * mask */
34 + u8 mask;
35 + struct crypto_bignum *pwe;
36 + size_t prime_len = sae->tmp->prime_len * 8;
37 + u8 *pwe_buf;
38
39 crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
40 sae->tmp->pwe_ffc = NULL;
41
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)
47 + goto fail;
48 +
49 wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
50 password, password_len);
51
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)
55 break;
56 - if (!pwe) {
57 - pwe = crypto_bignum_init();
58 - if (!pwe)
59 - break;
60 - }
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. */
64 if (res < 0)
65 break;
66 - if (res > 0) {
67 - found = 1;
68 - if (!sae->tmp->pwe_ffc) {
69 - wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
70 - sae->tmp->pwe_ffc = pwe;
71 - pwe = NULL;
72 - }
73 - }
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,
78 + prime_len) < 0)
79 + break;
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);
85 }
86
87 - crypto_bignum_deinit(pwe, 1);
88 + if (!found)
89 + goto fail;
90
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);
94 +fail:
95 + crypto_bignum_deinit(pwe, 1);
96 + bin_clear_free(pwe_buf, prime_len * 2);
97 + return sae->tmp->pwe_ffc ? 0 : -1;
98 }
99
100