Parcourir la source

SAE: Add Rc variable and peer send-confirm validation

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>
Jouni Malinen il y a 7 ans
Parent
commit
abcbd0604c
2 fichiers modifiés avec 28 ajouts et 3 suppressions
  1. 27 3
      src/ap/ieee802_11.c
  2. 1 0
      src/common/sae.h

+ 27 - 3
src/ap/ieee802_11.c

@@ -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 {

+ 1 - 0
src/common/sae.h

@@ -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;
 };