@ -20,6 +20,7 @@
# include "wpa_ie.h"
# include "aes_wrap.h"
# include "ieee802_11_defs.h"
# include "ieee802_11_common.h"
# ifdef CONFIG_IEEE80211R
@ -105,20 +106,23 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *mobility_domain,
/**
* wpa_ft_gen_req_ies - Generate FT ( IEEE 802.11 r ) IEs for Auth Request
* wpa_ft_gen_req_ies - Generate FT ( IEEE 802.11 r ) IEs for Auth / ReAssoc Request
* @ sm : Pointer to WPA state machine data from wpa_sm_init ( )
* @ len : Buffer for returning the length of the IEs
* @ anonce : ANonce or % NULL if not yet available
* @ pmk_name : PMKR0Name or PMKR1Name to be added into the RSN IE PMKID List
* @ kck : 128 - bit KCK for MIC or % NULL if no MIC is used
* @ target_ap : Target AP address
* @ ric_ies : Optional IE ( s ) , e . g . , WMM TSPEC ( s ) , for RIC - Request or % NULL
* @ ric_ies_len : Length of ric_ies buffer in octets
* Returns : Pointer to buffer with IEs or % NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free ( ) ;
*/
static u8 * wpa_ft_gen_req_ies ( struct wpa_sm * sm , size_t * len ,
const u8 * anonce , const u8 * pmk_name ,
const u8 * kck , const u8 * target_ap )
const u8 * kck , const u8 * target_ap ,
const u8 * ric_ies , size_t ric_ies_len )
{
size_t buf_len ;
u8 * buf , * pos , * ftie_len , * ftie_pos ;
@ -130,13 +134,13 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
sm - > ft_completed = 0 ;
buf_len = 2 + sizeof ( struct rsn_mdie ) + 2 + sizeof ( struct rsn_ftie ) +
2 + sm - > r0kh_id_len + 100 ;
2 + sm - > r0kh_id_len + ric_ies_len + 100 ;
buf = os_zalloc ( buf_len ) ;
if ( buf = = NULL )
return NULL ;
pos = buf ;
/* RSNIE[PMKR0Name ] */
/* RSNIE[PMKR0Name /PMKR1Name ] */
rsnie = ( struct rsn_ie_hdr * ) pos ;
rsnie - > elem_id = WLAN_EID_RSN ;
WPA_PUT_LE16 ( rsnie - > version , RSN_VERSION ) ;
@ -241,6 +245,12 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
pos + = sm - > r0kh_id_len ;
* ftie_len = pos - ftie_len - 1 ;
if ( ric_ies ) {
/* RIC Request */
os_memcpy ( pos , ric_ies , ric_ies_len ) ;
pos + = ric_ies_len ;
}
if ( kck ) {
/*
* IEEE Std 802.11 r - 2008 , 11 A .8 .4
@ -253,12 +263,14 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
* FTIE ( with MIC field set to 0 )
* RIC - Request ( if present )
*/
ftie - > mic_control [ 1 ] = 3 ; /* Information element count */
/* Information element count */
ftie - > mic_control [ 1 ] = 3 + ieee802_11_ie_count ( ric_ies ,
ric_ies_len ) ;
if ( wpa_ft_mic ( kck , sm - > own_addr , target_ap , 5 ,
( ( u8 * ) mdie ) - 2 , 2 + sizeof ( * mdie ) ,
ftie_pos , 2 + * ftie_len ,
( u8 * ) rsnie , 2 + rsnie - > len , NULL , 0 ,
ftie- > mic ) < 0 ) {
( u8 * ) rsnie , 2 + rsnie - > len , ric_ies ,
ric_ies_len, ftie- > mic ) < 0 ) {
wpa_printf ( MSG_INFO , " FT: Failed to calculate MIC " ) ;
os_free ( buf ) ;
return NULL ;
@ -440,7 +452,7 @@ int wpa_ft_prepare_auth_request(struct wpa_sm *sm)
}
ft_ies = wpa_ft_gen_req_ies ( sm , & ft_ies_len , NULL , sm - > pmk_r0_name ,
NULL , sm - > bssid );
NULL , sm - > bssid , NULL , 0 );
if ( ft_ies ) {
wpa_sm_update_ft_ies ( sm , sm - > mobility_domain ,
ft_ies , ft_ies_len ) ;
@ -452,7 +464,8 @@ int wpa_ft_prepare_auth_request(struct wpa_sm *sm)
int wpa_ft_process_response ( struct wpa_sm * sm , const u8 * ies , size_t ies_len ,
int ft_action , const u8 * target_ap )
int ft_action , const u8 * target_ap ,
const u8 * ric_ies , size_t ric_ies_len )
{
u8 * ft_ies ;
size_t ft_ies_len ;
@ -464,6 +477,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
const u8 * bssid ;
wpa_hexdump ( MSG_DEBUG , " FT: Response IEs " , ies , ies_len ) ;
wpa_hexdump ( MSG_DEBUG , " FT: RIC IEs " , ric_ies , ric_ies_len ) ;
if ( ft_action ) {
if ( ! sm - > over_the_ds_in_progress ) {
@ -553,7 +567,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
wpa_hexdump ( MSG_DEBUG , " FT: PTKName " , ptk_name , WPA_PMK_NAME_LEN ) ;
ft_ies = wpa_ft_gen_req_ies ( sm , & ft_ies_len , ftie - > anonce ,
sm - > pmk_r1_name , sm - > ptk . kck , bssid ) ;
sm - > pmk_r1_name , sm - > ptk . kck , bssid ,
ric_ies , ric_ies_len ) ;
if ( ft_ies ) {
wpa_sm_update_ft_ies ( sm , sm - > mobility_domain ,
ft_ies , ft_ies_len ) ;
@ -857,7 +872,7 @@ int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap)
}
ft_ies = wpa_ft_gen_req_ies ( sm , & ft_ies_len , NULL , sm - > pmk_r0_name ,
NULL , target_ap );
NULL , target_ap , NULL , 0 );
if ( ft_ies ) {
sm - > over_the_ds_in_progress = 1 ;
os_memcpy ( sm - > target_ap , target_ap , ETH_ALEN ) ;