|
@@ -25,31 +25,6 @@
|
|
|
|
|
|
#ifdef CONFIG_IEEE80211R
|
|
|
|
|
|
-struct wpa_ft_ies {
|
|
|
- const u8 *mdie;
|
|
|
- size_t mdie_len;
|
|
|
- const u8 *ftie;
|
|
|
- size_t ftie_len;
|
|
|
- const u8 *r1kh_id;
|
|
|
- const u8 *gtk;
|
|
|
- size_t gtk_len;
|
|
|
- const u8 *r0kh_id;
|
|
|
- size_t r0kh_id_len;
|
|
|
- const u8 *rsn;
|
|
|
- size_t rsn_len;
|
|
|
- const u8 *rsn_pmkid;
|
|
|
- const u8 *tie;
|
|
|
- size_t tie_len;
|
|
|
- const u8 *igtk;
|
|
|
- size_t igtk_len;
|
|
|
- const u8 *ric;
|
|
|
- size_t ric_len;
|
|
|
-};
|
|
|
-
|
|
|
-static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
|
|
|
- struct wpa_ft_ies *parse);
|
|
|
-
|
|
|
-
|
|
|
int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
|
|
|
const struct wpa_eapol_key *key,
|
|
|
struct wpa_ptk *ptk, size_t ptk_len)
|
|
@@ -347,153 +322,6 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
|
|
|
}
|
|
|
|
|
|
|
|
|
-static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
|
|
|
- struct wpa_ft_ies *parse)
|
|
|
-{
|
|
|
- const u8 *end, *pos;
|
|
|
-
|
|
|
- parse->ftie = ie;
|
|
|
- parse->ftie_len = ie_len;
|
|
|
-
|
|
|
- pos = ie + sizeof(struct rsn_ftie);
|
|
|
- end = ie + ie_len;
|
|
|
-
|
|
|
- while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
|
|
- switch (pos[0]) {
|
|
|
- case FTIE_SUBELEM_R1KH_ID:
|
|
|
- if (pos[1] != FT_R1KH_ID_LEN) {
|
|
|
- wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
|
|
|
- "length in FTIE: %d", pos[1]);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- parse->r1kh_id = pos + 2;
|
|
|
- break;
|
|
|
- case FTIE_SUBELEM_GTK:
|
|
|
- parse->gtk = pos + 2;
|
|
|
- parse->gtk_len = pos[1];
|
|
|
- break;
|
|
|
- case FTIE_SUBELEM_R0KH_ID:
|
|
|
- if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
|
|
|
- wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
|
|
|
- "length in FTIE: %d", pos[1]);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- parse->r0kh_id = pos + 2;
|
|
|
- parse->r0kh_id_len = pos[1];
|
|
|
- break;
|
|
|
-#ifdef CONFIG_IEEE80211W
|
|
|
- case FTIE_SUBELEM_IGTK:
|
|
|
- parse->igtk = pos + 2;
|
|
|
- parse->igtk_len = pos[1];
|
|
|
- break;
|
|
|
-#endif /* CONFIG_IEEE80211W */
|
|
|
- }
|
|
|
-
|
|
|
- pos += 2 + pos[1];
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
|
|
|
- struct wpa_ft_ies *parse)
|
|
|
-{
|
|
|
- const u8 *end, *pos;
|
|
|
- struct wpa_ie_data data;
|
|
|
- int ret;
|
|
|
- const struct rsn_ftie *ftie;
|
|
|
- int prot_ie_count = 0;
|
|
|
-
|
|
|
- os_memset(parse, 0, sizeof(*parse));
|
|
|
- if (ies == NULL)
|
|
|
- return 0;
|
|
|
-
|
|
|
- pos = ies;
|
|
|
- end = ies + ies_len;
|
|
|
- while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
|
|
- switch (pos[0]) {
|
|
|
- case WLAN_EID_RSN:
|
|
|
- parse->rsn = pos + 2;
|
|
|
- parse->rsn_len = pos[1];
|
|
|
- ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
|
|
|
- parse->rsn_len + 2,
|
|
|
- &data);
|
|
|
- if (ret < 0) {
|
|
|
- wpa_printf(MSG_DEBUG, "FT: Failed to parse "
|
|
|
- "RSN IE: %d", ret);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- if (data.num_pmkid == 1 && data.pmkid)
|
|
|
- parse->rsn_pmkid = data.pmkid;
|
|
|
- break;
|
|
|
- case WLAN_EID_MOBILITY_DOMAIN:
|
|
|
- parse->mdie = pos + 2;
|
|
|
- parse->mdie_len = pos[1];
|
|
|
- break;
|
|
|
- case WLAN_EID_FAST_BSS_TRANSITION:
|
|
|
- if (pos[1] < sizeof(*ftie))
|
|
|
- return -1;
|
|
|
- ftie = (const struct rsn_ftie *) (pos + 2);
|
|
|
- prot_ie_count = ftie->mic_control[1];
|
|
|
- if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- case WLAN_EID_TIMEOUT_INTERVAL:
|
|
|
- parse->tie = pos + 2;
|
|
|
- parse->tie_len = pos[1];
|
|
|
- break;
|
|
|
- case WLAN_EID_RIC_DATA:
|
|
|
- if (parse->ric == NULL)
|
|
|
- parse->ric = pos;
|
|
|
- }
|
|
|
-
|
|
|
- pos += 2 + pos[1];
|
|
|
- }
|
|
|
-
|
|
|
- if (prot_ie_count == 0)
|
|
|
- return 0; /* no MIC */
|
|
|
-
|
|
|
- /*
|
|
|
- * Check that the protected IE count matches with IEs included in the
|
|
|
- * frame.
|
|
|
- */
|
|
|
- if (parse->rsn)
|
|
|
- prot_ie_count--;
|
|
|
- if (parse->mdie)
|
|
|
- prot_ie_count--;
|
|
|
- if (parse->ftie)
|
|
|
- prot_ie_count--;
|
|
|
- if (prot_ie_count < 0) {
|
|
|
- wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
|
|
|
- "the protected IE count");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (prot_ie_count == 0 && parse->ric) {
|
|
|
- wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
|
|
|
- "included in protected IE count");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- /* Determine the end of the RIC IE(s) */
|
|
|
- pos = parse->ric;
|
|
|
- while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
|
|
|
- prot_ie_count) {
|
|
|
- prot_ie_count--;
|
|
|
- pos += 2 + pos[1];
|
|
|
- }
|
|
|
- parse->ric_len = pos - parse->ric;
|
|
|
- if (prot_ie_count) {
|
|
|
- wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
|
|
|
- "frame", (int) prot_ie_count);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
|
|
|
{
|
|
|
int keylen;
|