Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/wpa/dist/src/common These groups have significa...



details:   https://anonhg.NetBSD.org/src/rev/5ef95cf0a00a
branches:  trunk
changeset: 455710:5ef95cf0a00a
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Apr 10 18:00:21 2019 +0000

description:
These groups have significant probability of coming up with pwd-value
that is equal or greater than the prime and as such, need for going
through the PWE derivation loop multiple times. This can result in
sufficient timing different to allow an external observer to determine
how many rounds are needed and that can leak information about the used
password.

Force at least 40 loop rounds for these MODP groups similarly to the ECC
group design to mask timing. This behavior is not described in IEEE Std
802.11-2016 for SAE, but it does not result in different values (i.e.,
only different timing), so such implementation specific countermeasures
can be done without breaking interoperability with other implementation.

Note: These MODP groups 22, 23, and 24 are not considered sufficiently
strong to be used with SAE (or more or less anything else). As such,
they should never be enabled in runtime configuration for any production
use cases. These changes to introduce additional protection to mask
timing is only for completeness of implementation and not an indication
that these groups should be used.

This is related to CVE-2019-9494.

diffstat:

 external/bsd/wpa/dist/src/common/sae.c |  38 +++++++++++++++++++++++++--------
 1 files changed, 28 insertions(+), 10 deletions(-)

diffs (82 lines):

diff -r 045c9b192720 -r 5ef95cf0a00a external/bsd/wpa/dist/src/common/sae.c
--- a/external/bsd/wpa/dist/src/common/sae.c    Wed Apr 10 17:59:35 2019 +0000
+++ b/external/bsd/wpa/dist/src/common/sae.c    Wed Apr 10 18:00:21 2019 +0000
@@ -578,22 +578,27 @@
 }
 
 
+static int sae_modp_group_require_masking(int group)
+{
+       /* Groups for which pwd-value is likely to be >= p frequently */
+       return group == 22 || group == 23 || group == 24;
+}
+
+
 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;
+       u8 counter, k;
        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;
 
-       if (sae->tmp->pwe_ffc == NULL) {
-               sae->tmp->pwe_ffc = crypto_bignum_init();
-               if (sae->tmp->pwe_ffc == NULL)
-                       return -1;
-       }
+       crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
+       sae->tmp->pwe_ffc = NULL;
 
        wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
                              password, password_len);
@@ -617,7 +622,9 @@
        len[num_elem] = sizeof(counter);
        num_elem++;
 
-       for (counter = 1; !found; counter++) {
+       k = sae_modp_group_require_masking(sae->group) ? 40 : 1;
+
+       for (counter = 1; counter <= k || !found; counter++) {
                u8 pwd_seed[SHA256_MAC_LEN];
                int res;
 
@@ -627,19 +634,30 @@
                        break;
                }
 
-               wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
+               wpa_printf(MSG_DEBUG, "SAE: counter = %02u", counter);
                if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
                                       addr, len, pwd_seed) < 0)
                        break;
-               res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc);
+               if (!pwe) {
+                       pwe = crypto_bignum_init();
+                       if (!pwe)
+                               break;
+               }
+               res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
                if (res < 0)
                        break;
                if (res > 0) {
-                       wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
                        found = 1;
+                       if (!sae->tmp->pwe_ffc) {
+                               wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
+                               sae->tmp->pwe_ffc = pwe;
+                               pwe = NULL;
+                       }
                }
        }
 
+       crypto_bignum_deinit(pwe, 1);
+
        return found ? 0 : -1;
 }
 



Home | Main Index | Thread Index | Old Index