Add support for PMF configuration and negotiation

1. Add APIs for configuring PMF through set config.
2. Map Supplicant and Wifi Cipher types.
3. Add support for PMF negotiation while generating RSN IE.
This commit is contained in:
Nachiket Kukade
2019-11-12 11:35:08 +05:30
committed by bot
parent ddef4f9129
commit 773e095a65
10 changed files with 121 additions and 46 deletions

View File

@@ -46,7 +46,7 @@
/* fix buf for tx for now */
#define WPA_TX_MSG_BUFF_MAXLEN 200
#define ASSOC_IE_LEN 24 + 2 + PMKID_LEN
#define ASSOC_IE_LEN 24 + 2 + PMKID_LEN + RSN_SELECTOR_LEN
u8 assoc_ie_buf[ASSOC_IE_LEN+2];
void set_assoc_ie(u8 * assoc_buf);
@@ -76,6 +76,65 @@ void eapol_sm_notify_eap_success(Boolean success)
{
}
wifi_cipher_type_t cipher_type_map_supp_to_public(uint32_t wpa_cipher)
{
switch (wpa_cipher) {
case WPA_CIPHER_NONE:
return WIFI_CIPHER_TYPE_NONE;
case WPA_CIPHER_WEP40:
return WIFI_CIPHER_TYPE_WEP40;
case WPA_CIPHER_WEP104:
return WIFI_CIPHER_TYPE_WEP104;
case WPA_CIPHER_TKIP:
return WIFI_CIPHER_TYPE_TKIP;
case WPA_CIPHER_CCMP:
return WIFI_CIPHER_TYPE_CCMP;
case WPA_CIPHER_CCMP|WPA_CIPHER_TKIP:
return WIFI_CIPHER_TYPE_TKIP_CCMP;
case WPA_CIPHER_AES_128_CMAC:
return WIFI_CIPHER_TYPE_AES_CMAC128;
default:
return WIFI_CIPHER_TYPE_UNKNOWN;
}
}
uint32_t cipher_type_map_public_to_supp(wifi_cipher_type_t cipher)
{
switch (cipher) {
case WIFI_CIPHER_TYPE_NONE:
return WPA_CIPHER_NONE;
case WIFI_CIPHER_TYPE_WEP40:
return WPA_CIPHER_WEP40;
case WIFI_CIPHER_TYPE_WEP104:
return WPA_CIPHER_WEP104;
case WIFI_CIPHER_TYPE_TKIP:
return WPA_CIPHER_TKIP;
case WIFI_CIPHER_TYPE_CCMP:
return WPA_CIPHER_CCMP;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
return WPA_CIPHER_CCMP|WPA_CIPHER_TKIP;
case WIFI_CIPHER_TYPE_AES_CMAC128:
return WPA_CIPHER_AES_128_CMAC;
default:
return WPA_CIPHER_NONE;
}
}
/**
* get_bssid - Get the current BSSID
* @priv: private driver interface data
@@ -1169,7 +1228,7 @@ int ieee80211w_set_keys(struct wpa_sm *sm,
}
}
if (ieee80211w_set_keys(sm, &ie) < 0) {
if (sm->pmf_cfg.capable && ieee80211w_set_keys(sm, &ie) < 0) {
#ifdef DEBUG_PRINT
wpa_printf(MSG_DEBUG, "RSN: Failed to configure IGTK");
#endif
@@ -1746,7 +1805,11 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
}
key_info = WPA_GET_BE16(key->key_info);
ver = key_info & WPA_KEY_INFO_TYPE_MASK;
if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
#ifdef CONFIG_IEEE80211W
ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
#endif
ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
#ifdef DEBUG_PRINT
wpa_printf(MSG_DEBUG, "WPA: Unsupported EAPOL-Key descriptor "
@@ -1755,6 +1818,14 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
goto out;
}
#ifdef CONFIG_IEEE80211W
if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
goto out;
}
} else
#endif
if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
#ifdef DEBUG_PRINT
@@ -1977,10 +2048,13 @@ void wpa_set_profile(u32 wpa_proto, u8 auth_mode)
struct wpa_sm *sm = &gWpaSm;
sm->proto = wpa_proto;
if (auth_mode == WPA2_AUTH_ENT)
if (auth_mode == WPA2_AUTH_ENT) {
sm->key_mgmt = WPA_KEY_MGMT_IEEE8021X; /* for wpa2 enterprise */
else
} else if (auth_mode == WPA2_AUTH_PSK) {
sm->key_mgmt = WPA_KEY_MGMT_PSK; /* fixed to PSK for now */
} else if (auth_mode == WPA2_AUTH_PSK_SHA256) {
sm->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
}
}
void wpa_set_pmk(uint8_t *pmk)
@@ -2011,6 +2085,16 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher,
pmksa_cache_set_current(sm, NULL, (const u8*) bssid, 0, 0);
wpa_sm_set_pmk_from_pmksa(sm);
}
#ifdef CONFIG_IEEE80211W
if (esp_wifi_sta_pmf_enabled()) {
wifi_config_t wifi_cfg;
esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_cfg);
sm->pmf_cfg = wifi_cfg.sta.pmf_cfg;
sm->mgmt_group_cipher = cipher_type_map_public_to_supp(esp_wifi_sta_get_mgmt_group_cipher());
}
#endif
set_assoc_ie(assoc_ie_buf); /* use static buffer */
res = wpa_gen_wpa_ie(sm, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
if (res < 0)

View File

@@ -25,6 +25,7 @@
#include "utils/common.h"
#include "common/defs.h"
#include "common/wpa_common.h"
#include "esp_wifi_types.h"
#include "esp_wifi_crypto_types.h"
#include "wpa_i.h"
@@ -128,5 +129,9 @@ char * dup_binstr(const void *src, size_t len);
int wpa_michael_mic_failure(u16 isunicast);
wifi_cipher_type_t cipher_type_map_supp_to_public(uint32_t wpa_cipher);
uint32_t cipher_type_map_supp_to_public(wifi_cipher_type_t cipher);
#endif /* WPA_H */

View File

@@ -89,6 +89,7 @@ struct wpa_sm {
u16 key_info; //used for txcallback param
u16 txcb_flags;
bool ap_notify_completed_rsne;
wifi_pmf_config_t pmf_cfg;
};
/**

View File

@@ -214,10 +214,12 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
/* RSN Capabilities */
capab = 0;
#ifdef CONFIG_IEEE80211W
if (sm->mfp)
if (sm->pmf_cfg.capable) {
capab |= WPA_CAPABILITY_MFPC;
if (sm->mfp == 2)
capab |= WPA_CAPABILITY_MFPR;
if (sm->pmf_cfg.required) {
capab |= WPA_CAPABILITY_MFPR;
}
}
#endif /* CONFIG_IEEE80211W */
WPA_PUT_LE16(pos, capab);
pos += 2;
@@ -229,16 +231,14 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
/* PMKID */
os_memcpy(pos, sm->cur_pmksa->pmkid, PMKID_LEN);
pos += PMKID_LEN;
} else {
/* 0 PMKID Count */
WPA_PUT_LE16(pos, 0);
pos += 2;
}
#ifdef CONFIG_IEEE80211W
if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
if (!sm->cur_pmksa) {
/* PMKID Count */
WPA_PUT_LE16(pos, 0);
pos += 2;
}
/* Management Group Cipher Suite */
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
pos += RSN_SELECTOR_LEN;