PASN: Compute MIC from RSNE and RSNXE of the frame for Wi-Fi Aware
Wi-Fi Aware R4 specification defines Beacon RSNE/RSNXE to be same as RSNE/RSNXE present in Auth2 frame. So, MIC validation should be done with the RSNE and RSNXE received in Auth2 frame. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
6f80014b10
commit
1711fe9121
2 changed files with 87 additions and 22 deletions
|
@ -3067,6 +3067,7 @@ static int handle_auth_pasn_resp(struct wpas_pasn *pasn, const u8 *own_addr,
|
|||
u16 status)
|
||||
{
|
||||
struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
|
||||
struct wpabuf *rsn_buf = NULL;
|
||||
u8 mic[WPA_PASN_MAX_MIC_LEN];
|
||||
u8 mic_len;
|
||||
u8 *ptr;
|
||||
|
@ -3152,10 +3153,26 @@ static int handle_auth_pasn_resp(struct wpas_pasn *pasn, const u8 *own_addr,
|
|||
frame = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
|
||||
frame_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
|
||||
|
||||
if (!pasn->rsn_ie || !pasn->rsn_ie_len)
|
||||
goto fail;
|
||||
if (pasn->rsn_ie && pasn->rsn_ie_len) {
|
||||
rsn_ie = pasn->rsn_ie;
|
||||
} else {
|
||||
/*
|
||||
* Note: when pasn->rsn_ie is NULL, it is likely that Beacon
|
||||
* frame RSNE is not initialized. This is possible in case of
|
||||
* PASN authentication used for Wi-Fi Aware for which Beacon
|
||||
* frame RSNE and RSNXE are same as RSNE and RSNXE in the
|
||||
* Authentication frame.
|
||||
*/
|
||||
rsn_buf = wpabuf_alloc(500);
|
||||
if (!rsn_buf)
|
||||
goto fail;
|
||||
|
||||
rsn_ie = pasn->rsn_ie;
|
||||
if (wpa_pasn_add_rsne(rsn_buf, pmkid,
|
||||
pasn->akmp, pasn->cipher) < 0)
|
||||
goto fail;
|
||||
|
||||
rsn_ie = wpabuf_head_u8(rsn_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: wpa_auth_get_wpa_ie() might return not only the RSNE but also
|
||||
|
@ -3204,11 +3221,13 @@ done:
|
|||
if (ret)
|
||||
wpa_printf(MSG_INFO, "send_auth_reply: Send failed");
|
||||
|
||||
wpabuf_free(rsn_buf);
|
||||
wpabuf_free(buf);
|
||||
return ret;
|
||||
fail:
|
||||
wpabuf_free(wrapped_data_buf);
|
||||
wpabuf_free(pubkey);
|
||||
wpabuf_free(rsn_buf);
|
||||
wpabuf_free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1300,7 +1300,8 @@ static int wpas_pasn_start(struct wpas_pasn *pasn, const u8 *own_addr,
|
|||
#ifdef CONFIG_SAE
|
||||
case WPA_KEY_MGMT_SAE:
|
||||
|
||||
if (!ieee802_11_rsnx_capab(beacon_rsnxe,
|
||||
if (beacon_rsnxe &&
|
||||
!ieee802_11_rsnx_capab(beacon_rsnxe,
|
||||
WLAN_RSNX_CAPAB_SAE_H2E)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"PASN: AP does not support SAE H2E");
|
||||
|
@ -1333,17 +1334,21 @@ static int wpas_pasn_start(struct wpas_pasn *pasn, const u8 *own_addr,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
pasn->beacon_rsne_rsnxe = wpabuf_alloc(beacon_rsne_len +
|
||||
beacon_rsnxe_len);
|
||||
if (!pasn->beacon_rsne_rsnxe) {
|
||||
wpa_printf(MSG_DEBUG, "PASN: Failed storing beacon RSNE/RSNXE");
|
||||
goto fail;
|
||||
}
|
||||
if (beacon_rsne && beacon_rsne_len) {
|
||||
pasn->beacon_rsne_rsnxe = wpabuf_alloc(beacon_rsne_len +
|
||||
beacon_rsnxe_len);
|
||||
if (!pasn->beacon_rsne_rsnxe) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"PASN: Failed storing beacon RSNE/RSNXE");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsne, beacon_rsne_len);
|
||||
if (beacon_rsnxe && beacon_rsnxe_len)
|
||||
wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsnxe,
|
||||
beacon_rsnxe_len);
|
||||
wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsne,
|
||||
beacon_rsne_len);
|
||||
if (beacon_rsnxe && beacon_rsnxe_len)
|
||||
wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsnxe,
|
||||
beacon_rsnxe_len);
|
||||
}
|
||||
|
||||
pasn->akmp = akmp;
|
||||
pasn->cipher = cipher;
|
||||
|
@ -1920,14 +1925,55 @@ static int wpa_pasn_auth_rx(struct wpas_pasn *pasn, const u8 *data, size_t len,
|
|||
wpabuf_free(secret);
|
||||
secret = NULL;
|
||||
|
||||
/* Verify the MIC */
|
||||
ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
|
||||
pasn->bssid, pasn->own_addr,
|
||||
wpabuf_head(pasn->beacon_rsne_rsnxe),
|
||||
wpabuf_len(pasn->beacon_rsne_rsnxe),
|
||||
(u8 *) &mgmt->u.auth,
|
||||
len - offsetof(struct ieee80211_mgmt, u.auth),
|
||||
out_mic);
|
||||
if (pasn->beacon_rsne_rsnxe) {
|
||||
/* Verify the MIC */
|
||||
ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
|
||||
pasn->bssid, pasn->own_addr,
|
||||
wpabuf_head(pasn->beacon_rsne_rsnxe),
|
||||
wpabuf_len(pasn->beacon_rsne_rsnxe),
|
||||
(u8 *) &mgmt->u.auth,
|
||||
len - offsetof(struct ieee80211_mgmt, u.auth),
|
||||
out_mic);
|
||||
} else {
|
||||
u8 *rsne_rsnxe;
|
||||
size_t rsne_rsnxe_len = 0;
|
||||
|
||||
/*
|
||||
* Note: When Beacon rsne_rsnxe is not initialized, it is likely
|
||||
* that this is for Wi-Fi Aware using PASN handshake for which
|
||||
* Beacon RSNE/RSNXE are same as RSNE/RSNXE in the
|
||||
* Authentication frame
|
||||
*/
|
||||
if (elems.rsn_ie && elems.rsn_ie_len)
|
||||
rsne_rsnxe_len += elems.rsn_ie_len + 2;
|
||||
if (elems.rsnxe && elems.rsnxe_len)
|
||||
rsne_rsnxe_len += elems.rsnxe_len + 2;
|
||||
|
||||
rsne_rsnxe = os_zalloc(rsne_rsnxe_len);
|
||||
if (!rsne_rsnxe)
|
||||
goto fail;
|
||||
|
||||
if (elems.rsn_ie && elems.rsn_ie_len)
|
||||
os_memcpy(rsne_rsnxe, elems.rsn_ie - 2,
|
||||
elems.rsn_ie_len + 2);
|
||||
if (elems.rsnxe && elems.rsnxe_len)
|
||||
os_memcpy(rsne_rsnxe + elems.rsn_ie_len + 2,
|
||||
elems.rsnxe - 2, elems.rsnxe_len + 2);
|
||||
|
||||
wpa_hexdump_key(MSG_DEBUG, "PASN: RSN + RSNXE buf",
|
||||
rsne_rsnxe, rsne_rsnxe_len);
|
||||
|
||||
/* Verify the MIC */
|
||||
ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
|
||||
pasn->bssid, pasn->own_addr,
|
||||
rsne_rsnxe,
|
||||
rsne_rsnxe_len,
|
||||
(u8 *) &mgmt->u.auth,
|
||||
len - offsetof(struct ieee80211_mgmt, u.auth),
|
||||
out_mic);
|
||||
|
||||
os_free(rsne_rsnxe);
|
||||
}
|
||||
|
||||
wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
|
||||
if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
|
||||
|
|
Loading…
Reference in a new issue