]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Merge wpa_supplicant and hostapd EAPOL-Key KDE parsers
authorJouni Malinen <jouni@codeaurora.org>
Fri, 18 Oct 2019 10:02:27 +0000 (13:02 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 18 Oct 2019 10:02:27 +0000 (13:02 +0300)
Use a single struct definition and a single shared implementation for
parsing EAPOL-Key KDEs and IEs instead of maintaining more or less
identical functionality separately for wpa_supplicant and hostapd.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/wpa_auth_ie.c
src/ap/wpa_auth_ie.h
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa_ie.c
src/rsn_supp/wpa_ie.h

index 76f3aa972c8eb484099b742dee17c2330b32d582..2e6d0591040926cafcf48e8164d9f4f35cc26e3a 100644 (file)
@@ -1002,154 +1002,6 @@ int wpa_validate_osen(struct wpa_authenticator *wpa_auth,
 #endif /* CONFIG_HS20 */
 
 
-/**
- * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
- * @pos: Pointer to the IE header
- * @end: Pointer to the end of the Key Data buffer
- * @ie: Pointer to parsed IE data
- * Returns: 0 on success, 1 if end mark is found, -1 on failure
- */
-static int wpa_parse_generic(const u8 *pos, const u8 *end,
-                            struct wpa_eapol_ie_parse *ie)
-{
-       if (pos[1] == 0)
-               return 1;
-
-       if (pos[1] >= 6 &&
-           RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
-           pos[2 + WPA_SELECTOR_LEN] == 1 &&
-           pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
-               ie->wpa_ie = pos;
-               ie->wpa_ie_len = pos[1] + 2;
-               return 0;
-       }
-
-       if (pos[1] >= 4 && WPA_GET_BE32(pos + 2) == OSEN_IE_VENDOR_TYPE) {
-               ie->osen = pos;
-               ie->osen_len = pos[1] + 2;
-               return 0;
-       }
-
-       if (1 + RSN_SELECTOR_LEN < end - pos &&
-           pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
-               ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
-               return 0;
-       }
-
-       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
-               ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
-               ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
-               return 0;
-       }
-
-       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
-               ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
-               ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
-               return 0;
-       }
-
-       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
-               ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
-               ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
-               return 0;
-       }
-
-#ifdef CONFIG_P2P
-       if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
-           RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
-               ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
-               wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
-                           ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
-               return 0;
-       }
-
-       if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
-           RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
-               ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
-               wpa_hexdump(MSG_DEBUG,
-                           "WPA: IP Address Allocation in EAPOL-Key",
-                           ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
-               return 0;
-       }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_OCV
-       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_OCI) {
-               ie->oci = pos + 2 + RSN_SELECTOR_LEN;
-               ie->oci_len = pos[1] - RSN_SELECTOR_LEN;
-               return 0;
-       }
-#endif /* CONFIG_OCV */
-
-       return 0;
-}
-
-
-/**
- * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
- * @buf: Pointer to the Key Data buffer
- * @len: Key Data Length
- * @ie: Pointer to parsed IE data
- * Returns: 0 on success, -1 on failure
- */
-int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
-{
-       const u8 *pos, *end;
-       int ret = 0;
-
-       os_memset(ie, 0, sizeof(*ie));
-       for (pos = buf, end = pos + len; end - pos > 1; pos += 2 + pos[1]) {
-               if (pos[0] == 0xdd &&
-                   ((pos == buf + len - 1) || pos[1] == 0)) {
-                       /* Ignore padding */
-                       break;
-               }
-               if (2 + pos[1] > end - pos) {
-                       wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
-                                  "underflow (ie=%d len=%d pos=%d)",
-                                  pos[0], pos[1], (int) (pos - buf));
-                       wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
-                                       buf, len);
-                       ret = -1;
-                       break;
-               }
-               if (*pos == WLAN_EID_RSN) {
-                       ie->rsn_ie = pos;
-                       ie->rsn_ie_len = pos[1] + 2;
-               } else if (*pos == WLAN_EID_RSNX) {
-                       ie->rsnxe = pos;
-                       ie->rsnxe_len = pos[1] + 2;
-#ifdef CONFIG_IEEE80211R_AP
-               } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
-                       ie->mdie = pos;
-                       ie->mdie_len = pos[1] + 2;
-               } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
-                       ie->ftie = pos;
-                       ie->ftie_len = pos[1] + 2;
-#endif /* CONFIG_IEEE80211R_AP */
-               } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
-                       ret = wpa_parse_generic(pos, end, ie);
-                       if (ret < 0)
-                               break;
-                       if (ret > 0) {
-                               ret = 0;
-                               break;
-                       }
-               } else {
-                       wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
-                                   "Key Data IE", pos, 2 + pos[1]);
-               }
-       }
-
-       return ret;
-}
-
-
 int wpa_auth_uses_mfp(struct wpa_state_machine *sm)
 {
        return sm ? sm->mgmt_frame_prot : 0;
index e29e49681d38a5a09cad0d7bc87c5418d501ba88..dd44b9efe2c68591d4cc1e01afe180f54c22c66b 100644 (file)
@@ -9,41 +9,6 @@
 #ifndef WPA_AUTH_IE_H
 #define WPA_AUTH_IE_H
 
-struct wpa_eapol_ie_parse {
-       const u8 *wpa_ie;
-       size_t wpa_ie_len;
-       const u8 *rsn_ie;
-       size_t rsn_ie_len;
-       const u8 *pmkid;
-       const u8 *gtk;
-       size_t gtk_len;
-       const u8 *mac_addr;
-       size_t mac_addr_len;
-       const u8 *igtk;
-       size_t igtk_len;
-#ifdef CONFIG_IEEE80211R_AP
-       const u8 *mdie;
-       size_t mdie_len;
-       const u8 *ftie;
-       size_t ftie_len;
-#endif /* CONFIG_IEEE80211R_AP */
-#ifdef CONFIG_P2P
-       const u8 *ip_addr_req;
-       const u8 *ip_addr_alloc;
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_OCV
-       const u8 *oci;
-       size_t oci_len;
-#endif /* CONFIG_OCV */
-
-       const u8 *osen;
-       size_t osen_len;
-       const u8 *rsnxe;
-       size_t rsnxe_len;
-};
-
-int wpa_parse_kde_ies(const u8 *buf, size_t len,
-                     struct wpa_eapol_ie_parse *ie);
 u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len,
                 const u8 *data2, size_t data2_len);
 int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth);
index 142dace4a0556b58f6382e99dae08b5a50a558ce..1f8f18e902c63d07a5db2dc4aac5cc529930b529 100644 (file)
@@ -2586,3 +2586,266 @@ int fils_domain_name_hash(const char *domain, u8 *hash)
        return 0;
 }
 #endif /* CONFIG_FILS */
+
+
+/**
+ * wpa_parse_vendor_specific - Parse Vendor Specific IEs
+ * @pos: Pointer to the IE header
+ * @end: Pointer to the end of the Key Data buffer
+ * @ie: Pointer to parsed IE data
+ * Returns: 0 on success, 1 if end mark is found, -1 on failure
+ */
+static int wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
+                                    struct wpa_eapol_ie_parse *ie)
+{
+       unsigned int oui;
+
+       if (pos[1] < 4) {
+               wpa_printf(MSG_MSGDUMP,
+                          "Too short vendor specific IE ignored (len=%u)",
+                          pos[1]);
+               return 1;
+       }
+
+       oui = WPA_GET_BE24(&pos[2]);
+       if (oui == OUI_MICROSOFT && pos[5] == WMM_OUI_TYPE && pos[1] > 4) {
+               if (pos[6] == WMM_OUI_SUBTYPE_INFORMATION_ELEMENT) {
+                       ie->wmm = &pos[2];
+                       ie->wmm_len = pos[1];
+                       wpa_hexdump(MSG_DEBUG, "WPA: WMM IE",
+                                   ie->wmm, ie->wmm_len);
+               } else if (pos[6] == WMM_OUI_SUBTYPE_PARAMETER_ELEMENT) {
+                       ie->wmm = &pos[2];
+                       ie->wmm_len = pos[1];
+                       wpa_hexdump(MSG_DEBUG, "WPA: WMM Parameter Element",
+                                   ie->wmm, ie->wmm_len);
+               }
+       }
+       return 0;
+}
+
+
+/**
+ * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
+ * @pos: Pointer to the IE header
+ * @end: Pointer to the end of the Key Data buffer
+ * @ie: Pointer to parsed IE data
+ * Returns: 0 on success, 1 if end mark is found, -1 on failure
+ */
+static int wpa_parse_generic(const u8 *pos, const u8 *end,
+                            struct wpa_eapol_ie_parse *ie)
+{
+       if (pos[1] == 0)
+               return 1;
+
+       if (pos[1] >= 6 &&
+           RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
+           pos[2 + WPA_SELECTOR_LEN] == 1 &&
+           pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
+               ie->wpa_ie = pos;
+               ie->wpa_ie_len = pos[1] + 2;
+               wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
+                           ie->wpa_ie, ie->wpa_ie_len);
+               return 0;
+       }
+
+       if (pos[1] >= 4 && WPA_GET_BE32(pos + 2) == OSEN_IE_VENDOR_TYPE) {
+               ie->osen = pos;
+               ie->osen_len = pos[1] + 2;
+               return 0;
+       }
+
+       if (1 + RSN_SELECTOR_LEN < end - pos &&
+           pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
+           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
+               ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
+               wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key",
+                           pos, pos[1] + 2);
+               return 0;
+       }
+
+       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
+           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
+               ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
+               ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
+               wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key",
+                               pos, pos[1] + 2);
+               return 0;
+       }
+
+       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
+           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
+               ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
+               ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
+               wpa_hexdump(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key",
+                           pos, pos[1] + 2);
+               return 0;
+       }
+
+       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
+           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
+               ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
+               ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
+               wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
+                               pos, pos[1] + 2);
+               return 0;
+       }
+
+       if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
+           RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
+               ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
+               wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
+                           ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
+               return 0;
+       }
+
+       if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
+           RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
+               ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
+               wpa_hexdump(MSG_DEBUG,
+                           "WPA: IP Address Allocation in EAPOL-Key",
+                           ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
+               return 0;
+       }
+
+       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
+           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_OCI) {
+               ie->oci = pos + 2 + RSN_SELECTOR_LEN;
+               ie->oci_len = pos[1] - RSN_SELECTOR_LEN;
+               wpa_hexdump(MSG_DEBUG, "WPA: OCI KDE in EAPOL-Key",
+                           pos, pos[1] + 2);
+               return 0;
+       }
+
+       return 0;
+}
+
+
+/**
+ * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
+ * @buf: Pointer to the Key Data buffer
+ * @len: Key Data Length
+ * @ie: Pointer to parsed IE data
+ * Returns: 0 on success, -1 on failure
+ */
+int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
+{
+       const u8 *pos, *end;
+       int ret = 0;
+
+       os_memset(ie, 0, sizeof(*ie));
+       for (pos = buf, end = pos + len; end - pos > 1; pos += 2 + pos[1]) {
+               if (pos[0] == 0xdd &&
+                   ((pos == buf + len - 1) || pos[1] == 0)) {
+                       /* Ignore padding */
+                       break;
+               }
+               if (2 + pos[1] > end - pos) {
+                       wpa_printf(MSG_DEBUG,
+                                  "WPA: EAPOL-Key Key Data underflow (ie=%d len=%d pos=%d)",
+                                  pos[0], pos[1], (int) (pos - buf));
+                       wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data", buf, len);
+                       ret = -1;
+                       break;
+               }
+               if (*pos == WLAN_EID_RSN) {
+                       ie->rsn_ie = pos;
+                       ie->rsn_ie_len = pos[1] + 2;
+                       wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
+                                   ie->rsn_ie, ie->rsn_ie_len);
+               } else if (*pos == WLAN_EID_RSNX) {
+                       ie->rsnxe = pos;
+                       ie->rsnxe_len = pos[1] + 2;
+                       wpa_hexdump(MSG_DEBUG, "WPA: RSNXE in EAPOL-Key",
+                                   ie->rsnxe, ie->rsnxe_len);
+               } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
+                       ie->mdie = pos;
+                       ie->mdie_len = pos[1] + 2;
+                       wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
+                                   ie->mdie, ie->mdie_len);
+               } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) {
+                       ie->ftie = pos;
+                       ie->ftie_len = pos[1] + 2;
+                       wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
+                                   ie->ftie, ie->ftie_len);
+               } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
+                       if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
+                               ie->reassoc_deadline = pos;
+                               wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
+                                           "in EAPOL-Key",
+                                           ie->reassoc_deadline, pos[1] + 2);
+                       } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
+                               ie->key_lifetime = pos;
+                               wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
+                                           "in EAPOL-Key",
+                                           ie->key_lifetime, pos[1] + 2);
+                       } else {
+                               wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
+                                           "EAPOL-Key Key Data IE",
+                                           pos, 2 + pos[1]);
+                       }
+               } else if (*pos == WLAN_EID_LINK_ID) {
+                       if (pos[1] >= 18) {
+                               ie->lnkid = pos;
+                               ie->lnkid_len = pos[1] + 2;
+                       }
+               } else if (*pos == WLAN_EID_EXT_CAPAB) {
+                       ie->ext_capab = pos;
+                       ie->ext_capab_len = pos[1] + 2;
+               } else if (*pos == WLAN_EID_SUPP_RATES) {
+                       ie->supp_rates = pos;
+                       ie->supp_rates_len = pos[1] + 2;
+               } else if (*pos == WLAN_EID_EXT_SUPP_RATES) {
+                       ie->ext_supp_rates = pos;
+                       ie->ext_supp_rates_len = pos[1] + 2;
+               } else if (*pos == WLAN_EID_HT_CAP &&
+                          pos[1] >= sizeof(struct ieee80211_ht_capabilities)) {
+                       ie->ht_capabilities = pos + 2;
+               } else if (*pos == WLAN_EID_VHT_AID) {
+                       if (pos[1] >= 2)
+                               ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
+               } else if (*pos == WLAN_EID_VHT_CAP &&
+                          pos[1] >= sizeof(struct ieee80211_vht_capabilities))
+               {
+                       ie->vht_capabilities = pos + 2;
+               } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
+                       ie->qosinfo = pos[2];
+               } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
+                       ie->supp_channels = pos + 2;
+                       ie->supp_channels_len = pos[1];
+               } else if (*pos == WLAN_EID_SUPPORTED_OPERATING_CLASSES) {
+                       /*
+                        * The value of the Length field of the Supported
+                        * Operating Classes element is between 2 and 253.
+                        * Silently skip invalid elements to avoid interop
+                        * issues when trying to use the value.
+                        */
+                       if (pos[1] >= 2 && pos[1] <= 253) {
+                               ie->supp_oper_classes = pos + 2;
+                               ie->supp_oper_classes_len = pos[1];
+                       }
+               } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
+                       ret = wpa_parse_generic(pos, end, ie);
+                       if (ret < 0)
+                               break;
+                       if (ret > 0) {
+                               ret = 0;
+                               break;
+                       }
+
+                       ret = wpa_parse_vendor_specific(pos, end, ie);
+                       if (ret < 0)
+                               break;
+                       if (ret > 0) {
+                               ret = 0;
+                               break;
+                       }
+               } else {
+                       wpa_hexdump(MSG_DEBUG,
+                                   "WPA: Unrecognized EAPOL-Key Key Data IE",
+                                   pos, 2 + pos[1]);
+               }
+       }
+
+       return ret;
+}
index 35bec0415984eb61c767e24c26fd84ddc505719c..c7711f16853743b400a6d236f01199521fd7ef3f 100644 (file)
@@ -466,6 +466,60 @@ struct wpa_ft_ies {
 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
                     int use_sha384);
 
+struct wpa_eapol_ie_parse {
+       const u8 *wpa_ie;
+       size_t wpa_ie_len;
+       const u8 *rsn_ie;
+       size_t rsn_ie_len;
+       const u8 *pmkid;
+       const u8 *gtk;
+       size_t gtk_len;
+       const u8 *mac_addr;
+       size_t mac_addr_len;
+       const u8 *igtk;
+       size_t igtk_len;
+       const u8 *mdie;
+       size_t mdie_len;
+       const u8 *ftie;
+       size_t ftie_len;
+       const u8 *ip_addr_req;
+       const u8 *ip_addr_alloc;
+       const u8 *oci;
+       size_t oci_len;
+       const u8 *osen;
+       size_t osen_len;
+       const u8 *rsnxe;
+       size_t rsnxe_len;
+       const u8 *reassoc_deadline;
+       const u8 *key_lifetime;
+       const u8 *lnkid;
+       size_t lnkid_len;
+       const u8 *ext_capab;
+       size_t ext_capab_len;
+       const u8 *supp_rates;
+       size_t supp_rates_len;
+       const u8 *ext_supp_rates;
+       size_t ext_supp_rates_len;
+       const u8 *ht_capabilities;
+       const u8 *vht_capabilities;
+       const u8 *supp_channels;
+       size_t supp_channels_len;
+       const u8 *supp_oper_classes;
+       size_t supp_oper_classes_len;
+       u8 qosinfo;
+       u16 aid;
+       const u8 *wmm;
+       size_t wmm_len;
+};
+
+int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie);
+static inline int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
+                                          struct wpa_eapol_ie_parse *ie)
+{
+       return wpa_parse_kde_ies(buf, len, ie);
+}
+
+
 int wpa_cipher_key_len(int cipher);
 int wpa_cipher_rsc_len(int cipher);
 enum wpa_alg wpa_cipher_to_alg(int cipher);
index f4ac25c05accb3a9f0e7b0ae5f5c9d33dfd48583..03c0d7e85c24ebccde0f4194573c8ab2db30e465 100644 (file)
@@ -362,266 +362,3 @@ int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
 
        return pos - rsnxe;
 }
-
-
-/**
- * wpa_parse_vendor_specific - Parse Vendor Specific IEs
- * @pos: Pointer to the IE header
- * @end: Pointer to the end of the Key Data buffer
- * @ie: Pointer to parsed IE data
- * Returns: 0 on success, 1 if end mark is found, -1 on failure
- */
-static int wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
-                                    struct wpa_eapol_ie_parse *ie)
-{
-       unsigned int oui;
-
-       if (pos[1] < 4) {
-               wpa_printf(MSG_MSGDUMP, "Too short vendor specific IE ignored (len=%u)",
-                          pos[1]);
-               return 1;
-       }
-
-       oui = WPA_GET_BE24(&pos[2]);
-       if (oui == OUI_MICROSOFT && pos[5] == WMM_OUI_TYPE && pos[1] > 4) {
-               if (pos[6] == WMM_OUI_SUBTYPE_INFORMATION_ELEMENT) {
-                       ie->wmm = &pos[2];
-                       ie->wmm_len = pos[1];
-                       wpa_hexdump(MSG_DEBUG, "WPA: WMM IE",
-                                   ie->wmm, ie->wmm_len);
-               } else if (pos[6] == WMM_OUI_SUBTYPE_PARAMETER_ELEMENT) {
-                       ie->wmm = &pos[2];
-                       ie->wmm_len = pos[1];
-                       wpa_hexdump(MSG_DEBUG, "WPA: WMM Parameter Element",
-                                   ie->wmm, ie->wmm_len);
-               }
-       }
-       return 0;
-}
-
-
-/**
- * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
- * @pos: Pointer to the IE header
- * @end: Pointer to the end of the Key Data buffer
- * @ie: Pointer to parsed IE data
- * Returns: 0 on success, 1 if end mark is found, -1 on failure
- */
-static int wpa_parse_generic(const u8 *pos, const u8 *end,
-                            struct wpa_eapol_ie_parse *ie)
-{
-       if (pos[1] == 0)
-               return 1;
-
-       if (pos[1] >= 6 &&
-           RSN_SELECTOR_GET(pos + 2) == WPA_OUI_TYPE &&
-           pos[2 + WPA_SELECTOR_LEN] == 1 &&
-           pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
-               ie->wpa_ie = pos;
-               ie->wpa_ie_len = pos[1] + 2;
-               wpa_hexdump(MSG_DEBUG, "WPA: WPA IE in EAPOL-Key",
-                           ie->wpa_ie, ie->wpa_ie_len);
-               return 0;
-       }
-
-       if (1 + RSN_SELECTOR_LEN < end - pos &&
-           pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
-               ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
-               wpa_hexdump(MSG_DEBUG, "WPA: PMKID in EAPOL-Key",
-                           pos, pos[1] + 2);
-               return 0;
-       }
-
-       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_GROUPKEY) {
-               ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
-               ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
-               wpa_hexdump_key(MSG_DEBUG, "WPA: GTK in EAPOL-Key",
-                               pos, pos[1] + 2);
-               return 0;
-       }
-
-       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_MAC_ADDR) {
-               ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
-               ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
-               wpa_hexdump(MSG_DEBUG, "WPA: MAC Address in EAPOL-Key",
-                           pos, pos[1] + 2);
-               return 0;
-       }
-
-       if (pos[1] > RSN_SELECTOR_LEN + 2 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {
-               ie->igtk = pos + 2 + RSN_SELECTOR_LEN;
-               ie->igtk_len = pos[1] - RSN_SELECTOR_LEN;
-               wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK in EAPOL-Key",
-                               pos, pos[1] + 2);
-               return 0;
-       }
-
-#ifdef CONFIG_P2P
-       if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
-           RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_REQ) {
-               ie->ip_addr_req = pos + 2 + RSN_SELECTOR_LEN;
-               wpa_hexdump(MSG_DEBUG, "WPA: IP Address Request in EAPOL-Key",
-                           ie->ip_addr_req, pos[1] - RSN_SELECTOR_LEN);
-               return 0;
-       }
-
-       if (pos[1] >= RSN_SELECTOR_LEN + 3 * 4 &&
-           RSN_SELECTOR_GET(pos + 2) == WFA_KEY_DATA_IP_ADDR_ALLOC) {
-               ie->ip_addr_alloc = pos + 2 + RSN_SELECTOR_LEN;
-               wpa_hexdump(MSG_DEBUG,
-                           "WPA: IP Address Allocation in EAPOL-Key",
-                           ie->ip_addr_alloc, pos[1] - RSN_SELECTOR_LEN);
-               return 0;
-       }
-#endif /* CONFIG_P2P */
-
-#ifdef CONFIG_OCV
-       if (pos[1] >= RSN_SELECTOR_LEN + 1 &&
-           RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_OCI) {
-               ie->oci = pos + 2 + RSN_SELECTOR_LEN;
-               ie->oci_len = pos[1] - RSN_SELECTOR_LEN;
-               wpa_hexdump(MSG_DEBUG, "WPA: OCI KDE in EAPOL-Key",
-                           pos, pos[1] + 2);
-               return 0;
-       }
-#endif /* CONFIG_OCV */
-
-       return 0;
-}
-
-
-/**
- * wpa_supplicant_parse_ies - Parse EAPOL-Key Key Data IEs
- * @buf: Pointer to the Key Data buffer
- * @len: Key Data Length
- * @ie: Pointer to parsed IE data
- * Returns: 0 on success, -1 on failure
- */
-int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
-                            struct wpa_eapol_ie_parse *ie)
-{
-       const u8 *pos, *end;
-       int ret = 0;
-
-       os_memset(ie, 0, sizeof(*ie));
-       for (pos = buf, end = pos + len; end - pos > 1; pos += 2 + pos[1]) {
-               if (pos[0] == 0xdd &&
-                   ((pos == buf + len - 1) || pos[1] == 0)) {
-                       /* Ignore padding */
-                       break;
-               }
-               if (2 + pos[1] > end - pos) {
-                       wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
-                                  "underflow (ie=%d len=%d pos=%d)",
-                                  pos[0], pos[1], (int) (pos - buf));
-                       wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
-                                       buf, len);
-                       ret = -1;
-                       break;
-               }
-               if (*pos == WLAN_EID_RSN) {
-                       ie->rsn_ie = pos;
-                       ie->rsn_ie_len = pos[1] + 2;
-                       wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
-                                   ie->rsn_ie, ie->rsn_ie_len);
-               } else if (*pos == WLAN_EID_RSNX) {
-                       ie->rsnxe = pos;
-                       ie->rsnxe_len = pos[1] + 2;
-                       wpa_hexdump(MSG_DEBUG, "WPA: RSNXE in EAPOL-Key",
-                                   ie->rsnxe, ie->rsnxe_len);
-               } else if (*pos == WLAN_EID_MOBILITY_DOMAIN &&
-                          pos[1] >= sizeof(struct rsn_mdie)) {
-                       ie->mdie = pos;
-                       ie->mdie_len = pos[1] + 2;
-                       wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key",
-                                   ie->mdie, ie->mdie_len);
-               } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION &&
-                          pos[1] >= sizeof(struct rsn_ftie)) {
-                       ie->ftie = pos;
-                       ie->ftie_len = pos[1] + 2;
-                       wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",
-                                   ie->ftie, ie->ftie_len);
-               } else if (*pos == WLAN_EID_TIMEOUT_INTERVAL && pos[1] >= 5) {
-                       if (pos[2] == WLAN_TIMEOUT_REASSOC_DEADLINE) {
-                               ie->reassoc_deadline = pos;
-                               wpa_hexdump(MSG_DEBUG, "WPA: Reassoc Deadline "
-                                           "in EAPOL-Key",
-                                           ie->reassoc_deadline, pos[1] + 2);
-                       } else if (pos[2] == WLAN_TIMEOUT_KEY_LIFETIME) {
-                               ie->key_lifetime = pos;
-                               wpa_hexdump(MSG_DEBUG, "WPA: KeyLifetime "
-                                           "in EAPOL-Key",
-                                           ie->key_lifetime, pos[1] + 2);
-                       } else {
-                               wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized "
-                                           "EAPOL-Key Key Data IE",
-                                           pos, 2 + pos[1]);
-                       }
-               } else if (*pos == WLAN_EID_LINK_ID) {
-                       if (pos[1] >= 18) {
-                               ie->lnkid = pos;
-                               ie->lnkid_len = pos[1] + 2;
-                       }
-               } else if (*pos == WLAN_EID_EXT_CAPAB) {
-                       ie->ext_capab = pos;
-                       ie->ext_capab_len = pos[1] + 2;
-               } else if (*pos == WLAN_EID_SUPP_RATES) {
-                       ie->supp_rates = pos;
-                       ie->supp_rates_len = pos[1] + 2;
-               } else if (*pos == WLAN_EID_EXT_SUPP_RATES) {
-                       ie->ext_supp_rates = pos;
-                       ie->ext_supp_rates_len = pos[1] + 2;
-               } else if (*pos == WLAN_EID_HT_CAP &&
-                          pos[1] >= sizeof(struct ieee80211_ht_capabilities)) {
-                       ie->ht_capabilities = pos + 2;
-               } else if (*pos == WLAN_EID_VHT_AID) {
-                       if (pos[1] >= 2)
-                               ie->aid = WPA_GET_LE16(pos + 2) & 0x3fff;
-               } else if (*pos == WLAN_EID_VHT_CAP &&
-                          pos[1] >= sizeof(struct ieee80211_vht_capabilities))
-               {
-                       ie->vht_capabilities = pos + 2;
-               } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
-                       ie->qosinfo = pos[2];
-               } else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
-                       ie->supp_channels = pos + 2;
-                       ie->supp_channels_len = pos[1];
-               } else if (*pos == WLAN_EID_SUPPORTED_OPERATING_CLASSES) {
-                       /*
-                        * The value of the Length field of the Supported
-                        * Operating Classes element is between 2 and 253.
-                        * Silently skip invalid elements to avoid interop
-                        * issues when trying to use the value.
-                        */
-                       if (pos[1] >= 2 && pos[1] <= 253) {
-                               ie->supp_oper_classes = pos + 2;
-                               ie->supp_oper_classes_len = pos[1];
-                       }
-               } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
-                       ret = wpa_parse_generic(pos, end, ie);
-                       if (ret < 0)
-                               break;
-                       if (ret > 0) {
-                               ret = 0;
-                               break;
-                       }
-
-                       ret = wpa_parse_vendor_specific(pos, end, ie);
-                       if (ret < 0)
-                               break;
-                       if (ret > 0) {
-                               ret = 0;
-                               break;
-                       }
-               } else {
-                       wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
-                                   "Key Data IE", pos, 2 + pos[1]);
-               }
-       }
-
-       return ret;
-}
index fa7d0a317a42e30b5bf4ba9965a161a5d53a6ef7..6dc6cf560df938d07a77334000795df9a2309302 100644 (file)
 
 struct wpa_sm;
 
-struct wpa_eapol_ie_parse {
-       const u8 *wpa_ie;
-       size_t wpa_ie_len;
-       const u8 *rsn_ie;
-       size_t rsn_ie_len;
-       const u8 *pmkid;
-       const u8 *gtk;
-       size_t gtk_len;
-       const u8 *mac_addr;
-       size_t mac_addr_len;
-       const u8 *igtk;
-       size_t igtk_len;
-       const u8 *rsnxe;
-       size_t rsnxe_len;
-       const u8 *mdie;
-       size_t mdie_len;
-       const u8 *ftie;
-       size_t ftie_len;
-       const u8 *reassoc_deadline;
-       const u8 *key_lifetime;
-       const u8 *lnkid;
-       size_t lnkid_len;
-       const u8 *ext_capab;
-       size_t ext_capab_len;
-       const u8 *supp_rates;
-       size_t supp_rates_len;
-       const u8 *ext_supp_rates;
-       size_t ext_supp_rates_len;
-       const u8 *ht_capabilities;
-       const u8 *vht_capabilities;
-       const u8 *supp_channels;
-       size_t supp_channels_len;
-       const u8 *supp_oper_classes;
-       size_t supp_oper_classes_len;
-       u8 qosinfo;
-       u16 aid;
-       const u8 *wmm;
-       size_t wmm_len;
-#ifdef CONFIG_P2P
-       const u8 *ip_addr_req;
-       const u8 *ip_addr_alloc;
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_OCV
-       const u8 *oci;
-       size_t oci_len;
-#endif /* CONFIG_OCV */
-};
-
-int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
-                            struct wpa_eapol_ie_parse *ie);
 int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len);
 int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len);