aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/mesh_mpm.c
diff options
context:
space:
mode:
authorThomas Pedersen <thomas@noack.us>2014-09-01 04:23:29 (GMT)
committerJouni Malinen <j@w1.fi>2014-11-16 17:43:06 (GMT)
commit0f950df0298a91d9696da15933ef6e7bc291cfa4 (patch)
tree2a6f37af66cd4f411e756b5666bd839ddeaf0623 /wpa_supplicant/mesh_mpm.c
parent88cb27c7a5164f8ffe465e4f1a4ae5f5f7bea91c (diff)
downloadhostap-0f950df0298a91d9696da15933ef6e7bc291cfa4.zip
hostap-0f950df0298a91d9696da15933ef6e7bc291cfa4.tar.gz
hostap-0f950df0298a91d9696da15933ef6e7bc291cfa4.tar.bz2
mesh: Add mesh robust security network
This implementation provides: - Mesh SAE authentication mechanism - Key management (set/get PSK) - Cryptographic key establishment - Enhanced protection mechanisms for robust management frames Signed-off-by: Javier Lopez <jlopex@gmail.com> Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: Jason Mobarak <x@jason.mobarak.name> Signed-off-by: Thomas Pedersen <thomas@noack.us>
Diffstat (limited to 'wpa_supplicant/mesh_mpm.c')
-rw-r--r--wpa_supplicant/mesh_mpm.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 02bb32c4..de6c3eb 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -17,6 +17,7 @@
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "mesh_mpm.h"
+#include "mesh_rsn.h"
/* TODO make configurable */
#define dot11MeshMaxRetries 10
@@ -212,7 +213,7 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
struct hostapd_data *bss = ifmsh->bss[0];
struct mesh_conf *conf = ifmsh->mconf;
u8 supp_rates[2 + 2 + 32];
- u8 *pos;
+ u8 *pos, *cat;
u8 ie_len, add_plid = 0;
int ret;
int ampe = conf->security & MESH_CONF_SEC_AMPE;
@@ -234,6 +235,7 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
if (!buf)
return;
+ cat = wpabuf_mhead_u8(buf);
wpabuf_put_u8(buf, WLAN_ACTION_SELF_PROTECTED);
wpabuf_put_u8(buf, type);
@@ -303,9 +305,18 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
wpabuf_put_le16(buf, sta->peer_lid);
if (type == PLINK_CLOSE)
wpabuf_put_le16(buf, close_reason);
+ if (ampe)
+ mesh_rsn_get_pmkid(wpa_s->mesh_rsn, sta,
+ wpabuf_put(buf, PMKID_LEN));
/* TODO HT IEs */
+ if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Mesh MPM: failed to add AMPE and MIC IE");
+ goto fail;
+ }
+
ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
sta->addr, wpa_s->own_addr, wpa_s->own_addr,
wpabuf_head(buf), wpabuf_len(buf), 0);
@@ -313,6 +324,7 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO,
"Mesh MPM: failed to send peering frame");
+fail:
wpabuf_free(buf);
}
@@ -462,6 +474,8 @@ void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr)
* the AP code already sets this flag. */
sta->flags |= WLAN_STA_AUTH;
+ mesh_rsn_init_ampe_sta(wpa_s, sta);
+
os_memset(&params, 0, sizeof(params));
params.addr = sta->addr;
params.flags = WPA_STA_AUTHENTICATED | WPA_STA_AUTHORIZED;
@@ -539,7 +553,10 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
return;
}
- mesh_mpm_plink_open(wpa_s, sta, PLINK_OPEN_SENT);
+ if (conf->security == MESH_CONF_SEC_NONE)
+ mesh_mpm_plink_open(wpa_s, sta, PLINK_OPEN_SENT);
+ else
+ mesh_rsn_auth_sae_sta(wpa_s, sta);
}
@@ -559,10 +576,27 @@ static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
struct sta_info *sta)
{
struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
+ struct mesh_conf *conf = wpa_s->ifmsh->mconf;
+ u8 seq[6] = {};
wpa_msg(wpa_s, MSG_INFO, "mesh plink with " MACSTR " established",
MAC2STR(sta->addr));
+ if (conf->security & MESH_CONF_SEC_AMPE) {
+ wpa_drv_set_key(wpa_s, WPA_ALG_CCMP, sta->addr, 0, 0,
+ seq, sizeof(seq), sta->mtk, sizeof(sta->mtk));
+ wpa_drv_set_key(wpa_s, WPA_ALG_CCMP, sta->addr, 1, 0,
+ seq, sizeof(seq),
+ sta->mgtk, sizeof(sta->mgtk));
+ wpa_drv_set_key(wpa_s, WPA_ALG_IGTK, sta->addr, 4, 0,
+ seq, sizeof(seq),
+ sta->mgtk, sizeof(sta->mgtk));
+
+ wpa_hexdump_key(MSG_DEBUG, "mtk:", sta->mtk, sizeof(sta->mtk));
+ wpa_hexdump_key(MSG_DEBUG, "mgtk:",
+ sta->mgtk, sizeof(sta->mgtk));
+ }
+
wpa_mesh_set_plink_state(wpa_s, sta, PLINK_ESTAB);
hapd->num_plinks++;
@@ -580,6 +614,7 @@ static void mesh_mpm_fsm(struct wpa_supplicant *wpa_s, struct sta_info *sta,
enum plink_event event)
{
struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
+ struct mesh_conf *conf = wpa_s->ifmsh->mconf;
u16 reason = 0;
wpa_msg(wpa_s, MSG_DEBUG, "MPM " MACSTR " state %s event %s",
@@ -652,6 +687,8 @@ static void mesh_mpm_fsm(struct wpa_supplicant *wpa_s, struct sta_info *sta,
PLINK_CONFIRM, 0);
break;
case CNF_ACPT:
+ if (conf->security & MESH_CONF_SEC_AMPE)
+ mesh_rsn_derive_mtk(wpa_s, sta);
mesh_mpm_plink_estab(wpa_s, sta);
break;
default:
@@ -745,6 +782,7 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
{
u8 action_field;
struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
+ struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
struct sta_info *sta;
u16 plid = 0, llid = 0;
enum plink_event event;
@@ -804,9 +842,21 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
if (!sta)
return;
+#ifdef CONFIG_SAE
+ /* peer is in sae_accepted? */
+ if (sta->sae && sta->sae->state != SAE_ACCEPTED)
+ return;
+#endif /* CONFIG_SAE */
+
if (!sta->my_lid)
mesh_mpm_init_link(wpa_s, sta);
+ if (mconf->security & MESH_CONF_SEC_AMPE)
+ if (mesh_rsn_process_ampe(wpa_s, sta, &elems,
+ &mgmt->u.action.category,
+ ies, ie_len))
+ return;
+
if (sta->plink_state == PLINK_BLOCKED)
return;