Update AKMP, cipher, PMF for driver-based SME while roaming
After roaming to a new AP using driver-based SME and roaming trigger, update proto type, AKMP suite, and pairwise cipher suite based on the (Re)Association Request frame. Update PMF, group cipher, and group mgmt cipher based on the AP's RSNE into wpa_sm. group_mgmt_cipher needs to be updated based on PMF capabilities of STA and roamed AP. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
c8b94bc7b3
commit
0b853303ae
1 changed files with 114 additions and 25 deletions
|
@ -2694,6 +2694,8 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
|
|||
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;
|
||||
|
@ -2727,6 +2729,14 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
|
|||
"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;
|
||||
|
@ -2740,36 +2750,13 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
|
|||
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);
|
||||
|
||||
sel = ie.group_cipher;
|
||||
if (ssid->group_cipher)
|
||||
sel &= ssid->group_cipher;
|
||||
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"WPA: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x",
|
||||
ie.group_cipher, ssid->group_cipher, sel);
|
||||
if (ie.group_cipher && !sel) {
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_s->group_cipher = ie.group_cipher;
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
|
||||
wpa_cipher_txt(wpa_s->group_cipher));
|
||||
|
||||
/* Update pairwise cipher from (Re)Association Request frame info */
|
||||
sel = ie.pairwise_cipher;
|
||||
if (ssid->pairwise_cipher)
|
||||
sel &= ssid->pairwise_cipher;
|
||||
|
@ -2789,7 +2776,109 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
|
|||
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);
|
||||
/* 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: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x",
|
||||
ie.group_cipher, ssid->group_cipher, sel);
|
||||
if (ie.group_cipher && !sel) {
|
||||
wpa_supplicant_deauthenticate(
|
||||
wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_s->group_cipher = ie.group_cipher;
|
||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
|
||||
wpa_cipher_txt(wpa_s->group_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 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_CIPHER_SUITE_REJECTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue