static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
- const u8 *addr)
+ int group, const u8 *addr)
{
struct wpabuf *buf;
u8 *token;
hapd->last_sae_token_key_update = now;
}
- buf = wpabuf_alloc(SHA256_MAC_LEN);
+ buf = wpabuf_alloc(sizeof(le16) + SHA256_MAC_LEN);
if (buf == NULL)
return NULL;
+ wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
+
token = wpabuf_put(buf, SHA256_MAC_LEN);
hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
addr, ETH_ALEN, token);
}
if (auth_transaction == 1) {
- const u8 *token = NULL;
+ const u8 *token = NULL, *pos, *end;
size_t token_len = 0;
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
if ((hapd->conf->mesh & MESH_ENABLED) &&
mgmt->u.auth.status_code ==
WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ && sta->sae->tmp) {
+ pos = mgmt->u.auth.variable;
+ end = ((const u8 *) mgmt) + len;
+ if (pos + sizeof(le16) > end) {
+ wpa_printf(MSG_ERROR,
+ "SAE: Too short anti-clogging token request");
+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto reply;
+ }
+ resp = sae_group_allowed(sta->sae,
+ hapd->conf->sae_groups,
+ WPA_GET_LE16(pos));
+ if (resp != WLAN_STATUS_SUCCESS) {
+ wpa_printf(MSG_ERROR,
+ "SAE: Invalid group in anti-clogging token request");
+ goto reply;
+ }
+ pos += sizeof(le16);
+
wpabuf_free(sta->sae->tmp->anti_clogging_token);
sta->sae->tmp->anti_clogging_token =
- wpabuf_alloc_copy(mgmt->u.auth.variable,
- ((const u8 *) mgmt) + len -
- mgmt->u.auth.variable);
+ wpabuf_alloc_copy(pos, end - pos);
if (sta->sae->tmp->anti_clogging_token == NULL) {
wpa_printf(MSG_ERROR,
"SAE: Failed to alloc for anti-clogging token");
wpa_printf(MSG_DEBUG,
"SAE: Request anti-clogging token from "
MACSTR, MAC2STR(sta->addr));
- data = auth_build_token_req(hapd, sta->addr);
+ data = auth_build_token_req(hapd, sta->sae->group,
+ sta->addr);
resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
if (hapd->conf->mesh & MESH_ENABLED)
sta->sae->state = SAE_NOTHING;
}
-static u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups,
- u16 group)
+u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group)
{
if (allowed_groups) {
int i;
const u8 **token, size_t *token_len, int *allowed_groups);
void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf);
int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len);
+u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group);
#endif /* SAE_H */
static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
u16 status_code, const u8 *data, size_t len)
{
+ int *groups;
+
wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u "
"status code %u", auth_transaction, status_code);
status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
wpa_s->sme.sae.state == SAE_COMMITTED &&
wpa_s->current_bss && wpa_s->current_ssid) {
- wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE anti-clogging token "
- "requested");
+ int default_groups[] = { 19, 20, 21, 25, 26, 0 };
+ u16 group;
+
+ groups = wpa_s->conf->sae_groups;
+ if (!groups || groups[0] <= 0)
+ groups = default_groups;
+
+ if (len < sizeof(le16)) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "SME: Too short SAE anti-clogging token request");
+ return -1;
+ }
+ group = WPA_GET_LE16(data);
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "SME: SAE anti-clogging token requested (group %u)",
+ group);
+ if (sae_group_allowed(&wpa_s->sme.sae, groups, group) !=
+ WLAN_STATUS_SUCCESS) {
+ wpa_dbg(wpa_s, MSG_ERROR,
+ "SME: SAE group %u of anti-clogging request is invalid",
+ group);
+ return -1;
+ }
wpabuf_free(wpa_s->sme.sae_token);
- wpa_s->sme.sae_token = wpabuf_alloc_copy(data, len);
+ wpa_s->sme.sae_token = wpabuf_alloc_copy(data + sizeof(le16),
+ len - sizeof(le16));
sme_send_authentication(wpa_s, wpa_s->current_bss,
wpa_s->current_ssid, 1);
return 0;
return -1;
if (auth_transaction == 1) {
- int *groups = wpa_s->conf->sae_groups;
+ groups = wpa_s->conf->sae_groups;
wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
if (wpa_s->current_bss == NULL ||