diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index f8a1804c9..8309bd0da 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -322,114 +322,6 @@ u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len, } -static int wpa_selector_to_bitfield(const u8 *s) -{ - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE) - return WPA_CIPHER_NONE; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40) - return WPA_CIPHER_WEP40; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP) - return WPA_CIPHER_TKIP; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP) - return WPA_CIPHER_CCMP; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104) - return WPA_CIPHER_WEP104; - return 0; -} - - -static int wpa_key_mgmt_to_bitfield(const u8 *s) -{ - if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X) - return WPA_KEY_MGMT_IEEE8021X; - if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X) - return WPA_KEY_MGMT_PSK; - if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE) - return WPA_KEY_MGMT_WPA_NONE; - return 0; -} - - -static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, - struct wpa_ie_data *data) -{ - const struct wpa_ie_hdr *hdr; - const u8 *pos; - int left; - int i, count; - - os_memset(data, 0, sizeof(*data)); - data->pairwise_cipher = WPA_CIPHER_TKIP; - data->group_cipher = WPA_CIPHER_TKIP; - data->key_mgmt = WPA_KEY_MGMT_IEEE8021X; - data->mgmt_group_cipher = 0; - - if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) - return -1; - - hdr = (const struct wpa_ie_hdr *) wpa_ie; - - if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC || - hdr->len != wpa_ie_len - 2 || - RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE || - WPA_GET_LE16(hdr->version) != WPA_VERSION) { - return -2; - } - - pos = (const u8 *) (hdr + 1); - left = wpa_ie_len - sizeof(*hdr); - - if (left >= WPA_SELECTOR_LEN) { - data->group_cipher = wpa_selector_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } else if (left > 0) - return -3; - - if (left >= 2) { - data->pairwise_cipher = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) - return -4; - for (i = 0; i < count; i++) { - data->pairwise_cipher |= wpa_selector_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) - return -5; - - if (left >= 2) { - data->key_mgmt = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) - return -6; - for (i = 0; i < count; i++) { - data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) - return -7; - - if (left >= 2) { - data->capabilities = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - } - - if (left > 0) { - return -8; - } - - return 0; -} - - struct wpa_auth_okc_iter_data { struct rsn_pmksa_cache_entry *pmksa; const u8 *aa; diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index b295f3156..71b8599b6 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -403,6 +403,144 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, } +static int wpa_selector_to_bitfield(const u8 *s) +{ + if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE) + return WPA_CIPHER_NONE; + if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40) + return WPA_CIPHER_WEP40; + if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP) + return WPA_CIPHER_TKIP; + if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP) + return WPA_CIPHER_CCMP; + if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104) + return WPA_CIPHER_WEP104; + return 0; +} + + +static int wpa_key_mgmt_to_bitfield(const u8 *s) +{ + if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X) + return WPA_KEY_MGMT_IEEE8021X; + if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X) + return WPA_KEY_MGMT_PSK; + if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE) + return WPA_KEY_MGMT_WPA_NONE; + return 0; +} + + +int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, + struct wpa_ie_data *data) +{ + const struct wpa_ie_hdr *hdr; + const u8 *pos; + int left; + int i, count; + + os_memset(data, 0, sizeof(*data)); + data->proto = WPA_PROTO_WPA; + data->pairwise_cipher = WPA_CIPHER_TKIP; + data->group_cipher = WPA_CIPHER_TKIP; + data->key_mgmt = WPA_KEY_MGMT_IEEE8021X; + data->capabilities = 0; + data->pmkid = NULL; + data->num_pmkid = 0; + data->mgmt_group_cipher = 0; + + if (wpa_ie_len == 0) { + /* No WPA IE - fail silently */ + return -1; + } + + if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) { + wpa_printf(MSG_DEBUG, "%s: ie len too short %lu", + __func__, (unsigned long) wpa_ie_len); + return -1; + } + + hdr = (const struct wpa_ie_hdr *) wpa_ie; + + if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC || + hdr->len != wpa_ie_len - 2 || + RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE || + WPA_GET_LE16(hdr->version) != WPA_VERSION) { + wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", + __func__); + return -2; + } + + pos = (const u8 *) (hdr + 1); + left = wpa_ie_len - sizeof(*hdr); + + if (left >= WPA_SELECTOR_LEN) { + data->group_cipher = wpa_selector_to_bitfield(pos); + pos += WPA_SELECTOR_LEN; + left -= WPA_SELECTOR_LEN; + } else if (left > 0) { + wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much", + __func__, left); + return -3; + } + + if (left >= 2) { + data->pairwise_cipher = 0; + count = WPA_GET_LE16(pos); + pos += 2; + left -= 2; + if (count == 0 || left < count * WPA_SELECTOR_LEN) { + wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), " + "count %u left %u", __func__, count, left); + return -4; + } + for (i = 0; i < count; i++) { + data->pairwise_cipher |= wpa_selector_to_bitfield(pos); + pos += WPA_SELECTOR_LEN; + left -= WPA_SELECTOR_LEN; + } + } else if (left == 1) { + wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)", + __func__); + return -5; + } + + if (left >= 2) { + data->key_mgmt = 0; + count = WPA_GET_LE16(pos); + pos += 2; + left -= 2; + if (count == 0 || left < count * WPA_SELECTOR_LEN) { + wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), " + "count %u left %u", __func__, count, left); + return -6; + } + for (i = 0; i < count; i++) { + data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos); + pos += WPA_SELECTOR_LEN; + left -= WPA_SELECTOR_LEN; + } + } else if (left == 1) { + wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)", + __func__); + return -7; + } + + if (left >= 2) { + data->capabilities = WPA_GET_LE16(pos); + pos += 2; + left -= 2; + } + + if (left > 0) { + wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored", + __func__, left); + } + + return 0; +} + + #ifdef CONFIG_IEEE80211R /** diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index fd8a79fd6..1193d85d8 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -337,6 +337,8 @@ struct wpa_ie_data { int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, struct wpa_ie_data *data); +int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, + struct wpa_ie_data *data); void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa, u8 *pmkid, int use_sha256); diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index f447223bc..383d34538 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -22,144 +22,6 @@ #include "wpa_ie.h" -static int wpa_selector_to_bitfield(const u8 *s) -{ - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE) - return WPA_CIPHER_NONE; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40) - return WPA_CIPHER_WEP40; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP) - return WPA_CIPHER_TKIP; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP) - return WPA_CIPHER_CCMP; - if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104) - return WPA_CIPHER_WEP104; - return 0; -} - - -static int wpa_key_mgmt_to_bitfield(const u8 *s) -{ - if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X) - return WPA_KEY_MGMT_IEEE8021X; - if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X) - return WPA_KEY_MGMT_PSK; - if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE) - return WPA_KEY_MGMT_WPA_NONE; - return 0; -} - - -static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len, - struct wpa_ie_data *data) -{ - const struct wpa_ie_hdr *hdr; - const u8 *pos; - int left; - int i, count; - - os_memset(data, 0, sizeof(*data)); - data->proto = WPA_PROTO_WPA; - data->pairwise_cipher = WPA_CIPHER_TKIP; - data->group_cipher = WPA_CIPHER_TKIP; - data->key_mgmt = WPA_KEY_MGMT_IEEE8021X; - data->capabilities = 0; - data->pmkid = NULL; - data->num_pmkid = 0; - data->mgmt_group_cipher = 0; - - if (wpa_ie_len == 0) { - /* No WPA IE - fail silently */ - return -1; - } - - if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) { - wpa_printf(MSG_DEBUG, "%s: ie len too short %lu", - __func__, (unsigned long) wpa_ie_len); - return -1; - } - - hdr = (const struct wpa_ie_hdr *) wpa_ie; - - if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC || - hdr->len != wpa_ie_len - 2 || - RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE || - WPA_GET_LE16(hdr->version) != WPA_VERSION) { - wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", - __func__); - return -1; - } - - pos = (const u8 *) (hdr + 1); - left = wpa_ie_len - sizeof(*hdr); - - if (left >= WPA_SELECTOR_LEN) { - data->group_cipher = wpa_selector_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } else if (left > 0) { - wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much", - __func__, left); - return -1; - } - - if (left >= 2) { - data->pairwise_cipher = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) { - wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), " - "count %u left %u", __func__, count, left); - return -1; - } - for (i = 0; i < count; i++) { - data->pairwise_cipher |= wpa_selector_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) { - wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)", - __func__); - return -1; - } - - if (left >= 2) { - data->key_mgmt = 0; - count = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) { - wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), " - "count %u left %u", __func__, count, left); - return -1; - } - for (i = 0; i < count; i++) { - data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) { - wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)", - __func__); - return -1; - } - - if (left >= 2) { - data->capabilities = WPA_GET_LE16(pos); - pos += 2; - left -= 2; - } - - if (left > 0) { - wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored", - __func__, left); - } - - return 0; -} - - /** * wpa_parse_wpa_ie - Parse WPA/RSN IE * @wpa_ie: Pointer to WPA or RSN IE