]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mesh: Avoid use of hardcoded cipher
authorJouni Malinen <j@w1.fi>
Sat, 18 Jun 2016 19:14:37 +0000 (22:14 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 19 Jun 2016 17:18:09 +0000 (20:18 +0300)
This moves pairwise, group, and management group ciphers to various mesh
data structures to avoid having to hardcode cipher in number of places
through the code. While CCMP and BIP are still the hardcoded ciphers,
these are now set only in one location.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/ap_config.h
src/ap/sta_info.h
wpa_supplicant/mesh.c
wpa_supplicant/mesh_mpm.c
wpa_supplicant/mesh_rsn.c
wpa_supplicant/mesh_rsn.h

index 8ffd390784d9ae8a34f533e4aeef07c1dfef1da2..0ae9a6e0cc177388276a7f21bf5d54e1c80df923 100644 (file)
@@ -42,6 +42,9 @@ struct mesh_conf {
 #define MESH_CONF_SEC_AMPE BIT(2)
        unsigned int security;
        enum mfp_options ieee80211w;
+       unsigned int pairwise_cipher;
+       unsigned int group_cipher;
+       unsigned int mgmt_group_cipher;
        int dot11MeshMaxRetries;
        int dot11MeshRetryTimeout; /* msec */
        int dot11MeshConfirmTimeout; /* msec */
index c374ea0e88946a49a98ede9a9d7cfb15d2f937fd..5d4d0c82b41fd9f83587587277551c4becf01b59 100644 (file)
@@ -88,6 +88,7 @@ struct sta_info {
        u8 mtk[WPA_TK_MAX_LEN];
        size_t mtk_len;
        u8 mgtk_rsc[6];
+       u8 mgtk_key_id;
        u8 mgtk[WPA_TK_MAX_LEN];
        size_t mgtk_len;
        u8 igtk_rsc[6];
index aed55da8bb05e6a720bcdf76ce76ae0411266aaf..c5f089e51507dc67225ec4a642da65f6d75d9738 100644 (file)
@@ -90,6 +90,10 @@ static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s,
                else
                        conf->ieee80211w = NO_MGMT_FRAME_PROTECTION;
        }
+       conf->pairwise_cipher = WPA_CIPHER_CCMP;
+       conf->group_cipher = WPA_CIPHER_CCMP;
+       if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION)
+               conf->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
 
        /* defaults */
        conf->mesh_pp_id = MESH_PATH_PROTOCOL_HWMP;
@@ -343,15 +347,9 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
 
        wpa_supplicant_mesh_deinit(wpa_s);
 
-       if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
-               wpa_s->pairwise_cipher = WPA_CIPHER_CCMP;
-               wpa_s->group_cipher = WPA_CIPHER_CCMP;
-               wpa_s->mgmt_group_cipher = 0;
-       } else {
-               wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
-               wpa_s->group_cipher = WPA_CIPHER_NONE;
-               wpa_s->mgmt_group_cipher = 0;
-       }
+       wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
+       wpa_s->group_cipher = WPA_CIPHER_NONE;
+       wpa_s->mgmt_group_cipher = 0;
 
        os_memset(&params, 0, sizeof(params));
        params.meshid = ssid->ssid;
@@ -409,6 +407,12 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
                goto out;
        }
 
+       if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
+               wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
+               wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
+               wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
+       }
+
        if (wpa_s->ifmsh) {
                params.ies = wpa_s->ifmsh->mconf->rsn_ie;
                params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
index 74ad762bb175dd5b3d8d00a0ce60d077619f0425..3f36a6002301dd3585cec3c4220136edc8b11d29 100644 (file)
@@ -794,30 +794,30 @@ static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
 
        if (conf->security & MESH_CONF_SEC_AMPE) {
                wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
-               /* TODO: support for other ciphers */
-               wpa_drv_set_key(wpa_s, WPA_ALG_CCMP, sta->addr, 0, 0,
-                               seq, sizeof(seq), sta->mtk, sta->mtk_len);
+               wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->pairwise_cipher),
+                               sta->addr, 0, 0, seq, sizeof(seq),
+                               sta->mtk, sta->mtk_len);
 
                wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
                                sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
                wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK",
                                sta->mgtk, sta->mgtk_len);
-               /* TODO: support for other ciphers */
-               /* FIX: key index.. */
-               wpa_drv_set_key(wpa_s, WPA_ALG_CCMP, sta->addr, 1, 0,
+               wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->group_cipher),
+                               sta->addr, sta->mgtk_key_id, 0,
                                sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
                                sta->mgtk, sta->mgtk_len);
 
                if (sta->igtk_len) {
                        wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
                                        sta->igtk_rsc, sizeof(sta->igtk_rsc));
-                       wpa_hexdump_key(MSG_DEBUG, "RX IGTK",
-                                       sta->igtk, sta->igtk_len);
-                       /* FIX: key index.. */
-                       wpa_drv_set_key(wpa_s, WPA_ALG_IGTK, sta->addr,
-                                       sta->igtk_key_id, 0,
-                                       sta->igtk_rsc, sizeof(sta->igtk_rsc),
+                       wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK",
                                        sta->igtk, sta->igtk_len);
+                       wpa_drv_set_key(
+                               wpa_s,
+                               wpa_cipher_to_alg(conf->mgmt_group_cipher),
+                               sta->addr, sta->igtk_key_id, 0,
+                               sta->igtk_rsc, sizeof(sta->igtk_rsc),
+                               sta->igtk, sta->igtk_len);
                }
        }
 
index 6ca3837ff687d9256cb5abaecb9bf931624e5d44..c5f5d692bba1e177ab800c1632db2a12d3320e52 100644 (file)
@@ -146,17 +146,17 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
        wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
 
        os_memset(&conf, 0, sizeof(conf));
-       conf.wpa = 2;
+       conf.wpa = WPA_PROTO_RSN;
        conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE;
-       conf.wpa_pairwise = WPA_CIPHER_CCMP;
-       conf.rsn_pairwise = WPA_CIPHER_CCMP;
-       conf.wpa_group = WPA_CIPHER_CCMP;
+       conf.wpa_pairwise = rsn->pairwise_cipher;
+       conf.rsn_pairwise = rsn->pairwise_cipher;
+       conf.wpa_group = rsn->group_cipher;
        conf.eapol_version = 0;
        conf.wpa_group_rekey = -1;
 #ifdef CONFIG_IEEE80211W
        conf.ieee80211w = ieee80211w;
        if (ieee80211w != NO_MGMT_FRAME_PROTECTION)
-               conf.group_mgmt_cipher = WPA_CIPHER_AES_128_CMAC;
+               conf.group_mgmt_cipher = rsn->mgmt_group_cipher;
 #endif /* CONFIG_IEEE80211W */
 
        os_memset(&cb, 0, sizeof(cb));
@@ -173,14 +173,14 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
        }
 
        /* TODO: support rekeying */
-       rsn->mgtk_len = wpa_cipher_key_len(WPA_CIPHER_CCMP);
+       rsn->mgtk_len = wpa_cipher_key_len(conf.wpa_group);
        if (random_get_bytes(rsn->mgtk, rsn->mgtk_len) < 0)
                return -1;
        rsn->mgtk_key_id = 1;
 
 #ifdef CONFIG_IEEE80211W
        if (ieee80211w != NO_MGMT_FRAME_PROTECTION) {
-               rsn->igtk_len = wpa_cipher_key_len(WPA_CIPHER_AES_128_CMAC);
+               rsn->igtk_len = wpa_cipher_key_len(conf.group_mgmt_cipher);
                if (random_get_bytes(rsn->igtk, rsn->igtk_len) < 0)
                        return -1;
                rsn->igtk_key_id = 4;
@@ -188,7 +188,8 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
                /* group mgmt */
                wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX IGTK",
                                rsn->igtk, rsn->igtk_len);
-               wpa_drv_set_key(rsn->wpa_s, WPA_ALG_IGTK, NULL,
+               wpa_drv_set_key(rsn->wpa_s,
+                               wpa_cipher_to_alg(rsn->mgmt_group_cipher), NULL,
                                rsn->igtk_key_id, 1,
                                seq, sizeof(seq), rsn->igtk, rsn->igtk_len);
        }
@@ -197,8 +198,9 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
        /* group privacy / data frames */
        wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX MGTK",
                        rsn->mgtk, rsn->mgtk_len);
-       wpa_drv_set_key(rsn->wpa_s, WPA_ALG_CCMP, NULL, rsn->mgtk_key_id, 1,
-                       seq, sizeof(seq), rsn->mgtk, rsn->mgtk_len);
+       wpa_drv_set_key(rsn->wpa_s, wpa_cipher_to_alg(rsn->group_cipher), NULL,
+                       rsn->mgtk_key_id, 1, seq, sizeof(seq),
+                       rsn->mgtk, rsn->mgtk_len);
 
        return 0;
 }
@@ -227,6 +229,9 @@ struct mesh_rsn *mesh_rsn_auth_init(struct wpa_supplicant *wpa_s,
        if (mesh_rsn == NULL)
                return NULL;
        mesh_rsn->wpa_s = wpa_s;
+       mesh_rsn->pairwise_cipher = conf->pairwise_cipher;
+       mesh_rsn->group_cipher = conf->group_cipher;
+       mesh_rsn->mgmt_group_cipher = conf->mgmt_group_cipher;
 
        if (__mesh_rsn_auth_init(mesh_rsn, wpa_s->own_addr,
                                 conf->ieee80211w) < 0) {
@@ -464,7 +469,7 @@ int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta)
        ptr += ETH_ALEN;
        os_memcpy(ptr, max, ETH_ALEN);
 
-       sta->mtk_len = wpa_cipher_key_len(WPA_CIPHER_CCMP);
+       sta->mtk_len = wpa_cipher_key_len(wpa_s->mesh_rsn->pairwise_cipher);
        sha256_prf(sta->sae->pmk, SAE_PMK_LEN,
                   "Temporal Key Derivation", context, sizeof(context),
                   sta->mtk, sta->mtk_len);
@@ -682,7 +687,8 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
         * GTKdata[variable]:
         * MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]
         */
-       key_len = wpa_cipher_key_len(WPA_CIPHER_CCMP);
+       sta->mgtk_key_id = 1; /* FIX: Where to get Key ID? */
+       key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->group_cipher);
        if ((int) key_len + WPA_KEY_RSC_LEN + 4 > end - pos) {
                wpa_dbg(wpa_s, MSG_DEBUG, "mesh: Truncated AMPE element");
                ret = -1;
@@ -707,7 +713,7 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
         * IGTKdata[variable]:
         * Key ID[2], IPN[6], IGTK[variable]
         */
-       key_len = wpa_cipher_key_len(WPA_CIPHER_AES_128_CMAC);
+       key_len = wpa_cipher_key_len(wpa_s->mesh_rsn->mgmt_group_cipher);
        if (end - pos >= (int) (2 + 6 + key_len)) {
                sta->igtk_key_id = WPA_GET_LE16(pos);
                wpa_printf(MSG_DEBUG, "mesh: IGTKdata - Key ID %u",
index 85fba7dd3f9c939db909ef80a4c0ea1d97e6f777..8775cedc3b273e65f258d9c0d88b0da88f8efa58 100644 (file)
 struct mesh_rsn {
        struct wpa_supplicant *wpa_s;
        struct wpa_authenticator *auth;
+       unsigned int pairwise_cipher;
+       unsigned int group_cipher;
        u8 mgtk[WPA_TK_MAX_LEN];
        size_t mgtk_len;
        u8 mgtk_key_id;
+       unsigned int mgmt_group_cipher;
        u8 igtk_key_id;
        u8 igtk[WPA_TK_MAX_LEN];
        size_t igtk_len;