aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2017-12-27 10:14:41 (GMT)
committerJouni Malinen <j@w1.fi>2017-12-27 10:19:08 (GMT)
commitabcbd0604cc604bc62b6d47d30559111447ea88c (patch)
tree2181601abfd20cb4661952a79cadc073d5adf9bd
parent9249afc8e19d7d87faf88609bb99e00551e1acd8 (diff)
downloadhostap-abcbd0604cc604bc62b6d47d30559111447ea88c.zip
hostap-abcbd0604cc604bc62b6d47d30559111447ea88c.tar.gz
hostap-abcbd0604cc604bc62b6d47d30559111447ea88c.tar.bz2
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>
-rw-r--r--src/ap/ieee802_11.c30
-rw-r--r--src/common/sae.h1
2 files changed, 28 insertions, 3 deletions
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 5d50876..53672a7 100644
--- a/src/ap/ieee802_11.c
+++ b/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 {
diff --git a/src/common/sae.h b/src/common/sae.h
index 71275f8..7c07bfb 100644
--- a/src/common/sae.h
+++ b/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;
};