1189251Ssam/* 2214734Srpaulo * Internal WPA/RSN supplicant state machine definitions 3214734Srpaulo * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#ifndef WPA_I_H 10189251Ssam#define WPA_I_H 11189251Ssam 12214734Srpaulo#include "utils/list.h" 13214734Srpaulo 14189251Ssamstruct wpa_peerkey; 15252726Srpaulostruct wpa_tdls_peer; 16189251Ssamstruct wpa_eapol_key; 17189251Ssam 18189251Ssam/** 19189251Ssam * struct wpa_sm - Internal WPA state machine data 20189251Ssam */ 21189251Ssamstruct wpa_sm { 22189251Ssam u8 pmk[PMK_LEN]; 23189251Ssam size_t pmk_len; 24189251Ssam struct wpa_ptk ptk, tptk; 25189251Ssam int ptk_set, tptk_set; 26189251Ssam u8 snonce[WPA_NONCE_LEN]; 27189251Ssam u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ 28189251Ssam int renew_snonce; 29189251Ssam u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; 30189251Ssam int rx_replay_counter_set; 31189251Ssam u8 request_counter[WPA_REPLAY_COUNTER_LEN]; 32189251Ssam 33189251Ssam struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ 34189251Ssam 35189251Ssam struct rsn_pmksa_cache *pmksa; /* PMKSA cache */ 36189251Ssam struct rsn_pmksa_cache_entry *cur_pmksa; /* current PMKSA entry */ 37214734Srpaulo struct dl_list pmksa_candidates; 38189251Ssam 39189251Ssam struct l2_packet_data *l2_preauth; 40189251Ssam struct l2_packet_data *l2_preauth_br; 41252726Srpaulo struct l2_packet_data *l2_tdls; 42189251Ssam u8 preauth_bssid[ETH_ALEN]; /* current RSN pre-auth peer or 43189251Ssam * 00:00:00:00:00:00 if no pre-auth is 44189251Ssam * in progress */ 45189251Ssam struct eapol_sm *preauth_eapol; 46189251Ssam 47189251Ssam struct wpa_sm_ctx *ctx; 48189251Ssam 49189251Ssam void *scard_ctx; /* context for smartcard callbacks */ 50189251Ssam int fast_reauth; /* whether EAP fast re-authentication is enabled */ 51189251Ssam 52189251Ssam void *network_ctx; 53189251Ssam int peerkey_enabled; 54189251Ssam int allowed_pairwise_cipher; /* bitfield of WPA_CIPHER_* */ 55189251Ssam int proactive_key_caching; 56189251Ssam int eap_workaround; 57189251Ssam void *eap_conf_ctx; 58189251Ssam u8 ssid[32]; 59189251Ssam size_t ssid_len; 60189251Ssam int wpa_ptk_rekey; 61189251Ssam 62189251Ssam u8 own_addr[ETH_ALEN]; 63189251Ssam const char *ifname; 64189251Ssam const char *bridge_ifname; 65189251Ssam u8 bssid[ETH_ALEN]; 66189251Ssam 67189251Ssam unsigned int dot11RSNAConfigPMKLifetime; 68189251Ssam unsigned int dot11RSNAConfigPMKReauthThreshold; 69189251Ssam unsigned int dot11RSNAConfigSATimeout; 70189251Ssam 71189251Ssam unsigned int dot11RSNA4WayHandshakeFailures; 72189251Ssam 73189251Ssam /* Selected configuration (based on Beacon/ProbeResp WPA IE) */ 74189251Ssam unsigned int proto; 75189251Ssam unsigned int pairwise_cipher; 76189251Ssam unsigned int group_cipher; 77189251Ssam unsigned int key_mgmt; 78189251Ssam unsigned int mgmt_group_cipher; 79189251Ssam 80189251Ssam int rsn_enabled; /* Whether RSN is enabled in configuration */ 81214734Srpaulo int mfp; /* 0 = disabled, 1 = optional, 2 = mandatory */ 82189251Ssam 83189251Ssam u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */ 84189251Ssam size_t assoc_wpa_ie_len; 85189251Ssam u8 *ap_wpa_ie, *ap_rsn_ie; 86189251Ssam size_t ap_wpa_ie_len, ap_rsn_ie_len; 87189251Ssam 88189251Ssam#ifdef CONFIG_PEERKEY 89189251Ssam struct wpa_peerkey *peerkey; 90189251Ssam#endif /* CONFIG_PEERKEY */ 91252726Srpaulo#ifdef CONFIG_TDLS 92252726Srpaulo struct wpa_tdls_peer *tdls; 93252726Srpaulo int tdls_prohibited; 94252726Srpaulo int tdls_disabled; 95189251Ssam 96252726Srpaulo /* The driver supports TDLS */ 97252726Srpaulo int tdls_supported; 98252726Srpaulo 99252726Srpaulo /* 100252726Srpaulo * The driver requires explicit discovery/setup/teardown frames sent 101252726Srpaulo * to it via tdls_mgmt. 102252726Srpaulo */ 103252726Srpaulo int tdls_external_setup; 104252726Srpaulo#endif /* CONFIG_TDLS */ 105252726Srpaulo 106189251Ssam#ifdef CONFIG_IEEE80211R 107189251Ssam u8 xxkey[PMK_LEN]; /* PSK or the second 256 bits of MSK */ 108189251Ssam size_t xxkey_len; 109189251Ssam u8 pmk_r0[PMK_LEN]; 110189251Ssam u8 pmk_r0_name[WPA_PMK_NAME_LEN]; 111189251Ssam u8 pmk_r1[PMK_LEN]; 112189251Ssam u8 pmk_r1_name[WPA_PMK_NAME_LEN]; 113189251Ssam u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; 114189251Ssam u8 r0kh_id[FT_R0KH_ID_MAX_LEN]; 115189251Ssam size_t r0kh_id_len; 116189251Ssam u8 r1kh_id[FT_R1KH_ID_LEN]; 117189251Ssam int ft_completed; 118189251Ssam int over_the_ds_in_progress; 119189251Ssam u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ 120214734Srpaulo int set_ptk_after_assoc; 121214734Srpaulo u8 mdie_ft_capab; /* FT Capability and Policy from target AP MDIE */ 122214734Srpaulo u8 *assoc_resp_ies; /* MDIE and FTIE from (Re)Association Response */ 123214734Srpaulo size_t assoc_resp_ies_len; 124189251Ssam#endif /* CONFIG_IEEE80211R */ 125189251Ssam}; 126189251Ssam 127189251Ssam 128214734Srpaulostatic inline void wpa_sm_set_state(struct wpa_sm *sm, enum wpa_states state) 129189251Ssam{ 130189251Ssam WPA_ASSERT(sm->ctx->set_state); 131189251Ssam sm->ctx->set_state(sm->ctx->ctx, state); 132189251Ssam} 133189251Ssam 134214734Srpaulostatic inline enum wpa_states wpa_sm_get_state(struct wpa_sm *sm) 135189251Ssam{ 136189251Ssam WPA_ASSERT(sm->ctx->get_state); 137189251Ssam return sm->ctx->get_state(sm->ctx->ctx); 138189251Ssam} 139189251Ssam 140189251Ssamstatic inline void wpa_sm_deauthenticate(struct wpa_sm *sm, int reason_code) 141189251Ssam{ 142189251Ssam WPA_ASSERT(sm->ctx->deauthenticate); 143189251Ssam sm->ctx->deauthenticate(sm->ctx->ctx, reason_code); 144189251Ssam} 145189251Ssam 146214734Srpaulostatic inline int wpa_sm_set_key(struct wpa_sm *sm, enum wpa_alg alg, 147189251Ssam const u8 *addr, int key_idx, int set_tx, 148189251Ssam const u8 *seq, size_t seq_len, 149189251Ssam const u8 *key, size_t key_len) 150189251Ssam{ 151189251Ssam WPA_ASSERT(sm->ctx->set_key); 152189251Ssam return sm->ctx->set_key(sm->ctx->ctx, alg, addr, key_idx, set_tx, 153189251Ssam seq, seq_len, key, key_len); 154189251Ssam} 155189251Ssam 156189251Ssamstatic inline void * wpa_sm_get_network_ctx(struct wpa_sm *sm) 157189251Ssam{ 158189251Ssam WPA_ASSERT(sm->ctx->get_network_ctx); 159189251Ssam return sm->ctx->get_network_ctx(sm->ctx->ctx); 160189251Ssam} 161189251Ssam 162189251Ssamstatic inline int wpa_sm_get_bssid(struct wpa_sm *sm, u8 *bssid) 163189251Ssam{ 164189251Ssam WPA_ASSERT(sm->ctx->get_bssid); 165189251Ssam return sm->ctx->get_bssid(sm->ctx->ctx, bssid); 166189251Ssam} 167189251Ssam 168189251Ssamstatic inline int wpa_sm_ether_send(struct wpa_sm *sm, const u8 *dest, 169189251Ssam u16 proto, const u8 *buf, size_t len) 170189251Ssam{ 171189251Ssam WPA_ASSERT(sm->ctx->ether_send); 172189251Ssam return sm->ctx->ether_send(sm->ctx->ctx, dest, proto, buf, len); 173189251Ssam} 174189251Ssam 175189251Ssamstatic inline int wpa_sm_get_beacon_ie(struct wpa_sm *sm) 176189251Ssam{ 177189251Ssam WPA_ASSERT(sm->ctx->get_beacon_ie); 178189251Ssam return sm->ctx->get_beacon_ie(sm->ctx->ctx); 179189251Ssam} 180189251Ssam 181189251Ssamstatic inline void wpa_sm_cancel_auth_timeout(struct wpa_sm *sm) 182189251Ssam{ 183189251Ssam WPA_ASSERT(sm->ctx->cancel_auth_timeout); 184189251Ssam sm->ctx->cancel_auth_timeout(sm->ctx->ctx); 185189251Ssam} 186189251Ssam 187189251Ssamstatic inline u8 * wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, 188189251Ssam const void *data, u16 data_len, 189189251Ssam size_t *msg_len, void **data_pos) 190189251Ssam{ 191189251Ssam WPA_ASSERT(sm->ctx->alloc_eapol); 192189251Ssam return sm->ctx->alloc_eapol(sm->ctx->ctx, type, data, data_len, 193189251Ssam msg_len, data_pos); 194189251Ssam} 195189251Ssam 196189251Ssamstatic inline int wpa_sm_add_pmkid(struct wpa_sm *sm, const u8 *bssid, 197189251Ssam const u8 *pmkid) 198189251Ssam{ 199189251Ssam WPA_ASSERT(sm->ctx->add_pmkid); 200189251Ssam return sm->ctx->add_pmkid(sm->ctx->ctx, bssid, pmkid); 201189251Ssam} 202189251Ssam 203189251Ssamstatic inline int wpa_sm_remove_pmkid(struct wpa_sm *sm, const u8 *bssid, 204189251Ssam const u8 *pmkid) 205189251Ssam{ 206189251Ssam WPA_ASSERT(sm->ctx->remove_pmkid); 207189251Ssam return sm->ctx->remove_pmkid(sm->ctx->ctx, bssid, pmkid); 208189251Ssam} 209189251Ssam 210189251Ssamstatic inline int wpa_sm_mlme_setprotection(struct wpa_sm *sm, const u8 *addr, 211189251Ssam int protect_type, int key_type) 212189251Ssam{ 213189251Ssam WPA_ASSERT(sm->ctx->mlme_setprotection); 214189251Ssam return sm->ctx->mlme_setprotection(sm->ctx->ctx, addr, protect_type, 215189251Ssam key_type); 216189251Ssam} 217189251Ssam 218189251Ssamstatic inline int wpa_sm_update_ft_ies(struct wpa_sm *sm, const u8 *md, 219189251Ssam const u8 *ies, size_t ies_len) 220189251Ssam{ 221189251Ssam if (sm->ctx->update_ft_ies) 222189251Ssam return sm->ctx->update_ft_ies(sm->ctx->ctx, md, ies, ies_len); 223189251Ssam return -1; 224189251Ssam} 225189251Ssam 226189251Ssamstatic inline int wpa_sm_send_ft_action(struct wpa_sm *sm, u8 action, 227189251Ssam const u8 *target_ap, 228189251Ssam const u8 *ies, size_t ies_len) 229189251Ssam{ 230189251Ssam if (sm->ctx->send_ft_action) 231189251Ssam return sm->ctx->send_ft_action(sm->ctx->ctx, action, target_ap, 232189251Ssam ies, ies_len); 233189251Ssam return -1; 234189251Ssam} 235189251Ssam 236214734Srpaulostatic inline int wpa_sm_mark_authenticated(struct wpa_sm *sm, 237214734Srpaulo const u8 *target_ap) 238214734Srpaulo{ 239214734Srpaulo if (sm->ctx->mark_authenticated) 240214734Srpaulo return sm->ctx->mark_authenticated(sm->ctx->ctx, target_ap); 241214734Srpaulo return -1; 242214734Srpaulo} 243189251Ssam 244252726Srpaulostatic inline void wpa_sm_set_rekey_offload(struct wpa_sm *sm) 245252726Srpaulo{ 246252726Srpaulo if (!sm->ctx->set_rekey_offload) 247252726Srpaulo return; 248252726Srpaulo sm->ctx->set_rekey_offload(sm->ctx->ctx, sm->ptk.kek, 249252726Srpaulo sm->ptk.kck, sm->rx_replay_counter); 250252726Srpaulo} 251214734Srpaulo 252252726Srpaulo#ifdef CONFIG_TDLS 253252726Srpaulostatic inline int wpa_sm_tdls_get_capa(struct wpa_sm *sm, 254252726Srpaulo int *tdls_supported, 255252726Srpaulo int *tdls_ext_setup) 256252726Srpaulo{ 257252726Srpaulo if (sm->ctx->tdls_get_capa) 258252726Srpaulo return sm->ctx->tdls_get_capa(sm->ctx->ctx, tdls_supported, 259252726Srpaulo tdls_ext_setup); 260252726Srpaulo return -1; 261252726Srpaulo} 262252726Srpaulo 263252726Srpaulostatic inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst, 264252726Srpaulo u8 action_code, u8 dialog_token, 265252726Srpaulo u16 status_code, const u8 *buf, 266252726Srpaulo size_t len) 267252726Srpaulo{ 268252726Srpaulo if (sm->ctx->send_tdls_mgmt) 269252726Srpaulo return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code, 270252726Srpaulo dialog_token, status_code, 271252726Srpaulo buf, len); 272252726Srpaulo return -1; 273252726Srpaulo} 274252726Srpaulo 275252726Srpaulostatic inline int wpa_sm_tdls_oper(struct wpa_sm *sm, int oper, 276252726Srpaulo const u8 *peer) 277252726Srpaulo{ 278252726Srpaulo if (sm->ctx->tdls_oper) 279252726Srpaulo return sm->ctx->tdls_oper(sm->ctx->ctx, oper, peer); 280252726Srpaulo return -1; 281252726Srpaulo} 282252726Srpaulo 283252726Srpaulostatic inline int 284252726Srpaulowpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, 285252726Srpaulo u16 capability, const u8 *supp_rates, 286252726Srpaulo size_t supp_rates_len) 287252726Srpaulo{ 288252726Srpaulo if (sm->ctx->tdls_peer_addset) 289252726Srpaulo return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add, 290252726Srpaulo capability, supp_rates, 291252726Srpaulo supp_rates_len); 292252726Srpaulo return -1; 293252726Srpaulo} 294252726Srpaulo#endif /* CONFIG_TDLS */ 295252726Srpaulo 296189251Ssamvoid wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck, 297189251Ssam int ver, const u8 *dest, u16 proto, 298189251Ssam u8 *msg, size_t msg_len, u8 *key_mic); 299189251Ssamint wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, 300189251Ssam const struct wpa_eapol_key *key, 301189251Ssam int ver, const u8 *nonce, 302189251Ssam const u8 *wpa_ie, size_t wpa_ie_len, 303189251Ssam struct wpa_ptk *ptk); 304189251Ssamint wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst, 305189251Ssam const struct wpa_eapol_key *key, 306189251Ssam u16 ver, u16 key_info, 307189251Ssam const u8 *kde, size_t kde_len, 308189251Ssam struct wpa_ptk *ptk); 309189251Ssam 310189251Ssamint wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, 311189251Ssam const struct wpa_eapol_key *key, 312209158Srpaulo struct wpa_ptk *ptk, size_t ptk_len); 313189251Ssam 314252726Srpaulovoid wpa_tdls_assoc(struct wpa_sm *sm); 315252726Srpaulovoid wpa_tdls_disassoc(struct wpa_sm *sm); 316252726Srpaulo 317189251Ssam#endif /* WPA_I_H */ 318