mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-25 00:38:24 -05:00
mesh: Avoid use of hardcoded cipher
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>
This commit is contained in:
parent
f868d5607d
commit
3b6deac0e7
@ -42,6 +42,9 @@ struct mesh_conf {
|
|||||||
#define MESH_CONF_SEC_AMPE BIT(2)
|
#define MESH_CONF_SEC_AMPE BIT(2)
|
||||||
unsigned int security;
|
unsigned int security;
|
||||||
enum mfp_options ieee80211w;
|
enum mfp_options ieee80211w;
|
||||||
|
unsigned int pairwise_cipher;
|
||||||
|
unsigned int group_cipher;
|
||||||
|
unsigned int mgmt_group_cipher;
|
||||||
int dot11MeshMaxRetries;
|
int dot11MeshMaxRetries;
|
||||||
int dot11MeshRetryTimeout; /* msec */
|
int dot11MeshRetryTimeout; /* msec */
|
||||||
int dot11MeshConfirmTimeout; /* msec */
|
int dot11MeshConfirmTimeout; /* msec */
|
||||||
|
@ -88,6 +88,7 @@ struct sta_info {
|
|||||||
u8 mtk[WPA_TK_MAX_LEN];
|
u8 mtk[WPA_TK_MAX_LEN];
|
||||||
size_t mtk_len;
|
size_t mtk_len;
|
||||||
u8 mgtk_rsc[6];
|
u8 mgtk_rsc[6];
|
||||||
|
u8 mgtk_key_id;
|
||||||
u8 mgtk[WPA_TK_MAX_LEN];
|
u8 mgtk[WPA_TK_MAX_LEN];
|
||||||
size_t mgtk_len;
|
size_t mgtk_len;
|
||||||
u8 igtk_rsc[6];
|
u8 igtk_rsc[6];
|
||||||
|
@ -90,6 +90,10 @@ static struct mesh_conf * mesh_config_create(struct wpa_supplicant *wpa_s,
|
|||||||
else
|
else
|
||||||
conf->ieee80211w = NO_MGMT_FRAME_PROTECTION;
|
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 */
|
/* defaults */
|
||||||
conf->mesh_pp_id = MESH_PATH_PROTOCOL_HWMP;
|
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);
|
wpa_supplicant_mesh_deinit(wpa_s);
|
||||||
|
|
||||||
if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
|
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
|
||||||
wpa_s->pairwise_cipher = WPA_CIPHER_CCMP;
|
wpa_s->group_cipher = WPA_CIPHER_NONE;
|
||||||
wpa_s->group_cipher = WPA_CIPHER_CCMP;
|
wpa_s->mgmt_group_cipher = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memset(¶ms, 0, sizeof(params));
|
os_memset(¶ms, 0, sizeof(params));
|
||||||
params.meshid = ssid->ssid;
|
params.meshid = ssid->ssid;
|
||||||
@ -409,6 +407,12 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
|
|||||||
goto out;
|
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) {
|
if (wpa_s->ifmsh) {
|
||||||
params.ies = wpa_s->ifmsh->mconf->rsn_ie;
|
params.ies = wpa_s->ifmsh->mconf->rsn_ie;
|
||||||
params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
|
params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
|
||||||
|
@ -794,30 +794,30 @@ static void mesh_mpm_plink_estab(struct wpa_supplicant *wpa_s,
|
|||||||
|
|
||||||
if (conf->security & MESH_CONF_SEC_AMPE) {
|
if (conf->security & MESH_CONF_SEC_AMPE) {
|
||||||
wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
|
wpa_hexdump_key(MSG_DEBUG, "mesh: MTK", sta->mtk, sta->mtk_len);
|
||||||
/* TODO: support for other ciphers */
|
wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->pairwise_cipher),
|
||||||
wpa_drv_set_key(wpa_s, WPA_ALG_CCMP, sta->addr, 0, 0,
|
sta->addr, 0, 0, seq, sizeof(seq),
|
||||||
seq, sizeof(seq), sta->mtk, sta->mtk_len);
|
sta->mtk, sta->mtk_len);
|
||||||
|
|
||||||
wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
|
wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK Key RSC",
|
||||||
sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
|
sta->mgtk_rsc, sizeof(sta->mgtk_rsc));
|
||||||
wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK",
|
wpa_hexdump_key(MSG_DEBUG, "mesh: RX MGTK",
|
||||||
sta->mgtk, sta->mgtk_len);
|
sta->mgtk, sta->mgtk_len);
|
||||||
/* TODO: support for other ciphers */
|
wpa_drv_set_key(wpa_s, wpa_cipher_to_alg(conf->group_cipher),
|
||||||
/* FIX: key index.. */
|
sta->addr, sta->mgtk_key_id, 0,
|
||||||
wpa_drv_set_key(wpa_s, WPA_ALG_CCMP, sta->addr, 1, 0,
|
|
||||||
sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
|
sta->mgtk_rsc, sizeof(sta->mgtk_rsc),
|
||||||
sta->mgtk, sta->mgtk_len);
|
sta->mgtk, sta->mgtk_len);
|
||||||
|
|
||||||
if (sta->igtk_len) {
|
if (sta->igtk_len) {
|
||||||
wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
|
wpa_hexdump_key(MSG_DEBUG, "mesh: RX IGTK Key RSC",
|
||||||
sta->igtk_rsc, sizeof(sta->igtk_rsc));
|
sta->igtk_rsc, sizeof(sta->igtk_rsc));
|
||||||
wpa_hexdump_key(MSG_DEBUG, "RX IGTK",
|
wpa_hexdump_key(MSG_DEBUG, "mesh: 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),
|
|
||||||
sta->igtk, sta->igtk_len);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
|
||||||
|
|
||||||
os_memset(&conf, 0, sizeof(conf));
|
os_memset(&conf, 0, sizeof(conf));
|
||||||
conf.wpa = 2;
|
conf.wpa = WPA_PROTO_RSN;
|
||||||
conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE;
|
conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE;
|
||||||
conf.wpa_pairwise = WPA_CIPHER_CCMP;
|
conf.wpa_pairwise = rsn->pairwise_cipher;
|
||||||
conf.rsn_pairwise = WPA_CIPHER_CCMP;
|
conf.rsn_pairwise = rsn->pairwise_cipher;
|
||||||
conf.wpa_group = WPA_CIPHER_CCMP;
|
conf.wpa_group = rsn->group_cipher;
|
||||||
conf.eapol_version = 0;
|
conf.eapol_version = 0;
|
||||||
conf.wpa_group_rekey = -1;
|
conf.wpa_group_rekey = -1;
|
||||||
#ifdef CONFIG_IEEE80211W
|
#ifdef CONFIG_IEEE80211W
|
||||||
conf.ieee80211w = ieee80211w;
|
conf.ieee80211w = ieee80211w;
|
||||||
if (ieee80211w != NO_MGMT_FRAME_PROTECTION)
|
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 */
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
|
||||||
os_memset(&cb, 0, sizeof(cb));
|
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 */
|
/* 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)
|
if (random_get_bytes(rsn->mgtk, rsn->mgtk_len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
rsn->mgtk_key_id = 1;
|
rsn->mgtk_key_id = 1;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211W
|
#ifdef CONFIG_IEEE80211W
|
||||||
if (ieee80211w != NO_MGMT_FRAME_PROTECTION) {
|
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)
|
if (random_get_bytes(rsn->igtk, rsn->igtk_len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
rsn->igtk_key_id = 4;
|
rsn->igtk_key_id = 4;
|
||||||
@ -188,7 +188,8 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
|
|||||||
/* group mgmt */
|
/* group mgmt */
|
||||||
wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX IGTK",
|
wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX IGTK",
|
||||||
rsn->igtk, rsn->igtk_len);
|
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,
|
rsn->igtk_key_id, 1,
|
||||||
seq, sizeof(seq), rsn->igtk, rsn->igtk_len);
|
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 */
|
/* group privacy / data frames */
|
||||||
wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX MGTK",
|
wpa_hexdump_key(MSG_DEBUG, "mesh: Own TX MGTK",
|
||||||
rsn->mgtk, rsn->mgtk_len);
|
rsn->mgtk, rsn->mgtk_len);
|
||||||
wpa_drv_set_key(rsn->wpa_s, WPA_ALG_CCMP, NULL, rsn->mgtk_key_id, 1,
|
wpa_drv_set_key(rsn->wpa_s, wpa_cipher_to_alg(rsn->group_cipher), NULL,
|
||||||
seq, sizeof(seq), rsn->mgtk, rsn->mgtk_len);
|
rsn->mgtk_key_id, 1, seq, sizeof(seq),
|
||||||
|
rsn->mgtk, rsn->mgtk_len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -227,6 +229,9 @@ struct mesh_rsn *mesh_rsn_auth_init(struct wpa_supplicant *wpa_s,
|
|||||||
if (mesh_rsn == NULL)
|
if (mesh_rsn == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
mesh_rsn->wpa_s = wpa_s;
|
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,
|
if (__mesh_rsn_auth_init(mesh_rsn, wpa_s->own_addr,
|
||||||
conf->ieee80211w) < 0) {
|
conf->ieee80211w) < 0) {
|
||||||
@ -464,7 +469,7 @@ int mesh_rsn_derive_mtk(struct wpa_supplicant *wpa_s, struct sta_info *sta)
|
|||||||
ptr += ETH_ALEN;
|
ptr += ETH_ALEN;
|
||||||
os_memcpy(ptr, max, 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,
|
sha256_prf(sta->sae->pmk, SAE_PMK_LEN,
|
||||||
"Temporal Key Derivation", context, sizeof(context),
|
"Temporal Key Derivation", context, sizeof(context),
|
||||||
sta->mtk, sta->mtk_len);
|
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]:
|
* GTKdata[variable]:
|
||||||
* MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]
|
* 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) {
|
if ((int) key_len + WPA_KEY_RSC_LEN + 4 > end - pos) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "mesh: Truncated AMPE element");
|
wpa_dbg(wpa_s, MSG_DEBUG, "mesh: Truncated AMPE element");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -707,7 +713,7 @@ int mesh_rsn_process_ampe(struct wpa_supplicant *wpa_s, struct sta_info *sta,
|
|||||||
* IGTKdata[variable]:
|
* IGTKdata[variable]:
|
||||||
* Key ID[2], IPN[6], IGTK[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)) {
|
if (end - pos >= (int) (2 + 6 + key_len)) {
|
||||||
sta->igtk_key_id = WPA_GET_LE16(pos);
|
sta->igtk_key_id = WPA_GET_LE16(pos);
|
||||||
wpa_printf(MSG_DEBUG, "mesh: IGTKdata - Key ID %u",
|
wpa_printf(MSG_DEBUG, "mesh: IGTKdata - Key ID %u",
|
||||||
|
@ -12,9 +12,12 @@
|
|||||||
struct mesh_rsn {
|
struct mesh_rsn {
|
||||||
struct wpa_supplicant *wpa_s;
|
struct wpa_supplicant *wpa_s;
|
||||||
struct wpa_authenticator *auth;
|
struct wpa_authenticator *auth;
|
||||||
|
unsigned int pairwise_cipher;
|
||||||
|
unsigned int group_cipher;
|
||||||
u8 mgtk[WPA_TK_MAX_LEN];
|
u8 mgtk[WPA_TK_MAX_LEN];
|
||||||
size_t mgtk_len;
|
size_t mgtk_len;
|
||||||
u8 mgtk_key_id;
|
u8 mgtk_key_id;
|
||||||
|
unsigned int mgmt_group_cipher;
|
||||||
u8 igtk_key_id;
|
u8 igtk_key_id;
|
||||||
u8 igtk[WPA_TK_MAX_LEN];
|
u8 igtk[WPA_TK_MAX_LEN];
|
||||||
size_t igtk_len;
|
size_t igtk_len;
|
||||||
|
Loading…
Reference in New Issue
Block a user