diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 8ffd39078..0ae9a6e0c 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -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 */ diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h index c374ea0e8..5d4d0c82b 100644 --- a/src/ap/sta_info.h +++ b/src/ap/sta_info.h @@ -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]; diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index aed55da8b..c5f089e51 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -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(¶ms, 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; diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c index 74ad762bb..3f36a6002 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -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); } } diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c index 6ca3837ff..c5f5d692b 100644 --- a/wpa_supplicant/mesh_rsn.c +++ b/wpa_supplicant/mesh_rsn.c @@ -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", diff --git a/wpa_supplicant/mesh_rsn.h b/wpa_supplicant/mesh_rsn.h index 85fba7dd3..8775cedc3 100644 --- a/wpa_supplicant/mesh_rsn.h +++ b/wpa_supplicant/mesh_rsn.h @@ -12,9 +12,12 @@ 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;