From 9992d3aeda70c9990913e78baadcb9d2953592b0 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 19 May 2015 00:05:53 -0500 Subject: [PATCH] eapol: Extract & keep track of desired ciphers When our own WPA IE or RSN IE are set, extract group and pairwise ciphers. These ciphers are the ones we desire to use for the secure connection. --- src/eapol.c | 35 +++++++++++++++++++++++++++++++++-- src/eapol.h | 4 ++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/eapol.c b/src/eapol.c index 02e1b9c3..e76d0152 100644 --- a/src/eapol.c +++ b/src/eapol.c @@ -590,6 +590,8 @@ struct eapol_sm { uint8_t aa[6]; uint8_t *ap_ie; uint8_t *own_ie; + enum ie_rsn_cipher_suite pairwise_cipher; + enum ie_rsn_cipher_suite group_cipher; uint8_t pmk[32]; uint64_t replay_counter; uint8_t snonce[32]; @@ -671,10 +673,32 @@ void eapol_sm_set_ap_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie, size_t len) eapol_sm_set_ap_ie(sm, rsn_ie, len, false); } -void eapol_sm_set_own_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie, +static bool eapol_sm_setup_own_ciphers(struct eapol_sm *sm, + const struct ie_rsn_info *info) +{ + if (__builtin_popcount(info->pairwise_ciphers) != 1) + return false; + + if (__builtin_popcount(info->akm_suites) != 1) + return false; + + sm->pairwise_cipher = info->pairwise_ciphers; + sm->group_cipher = info->group_cipher; + + return true; +} + +bool eapol_sm_set_own_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie, size_t len) { + struct ie_rsn_info info; + eapol_sm_set_own_ie(sm, rsn_ie, len, false); + + if (ie_parse_rsne_from_data(rsn_ie, rsn_ie[1] + 2, &info) < 0) + return false; + + return eapol_sm_setup_own_ciphers(sm, &info); } void eapol_sm_set_ap_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie, size_t len) @@ -682,10 +706,17 @@ void eapol_sm_set_ap_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie, size_t len) eapol_sm_set_ap_ie(sm, wpa_ie, len, true); } -void eapol_sm_set_own_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie, +bool eapol_sm_set_own_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie, size_t len) { + struct ie_rsn_info info; + eapol_sm_set_own_ie(sm, wpa_ie, len, true); + + if (ie_parse_wpa_from_data(wpa_ie, wpa_ie[1] + 2, &info) < 0) + return false; + + return eapol_sm_setup_own_ciphers(sm, &info); } void eapol_sm_set_user_data(struct eapol_sm *sm, void *user_data) diff --git a/src/eapol.h b/src/eapol.h index 90c2f5c9..62f0a1d9 100644 --- a/src/eapol.h +++ b/src/eapol.h @@ -168,11 +168,11 @@ void eapol_sm_set_authenticator_address(struct eapol_sm *sm, const uint8_t *aa); void eapol_sm_set_pmk(struct eapol_sm *sm, const uint8_t *pmk); void eapol_sm_set_ap_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie, size_t len); -void eapol_sm_set_own_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie, +bool eapol_sm_set_own_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie, size_t len); void eapol_sm_set_ap_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie, size_t len); -void eapol_sm_set_own_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie, +bool eapol_sm_set_own_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie, size_t len); void eapol_sm_set_user_data(struct eapol_sm *sm, void *user_data); struct l_io *eapol_open_pae(uint32_t index);