diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index f79783b91..4e735f6c3 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -210,6 +210,30 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, pos += RSN_SELECTOR_LEN; num_suites++; } +#ifdef CONFIG_FILS + if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA256) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256); + pos += RSN_SELECTOR_LEN; + num_suites++; + } + if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA384) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384); + pos += RSN_SELECTOR_LEN; + num_suites++; + } +#ifdef CONFIG_IEEE80211R + if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256); + pos += RSN_SELECTOR_LEN; + num_suites++; + } + if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384); + pos += RSN_SELECTOR_LEN; + num_suites++; + } +#endif /* CONFIG_IEEE80211R */ +#endif /* CONFIG_FILS */ #ifdef CONFIG_RSN_TESTING if (rsn_testing) { diff --git a/src/common/defs.h b/src/common/defs.h index 4ab6c3f8c..8a62a4c79 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -51,6 +51,10 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean; #define WPA_KEY_MGMT_OSEN BIT(15) #define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16) #define WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 BIT(17) +#define WPA_KEY_MGMT_FILS_SHA256 BIT(18) +#define WPA_KEY_MGMT_FILS_SHA384 BIT(19) +#define WPA_KEY_MGMT_FT_FILS_SHA256 BIT(20) +#define WPA_KEY_MGMT_FT_FILS_SHA384 BIT(21) static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) { @@ -60,7 +64,11 @@ static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) WPA_KEY_MGMT_OSEN | WPA_KEY_MGMT_IEEE8021X_SHA256 | WPA_KEY_MGMT_IEEE8021X_SUITE_B | - WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)); + WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 | + WPA_KEY_MGMT_FILS_SHA256 | + WPA_KEY_MGMT_FILS_SHA384 | + WPA_KEY_MGMT_FT_FILS_SHA256 | + WPA_KEY_MGMT_FT_FILS_SHA384)); } static inline int wpa_key_mgmt_wpa_psk(int akm) @@ -76,7 +84,9 @@ static inline int wpa_key_mgmt_ft(int akm) { return !!(akm & (WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X | - WPA_KEY_MGMT_FT_SAE)); + WPA_KEY_MGMT_FT_SAE | + WPA_KEY_MGMT_FT_FILS_SHA256 | + WPA_KEY_MGMT_FT_FILS_SHA384)); } static inline int wpa_key_mgmt_ft_psk(int akm) @@ -90,17 +100,29 @@ static inline int wpa_key_mgmt_sae(int akm) WPA_KEY_MGMT_FT_SAE)); } +static inline int wpa_key_mgmt_fils(int akm) +{ + return !!(akm & (WPA_KEY_MGMT_FILS_SHA256 | + WPA_KEY_MGMT_FILS_SHA384 | + WPA_KEY_MGMT_FT_FILS_SHA256 | + WPA_KEY_MGMT_FT_FILS_SHA384)); +} + static inline int wpa_key_mgmt_sha256(int akm) { return !!(akm & (WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_IEEE8021X_SHA256 | WPA_KEY_MGMT_OSEN | - WPA_KEY_MGMT_IEEE8021X_SUITE_B)); + WPA_KEY_MGMT_IEEE8021X_SUITE_B | + WPA_KEY_MGMT_FILS_SHA256 | + WPA_KEY_MGMT_FT_FILS_SHA256)); } static inline int wpa_key_mgmt_sha384(int akm) { - return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192); + return !!(akm & (WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 | + WPA_KEY_MGMT_FILS_SHA384 | + WPA_KEY_MGMT_FT_FILS_SHA384)); } static inline int wpa_key_mgmt_suite_b(int akm) @@ -113,6 +135,7 @@ static inline int wpa_key_mgmt_wpa(int akm) { return wpa_key_mgmt_wpa_ieee8021x(akm) || wpa_key_mgmt_wpa_psk(akm) || + wpa_key_mgmt_fils(akm) || wpa_key_mgmt_sae(akm); } diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index fea6eee5e..bd8477287 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1416,6 +1416,10 @@ enum plink_action_field { #define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06 #define WLAN_AKM_SUITE_8021X_SUITE_B 0x000FAC11 #define WLAN_AKM_SUITE_8021X_SUITE_B_192 0x000FAC12 +#define WLAN_AKM_SUITE_FILS_SHA256 0x000FAC14 +#define WLAN_AKM_SUITE_FILS_SHA384 0x000FAC15 +#define WLAN_AKM_SUITE_FT_FILS_SHA256 0x000FAC16 +#define WLAN_AKM_SUITE_FT_FILS_SHA384 0x000FAC17 #define WLAN_AKM_SUITE_CCKM 0x00409600 #define WLAN_AKM_SUITE_OSEN 0x506f9a01 diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 5477a98e1..9a7bc7502 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -22,25 +22,49 @@ static unsigned int wpa_kck_len(int akmp) { - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + switch (akmp) { + case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: return 24; - return 16; + case WPA_KEY_MGMT_FILS_SHA256: + case WPA_KEY_MGMT_FT_FILS_SHA256: + case WPA_KEY_MGMT_FILS_SHA384: + case WPA_KEY_MGMT_FT_FILS_SHA384: + return 0; + default: + return 16; + } } static unsigned int wpa_kek_len(int akmp) { - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + switch (akmp) { + case WPA_KEY_MGMT_FILS_SHA384: + case WPA_KEY_MGMT_FT_FILS_SHA384: + return 64; + case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: + case WPA_KEY_MGMT_FILS_SHA256: + case WPA_KEY_MGMT_FT_FILS_SHA256: return 32; - return 16; + default: + return 16; + } } unsigned int wpa_mic_len(int akmp) { - if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + switch (akmp) { + case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: return 24; - return 16; + case WPA_KEY_MGMT_FILS_SHA256: + case WPA_KEY_MGMT_FILS_SHA384: + case WPA_KEY_MGMT_FT_FILS_SHA256: + case WPA_KEY_MGMT_FT_FILS_SHA384: + return 0; + default: + return 16; + } } @@ -512,6 +536,14 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s) return WPA_KEY_MGMT_IEEE8021X_SUITE_B; if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192) return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192; + if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FILS_SHA256) + return WPA_KEY_MGMT_FILS_SHA256; + if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FILS_SHA384) + return WPA_KEY_MGMT_FILS_SHA384; + if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_FILS_SHA256) + return WPA_KEY_MGMT_FT_FILS_SHA256; + if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_FILS_SHA384) + return WPA_KEY_MGMT_FT_FILS_SHA384; if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN) return WPA_KEY_MGMT_OSEN; return 0; @@ -1214,6 +1246,14 @@ const char * wpa_key_mgmt_txt(int key_mgmt, int proto) return "WPA2-EAP-SUITE-B"; case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192: return "WPA2-EAP-SUITE-B-192"; + case WPA_KEY_MGMT_FILS_SHA256: + return "FILS-SHA256"; + case WPA_KEY_MGMT_FILS_SHA384: + return "FILS-SHA384"; + case WPA_KEY_MGMT_FT_FILS_SHA256: + return "FT-FILS-SHA256"; + case WPA_KEY_MGMT_FT_FILS_SHA384: + return "FT-FILS-SHA384"; default: return "UNKNOWN"; } @@ -1244,6 +1284,14 @@ u32 wpa_akm_to_suite(int akm) return WLAN_AKM_SUITE_8021X_SUITE_B; if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) return WLAN_AKM_SUITE_8021X_SUITE_B_192; + if (akm & WPA_KEY_MGMT_FILS_SHA256) + return WLAN_AKM_SUITE_FILS_SHA256; + if (akm & WPA_KEY_MGMT_FILS_SHA384) + return WLAN_AKM_SUITE_FILS_SHA384; + if (akm & WPA_KEY_MGMT_FT_FILS_SHA256) + return WLAN_AKM_SUITE_FT_FILS_SHA256; + if (akm & WPA_KEY_MGMT_FT_FILS_SHA384) + return WLAN_AKM_SUITE_FT_FILS_SHA384; return 0; } diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 6d446e8e5..25be93918 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -61,6 +61,10 @@ WPA_CIPHER_GTK_NOT_USED) #define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192 RSN_SELECTOR(0x00, 0x0f, 0xac, 12) #define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_192 \ RSN_SELECTOR(0x00, 0x0f, 0xac, 13) +#define RSN_AUTH_KEY_MGMT_FILS_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 14) +#define RSN_AUTH_KEY_MGMT_FILS_SHA384 RSN_SELECTOR(0x00, 0x0f, 0xac, 15) +#define RSN_AUTH_KEY_MGMT_FT_FILS_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 16) +#define RSN_AUTH_KEY_MGMT_FT_FILS_SHA384 RSN_SELECTOR(0x00, 0x0f, 0xac, 17) #define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00) #define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01) @@ -201,7 +205,7 @@ struct wpa_eapol_key_192 { #define WPA_EAPOL_KEY_MIC_MAX_LEN 24 #define WPA_KCK_MAX_LEN 24 -#define WPA_KEK_MAX_LEN 32 +#define WPA_KEK_MAX_LEN 64 #define WPA_TK_MAX_LEN 32 /** diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index c44844ec5..3be3087da 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -180,6 +180,18 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len, RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192); } else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B); +#ifdef CONFIG_FILS + } else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA256) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256); + } else if (key_mgmt & WPA_KEY_MGMT_FILS_SHA384) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384); +#ifdef CONFIG_IEEE80211R + } else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256); + } else if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) { + RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384); +#endif /* CONFIG_IEEE80211R */ +#endif /* CONFIG_FILS */ } else { wpa_printf(MSG_WARNING, "Invalid key management type (%d).", key_mgmt);