]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Fix cipher suite selector default value in RSNE for DMG
authorLior David <liord@codeaurora.org>
Wed, 6 Feb 2019 10:33:35 +0000 (12:33 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 21 Feb 2019 10:42:24 +0000 (12:42 +0200)
According to IEEE Std 802.11-2016, 9.4.2.25 when fields of an RSNE are
not included, the default values are used. The cipher suite defaults
were hardcoded to CCMP in the previous implementation, but the default
is actually different for DMG: GCMP (per 9.4.2.25.2).

It is not possible to find out from the RSNE if the network is non-DMG
or DMG, so callers of wpa_parse_wpa_ie_rsn() need to handle this case
based on context, which can be different for each caller.

In order to fix this issue, add flags to the wpa_ie_data indicating
whether pairwise/group ciphers were included in the RSNE. Callers can
check these flags and fill in the appropriate ciphers. The
wpa_parse_wpa_ie_rsn() function still initializes the ciphers to CCMP by
default so existing callers will not break. This change also fixes some
callers which need to handle the DMG network case.

Signed-off-by: Lior David <liord@codeaurora.org>
src/ap/drv_callbacks.c
src/ap/ieee802_11.c
src/ap/wpa_auth.h
src/ap/wpa_auth_ie.c
src/common/wpa_common.c
src/common/wpa_common.h
wpa_supplicant/events.c
wpa_supplicant/ibss_rsn.c
wpa_supplicant/wpa_supplicant.c

index 54be3b52439c0bad1f85d3722554795d82989d42..e0c85cae64c2fd3ecc028dcd272c9c0d54d2dc1b 100644 (file)
@@ -305,6 +305,7 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
                        return -1;
                }
                res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
+                                         hapd->iface->freq,
                                          ie, ielen,
                                          elems.mdie, elems.mdie_len,
                                          elems.owe_dh, elems.owe_dh_len);
index 80d2d67ea73620fd21e6f6492b8702aeaa668782..d40ebad0e7d5cda49a019ad66d974373f59495d4 100644 (file)
@@ -1328,6 +1328,7 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
        }
 
        res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
+                                 hapd->iface->freq,
                                  elems.rsn_ie - 2, elems.rsn_ie_len + 2,
                                  elems.mdie, elems.mdie_len, NULL, 0);
        resp = wpa_res_to_status_code(res);
@@ -2700,6 +2701,7 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
                        return WLAN_STATUS_UNSPECIFIED_FAILURE;
                }
                res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
+                                         hapd->iface->freq,
                                          wpa_ie, wpa_ie_len,
                                          elems.mdie, elems.mdie_len,
                                          elems.owe_dh, elems.owe_dh_len);
index 4fc4ec3fb665a962874d7e6e14a45b675ddc563f..1d57dcae7fad19bee968690096d9f2f7c64ab702 100644 (file)
@@ -318,7 +318,7 @@ enum {
 };
 
 int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
-                       struct wpa_state_machine *sm,
+                       struct wpa_state_machine *sm, int freq,
                        const u8 *wpa_ie, size_t wpa_ie_len,
                        const u8 *mdie, size_t mdie_len,
                        const u8 *owe_dh, size_t owe_dh_len);
index 3bcbef793ce41f5999d9642cbdee70ab766b4f4e..4a96008c1ff18e9e6c526e0090319e412c52a28e 100644 (file)
@@ -530,7 +530,7 @@ static int wpa_auth_okc_iter(struct wpa_authenticator *a, void *ctx)
 
 
 int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
-                       struct wpa_state_machine *sm,
+                       struct wpa_state_machine *sm, int freq,
                        const u8 *wpa_ie, size_t wpa_ie_len,
                        const u8 *mdie, size_t mdie_len,
                        const u8 *owe_dh, size_t owe_dh_len)
@@ -560,6 +560,10 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
 
        if (version == WPA_PROTO_RSN) {
                res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
+               if (!data.has_pairwise)
+                       data.pairwise_cipher = wpa_default_rsn_cipher(freq);
+               if (!data.has_group)
+                       data.group_cipher = wpa_default_rsn_cipher(freq);
 
                if (wpa_key_mgmt_ft(data.key_mgmt) && !mdie &&
                    !wpa_key_mgmt_only_ft(data.key_mgmt)) {
index b47f632e50c5683672b9a2d14fc6ea85247e3644..613d5d05b1f51bdbb58ce507712f3bcaf409f320 100644 (file)
@@ -1209,6 +1209,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
                left = rsn_ie_len - 6;
 
                data->group_cipher = WPA_CIPHER_GTK_NOT_USED;
+               data->has_group = 1;
                data->key_mgmt = WPA_KEY_MGMT_OSEN;
                data->proto = WPA_PROTO_OSEN;
        } else {
@@ -1230,6 +1231,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
 
        if (left >= RSN_SELECTOR_LEN) {
                data->group_cipher = rsn_selector_to_bitfield(pos);
+               data->has_group = 1;
                if (!wpa_cipher_valid_group(data->group_cipher)) {
                        wpa_printf(MSG_DEBUG,
                                   "%s: invalid group cipher 0x%x (%08x)",
@@ -1255,6 +1257,8 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
                                   "count %u left %u", __func__, count, left);
                        return -4;
                }
+               if (count)
+                       data->has_pairwise = 1;
                for (i = 0; i < count; i++) {
                        data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
                        pos += RSN_SELECTOR_LEN;
@@ -1473,6 +1477,15 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
 }
 
 
+int wpa_default_rsn_cipher(int freq)
+{
+       if (freq > 56160)
+               return WPA_CIPHER_GCMP; /* DMG */
+
+       return WPA_CIPHER_CCMP;
+}
+
+
 #ifdef CONFIG_IEEE80211R
 
 /**
index 37b58341a73270499e7b29f78bf608380a53de32..2d9a71564353a5fdcca1b669c2c6741a8fefff0a 100644 (file)
@@ -392,7 +392,9 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len, const u8 *snonce,
 struct wpa_ie_data {
        int proto;
        int pairwise_cipher;
+       int has_pairwise;
        int group_cipher;
+       int has_group;
        int key_mgmt;
        int capabilities;
        size_t num_pmkid;
@@ -405,6 +407,7 @@ 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);
+int wpa_default_rsn_cipher(int freq);
 
 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
               u8 *pmkid, int akmp);
index b254d4ee2e2554a092e80a515168809e356eb912..f2462d794b2b7bc27c2a71b2b9e7a9d12166b6eb 100644 (file)
@@ -559,6 +559,10 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                                        "   skip RSN IE - parse failed");
                        break;
                }
+               if (!ie.has_pairwise)
+                       ie.pairwise_cipher = wpa_default_rsn_cipher(bss->freq);
+               if (!ie.has_group)
+                       ie.group_cipher = wpa_default_rsn_cipher(bss->freq);
 
                if (wep_ok &&
                    (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
index 187e951271fc58e78cb21b830556f0e79bf078ee..e96ea65a788751032739bd1e80e7b9d934235884 100644 (file)
@@ -459,7 +459,7 @@ static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn,
        }
 
        /* TODO: get peer RSN IE with Probe Request */
-       if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth,
+       if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth, 0,
                                (u8 *) "\x30\x14\x01\x00"
                                "\x00\x0f\xac\x04"
                                "\x01\x00\x00\x0f\xac\x04"
index 24c243149c0c52efc36d5fc2deb43db2603336ba..c2e4218c5d2b3ff0cd73fd165042a8655bd386fe 100644 (file)
@@ -1189,6 +1189,18 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
 }
 
 
+static int matching_ciphers(struct wpa_ssid *ssid, struct wpa_ie_data *ie,
+                           int freq)
+{
+       if (!ie->has_group)
+               ie->group_cipher = wpa_default_rsn_cipher(freq);
+       if (!ie->has_pairwise)
+               ie->pairwise_cipher = wpa_default_rsn_cipher(freq);
+       return (ie->group_cipher & ssid->group_cipher) &&
+               (ie->pairwise_cipher & ssid->pairwise_cipher);
+}
+
+
 /**
  * wpa_supplicant_set_suites - Set authentication and encryption parameters
  * @wpa_s: Pointer to wpa_supplicant data
@@ -1220,8 +1232,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 
        if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
            wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
-           (ie.group_cipher & ssid->group_cipher) &&
-           (ie.pairwise_cipher & ssid->pairwise_cipher) &&
+           matching_ciphers(ssid, &ie, bss->freq) &&
            (ie.key_mgmt & ssid->key_mgmt)) {
                wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
                proto = WPA_PROTO_RSN;