From 0bd15747c05759b2d40ab349ea2c1a7d99bfec9c Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Mon, 11 Mar 2019 23:43:33 +0530 Subject: [PATCH] qcacld-3.0: Save FTIE from auth response in FT-FILS IM connection FT-FILS initial mobility domain association requires FTIE in the association request frame sent to the AP. FTIE has the R0-KH and R1-KH ID that is needed to derive the FILS-FT key. Host driver should save the FTIE received from the AP in the authentication response frame and send it without any modification to the AP in association request frame. Change-ID: I047538e13b37e10c2cebad4959fc796af5d16df6 CRs-Fixed: 2414662 --- core/mac/inc/sir_mac_prot_def.h | 1 + core/mac/src/pe/include/lim_fils_defs.h | 76 +++++++++++++++++++ core/mac/src/pe/lim/lim_process_fils.c | 11 +++ .../src/sys/legacy/src/utils/src/parser_api.c | 71 ++++++++++++++++- 4 files changed, 157 insertions(+), 2 deletions(-) diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index ac3a16cbc494..248f288a3aef 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -1466,6 +1466,7 @@ typedef struct sSirMacAuthFrameBody { uint8_t challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH]; #ifdef WLAN_FEATURE_FILS_SK tSirMacRsnInfo rsn_ie; + struct mac_ft_ie ft_ie; uint8_t assoc_delay_info; uint8_t session[SIR_FILS_SESSION_LENGTH]; uint8_t wrapped_data_len; diff --git a/core/mac/src/pe/include/lim_fils_defs.h b/core/mac/src/pe/include/lim_fils_defs.h index d34f94fa1a49..842838654d57 100644 --- a/core/mac/src/pe/include/lim_fils_defs.h +++ b/core/mac/src/pe/include/lim_fils_defs.h @@ -169,6 +169,80 @@ struct fils_auth_rsp_info { uint8_t assoc_delay; }; +#define FT_R0KH_ID_MAX_LEN 48 +#define FT_R1KH_ID_LEN 6 +#define FT_NONCE_LEN 32 + +/* MIC Length Specified in Table 12-8- 802.11-2016 Spec */ +#define FT_MIC_LEN 16 +#define FT_GTK_RSC_LEN 8 +#define FT_GTK_KEY_LEN 32 +#define FT_IGTK_KEY_ID_LEN 2 +#define FT_IGTK_IPN_LEN 6 +#define FT_IGTK_KEY_LEN 24 + +/** + * struct mac_ft_gtk_ie - structure to parse the gtk ie + * @present: flag to indicate ie is present + * @key_id: Key-Id + * @reserved: reserved bits + * @key_length: gtk key length + * @rsc: denotes the last TSC or PN sent using the GTK + * @num_key: number of keys + * @key: actual keys + */ +struct mac_ft_gtk_ie { + uint8_t present; + uint16_t key_id:2; + uint16_t reserved:14; + uint8_t key_len; + uint8_t rsc[FT_GTK_RSC_LEN]; + uint8_t num_key; + uint8_t key[FT_GTK_KEY_LEN]; +}; + +/** + * struct mac_ft_gtk_ie - structure to parse the gtk ie + * @present: IE present or not present + * @key_id: 2Byte Key-ID + * @ipn: icorresponds to the last packet number used by broadcaster/multicaster + * @key_len: IGTK key length + * @key: IGTK Key + */ +struct mac_ft_igtk_ie { + uint8_t present; + uint8_t key_id[FT_IGTK_KEY_ID_LEN]; + uint8_t ipn[FT_IGTK_IPN_LEN]; + uint8_t key_len; + uint8_t key[FT_IGTK_KEY_LEN]; +}; + +/** + * struct mac_ft_ie - structure to parse the FT ie from auth frame + * @present: true if IE is present in Auth Frame + * @element_count: number of elements + * @mic: MIC. Will be zero in auth frame sent from AP. (Refer 13.2.4 802.11ai) + * @anonce: Authenticator NONCE. Will be zero in auth frame sent from AP. + * @snonce: Supplicant NONCE. Will be zero in auth frame + * @r1kh_id: R1KH ID. Length of R1KH ID is fixed(6 bytes). + * @r0kh_id_len: Length of R0KH ID + * @r0kh_id: R0KH id + * @gtk_ie: GTK subelement in FTIE + * @igtk_ie: IGTK subelement in FTIE + */ +struct mac_ft_ie { + bool present; + uint8_t element_count; + uint8_t mic[FT_MIC_LEN]; + uint8_t anonce[FT_NONCE_LEN]; + uint8_t snonce[FT_NONCE_LEN]; + uint8_t r1kh_id[FT_R1KH_ID_LEN]; + uint8_t r0kh_id_len; + uint8_t r0kh_id[FT_R0KH_ID_MAX_LEN]; + struct mac_ft_gtk_ie gtk_ie; + struct mac_ft_igtk_ie igtk_ie; +}; + /* * struct pe_fils_session: fils session info used in PE session * @is_fils_connection: whether connection is fils or not @@ -188,6 +262,7 @@ struct fils_auth_rsp_info { * @fils_nonce: fils snonce * @rsn_ie: rsn ie used in auth request * @rsn_ie_len: rsn ie length + * @ft_ie: structure to store the parsed FTIE from auth response frame * @fils_eap_finish_pkt: pointer to eap finish packet * @fils_eap_finish_pkt_len: eap finish packet length * @fils_rmsk: rmsk data pointer @@ -235,6 +310,7 @@ struct pe_fils_session { uint8_t fils_nonce[SIR_FILS_NONCE_LENGTH]; uint8_t rsn_ie[WLAN_MAX_IE_LEN]; uint8_t rsn_ie_len; + struct mac_ft_ie ft_ie; uint8_t *fils_eap_finish_pkt; uint8_t fils_eap_finish_pkt_len; uint8_t *fils_rmsk; diff --git a/core/mac/src/pe/lim/lim_process_fils.c b/core/mac/src/pe/lim/lim_process_fils.c index 97b8de3a3fe9..3bf9d5bbb767 100644 --- a/core/mac/src/pe/lim/lim_process_fils.c +++ b/core/mac/src/pe/lim/lim_process_fils.c @@ -1109,6 +1109,17 @@ bool lim_process_fils_auth_frame2(struct mac_context *mac_ctx, return false; } + /* + * copy FTIE to fils_info and send it over assoc response frame + * for FT-FILS connection + */ + if (pe_session->is11Rconnection && pe_session->fils_info) { + pe_session->fils_info->ft_ie = rx_auth_frm_body->ft_ie; + if (!pe_session->fils_info->ft_ie.present) { + pe_err("FT-FILS: NO FTIE in auth response"); + } + } + for (i = 0; i < dot11f_ie_rsn.pmkid_count; i++) { if (qdf_mem_cmp(dot11f_ie_rsn.pmkid[i], pe_session->fils_info->fils_pmkid, diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 4f2b4a8dc59e..6f3e566e8975 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -4167,6 +4167,69 @@ sir_convert_beacon_frame2_struct(struct mac_context *mac, } /* End sir_convert_beacon_frame2_struct. */ #ifdef WLAN_FEATURE_FILS_SK + +/* update_ftie_in_fils_conf() - API to update fils info from auth + * response packet from AP + * @auth: auth packet pointer received from AP + * @auth_frame: data structure needs to be updated + * + * Return: None + */ +static void +update_ftie_in_fils_conf(tDot11fAuthentication *auth, + tpSirMacAuthFrameBody auth_frame) +{ + /** + * Copy the FTIE sent by the AP in the auth request frame. + * This is required for FT-FILS connection. + * This FTIE will be sent in Assoc request frame without + * any modification. + */ + if (auth->FTInfo.present) { + pe_debug("FT-FILS: r0kh_len:%d r1kh_present:%d", + auth->FTInfo.R0KH_ID.num_PMK_R0_ID, + auth->FTInfo.R1KH_ID.present); + + auth_frame->ft_ie.present = 1; + if (auth->FTInfo.R1KH_ID.present) { + qdf_mem_copy(auth_frame->ft_ie.r1kh_id, + auth->FTInfo.R1KH_ID.PMK_R1_ID, + FT_R1KH_ID_LEN); + } + + if (auth->FTInfo.R0KH_ID.present) { + qdf_mem_copy(auth_frame->ft_ie.r0kh_id, + auth->FTInfo.R0KH_ID.PMK_R0_ID, + auth->FTInfo.R0KH_ID.num_PMK_R0_ID); + auth_frame->ft_ie.r0kh_id_len = + auth->FTInfo.R0KH_ID.num_PMK_R0_ID; + } + + if (auth_frame->ft_ie.gtk_ie.present) { + pe_debug("FT-FILS: GTK present"); + qdf_mem_copy(&auth_frame->ft_ie.gtk_ie, + &auth->FTInfo.GTK, + sizeof(struct mac_ft_gtk_ie)); + } + + if (auth_frame->ft_ie.igtk_ie.present) { + pe_debug("FT-FILS: IGTK present"); + qdf_mem_copy(&auth_frame->ft_ie.igtk_ie, + &auth->FTInfo.IGTK, + sizeof(struct mac_ft_igtk_ie)); + } + + qdf_mem_copy(auth_frame->ft_ie.anonce, auth->FTInfo.Anonce, + FT_NONCE_LEN); + qdf_mem_copy(auth_frame->ft_ie.snonce, auth->FTInfo.Snonce, + FT_NONCE_LEN); + + qdf_mem_copy(auth_frame->ft_ie.mic, auth->FTInfo.MIC, + FT_MIC_LEN); + auth_frame->ft_ie.element_count = auth->FTInfo.IECount; + } +} + /* sir_update_auth_frame2_struct_fils_conf: API to update fils info from auth * packet type 2 * @auth: auth packet pointer received from AP @@ -4174,8 +4237,9 @@ sir_convert_beacon_frame2_struct(struct mac_context *mac, * * Return: None */ -static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth, - tpSirMacAuthFrameBody auth_frame) +static void +sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth, + tpSirMacAuthFrameBody auth_frame) { if (auth->AuthAlgo.algo != SIR_FILS_SK_WITHOUT_PFS) return; @@ -4204,6 +4268,9 @@ static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth, auth->RSNOpaque.num_data); auth_frame->rsn_ie.length = auth->RSNOpaque.num_data; } + + update_ftie_in_fils_conf(auth, auth_frame); + } #else static void sir_update_auth_frame2_struct_fils_conf(tDot11fAuthentication *auth,