From 70c93963edefa37ef84b73efb9d04ea10268341c Mon Sep 17 00:00:00 2001 From: Masashi Honma Date: Mon, 15 Feb 2016 11:23:37 +0900 Subject: [PATCH] SAE: Fix PMKID calculation for PMKSA cache The SAE PMKID is calculated with IEEE Std 802.11-2012 11.3.5.4, but the PMKID was re-calculated with 11.6.1.3 and saved into PMKSA cache. Fix this to save the PMKID calculated with 11.3.5.4 into the PMKSA cache. Signed-off-by: Masashi Honma --- src/ap/ieee802_11.c | 2 +- src/ap/pmksa_cache_auth.c | 7 +++++-- src/ap/pmksa_cache_auth.h | 2 +- src/ap/wpa_auth.c | 8 ++++---- src/ap/wpa_auth.h | 2 +- src/rsn_supp/pmksa_cache.c | 9 ++++++--- src/rsn_supp/pmksa_cache.h | 4 ++-- src/rsn_supp/preauth.c | 2 +- src/rsn_supp/wpa.c | 9 +++++---- src/rsn_supp/wpa.h | 5 +++-- wpa_supplicant/ibss_rsn.c | 2 +- wpa_supplicant/sme.c | 2 +- wpa_supplicant/wpa_supplicant.c | 11 +++++++---- 13 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index de32f66..dbabab8 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -665,7 +665,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta, wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); sta->sae->state = SAE_ACCEPTED; wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr, - sta->sae->pmk); + sta->sae->pmk, sta->sae->pmkid); } break; case SAE_ACCEPTED: diff --git a/src/ap/pmksa_cache_auth.c b/src/ap/pmksa_cache_auth.c index 5e8491a..30be30c 100644 --- a/src/ap/pmksa_cache_auth.c +++ b/src/ap/pmksa_cache_auth.c @@ -247,6 +247,7 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa, * @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init() * @pmk: The new pairwise master key * @pmk_len: PMK length in bytes, usually PMK_LEN (32) + * @pmkid: Calculated PMKID * @kck: Key confirmation key or %NULL if not yet derived * @kck_len: KCK length in bytes * @aa: Authenticator address @@ -263,7 +264,7 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa, */ struct rsn_pmksa_cache_entry * pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa, - const u8 *pmk, size_t pmk_len, + const u8 *pmk, size_t pmk_len, const u8 *pmkid, const u8 *kck, size_t kck_len, const u8 *aa, const u8 *spa, int session_timeout, struct eapol_state_machine *eapol, int akmp) @@ -282,7 +283,9 @@ pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa, return NULL; os_memcpy(entry->pmk, pmk, pmk_len); entry->pmk_len = pmk_len; - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + if (pmkid) + os_memcpy(entry->pmkid, pmkid, PMKID_LEN); + else if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) rsn_pmkid_suite_b_192(kck, kck_len, aa, spa, entry->pmkid); else if (wpa_key_mgmt_suite_b(akmp)) rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid); diff --git a/src/ap/pmksa_cache_auth.h b/src/ap/pmksa_cache_auth.h index daf0834..3e60277 100644 --- a/src/ap/pmksa_cache_auth.h +++ b/src/ap/pmksa_cache_auth.h @@ -48,7 +48,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_okc( const u8 *pmkid); struct rsn_pmksa_cache_entry * pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa, - const u8 *pmk, size_t pmk_len, + const u8 *pmk, size_t pmk_len, const u8 *pmkid, const u8 *kck, size_t kck_len, const u8 *aa, const u8 *spa, int session_timeout, struct eapol_state_machine *eapol, int akmp); diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 9b2382f..4ded9bb 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3298,7 +3298,7 @@ int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk, pmk_len = PMK_LEN; } - if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, pmk_len, + if (pmksa_cache_auth_add(sm->wpa_auth->pmksa, pmk, pmk_len, NULL, sm->PTK.kck, sm->PTK.kck_len, sm->wpa_auth->addr, sm->addr, session_timeout, eapol, sm->wpa_key_mgmt)) @@ -3316,7 +3316,7 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, if (wpa_auth == NULL) return -1; - if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, len, + if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, len, NULL, NULL, 0, wpa_auth->addr, sta_addr, session_timeout, eapol, @@ -3328,12 +3328,12 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk) + const u8 *pmk, const u8 *pmkid) { if (wpa_auth->conf.disable_pmksa_caching) return -1; - if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, + if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, pmkid, NULL, 0, wpa_auth->addr, addr, 0, NULL, WPA_KEY_MGMT_SAE)) diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 75b73f0..b303324 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -286,7 +286,7 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth, int session_timeout, struct eapol_state_machine *eapol); int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr, - const u8 *pmk); + const u8 *pmk, const u8 *pmkid); void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, const u8 *sta_addr); int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id); diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c index 1afeaa2..3d8d122 100644 --- a/src/rsn_supp/pmksa_cache.c +++ b/src/rsn_supp/pmksa_cache.c @@ -109,6 +109,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa) * @pmksa: Pointer to PMKSA cache data from pmksa_cache_init() * @pmk: The new pairwise master key * @pmk_len: PMK length in bytes, usually PMK_LEN (32) + * @pmkid: Calculated PMKID * @kck: Key confirmation key or %NULL if not yet derived * @kck_len: KCK length in bytes * @aa: Authenticator address @@ -124,7 +125,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa) */ struct rsn_pmksa_cache_entry * pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, - const u8 *kck, size_t kck_len, + const u8 *pmkid, const u8 *kck, size_t kck_len, const u8 *aa, const u8 *spa, void *network_ctx, int akmp) { struct rsn_pmksa_cache_entry *entry, *pos, *prev; @@ -141,7 +142,9 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, return NULL; os_memcpy(entry->pmk, pmk, pmk_len); entry->pmk_len = pmk_len; - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + if (pmkid) + os_memcpy(entry->pmkid, pmkid, PMKID_LEN); + else if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) rsn_pmkid_suite_b_192(kck, kck_len, aa, spa, entry->pmkid); else if (wpa_key_mgmt_suite_b(akmp)) rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid); @@ -344,7 +347,7 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa, struct rsn_pmksa_cache_entry *new_entry; new_entry = pmksa_cache_add(pmksa, old_entry->pmk, old_entry->pmk_len, - NULL, 0, + NULL, NULL, 0, aa, pmksa->sm->own_addr, old_entry->network_ctx, old_entry->akmp); if (new_entry == NULL) diff --git a/src/rsn_supp/pmksa_cache.h b/src/rsn_supp/pmksa_cache.h index d559430..daede6d 100644 --- a/src/rsn_supp/pmksa_cache.h +++ b/src/rsn_supp/pmksa_cache.h @@ -57,7 +57,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa, int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len); struct rsn_pmksa_cache_entry * pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, - const u8 *kck, size_t kck_len, + const u8 *pmkid, const u8 *kck, size_t kck_len, const u8 *aa, const u8 *spa, void *network_ctx, int akmp); struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm); void pmksa_cache_clear_current(struct wpa_sm *sm); @@ -105,7 +105,7 @@ static inline int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, static inline struct rsn_pmksa_cache_entry * pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, - const u8 *kck, size_t kck_len, + const u8 *pmkid, const u8 *kck, size_t kck_len, const u8 *aa, const u8 *spa, void *network_ctx, int akmp) { return NULL; diff --git a/src/rsn_supp/preauth.c b/src/rsn_supp/preauth.c index 55a4a74..4c9a4fb 100644 --- a/src/rsn_supp/preauth.c +++ b/src/rsn_supp/preauth.c @@ -93,7 +93,7 @@ static void rsn_preauth_eapol_cb(struct eapol_sm *eapol, wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from pre-auth", pmk, pmk_len); sm->pmk_len = pmk_len; - pmksa_cache_add(sm->pmksa, pmk, pmk_len, + pmksa_cache_add(sm->pmksa, pmk, pmk_len, NULL, NULL, 0, sm->preauth_bssid, sm->own_addr, sm->network_ctx, diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 64ef933..e850119 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -249,7 +249,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, !wpa_key_mgmt_suite_b(sm->key_mgmt) && !wpa_key_mgmt_ft(sm->key_mgmt)) { sa = pmksa_cache_add(sm->pmksa, - sm->pmk, pmk_len, + sm->pmk, pmk_len, NULL, NULL, 0, src_addr, sm->own_addr, sm->network_ctx, @@ -1297,7 +1297,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) { struct rsn_pmksa_cache_entry *sa; - sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, + sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL, sm->ptk.kck, sm->ptk.kck_len, sm->bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt); @@ -2391,12 +2391,13 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm) * @sm: Pointer to WPA state machine data from wpa_sm_init() * @pmk: The new PMK * @pmk_len: The length of the new PMK in bytes + * @pmkid: Calculated PMKID * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK * * Configure the PMK for WPA state machine. */ void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len, - const u8 *bssid) + const u8 *pmkid, const u8 *bssid) { if (sm == NULL) return; @@ -2411,7 +2412,7 @@ void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len, #endif /* CONFIG_IEEE80211R */ if (bssid) { - pmksa_cache_add(sm->pmksa, pmk, pmk_len, NULL, 0, + pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0, bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt); } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index f9c89b3..c89799a 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -114,7 +114,7 @@ void wpa_sm_deinit(struct wpa_sm *sm); void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid); void wpa_sm_notify_disassoc(struct wpa_sm *sm); void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len, - const u8 *bssid); + const u8 *pmkid, const u8 *bssid); void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm); void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth); void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx); @@ -181,7 +181,8 @@ static inline void wpa_sm_notify_disassoc(struct wpa_sm *sm) } static inline void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, - size_t pmk_len, const u8 *bssid) + size_t pmk_len, const u8 *pmkid, + const u8 *bssid) { } diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index d9d0ae7..c00db31 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -230,7 +230,7 @@ static int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr, wpa_sm_set_param(peer->supp, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP); wpa_sm_set_param(peer->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP); wpa_sm_set_param(peer->supp, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK); - wpa_sm_set_pmk(peer->supp, psk, PMK_LEN, NULL); + wpa_sm_set_pmk(peer->supp, psk, PMK_LEN, NULL, NULL); peer->supp_ie_len = sizeof(peer->supp_ie); if (wpa_sm_set_assoc_wpa_ie_default(peer->supp, peer->supp_ie, diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 2a3a728..fd38b9d 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -814,7 +814,7 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for " "4-way handshake"); wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN, - wpa_s->pending_bssid); + wpa_s->sme.sae.pmkid, wpa_s->pending_bssid); } #endif /* CONFIG_SAE */ diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index f362638..8171b62 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1293,7 +1293,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, int psk_set = 0; if (ssid->psk_set) { - wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL); + wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL, + NULL); psk_set = 1; } #ifndef CONFIG_NO_PBKDF2 @@ -1304,7 +1305,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, 4096, psk, PMK_LEN); wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)", psk, PMK_LEN); - wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL); + wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, NULL); psk_set = 1; os_memset(psk, 0, sizeof(psk)); } @@ -1342,7 +1343,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, wpa_hexdump_key(MSG_MSGDUMP, "PSK (from " "external passphrase)", psk, PMK_LEN); - wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL); + wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, + NULL); psk_set = 1; os_memset(psk, 0, sizeof(psk)); } else @@ -1355,7 +1357,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, ext_password_free(pw); return -1; } - wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL); + wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, + NULL); psk_set = 1; os_memset(psk, 0, sizeof(psk)); } else { -- 2.1.4