PASN: Include RSNXE in the PASN negotiation

IEEE P802.11az/D2.6 added definitions to include RSNXE in the PASN
negotiation. Implement the new functionality in both wpa_supplicant and
hostapd.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
Ilan Peer 2020-12-16 13:01:38 +02:00 committed by Jouni Malinen
parent d8cd20e37b
commit 9e7b980d65
7 changed files with 86 additions and 18 deletions

View file

@ -266,7 +266,7 @@ static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
}
static const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
{
const u8 *ies;
size_t ies_len;

View file

@ -30,4 +30,6 @@ sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
struct wpabuf **probe_ie_taxonomy);
const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid);
#endif /* BEACON_H */

View file

@ -2877,9 +2877,10 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd,
{
struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
u8 mic[WPA_PASN_MAX_MIC_LEN];
u8 mic_len, data_len;
u8 mic_len, frame_len, data_len;
u8 *ptr;
const u8 *data, *rsn_ie;
const u8 *frame, *data, *rsn_ie, *rsnxe_ie;
u8 *data_buf = NULL;
size_t rsn_ie_len;
int ret;
@ -2926,6 +2927,11 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd,
wpabuf_free(pubkey);
pubkey = NULL;
/* Add RSNXE if needed */
rsnxe_ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
if (rsnxe_ie)
wpabuf_put_data(buf, rsnxe_ie, 2 + rsnxe_ie[1]);
/* Add the mic */
mic_len = pasn_mic_len(sta->pasn->akmp, sta->pasn->cipher);
wpabuf_put_u8(buf, WLAN_EID_MIC);
@ -2934,8 +2940,8 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd,
os_memset(ptr, 0, mic_len);
data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
frame = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
frame_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
rsn_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &rsn_ie_len);
if (!rsn_ie || !rsn_ie_len)
@ -2946,9 +2952,24 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd,
* MDE, etc. Thus, do not use the returned length but instead use the
* length specified in the IE header.
*/
data_len = rsn_ie[1] + 2;
if (rsnxe_ie) {
data_buf = os_zalloc(rsn_ie[1] + 2 + rsnxe_ie[1] + 2);
if (!data_buf)
goto fail;
os_memcpy(data_buf, rsn_ie, rsn_ie[1] + 2);
os_memcpy(data_buf + rsn_ie[1] + 2, rsnxe_ie, rsnxe_ie[1] + 2);
data_len += rsnxe_ie[1] + 2;
data = data_buf;
} else {
data = rsn_ie;
}
ret = pasn_mic(sta->pasn->ptk.kck, sta->pasn->akmp, sta->pasn->cipher,
hapd->own_addr, sta->addr, rsn_ie, rsn_ie[1] + 2,
data, data_len, mic);
hapd->own_addr, sta->addr, data, data_len,
frame, frame_len, mic);
os_free(data_buf);
if (ret) {
wpa_printf(MSG_DEBUG, "PASN: Frame 3: Failed MIC calculation");
goto fail;

View file

@ -1327,8 +1327,8 @@ u8 pasn_mic_len(int akmp, int cipher)
* @addr2: For the 2nd PASN frame the BSSID; for the 3rd frame the supplicant
* address
* @data: For calculating the MIC for the 2nd PASN frame, this should hold the
* Beacon frame RSNE. For calculating the MIC for the 3rd PASN frame, this
* should hold the hash of the body of the PASN 1st frame.
* Beacon frame RSNE + RSNXE. For calculating the MIC for the 3rd PASN
* frame, this should hold the hash of the body of the PASN 1st frame.
* @data_len: The length of data
* @frame: The body of the PASN frame including the MIC element with the octets
* in the MIC field of the MIC element set to 0.
@ -3692,4 +3692,24 @@ int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
return 0;
}
void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab)
{
size_t flen;
flen = (capab & 0xff00) ? 2 : 1;
if (!capab)
return; /* no supported extended RSN capabilities */
if (wpabuf_tailroom(buf) < 2 + flen)
return;
capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
wpabuf_put_u8(buf, WLAN_EID_RSNX);
wpabuf_put_u8(buf, flen);
wpabuf_put_u8(buf, capab & 0x00ff);
capab >>= 8;
if (capab)
wpabuf_put_u8(buf, capab);
}
#endif /* CONFIG_PASN */

View file

@ -21,6 +21,7 @@
#define WPA_GTK_MAX_LEN 32
#define WPA_PASN_PMK_LEN 32
#define WPA_PASN_MAX_MIC_LEN 24
#define WPA_MAX_RSNXE_LEN 4
#define OWE_DH_GROUP 19
@ -664,4 +665,6 @@ int wpa_pasn_validate_rsne(const struct wpa_ie_data *data);
int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
struct wpa_pasn_params_data *pasn_params);
void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab);
#endif /* WPA_COMMON_H */