]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Add Rc variable and peer send-confirm validation
authorJouni Malinen <j@w1.fi>
Wed, 27 Dec 2017 10:14:41 +0000 (12:14 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 27 Dec 2017 10:19:08 +0000 (12:19 +0200)
This implements the behavior described in IEEE Std 802.11-2016,
12.4.8.6.6 (Protocol instance behavior - Accepted state) to silently
discard received Confirm message in the Accepted state if the new
message does not use an incremented send-confirm value or if the special
2^16-1 value is used. This avoids unnecessary processing of
retransmitted Confirm messages.

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

index 5d5087647d525d7671ffcb726790762103e76b1b..53672a7d2124848dec8df1d77dbff34e4149a970 100644 (file)
@@ -963,12 +963,36 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
                        goto remove_sta;
                if (sta->sae->state >= SAE_CONFIRMED ||
                    !(hapd->conf->mesh & MESH_ENABLED)) {
-                       if (sae_check_confirm(sta->sae, mgmt->u.auth.variable,
-                                             ((u8 *) mgmt) + len -
-                                             mgmt->u.auth.variable) < 0) {
+                       const u8 *var;
+                       size_t var_len;
+                       u16 peer_send_confirm;
+
+                       var = mgmt->u.auth.variable;
+                       var_len = ((u8 *) mgmt) + len - mgmt->u.auth.variable;
+                       if (var_len < 2) {
+                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+                               goto reply;
+                       }
+
+                       peer_send_confirm = WPA_GET_LE16(var);
+
+                       if (sta->sae->state == SAE_ACCEPTED &&
+                           (peer_send_confirm <= sta->sae->rc ||
+                            peer_send_confirm == 0xffff)) {
+                               wpa_printf(MSG_DEBUG,
+                                          "SAE: Silently ignore unexpected Confirm from peer "
+                                          MACSTR
+                                          " (peer-send-confirm=%u Rc=%u)",
+                                          MAC2STR(sta->addr),
+                                          peer_send_confirm, sta->sae->rc);
+                               return;
+                       }
+
+                       if (sae_check_confirm(sta->sae, var, var_len) < 0) {
                                resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
                                goto reply;
                        }
+                       sta->sae->rc = peer_send_confirm;
                }
                resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction);
        } else {
index 71275f8c91a50c3272150debfc207baec2ef2f7a..7c07bfba28181bd22700dc68c4316612f43c84fd 100644 (file)
@@ -53,6 +53,7 @@ struct sae_data {
        struct crypto_bignum *peer_commit_scalar;
        int group;
        unsigned int sync; /* protocol instance variable: Sync */
+       u16 rc; /* protocol instance variable: Rc (received send-confirm) */
        struct sae_temporary_data *tmp;
 };