aboutsummaryrefslogtreecommitdiffstats
path: root/main/hostapd/0006-SAE-Use-const_time-selection-for-PWE-in-FFC.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/hostapd/0006-SAE-Use-const_time-selection-for-PWE-in-FFC.patch')
-rw-r--r--main/hostapd/0006-SAE-Use-const_time-selection-for-PWE-in-FFC.patch105
1 files changed, 105 insertions, 0 deletions
diff --git a/main/hostapd/0006-SAE-Use-const_time-selection-for-PWE-in-FFC.patch b/main/hostapd/0006-SAE-Use-const_time-selection-for-PWE-in-FFC.patch
new file mode 100644
index 0000000000..f336d5b74a
--- /dev/null
+++ b/main/hostapd/0006-SAE-Use-const_time-selection-for-PWE-in-FFC.patch
@@ -0,0 +1,105 @@
+From f8f20717f87eff1f025f48ed585c7684debacf72 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@codeaurora.org>
+Date: Sat, 2 Mar 2019 12:45:33 +0200
+Subject: [PATCH] SAE: Use const_time selection for PWE in FFC
+
+This is an initial step towards making the FFC case use strictly
+constant time operations similarly to the ECC case.
+sae_test_pwd_seed_ffc() does not yet have constant time behavior,
+though.
+
+This is related to CVE-2019-9494.
+
+Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
+---
+ src/common/sae.c | 53 ++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 35 insertions(+), 18 deletions(-)
+
+diff --git a/src/common/sae.c b/src/common/sae.c
+index 75b1b4a83..fa9a145e3 100644
+--- a/src/common/sae.c
++++ b/src/common/sae.c
+@@ -612,17 +612,28 @@ static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
+ const u8 *addr2, const u8 *password,
+ size_t password_len, const char *identifier)
+ {
+- u8 counter, k;
++ u8 counter, k, sel_counter = 0;
+ u8 addrs[2 * ETH_ALEN];
+ const u8 *addr[3];
+ size_t len[3];
+ size_t num_elem;
+- int found = 0;
+- struct crypto_bignum *pwe = NULL;
++ u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
++ * mask */
++ u8 mask;
++ struct crypto_bignum *pwe;
++ size_t prime_len = sae->tmp->prime_len * 8;
++ u8 *pwe_buf;
+
+ crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
+ sae->tmp->pwe_ffc = NULL;
+
++ /* Allocate a buffer to maintain selected and candidate PWE for constant
++ * time selection. */
++ pwe_buf = os_zalloc(prime_len * 2);
++ pwe = crypto_bignum_init();
++ if (!pwe_buf || !pwe)
++ goto fail;
++
+ wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
+ password, password_len);
+
+@@ -661,27 +672,33 @@ static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
+ if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
+ addr, len, pwd_seed) < 0)
+ break;
+- if (!pwe) {
+- pwe = crypto_bignum_init();
+- if (!pwe)
+- break;
+- }
+ res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
++ /* res is -1 for fatal failure, 0 if a valid PWE was not found,
++ * or 1 if a valid PWE was found. */
+ if (res < 0)
+ break;
+- if (res > 0) {
+- found = 1;
+- if (!sae->tmp->pwe_ffc) {
+- wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
+- sae->tmp->pwe_ffc = pwe;
+- pwe = NULL;
+- }
+- }
++ /* Store the candidate PWE into the second half of pwe_buf and
++ * the selected PWE in the beginning of pwe_buf using constant
++ * time selection. */
++ if (crypto_bignum_to_bin(pwe, pwe_buf + prime_len, prime_len,
++ prime_len) < 0)
++ break;
++ const_time_select_bin(found, pwe_buf, pwe_buf + prime_len,
++ prime_len, pwe_buf);
++ sel_counter = const_time_select_u8(found, sel_counter, counter);
++ mask = const_time_eq_u8(res, 1);
++ found = const_time_select_u8(found, found, mask);
+ }
+
+- crypto_bignum_deinit(pwe, 1);
++ if (!found)
++ goto fail;
+
+- return found ? 0 : -1;
++ wpa_printf(MSG_DEBUG, "SAE: Use PWE from counter = %02u", sel_counter);
++ sae->tmp->pwe_ffc = crypto_bignum_init_set(pwe_buf, prime_len);
++fail:
++ crypto_bignum_deinit(pwe, 1);
++ bin_clear_free(pwe_buf, prime_len * 2);
++ return sae->tmp->pwe_ffc ? 0 : -1;
+ }
+
+
+--
+2.21.0
+