1 From: Hante Meuleman <hante.meuleman@broadcom.com>
2 Date: Wed, 17 Feb 2016 11:27:10 +0100
3 Subject: [PATCH] brcmfmac: add 802.11w management frame protection support
5 Add full support for both AP and STA for management frame protection.
7 Reviewed-by: Arend Van Spriel <arend.van@broadcom.com>
8 Reviewed-by: Franky (Zhenhui) Lin <franky.lin@broadcom.com>
9 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
10 Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
11 Signed-off-by: Arend van Spriel <arend@broadcom.com>
12 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
15 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
16 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
18 #define RSN_AKM_NONE 0 /* None (IBSS) */
19 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
20 #define RSN_AKM_PSK 2 /* Pre-shared Key */
21 +#define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */
22 +#define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */
23 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
24 -#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
25 +#define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
26 +#define RSN_CAP_MFPR_MASK BIT(6)
27 +#define RSN_CAP_MFPC_MASK BIT(7)
28 +#define RSN_PMKID_COUNT_LEN 2
30 #define VNDR_IE_CMD_LEN 4 /* length of the set command
31 * string :"add", "del" (+ NUL)
32 @@ -211,12 +216,19 @@ static const struct ieee80211_regdomain
33 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
36 -static const u32 __wl_cipher_suites[] = {
37 +/* Note: brcmf_cipher_suites is an array of int defining which cipher suites
38 + * are supported. A pointer to this array and the number of entries is passed
39 + * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
40 + * So the cipher suite AES_CMAC has to be the last one in the array, and when
41 + * device does not support MFP then the number of suites will be decreased by 1
43 +static const u32 brcmf_cipher_suites[] = {
44 WLAN_CIPHER_SUITE_WEP40,
45 WLAN_CIPHER_SUITE_WEP104,
46 WLAN_CIPHER_SUITE_TKIP,
47 WLAN_CIPHER_SUITE_CCMP,
48 - WLAN_CIPHER_SUITE_AES_CMAC,
49 + /* Keep as last entry: */
50 + WLAN_CIPHER_SUITE_AES_CMAC
53 /* Vendor specific ie. id = 221, oui and type defines exact ie */
54 @@ -1533,7 +1545,7 @@ static s32 brcmf_set_auth_type(struct ne
57 brcmf_set_wsec_mode(struct net_device *ndev,
58 - struct cfg80211_connect_params *sme, bool mfp)
59 + struct cfg80211_connect_params *sme)
61 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
62 struct brcmf_cfg80211_security *sec;
63 @@ -1592,10 +1604,7 @@ brcmf_set_wsec_mode(struct net_device *n
68 - wsec = pval | gval | MFP_CAPABLE;
72 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
74 brcmf_err("error (%d)\n", err);
75 @@ -1612,56 +1621,100 @@ brcmf_set_wsec_mode(struct net_device *n
77 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
79 - struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
80 - struct brcmf_cfg80211_security *sec;
83 + struct brcmf_if *ifp = netdev_priv(ndev);
86 + const struct brcmf_tlv *rsn_ie;
94 - if (sme->crypto.n_akm_suites) {
95 - err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
98 - brcmf_err("could not get wpa_auth (%d)\n", err);
100 + if (!sme->crypto.n_akm_suites)
103 + err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
105 + brcmf_err("could not get wpa_auth (%d)\n", err);
108 + if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
109 + switch (sme->crypto.akm_suites[0]) {
110 + case WLAN_AKM_SUITE_8021X:
111 + val = WPA_AUTH_UNSPECIFIED;
113 + case WLAN_AKM_SUITE_PSK:
114 + val = WPA_AUTH_PSK;
117 + brcmf_err("invalid cipher group (%d)\n",
118 + sme->crypto.cipher_group);
121 - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
122 - switch (sme->crypto.akm_suites[0]) {
123 - case WLAN_AKM_SUITE_8021X:
124 - val = WPA_AUTH_UNSPECIFIED;
126 - case WLAN_AKM_SUITE_PSK:
127 - val = WPA_AUTH_PSK;
130 - brcmf_err("invalid cipher group (%d)\n",
131 - sme->crypto.cipher_group);
134 - } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
135 - switch (sme->crypto.akm_suites[0]) {
136 - case WLAN_AKM_SUITE_8021X:
137 - val = WPA2_AUTH_UNSPECIFIED;
139 - case WLAN_AKM_SUITE_PSK:
140 - val = WPA2_AUTH_PSK;
143 - brcmf_err("invalid cipher group (%d)\n",
144 - sme->crypto.cipher_group);
147 + } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
148 + switch (sme->crypto.akm_suites[0]) {
149 + case WLAN_AKM_SUITE_8021X:
150 + val = WPA2_AUTH_UNSPECIFIED;
152 + case WLAN_AKM_SUITE_8021X_SHA256:
153 + val = WPA2_AUTH_1X_SHA256;
155 + case WLAN_AKM_SUITE_PSK_SHA256:
156 + val = WPA2_AUTH_PSK_SHA256;
158 + case WLAN_AKM_SUITE_PSK:
159 + val = WPA2_AUTH_PSK;
162 + brcmf_err("invalid cipher group (%d)\n",
163 + sme->crypto.cipher_group);
168 - brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
169 - err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
172 - brcmf_err("could not set wpa_auth (%d)\n", err);
175 + if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
176 + goto skip_mfp_config;
177 + /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
178 + * IE will not be verified, just a quick search for MFP config
180 + rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
183 + goto skip_mfp_config;
184 + ie = (const u8 *)rsn_ie;
185 + ie_len = rsn_ie->len + TLV_HDR_LEN;
186 + /* Skip unicast suite */
187 + offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
188 + if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
189 + goto skip_mfp_config;
190 + /* Skip multicast suite */
191 + count = ie[offset] + (ie[offset + 1] << 8);
192 + offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
193 + if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
194 + goto skip_mfp_config;
195 + /* Skip auth key management suite(s) */
196 + count = ie[offset] + (ie[offset + 1] << 8);
197 + offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
198 + if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
199 + goto skip_mfp_config;
200 + /* Ready to read capabilities */
201 + mfp = BRCMF_MFP_NONE;
202 + rsn_cap = ie[offset] + (ie[offset + 1] << 8);
203 + if (rsn_cap & RSN_CAP_MFPR_MASK)
204 + mfp = BRCMF_MFP_REQUIRED;
205 + else if (rsn_cap & RSN_CAP_MFPC_MASK)
206 + mfp = BRCMF_MFP_CAPABLE;
207 + brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
210 + brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
211 + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
213 + brcmf_err("could not set wpa_auth (%d)\n", err);
216 - sec = &profile->sec;
217 - sec->wpa_auth = sme->crypto.akm_suites[0];
221 @@ -1827,7 +1880,7 @@ brcmf_cfg80211_connect(struct wiphy *wip
225 - err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
226 + err = brcmf_set_wsec_mode(ndev, sme);
228 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
230 @@ -2077,10 +2130,12 @@ brcmf_cfg80211_del_key(struct wiphy *wip
231 u8 key_idx, bool pairwise, const u8 *mac_addr)
233 struct brcmf_if *ifp = netdev_priv(ndev);
234 - struct brcmf_wsec_key key;
236 + struct brcmf_wsec_key *key;
239 brcmf_dbg(TRACE, "Enter\n");
240 + brcmf_dbg(CONN, "key index (%d)\n", key_idx);
242 if (!check_vif_up(ifp->vif))
245 @@ -2089,16 +2144,19 @@ brcmf_cfg80211_del_key(struct wiphy *wip
249 - memset(&key, 0, sizeof(key));
250 + key = &ifp->vif->profile.key[key_idx];
252 - key.index = (u32)key_idx;
253 - key.flags = BRCMF_PRIMARY_KEY;
254 - key.algo = CRYPTO_ALGO_OFF;
255 + if (key->algo == CRYPTO_ALGO_OFF) {
256 + brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
260 - brcmf_dbg(CONN, "key index (%d)\n", key_idx);
261 + memset(key, 0, sizeof(*key));
262 + key->index = (u32)key_idx;
263 + key->flags = BRCMF_PRIMARY_KEY;
265 - /* Set the new key/index */
266 - err = send_key_to_dongle(ifp, &key);
267 + /* Clear the key/index */
268 + err = send_key_to_dongle(ifp, key);
270 brcmf_dbg(TRACE, "Exit\n");
272 @@ -2106,8 +2164,8 @@ brcmf_cfg80211_del_key(struct wiphy *wip
275 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
276 - u8 key_idx, bool pairwise, const u8 *mac_addr,
277 - struct key_params *params)
278 + u8 key_idx, bool pairwise, const u8 *mac_addr,
279 + struct key_params *params)
281 struct brcmf_if *ifp = netdev_priv(ndev);
282 struct brcmf_wsec_key *key;
283 @@ -2214,9 +2272,10 @@ done:
287 -brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
288 - u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
289 - void (*callback) (void *cookie, struct key_params * params))
290 +brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
291 + bool pairwise, const u8 *mac_addr, void *cookie,
292 + void (*callback)(void *cookie,
293 + struct key_params *params))
295 struct key_params params;
296 struct brcmf_if *ifp = netdev_priv(ndev);
297 @@ -2268,8 +2327,15 @@ done:
300 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
301 - struct net_device *ndev, u8 key_idx)
302 + struct net_device *ndev, u8 key_idx)
304 + struct brcmf_if *ifp = netdev_priv(ndev);
306 + brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
308 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
311 brcmf_dbg(INFO, "Not supported\n");
314 @@ -3769,7 +3835,7 @@ brcmf_configure_wpaie(struct brcmf_if *i
315 u32 auth = 0; /* d11 open authentication */
323 @@ -3779,6 +3845,7 @@ brcmf_configure_wpaie(struct brcmf_if *i
329 brcmf_dbg(TRACE, "Enter\n");
331 @@ -3893,19 +3960,53 @@ brcmf_configure_wpaie(struct brcmf_if *i
332 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
333 (wpa_auth |= WPA_AUTH_PSK);
335 + case RSN_AKM_SHA256_PSK:
336 + brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
337 + wpa_auth |= WPA2_AUTH_PSK_SHA256;
339 + case RSN_AKM_SHA256_1X:
340 + brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
341 + wpa_auth |= WPA2_AUTH_1X_SHA256;
344 brcmf_err("Ivalid key mgmt info\n");
349 + mfp = BRCMF_MFP_NONE;
352 if ((offset + RSN_CAP_LEN) <= len) {
353 rsn_cap = data[offset] + (data[offset + 1] << 8);
354 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
356 + if (rsn_cap & RSN_CAP_MFPR_MASK) {
357 + brcmf_dbg(TRACE, "MFP Required\n");
358 + mfp = BRCMF_MFP_REQUIRED;
359 + /* Firmware only supports mfp required in
360 + * combination with WPA2_AUTH_PSK_SHA256 or
361 + * WPA2_AUTH_1X_SHA256.
363 + if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
364 + WPA2_AUTH_1X_SHA256))) {
368 + /* Firmware has requirement that WPA2_AUTH_PSK/
369 + * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
370 + * is to be included in the rsn ie.
372 + if (wpa_auth & WPA2_AUTH_PSK_SHA256)
373 + wpa_auth |= WPA2_AUTH_PSK;
374 + else if (wpa_auth & WPA2_AUTH_1X_SHA256)
375 + wpa_auth |= WPA2_AUTH_UNSPECIFIED;
376 + } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
377 + brcmf_dbg(TRACE, "MFP Capable\n");
378 + mfp = BRCMF_MFP_CAPABLE;
381 + offset += RSN_CAP_LEN;
382 /* set wme_bss_disable to sync RSN Capabilities */
383 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
385 @@ -3913,6 +4014,21 @@ brcmf_configure_wpaie(struct brcmf_if *i
386 brcmf_err("wme_bss_disable error %d\n", err);
390 + /* Skip PMKID cnt as it is know to be 0 for AP. */
391 + offset += RSN_PMKID_COUNT_LEN;
393 + /* See if there is BIP wpa suite left for MFP */
394 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
395 + ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
396 + err = brcmf_fil_bsscfg_data_set(ifp, "bip",
398 + WPA_IE_MIN_OUI_LEN);
400 + brcmf_err("bip error %d\n", err);
405 /* FOR WPS , set SES_OW_ENABLED */
406 wsec = (pval | gval | SES_OW_ENABLED);
407 @@ -3929,6 +4045,16 @@ brcmf_configure_wpaie(struct brcmf_if *i
408 brcmf_err("wsec error %d\n", err);
411 + /* Configure MFP, this needs to go after wsec otherwise the wsec command
412 + * will overwrite the values set by MFP
414 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
415 + err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
417 + brcmf_err("mfp error %d\n", err);
421 /* set upper-layer auth */
422 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
424 @@ -6149,8 +6275,10 @@ static int brcmf_setup_wiphy(struct wiph
425 wiphy->n_addresses = i;
427 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
428 - wiphy->cipher_suites = __wl_cipher_suites;
429 - wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
430 + wiphy->cipher_suites = brcmf_cipher_suites;
431 + wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
432 + if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
433 + wiphy->n_cipher_suites--;
434 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
435 WIPHY_FLAG_OFFCHAN_TX |
436 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
437 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
438 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
441 #define BRCMF_VNDR_IE_P2PAF_SHIFT 12
443 -#define BRCMF_MAX_DEFAULT_KEYS 4
444 +#define BRCMF_MAX_DEFAULT_KEYS 6
446 /* beacon loss timeout defaults */
447 #define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2
448 @@ -107,7 +107,6 @@ struct brcmf_cfg80211_security {
456 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
457 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
458 @@ -161,6 +161,7 @@ void brcmf_feat_attach(struct brcmf_pub
459 ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
460 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
461 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
462 + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp");
464 pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
465 err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac,
466 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
467 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
469 * WOWL_ND: WOWL net detect (PNO)
470 * WOWL_GTK: (WOWL) GTK rekeying offload
471 * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL.
472 + * MFP: 802.11w Management Frame Protection.
474 #define BRCMF_FEAT_LIST \
475 BRCMF_FEAT_DEF(MBSS) \
477 BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \
478 BRCMF_FEAT_DEF(WOWL_ND) \
479 BRCMF_FEAT_DEF(WOWL_GTK) \
480 - BRCMF_FEAT_DEF(WOWL_ARP_ND)
481 + BRCMF_FEAT_DEF(WOWL_ARP_ND) \
482 + BRCMF_FEAT_DEF(MFP)
486 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
487 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
489 #define BRCMF_RSN_KEK_LENGTH 16
490 #define BRCMF_RSN_REPLAY_LEN 8
492 +#define BRCMF_MFP_NONE 0
493 +#define BRCMF_MFP_CAPABLE 1
494 +#define BRCMF_MFP_REQUIRED 2
496 /* join preference types for join_pref iovar */
497 enum brcmf_join_pref_types {
498 BRCMF_JOIN_PREF_RSSI = 1,
499 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
500 +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
501 @@ -236,6 +236,8 @@ static inline bool ac_bitmap_tst(u8 bitm
502 #define WPA2_AUTH_RESERVED3 0x0200
503 #define WPA2_AUTH_RESERVED4 0x0400
504 #define WPA2_AUTH_RESERVED5 0x0800
505 +#define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */
506 +#define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */
508 #define DOT11_DEFAULT_RTS_LEN 2347
509 #define DOT11_DEFAULT_FRAG_LEN 2346