bool found = false;
struct wpa_ie_data ie;
struct wpa_ssid *ssid = wpa_s->current_ssid;
+ struct wpa_bss *bss = wpa_s->current_bss;
+ int pmf;
if (!ssid)
return 0;
"WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq",
p, l);
+ /* Update proto from (Re)Association Request frame info */
+ wpa_s->wpa_proto = ie.proto;
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto);
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
+ !!(wpa_s->wpa_proto &
+ (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
+
+ /* Update AKMP suite from (Re)Association Request frame info */
sel = ie.key_mgmt;
if (ssid->key_mgmt)
sel &= ssid->key_mgmt;
return -1;
}
- wpa_s->wpa_proto = ie.proto;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto);
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
- !!(wpa_s->wpa_proto &
- (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
-
wpa_s->key_mgmt = ie.key_mgmt;
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT %s and proto %d",
wpa_key_mgmt_txt(wpa_s->key_mgmt, wpa_s->wpa_proto),
wpa_s->wpa_proto);
+ /* Update pairwise cipher from (Re)Association Request frame info */
+ sel = ie.pairwise_cipher;
+ if (ssid->pairwise_cipher)
+ sel &= ssid->pairwise_cipher;
+
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: AP pairwise cipher 0x%x network pairwise cipher 0x%x; available pairwise cipher 0x%x",
+ ie.pairwise_cipher, ssid->pairwise_cipher, sel);
+ if (ie.pairwise_cipher && !sel) {
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID);
+ return -1;
+ }
+
+ wpa_s->pairwise_cipher = ie.pairwise_cipher;
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
+ wpa_s->pairwise_cipher);
+ wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
+ wpa_cipher_txt(wpa_s->pairwise_cipher));
+
+ /* Update other parameters based on AP's WPA IE/RSNE, if available */
+ if (!bss) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: current_bss == NULL - skip AP IE check");
+ return 0;
+ }
+
+ /* Update GTK and IGTK from AP's RSNE */
+ found = false;
+
+ if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) {
+ const u8 *bss_rsn;
+
+ bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+ if (bss_rsn) {
+ p = bss_rsn;
+ len = 2 + bss_rsn[1];
+ found = true;
+ }
+ } else if (wpa_s->wpa_proto & WPA_PROTO_WPA) {
+ const u8 *bss_wpa;
+
+ bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+ if (bss_wpa) {
+ p = bss_wpa;
+ len = 2 + bss_wpa[1];
+ found = true;
+ }
+ }
+
+ if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
+ return 0;
+
+ pmf = wpas_get_ssid_pmf(wpa_s, ssid);
+ if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
+ pmf == MGMT_FRAME_PROTECTION_REQUIRED) {
+ /* AP does not support MFP, local configuration requires it */
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
+ return -1;
+ }
+ if ((ie.capabilities & WPA_CAPABILITY_MFPR) &&
+ pmf == NO_MGMT_FRAME_PROTECTION) {
+ /* AP requires MFP, local configuration disables it */
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
+ return -1;
+ }
+
+ /* Update PMF from local configuration now that MFP validation was done
+ * above */
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, pmf);
+
+ /* Update GTK from AP's RSNE */
sel = ie.group_cipher;
if (ssid->group_cipher)
sel &= ssid->group_cipher;
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
wpa_cipher_txt(wpa_s->group_cipher));
- sel = ie.pairwise_cipher;
- if (ssid->pairwise_cipher)
- sel &= ssid->pairwise_cipher;
+ /* Update IGTK from AP RSN IE */
+ sel = ie.mgmt_group_cipher;
+ if (ssid->group_mgmt_cipher)
+ sel &= ssid->group_mgmt_cipher;
wpa_dbg(wpa_s, MSG_DEBUG,
- "WPA: AP pairwise cipher 0x%x network pairwise cipher 0x%x; available pairwise cipher 0x%x",
- ie.pairwise_cipher, ssid->pairwise_cipher, sel);
- if (ie.pairwise_cipher && !sel) {
+ "WPA: AP mgmt_group_cipher 0x%x network mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
+ ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
+
+ if (pmf == NO_MGMT_FRAME_PROTECTION ||
+ !(ie.capabilities & WPA_CAPABILITY_MFPC)) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "WPA: STA/AP is not MFP capable; AP RSNE caps 0x%x",
+ ie.capabilities);
+ ie.mgmt_group_cipher = 0;
+ }
+
+ if (ie.mgmt_group_cipher && !sel) {
wpa_supplicant_deauthenticate(
- wpa_s, WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID);
+ wpa_s, WLAN_REASON_CIPHER_SUITE_REJECTED);
return -1;
}
- wpa_s->pairwise_cipher = ie.pairwise_cipher;
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
- wpa_s->pairwise_cipher);
- wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
- wpa_cipher_txt(wpa_s->pairwise_cipher));
-
- wpas_set_mgmt_group_cipher(wpa_s, ssid, &ie);
+ wpa_s->mgmt_group_cipher = ie.mgmt_group_cipher;
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
+ wpa_s->mgmt_group_cipher);
+ if (wpa_s->mgmt_group_cipher)
+ wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher %s",
+ wpa_cipher_txt(wpa_s->mgmt_group_cipher));
+ else
+ wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
return 0;
}