@ -35,8 +35,8 @@
static void wpa_send_eapol_timeout ( void * eloop_ctx , void * timeout_ctx ) ;
static int wpa_sm_step ( struct wpa_state_machine * sm ) ;
static int wpa_verify_key_mic ( int akmp , struct wpa_ptk * PTK , u8 * data ,
size_t data_len ) ;
static int wpa_verify_key_mic ( int akmp , size_t pmk_len , struct wpa_ptk * PTK ,
u8 * data , size_t data_len ) ;
# ifdef CONFIG_FILS
static int wpa_aead_decrypt ( struct wpa_state_machine * sm , struct wpa_ptk * ptk ,
u8 * buf , size_t buf_len , u16 * _key_data_len ) ;
@ -226,13 +226,13 @@ void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth, const u8 *addr,
static void wpa_sta_disconnect ( struct wpa_authenticator * wpa_auth ,
const u8 * addr )
const u8 * addr , u16 reason )
{
if ( wpa_auth - > cb - > disconnect = = NULL )
return ;
wpa_printf ( MSG_DEBUG , " wpa_sta_disconnect STA " MACSTR , MAC2STR ( addr ) ) ;
wpa_auth - > cb - > disconnect ( wpa_auth - > cb_ctx , addr ,
WLAN_REASON_PREV_AUTH_NOT_VALID ) ;
wpa_printf ( MSG_DEBUG , " wpa_sta_disconnect STA " MACSTR " (reason %u) " ,
MAC2STR ( addr ) , reason ) ;
wpa_auth - > cb - > disconnect ( wpa_auth - > cb_ctx , addr , reason ) ;
}
@ -866,8 +866,8 @@ static int wpa_try_alt_snonce(struct wpa_state_machine *sm, u8 *data,
if ( wpa_derive_ptk ( sm , sm - > alt_SNonce , pmk , pmk_len , & PTK ) < 0 )
break ;
if ( wpa_verify_key_mic ( sm - > wpa_key_mgmt , & PTK , data , data_len )
= = 0 ) {
if ( wpa_verify_key_mic ( sm - > wpa_key_mgmt , pmk_len , & PTK ,
data , data_len ) = = 0 ) {
ok = 1 ;
break ;
}
@ -912,7 +912,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
return ;
wpa_hexdump ( MSG_MSGDUMP , " WPA: RX EAPOL data " , data , data_len ) ;
mic_len = wpa_mic_len ( sm - > wpa_key_mgmt );
mic_len = wpa_mic_len ( sm - > wpa_key_mgmt , sm - > pmk_len );
keyhdrlen = sizeof ( * key ) + mic_len + 2 ;
if ( data_len < sizeof ( * hdr ) + keyhdrlen ) {
@ -1025,6 +1025,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
if ( ! wpa_use_aes_cmac ( sm ) & &
! wpa_key_mgmt_fils ( sm - > wpa_key_mgmt ) & &
sm - > wpa_key_mgmt ! = WPA_KEY_MGMT_OWE & &
sm - > wpa_key_mgmt ! = WPA_KEY_MGMT_DPP & &
ver ! = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ) {
wpa_auth_logger ( wpa_auth , sm - > addr ,
LOGGER_WARNING ,
@ -1036,6 +1037,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
if ( ( wpa_key_mgmt_suite_b ( sm - > wpa_key_mgmt ) | |
wpa_key_mgmt_fils ( sm - > wpa_key_mgmt ) | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OWE ) & &
ver ! = WPA_KEY_INFO_TYPE_AKM_DEFINED ) {
wpa_auth_logger ( wpa_auth , sm - > addr , LOGGER_WARNING ,
@ -1160,7 +1162,8 @@ continue_processing:
" collect more entropy for random number "
" generation " ) ;
random_mark_pool_ready ( ) ;
wpa_sta_disconnect ( wpa_auth , sm - > addr ) ;
wpa_sta_disconnect ( wpa_auth , sm - > addr ,
WLAN_REASON_PREV_AUTH_NOT_VALID ) ;
return ;
}
break ;
@ -1238,8 +1241,8 @@ continue_processing:
sm - > MICVerified = FALSE ;
if ( sm - > PTK_valid & & ! sm - > update_snonce ) {
if ( mic_len & &
wpa_verify_key_mic ( sm - > wpa_key_mgmt , & sm - > PTK , data ,
data _len) & &
wpa_verify_key_mic ( sm - > wpa_key_mgmt , sm - > pmk_len , & sm - > PTK ,
data , data _len) & &
( msg ! = PAIRWISE_4 | | ! sm - > alt_snonce_valid | |
wpa_try_alt_snonce ( sm , data , data_len ) ) ) {
wpa_auth_logger ( wpa_auth , sm - > addr , LOGGER_INFO ,
@ -1419,7 +1422,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
int i ;
u8 * key_mic , * key_data ;
mic_len = wpa_mic_len ( sm - > wpa_key_mgmt );
mic_len = wpa_mic_len ( sm - > wpa_key_mgmt , sm - > pmk_len );
keyhdrlen = sizeof ( * key ) + mic_len + 2 ;
len = sizeof ( struct ieee802_1x_hdr ) + keyhdrlen ;
@ -1428,6 +1431,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
version = force_version ;
else if ( sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OSEN | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OWE | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP | |
wpa_key_mgmt_suite_b ( sm - > wpa_key_mgmt ) | |
wpa_key_mgmt_fils ( sm - > wpa_key_mgmt ) )
version = WPA_KEY_INFO_TYPE_AKM_DEFINED ;
@ -1454,6 +1458,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
if ( ( version = = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OWE | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OSEN | |
wpa_key_mgmt_suite_b ( sm - > wpa_key_mgmt ) | |
version = = WPA_KEY_INFO_TYPE_AES_128_CMAC ) & & encr ) {
@ -1557,6 +1562,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
buf , key_data_len ) ;
if ( version = = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OWE | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OSEN | |
wpa_key_mgmt_suite_b ( sm - > wpa_key_mgmt ) | |
version = = WPA_KEY_INFO_TYPE_AES_128_CMAC ) {
@ -1656,15 +1662,15 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
}
static int wpa_verify_key_mic ( int akmp , struct wpa_ptk * PTK , u8 * data ,
size_t data_len )
static int wpa_verify_key_mic ( int akmp , size_t pmk_len , struct wpa_ptk * PTK ,
u8 * data , size_t data_len )
{
struct ieee802_1x_hdr * hdr ;
struct wpa_eapol_key * key ;
u16 key_info ;
int ret = 0 ;
u8 mic [ WPA_EAPOL_KEY_MIC_MAX_LEN ] , * mic_pos ;
size_t mic_len = wpa_mic_len ( akmp );
size_t mic_len = wpa_mic_len ( akmp , pmk_len );
if ( data_len < sizeof ( * hdr ) + sizeof ( * key ) )
return - 1 ;
@ -1837,6 +1843,7 @@ SM_STATE(WPA_PTK, INITIALIZE)
wpa_auth_set_eapol ( sm - > wpa_auth , sm - > addr , WPA_EAPOL_portValid , 0 ) ;
sm - > TimeoutCtr = 0 ;
if ( wpa_key_mgmt_wpa_psk ( sm - > wpa_key_mgmt ) | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OWE ) {
wpa_auth_set_eapol ( sm - > wpa_auth , sm - > addr ,
WPA_EAPOL_authorized , 0 ) ;
@ -1846,9 +1853,14 @@ SM_STATE(WPA_PTK, INITIALIZE)
SM_STATE ( WPA_PTK , DISCONNECT )
{
u16 reason = sm - > disconnect_reason ;
SM_ENTRY_MA ( WPA_PTK , DISCONNECT , wpa_ptk ) ;
sm - > Disconnect = FALSE ;
wpa_sta_disconnect ( sm - > wpa_auth , sm - > addr ) ;
sm - > disconnect_reason = 0 ;
if ( ! reason )
reason = WLAN_REASON_PREV_AUTH_NOT_VALID ;
wpa_sta_disconnect ( sm - > wpa_auth , sm - > addr , reason ) ;
}
@ -1949,6 +1961,14 @@ SM_STATE(WPA_PTK, INITPMK)
wpa_printf ( MSG_DEBUG , " WPA: PMK from PMKSA cache " ) ;
os_memcpy ( sm - > PMK , sm - > pmksa - > pmk , sm - > pmksa - > pmk_len ) ;
sm - > pmk_len = sm - > pmksa - > pmk_len ;
# ifdef CONFIG_DPP
} else if ( sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP ) {
wpa_printf ( MSG_DEBUG ,
" DPP: No PMKSA cache entry for STA - reject connection " ) ;
sm - > Disconnect = TRUE ;
sm - > disconnect_reason = WLAN_REASON_INVALID_PMKID ;
return ;
# endif /* CONFIG_DPP */
} else if ( wpa_auth_get_msk ( sm - > wpa_auth , sm - > addr , msk , & len ) = = 0 ) {
unsigned int pmk_len ;
@ -2596,7 +2616,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
sm - > update_snonce = FALSE ;
os_memset ( & PTK , 0 , sizeof ( PTK ) ) ;
mic_len = wpa_mic_len ( sm - > wpa_key_mgmt );
mic_len = wpa_mic_len ( sm - > wpa_key_mgmt , sm - > pmk_len );
/* WPA with IEEE 802.1X: use the derived PMK from EAP
* WPA - PSK : iterate through possible PSKs and select the one matching
@ -2618,7 +2638,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
break ;
if ( mic_len & &
wpa_verify_key_mic ( sm - > wpa_key_mgmt , & PTK ,
wpa_verify_key_mic ( sm - > wpa_key_mgmt , pmk_len , & PTK ,
sm - > last_rx_eapol_key ,
sm - > last_rx_eapol_key_len ) = = 0 ) {
ok = 1 ;
@ -2687,12 +2707,14 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
wpa_hexdump ( MSG_DEBUG , " WPA IE in msg 2/4 " ,
eapol_key_ie , eapol_key_ie_len ) ;
/* MLME-DEAUTHENTICATE.request */
wpa_sta_disconnect ( wpa_auth , sm - > addr ) ;
wpa_sta_disconnect ( wpa_auth , sm - > addr ,
WLAN_REASON_PREV_AUTH_NOT_VALID ) ;
return ;
}
# ifdef CONFIG_IEEE80211R_AP
if ( ft & & ft_check_msg_2_of_4 ( wpa_auth , sm , & kde ) < 0 ) {
wpa_sta_disconnect ( wpa_auth , sm - > addr ) ;
wpa_sta_disconnect ( wpa_auth , sm - > addr ,
WLAN_REASON_PREV_AUTH_NOT_VALID ) ;
return ;
}
# endif /* CONFIG_IEEE80211R_AP */
@ -3002,7 +3024,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
wpa_send_eapol ( sm - > wpa_auth , sm ,
( secure ? WPA_KEY_INFO_SECURE : 0 ) |
( wpa_mic_len ( sm - > wpa_key_mgmt ) ? WPA_KEY_INFO_MIC : 0 ) |
( wpa_mic_len ( sm - > wpa_key_mgmt , sm - > pmk_len ) ?
WPA_KEY_INFO_MIC : 0 ) |
WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL |
WPA_KEY_INFO_KEY_TYPE ,
_rsc , sm - > ANonce , kde , pos - kde , keyidx , encr ) ;
@ -3019,7 +3042,8 @@ SM_STATE(WPA_PTK, PTKINITDONE)
int klen = wpa_cipher_key_len ( sm - > pairwise ) ;
if ( wpa_auth_set_key ( sm - > wpa_auth , 0 , alg , sm - > addr , 0 ,
sm - > PTK . tk , klen ) ) {
wpa_sta_disconnect ( sm - > wpa_auth , sm - > addr ) ;
wpa_sta_disconnect ( sm - > wpa_auth , sm - > addr ,
WLAN_REASON_PREV_AUTH_NOT_VALID ) ;
return ;
}
/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
@ -3033,6 +3057,7 @@ SM_STATE(WPA_PTK, PTKINITDONE)
}
if ( wpa_key_mgmt_wpa_psk ( sm - > wpa_key_mgmt ) | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP | |
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OWE ) {
wpa_auth_set_eapol ( sm - > wpa_auth , sm - > addr ,
WPA_EAPOL_authorized , 1 ) ;
@ -3106,12 +3131,18 @@ SM_STEP(WPA_PTK)
sm - > wpa_key_mgmt = = WPA_KEY_MGMT_OWE
/* FIX: && 802.1X::keyRun */ )
SM_ENTER ( WPA_PTK , INITPSK ) ;
else if ( sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP )
SM_ENTER ( WPA_PTK , INITPMK ) ;
break ;
case WPA_PTK_INITPMK :
if ( wpa_auth_get_eapol ( sm - > wpa_auth , sm - > addr ,
WPA_EAPOL_keyAvailable ) > 0 )
WPA_EAPOL_keyAvailable ) > 0 ) {
SM_ENTER ( WPA_PTK , PTKSTART ) ;
else {
# ifdef CONFIG_DPP
} else if ( sm - > wpa_key_mgmt = = WPA_KEY_MGMT_DPP & & sm - > pmksa ) {
SM_ENTER ( WPA_PTK , PTKSTART ) ;
# endif /* CONFIG_DPP */
} else {
wpa_auth - > dot11RSNA4WayHandshakeFailures + + ;
wpa_auth_logger ( sm - > wpa_auth , sm - > addr , LOGGER_INFO ,
" INITPMK - keyAvailable = false " ) ;
@ -3250,7 +3281,8 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
wpa_send_eapol ( sm - > wpa_auth , sm ,
WPA_KEY_INFO_SECURE |
( wpa_mic_len ( sm - > wpa_key_mgmt ) ? WPA_KEY_INFO_MIC : 0 ) |
( wpa_mic_len ( sm - > wpa_key_mgmt , sm - > pmk_len ) ?
WPA_KEY_INFO_MIC : 0 ) |
WPA_KEY_INFO_ACK |
( ! sm - > Pair ? WPA_KEY_INFO_INSTALL : 0 ) ,
rsc , NULL , kde , kde_len , gsm - > GN , 1 ) ;