eapol: allow 'secure' to be set on rekeys

About a month ago hostapd was changed to set the secure bit on
eapol frames during rekeys (bc36991791). The spec is ambiguous
about this and has conflicting info depending on the sections you
read (12.7.2 vs 12.7.6). According to the hostapd commit log TGme
is trying to clarify this and wants to set secure=1 in the case
of rekeys. Because of this, IWD is completely broken with rekeys
since its disallows secure=1 on PTK 1/4 and 2/4.

Now, a bool is passed to the verify functions which signifies if
the PTK has been negotiated already. If secure differs from this
the key frame is not verified.
This commit is contained in:
James Prestwood 2022-06-24 16:07:40 -07:00 committed by Denis Kenzior
parent cfb782cfff
commit 7fad6590bd
2 changed files with 11 additions and 8 deletions

View File

@ -443,7 +443,8 @@ static void eapol_key_data_append(struct eapol_key *ek,
if (ek->error) \
return false \
bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len)
bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len,
bool ptk_complete)
{
/* Verify according to 802.11, Section 11.6.6.2 */
VERIFY_PTK_COMMON(ek);
@ -457,7 +458,7 @@ bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len)
if (ek->key_mic)
return false;
if (ek->secure)
if (ek->secure != ptk_complete)
return false;
if (ek->encrypted_key_data)
@ -475,7 +476,7 @@ bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len)
return true;
}
bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek)
bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek, bool ptk_complete)
{
uint16_t key_len;
@ -491,7 +492,7 @@ bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek)
if (!ek->key_mic)
return false;
if (ek->secure)
if (ek->secure != ptk_complete)
return false;
if (ek->encrypted_key_data)
@ -1151,7 +1152,8 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
l_debug("ifindex=%u", sm->handshake->ifindex);
if (!eapol_verify_ptk_1_of_4(ek, sm->mic_len))
if (!eapol_verify_ptk_1_of_4(ek, sm->mic_len,
sm->handshake->ptk_complete))
return;
if (sm->handshake->ptk_complete && unencrypted) {
@ -1523,7 +1525,7 @@ static void eapol_handle_ptk_2_of_4(struct eapol_sm *sm,
l_debug("ifindex=%u", sm->handshake->ifindex);
if (!eapol_verify_ptk_2_of_4(ek))
if (!eapol_verify_ptk_2_of_4(ek, sm->handshake->ptk_complete))
return;
if (L_BE64_TO_CPU(ek->key_replay_counter) != sm->replay_counter)

View File

@ -65,8 +65,9 @@ uint8_t *eapol_decrypt_key_data(enum ie_rsn_akm_suite akm, const uint8_t *kek,
const struct eapol_key *frame,
size_t *decrypted_size, size_t mic_len);
bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len);
bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek);
bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len,
bool ptk_complete);
bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek, bool ptk_complete);
bool eapol_verify_ptk_3_of_4(const struct eapol_key *ek, bool is_wpa,
size_t mic_len);
bool eapol_verify_ptk_4_of_4(const struct eapol_key *ek, bool is_wpa);