3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-26 02:19:26 +01:00

eapol: Tighten up GTK/IGTK KDE validation

GTK KDE was being checked for being a minimum of 6 bytes.  Not quite
sure why since the minimum GTK key length is 16 bytes for CCMP.
Similarly make sure that the maximum length is not more than 32, which
is currently the largest key size (TKIP)
This commit is contained in:
Denis Kenzior 2017-10-19 14:40:15 -05:00
parent c93a52c066
commit cd7af67aac
3 changed files with 55 additions and 14 deletions

View File

@ -43,6 +43,12 @@ enum crypto_akm {
CRYPTO_AKM_FT_OVER_SAE_SHA256 = 0x000fac09, CRYPTO_AKM_FT_OVER_SAE_SHA256 = 0x000fac09,
}; };
/* Min & Max reported by crypto_cipher_key_len when ignoring WEP */
#define CRYPTO_MIN_GTK_LEN 16
#define CRYPTO_MAX_GTK_LEN 32
#define CRYPTO_MIN_IGTK_LEN 16
#define CRYPTO_MAX_IGTK_LEN 32
struct crypto_ptk { struct crypto_ptk {
uint8_t kck[16]; uint8_t kck[16];
uint8_t kek[16]; uint8_t kek[16];

View File

@ -1231,7 +1231,7 @@ static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
gtk = handshake_util_find_gtk_kde(decrypted_key_data, gtk = handshake_util_find_gtk_kde(decrypted_key_data,
decrypted_key_data_size, decrypted_key_data_size,
&gtk_len); &gtk_len);
if (!gtk || gtk_len < 8) { if (!gtk) {
handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED); handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED);
return; return;
} }
@ -1248,7 +1248,7 @@ static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
igtk = handshake_util_find_igtk_kde(decrypted_key_data, igtk = handshake_util_find_igtk_kde(decrypted_key_data,
decrypted_key_data_size, decrypted_key_data_size,
&igtk_len); &igtk_len);
if (!igtk || igtk_len < 8) { if (!igtk) {
handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED); handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED);
return; return;
} }
@ -1336,29 +1336,28 @@ static void eapol_handle_gtk_1_of_2(struct eapol_sm *sm,
gtk = handshake_util_find_gtk_kde(decrypted_key_data, gtk = handshake_util_find_gtk_kde(decrypted_key_data,
decrypted_key_data_size, decrypted_key_data_size,
&gtk_len); &gtk_len);
if (!gtk)
if (!gtk || gtk_len < 8)
return; return;
gtk_key_index = util_bit_field(gtk[0], 0, 2);
gtk += 2;
gtk_len -= 2;
} else { } else {
gtk = decrypted_key_data; gtk = decrypted_key_data;
gtk_len = decrypted_key_data_size; gtk_len = decrypted_key_data_size;
if (!gtk || gtk_len < 6) if (!gtk || gtk_len < CRYPTO_MIN_GTK_LEN ||
gtk_len > CRYPTO_MAX_GTK_LEN)
return; return;
}
if (!sm->handshake->wpa_ie) {
gtk_key_index = util_bit_field(gtk[0], 0, 2);
gtk += 2;
gtk_len -= 2;
} else
gtk_key_index = ek->wpa_key_id; gtk_key_index = ek->wpa_key_id;
}
if (sm->handshake->mfp) { if (sm->handshake->mfp) {
igtk = handshake_util_find_igtk_kde(decrypted_key_data, igtk = handshake_util_find_igtk_kde(decrypted_key_data,
decrypted_key_data_size, decrypted_key_data_size,
&igtk_len); &igtk_len);
if (!igtk || igtk_len < 8) if (!igtk)
return; return;
igtk_key_index = l_get_le16(igtk);; igtk_key_index = l_get_le16(igtk);;

View File

@ -512,8 +512,26 @@ const uint8_t *handshake_util_find_gtk_kde(const uint8_t *data, size_t data_len,
size_t *out_gtk_len) size_t *out_gtk_len)
{ {
static const unsigned char gtk_oui[] = { 0x00, 0x0f, 0xac, 0x01 }; static const unsigned char gtk_oui[] = { 0x00, 0x0f, 0xac, 0x01 };
size_t gtk_len;
const uint8_t *gtk = find_kde(data, data_len, &gtk_len, gtk_oui);
return find_kde(data, data_len, out_gtk_len, gtk_oui); if (!gtk)
return NULL;
/*
* Account for KeyId, TX and Reserved octet
* See 802.11-2016, Figure 12-35
*/
if (gtk_len < CRYPTO_MIN_GTK_LEN + 2)
return NULL;
if (gtk_len > CRYPTO_MAX_GTK_LEN + 2)
return NULL;
if (out_gtk_len)
*out_gtk_len = gtk_len;
return gtk;
} }
const uint8_t *handshake_util_find_igtk_kde(const uint8_t *data, const uint8_t *handshake_util_find_igtk_kde(const uint8_t *data,
@ -521,8 +539,26 @@ const uint8_t *handshake_util_find_igtk_kde(const uint8_t *data,
size_t *out_igtk_len) size_t *out_igtk_len)
{ {
static const unsigned char igtk_oui[] = { 0x00, 0x0f, 0xac, 0x09 }; static const unsigned char igtk_oui[] = { 0x00, 0x0f, 0xac, 0x09 };
size_t igtk_len;
const uint8_t *igtk = find_kde(data, data_len, &igtk_len, igtk_oui);
return find_kde(data, data_len, out_igtk_len, igtk_oui); if (!igtk)
return NULL;
/*
* Account for KeyId and IPN
* See 802.11-2016, Figure 12-42
*/
if (igtk_len < CRYPTO_MIN_IGTK_LEN + 8)
return NULL;
if (igtk_len > CRYPTO_MAX_IGTK_LEN + 8)
return NULL;
if (out_igtk_len)
*out_igtk_len = igtk_len;
return igtk;
} }
const uint8_t *handshake_util_find_pmkid_kde(const uint8_t *data, const uint8_t *handshake_util_find_pmkid_kde(const uint8_t *data,