mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-03 22:08:28 +00:00 
			
		
		
		
	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:
		@@ -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) 
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user