]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Verify that own/peer commit-scalar and COMMIT-ELEMENT are different
authorJouni Malinen <j@w1.fi>
Tue, 23 Jun 2015 19:30:15 +0000 (22:30 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 23 Jun 2015 20:10:36 +0000 (23:10 +0300)
This check explicitly for reflection attack and stops authentication
immediately if that is detected instead of continuing to the following
4-way handshake that would fail due to the attacker not knowing the key
from the SAE exchange.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/ieee802_11.c
src/common/sae.c
src/common/sae.h
wpa_supplicant/sme.c

index 8d2a06637cb7c9ba66907a50db65311157246d56..db20c86790936b8be17847039c29139b8e54a8e3 100644 (file)
@@ -769,6 +769,12 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
                                        ((const u8 *) mgmt) + len -
                                        mgmt->u.auth.variable, &token,
                                        &token_len, hapd->conf->sae_groups);
+               if (resp == SAE_SILENTLY_DISCARD) {
+                       wpa_printf(MSG_DEBUG,
+                                  "SAE: Drop commit message from " MACSTR " due to reflection attack",
+                                  MAC2STR(sta->addr));
+                       return;
+               }
                if (token && check_sae_token(hapd, sta->addr, token, token_len)
                    < 0) {
                        wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
index ae200f3e0b8194914c9c0437931734d4fd3b9db3..e3b61a63f155ded86dd3ed43678eab8338e92449 100644 (file)
@@ -915,7 +915,34 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
                return res;
 
        /* commit-element */
-       return sae_parse_commit_element(sae, pos, end);
+       res = sae_parse_commit_element(sae, pos, end);
+       if (res != WLAN_STATUS_SUCCESS)
+               return res;
+
+       /*
+        * Check whether peer-commit-scalar and PEER-COMMIT-ELEMENT are same as
+        * the values we sent which would be evidence of a reflection attack.
+        */
+       if (!sae->tmp->own_commit_scalar ||
+           crypto_bignum_cmp(sae->tmp->own_commit_scalar,
+                             sae->peer_commit_scalar) != 0 ||
+           (sae->tmp->dh &&
+            (!sae->tmp->own_commit_element_ffc ||
+             crypto_bignum_cmp(sae->tmp->own_commit_element_ffc,
+                               sae->tmp->peer_commit_element_ffc) != 0)) ||
+           (sae->tmp->ec &&
+            (!sae->tmp->own_commit_element_ecc ||
+             crypto_ec_point_cmp(sae->tmp->ec,
+                                 sae->tmp->own_commit_element_ecc,
+                                 sae->tmp->peer_commit_element_ecc) != 0)))
+               return WLAN_STATUS_SUCCESS; /* scalars/elements are different */
+
+       /*
+        * This is a reflection attack - return special value to trigger caller
+        * to silently discard the frame instead of replying with a specific
+        * status code.
+        */
+       return SAE_SILENTLY_DISCARD;
 }
 
 
index 3ebf40cf4a45d795093a6728053125280515aaae..c07026cd497ccaa2de1cb0643776131d39ec102d 100644 (file)
@@ -18,6 +18,9 @@
 #define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN)
 #define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_PRIME_LEN)
 
+/* Special value returned by sae_parse_commit() */
+#define SAE_SILENTLY_DISCARD 65535
+
 struct sae_temporary_data {
        u8 kck[SAE_KCK_LEN];
        struct crypto_bignum *own_commit_scalar;
index 234670ae255bcaa4092375fe822f2253860867d4..a472febbb6c0863e2fbe9cc3546bdbd9ff3bd082 100644 (file)
@@ -698,6 +698,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
                return -1;
 
        if (auth_transaction == 1) {
+               u16 res;
+
                groups = wpa_s->conf->sae_groups;
 
                wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
@@ -708,8 +710,14 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
                        return -1;
                if (groups && groups[0] <= 0)
                        groups = NULL;
-               if (sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
-                                    groups) != WLAN_STATUS_SUCCESS)
+               res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
+                                      groups);
+               if (res == SAE_SILENTLY_DISCARD) {
+                       wpa_printf(MSG_DEBUG,
+                                  "SAE: Drop commit message due to reflection attack");
+                       return 0;
+               }
+               if (res != WLAN_STATUS_SUCCESS)
                        return -1;
 
                if (sae_process_commit(&wpa_s->sme.sae) < 0) {