diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index bf553797bdff..d157b250ff77 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -30,6 +30,7 @@ #include "driver-ops.h" #include "rate.h" #include "led.h" +#include "fils_aead.h" #define IEEE80211_AUTH_TIMEOUT (HZ / 5) #define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2) @@ -652,6 +653,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */ assoc_data->ie_len + /* extra IEs */ + (assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) + 9, /* WMM */ GFP_KERNEL); if (!skb) @@ -875,6 +877,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) memcpy(pos, assoc_data->ie + offset, noffset - offset); } + if (assoc_data->fils_kek_len && + fils_encrypt_assoc_req(skb, assoc_data) < 0) { + dev_kfree_skb(skb); + return; + } + drv_mgd_prepare_tx(local, sdata); IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; @@ -3146,6 +3154,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, reassoc ? "Rea" : "A", mgmt->sa, capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); + if (assoc_data->fils_kek_len && + fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0) + return; + pos = mgmt->u.assoc_resp.variable; ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), false, &elems); @@ -4707,6 +4719,21 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, assoc_data->ie_len = req->ie_len; } + if (req->fils_kek) { + /* should already be checked in cfg80211 - so warn */ + if (WARN_ON(req->fils_kek_len > FILS_MAX_KEK_LEN)) { + err = -EINVAL; + goto err_free; + } + memcpy(assoc_data->fils_kek, req->fils_kek, + req->fils_kek_len); + assoc_data->fils_kek_len = req->fils_kek_len; + } + + if (req->fils_nonces) + memcpy(assoc_data->fils_nonces, req->fils_nonces, + 2 * FILS_NONCE_LEN); + assoc_data->bss = req->bss; if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) { |