diff options
author | Jouni Malinen <j@w1.fi> | 2017-12-27 10:14:41 (GMT) |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2017-12-27 10:19:08 (GMT) |
commit | abcbd0604cc604bc62b6d47d30559111447ea88c (patch) | |
tree | 2181601abfd20cb4661952a79cadc073d5adf9bd | |
parent | 9249afc8e19d7d87faf88609bb99e00551e1acd8 (diff) | |
download | hostap-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.c | 30 | ||||
-rw-r--r-- | src/common/sae.h | 1 |
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; }; |