mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-26 10:39:23 +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:
parent
c93a52c066
commit
cd7af67aac
@ -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];
|
||||||
|
23
src/eapol.c
23
src/eapol.c
@ -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,
|
||||||
>k_len);
|
>k_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,
|
||||||
>k_len);
|
>k_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);;
|
||||||
|
@ -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, >k_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,
|
||||||
|
Loading…
Reference in New Issue
Block a user