RSN: Do not replace existing Suite B PMKSA on 4-way handshake

PMKID derivation with the Suite B AKMs is a special case compared to
other AKMs since that derivation uses KCK instead of PMK as an input.
This means that the PMKSA cache entry can be added only after KCK has
been derived during 4-way handshake. This also means that PMKID would
change every time 4-way handshake is repeated even when maintaining the
same PMK (i.e., during PTK rekeying and new associations even if they
use PMKSA caching).

wpa_supplicant was previously replacing the PMKSA cache entry whenever a
new PMKID was derived. This did not match hostapd expectations on the AP
side since hostapd did not update the PMKSA cache entry after it was
created. Consequently, PMKSA caching could be used only once (assuming
no PTK rekeying happened before that). Fix this by making wpa_supplicant
behave consistently with hostapd, i.e., by adding the Suite B PMKSA
cache entries with the PMKID from the very first 4-way handshake
following PMK derivation and then not updating the PMKID.

IEEE Std 802.11-2016 is somewhat vague in this area and it seems to
allow both cases to be used (initial PMKID or any consecutive PMKID
derived from the same PMK). While both cases could be supported that
would result in significantly more complex implementation and need to
store multiple PMKID values. It looks better to clarify the standard to
explicitly note that only the first PMKID derived after PMK derivation
is used (i.e., match the existing hostapd implementation).

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2018-09-27 11:37:19 +03:00 committed by Jouni Malinen
parent 4d1f7b6856
commit 17d4b77472

View file

@ -1461,7 +1461,13 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
if (ie.gtk) if (ie.gtk)
wpa_sm_set_rekey_offload(sm); wpa_sm_set_rekey_offload(sm);
if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) { /* Add PMKSA cache entry for Suite B AKMs here since PMKID can be
* calculated only after KCK has been derived. Though, do not replace an
* existing PMKSA entry after each 4-way handshake (i.e., new KCK/PMKID)
* to avoid unnecessary changes of PMKID while continuing to use the
* same PMK. */
if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt) &&
!sm->cur_pmksa) {
struct rsn_pmksa_cache_entry *sa; struct rsn_pmksa_cache_entry *sa;
sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL, sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL,