diff --git a/src/eapol.c b/src/eapol.c index f290f40a..6fb2f306 100644 --- a/src/eapol.c +++ b/src/eapol.c @@ -1234,12 +1234,7 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm, if (!found) goto error_unspecified; } else if (pmkid) { - uint8_t own_pmkid[16]; - - if (!handshake_state_get_pmkid(sm->handshake, own_pmkid)) - goto error_unspecified; - - if (l_secure_memcmp(pmkid, own_pmkid, 16)) { + if (!handshake_state_pmkid_matches(sm->handshake, pmkid)) { l_debug("Authenticator sent a PMKID that didn't match"); /* diff --git a/src/handshake.c b/src/handshake.c index ac5bda51..46755841 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -734,10 +734,9 @@ void handshake_state_set_pmkid(struct handshake_state *s, const uint8_t *pmkid) s->have_pmkid = true; } -bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid) +bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid, + enum l_checksum_type sha) { - enum l_checksum_type sha; - /* SAE exports pmkid */ if (s->have_pmkid) { memcpy(out_pmkid, s->pmkid, 16); @@ -747,13 +746,15 @@ bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid) if (!s->have_pmk) return false; - /* - * Note 802.11 section 11.6.1.3: - * "When the PMKID is calculated for the PMKSA as part of RSN - * preauthentication, the AKM has not yet been negotiated. In this - * case, the HMAC-SHA1-128 based derivation is used for the PMKID - * calculation." - */ + return crypto_derive_pmkid(s->pmk, 32, s->spa, s->aa, out_pmkid, + sha); +} + +bool handshake_state_pmkid_matches(struct handshake_state *s, + const uint8_t *check) +{ + uint8_t own_pmkid[16]; + enum l_checksum_type sha; if (s->akm_suite & (IE_RSN_AKM_SUITE_8021X_SHA256 | IE_RSN_AKM_SUITE_PSK_SHA256)) @@ -761,7 +762,10 @@ bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid) else sha = L_CHECKSUM_SHA1; - return crypto_derive_pmkid(s->pmk, 32, s->spa, s->aa, out_pmkid, sha); + if (!handshake_state_get_pmkid(s, own_pmkid, sha)) + return false; + + return l_secure_memcmp(own_pmkid, check, 16) == 0; } void handshake_state_set_gtk(struct handshake_state *s, const uint8_t *key, diff --git a/src/handshake.h b/src/handshake.h index 863ffac7..7200c361 100644 --- a/src/handshake.h +++ b/src/handshake.h @@ -269,8 +269,10 @@ void handshake_state_install_igtk(struct handshake_state *s, void handshake_state_override_pairwise_cipher(struct handshake_state *s, enum ie_rsn_cipher_suite pairwise); -bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid); - +bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid, + enum l_checksum_type sha); +bool handshake_state_pmkid_matches(struct handshake_state *s, + const uint8_t *check); bool handshake_decode_fte_key(struct handshake_state *s, const uint8_t *wrapped, size_t key_len, uint8_t *key_out); diff --git a/src/station.c b/src/station.c index f830ab7a..2473de2a 100644 --- a/src/station.c +++ b/src/station.c @@ -2236,7 +2236,15 @@ static void station_preauthenticate_cb(struct netdev *netdev, new_hs->supplicant_ie[1] + 2, &rsn_info); - handshake_state_get_pmkid(new_hs, pmkid); + /* + * IEEE 802.11 Section 12.7.1.3: + * + * "When the PMKID is calculated for the PMKSA as part of + * preauthentication, the AKM has not yet been negotiated. + * In this case, the HMAC-SHA-1 based derivation is used for + * the PMKID calculation." + */ + handshake_state_get_pmkid(new_hs, pmkid, L_CHECKSUM_SHA1); rsn_info.num_pmkids = 1; rsn_info.pmkids = pmkid;