@ -39,8 +39,47 @@ static void sme_stop_sa_query(struct wpa_supplicant *wpa_s);
# endif /* CONFIG_IEEE80211W */
void sme_authenticate ( struct wpa_supplicant * wpa_s ,
struct wpa_bss * bss , struct wpa_ssid * ssid )
# ifdef CONFIG_SAE
static struct wpabuf * sme_auth_build_sae_commit ( struct wpa_supplicant * wpa_s )
{
struct wpabuf * buf ;
buf = wpabuf_alloc ( 4 + 4 ) ;
if ( buf = = NULL )
return NULL ;
wpabuf_put_le16 ( buf , 1 ) ; /* Transaction seq# */
wpabuf_put_le16 ( buf , WLAN_STATUS_SUCCESS ) ;
wpabuf_put_str ( buf , " TEST " ) ;
/* TODO: full SAE commit */
return buf ;
}
static struct wpabuf * sme_auth_build_sae_confirm ( struct wpa_supplicant * wpa_s )
{
struct wpabuf * buf ;
buf = wpabuf_alloc ( 4 + 4 ) ;
if ( buf = = NULL )
return NULL ;
wpabuf_put_le16 ( buf , 2 ) ; /* Transaction seq# */
wpabuf_put_le16 ( buf , WLAN_STATUS_SUCCESS ) ;
wpabuf_put_str ( buf , " TEST " ) ;
/* TODO: full SAE confirm */
return buf ;
}
# endif /* CONFIG_SAE */
void sme_send_authentication ( struct wpa_supplicant * wpa_s ,
struct wpa_bss * bss , struct wpa_ssid * ssid ,
int start )
{
struct wpa_driver_auth_params params ;
struct wpa_ssid * old_ssid ;
@ -51,6 +90,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
const u8 * md = NULL ;
# endif /* CONFIG_IEEE80211R */
int i , bssid_changed ;
struct wpabuf * resp = NULL ;
if ( bss = = NULL ) {
wpa_msg ( wpa_s , MSG_ERROR , " SME: No scan result available for "
@ -95,6 +135,21 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
wpa_dbg ( wpa_s , MSG_DEBUG , " Overriding auth_alg selection: "
" 0x%x " , params . auth_alg ) ;
}
# ifdef CONFIG_SAE
if ( wpa_key_mgmt_sae ( ssid - > key_mgmt ) ) {
const u8 * rsn ;
struct wpa_ie_data ied ;
rsn = wpa_bss_get_ie ( bss , WLAN_EID_RSN ) ;
if ( rsn & &
wpa_parse_wpa_ie ( rsn , 2 + rsn [ 1 ] , & ied ) = = 0 ) {
if ( wpa_key_mgmt_sae ( ied . key_mgmt ) ) {
wpa_dbg ( wpa_s , MSG_DEBUG , " Using SAE auth_alg " ) ;
params . auth_alg = WPA_AUTH_ALG_SAE ;
}
}
}
# endif /* CONFIG_SAE */
for ( i = 0 ; i < NUM_WEP_KEYS ; i + + ) {
if ( ssid - > wep_key_len [ i ] )
@ -265,6 +320,19 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
}
# endif /* CONFIG_INTERWORKING */
# ifdef CONFIG_SAE
if ( params . auth_alg = = WPA_AUTH_ALG_SAE ) {
if ( start )
resp = sme_auth_build_sae_commit ( wpa_s ) ;
else
resp = sme_auth_build_sae_confirm ( wpa_s ) ;
if ( resp = = NULL )
return ;
params . sae_data = wpabuf_head ( resp ) ;
params . sae_data_len = wpabuf_len ( resp ) ;
}
# endif /* CONFIG_SAE */
wpa_supplicant_cancel_sched_scan ( wpa_s ) ;
wpa_supplicant_cancel_scan ( wpa_s ) ;
@ -287,6 +355,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
" driver failed " ) ;
wpas_connection_failed ( wpa_s , bss - > bssid ) ;
wpa_supplicant_mark_disassoc ( wpa_s ) ;
wpabuf_free ( resp ) ;
return ;
}
@ -297,7 +366,45 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
* Association will be started based on the authentication event from
* the driver .
*/
wpabuf_free ( resp ) ;
}
void sme_authenticate ( struct wpa_supplicant * wpa_s ,
struct wpa_bss * bss , struct wpa_ssid * ssid )
{
sme_send_authentication ( wpa_s , bss , ssid , 1 ) ;
}
# ifdef CONFIG_SAE
static int sme_sae_auth ( struct wpa_supplicant * wpa_s , u16 auth_transaction ,
u16 status_code , const u8 * data , size_t len )
{
wpa_dbg ( wpa_s , MSG_DEBUG , " SME: SAE authentication transaction %u "
" status code %u " , auth_transaction , status_code ) ;
wpa_hexdump ( MSG_DEBUG , " SME: SAE fields " , data , len ) ;
if ( status_code ! = WLAN_STATUS_SUCCESS )
return - 1 ;
if ( auth_transaction = = 1 ) {
wpa_dbg ( wpa_s , MSG_DEBUG , " SME SAE commit " ) ;
if ( wpa_s - > current_bss = = NULL | |
wpa_s - > current_ssid = = NULL )
return - 1 ;
sme_send_authentication ( wpa_s , wpa_s - > current_bss ,
wpa_s - > current_ssid , 0 ) ;
return 0 ;
} else if ( auth_transaction = = 2 ) {
wpa_dbg ( wpa_s , MSG_DEBUG , " SME SAE confirm " ) ;
return 1 ;
}
return - 1 ;
}
# endif /* CONFIG_SAE */
void sme_event_auth ( struct wpa_supplicant * wpa_s , union wpa_event_data * data )
@ -324,14 +431,23 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
}
wpa_dbg ( wpa_s , MSG_DEBUG , " SME: Authentication response: peer= " MACSTR
" auth_type=%d status_code=%d" ,
" auth_type=%d auth_transaction=%d status_code=%d" ,
MAC2STR ( data - > auth . peer ) , data - > auth . auth_type ,
data - > auth . status_code) ;
data - > auth . auth_transaction, data - > auth . status_code) ;
wpa_hexdump ( MSG_MSGDUMP , " SME: Authentication response IEs " ,
data - > auth . ies , data - > auth . ies_len ) ;
eloop_cancel_timeout ( sme_auth_timer , wpa_s , NULL ) ;
# ifdef CONFIG_SAE
if ( data - > auth . auth_type = = WLAN_AUTH_SAE ) {
if ( sme_sae_auth ( wpa_s , data - > auth . auth_transaction ,
data - > auth . status_code , data - > auth . ies ,
data - > auth . ies_len ) ! = 1 )
return ;
}
# endif /* CONFIG_SAE */
if ( data - > auth . status_code ! = WLAN_STATUS_SUCCESS ) {
wpa_dbg ( wpa_s , MSG_DEBUG , " SME: Authentication failed (status "
" code %d) " , data - > auth . status_code ) ;