]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Internal WPA/RSN supplicant state machine definitions | |
3 | * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi> | |
4 | * | |
5 | * This software may be distributed under the terms of the BSD license. | |
6 | * See README for more details. | |
7 | */ | |
8 | ||
9 | #ifndef WPA_I_H | |
10 | #define WPA_I_H | |
11 | ||
12 | #include "utils/list.h" | |
13 | ||
14 | struct wpa_tdls_peer; | |
15 | struct wpa_eapol_key; | |
16 | ||
17 | /** | |
18 | * struct wpa_sm - Internal WPA state machine data | |
19 | */ | |
20 | struct wpa_sm { | |
21 | u8 pmk[PMK_LEN_MAX]; | |
22 | size_t pmk_len; | |
23 | struct wpa_ptk ptk, tptk; | |
24 | int ptk_set, tptk_set; | |
25 | unsigned int msg_3_of_4_ok:1; | |
26 | u8 snonce[WPA_NONCE_LEN]; | |
27 | u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ | |
28 | int renew_snonce; | |
29 | u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; | |
30 | int rx_replay_counter_set; | |
31 | u8 request_counter[WPA_REPLAY_COUNTER_LEN]; | |
32 | struct wpa_gtk gtk; | |
33 | struct wpa_gtk gtk_wnm_sleep; | |
34 | struct wpa_igtk igtk; | |
35 | struct wpa_igtk igtk_wnm_sleep; | |
36 | struct wpa_bigtk bigtk; | |
37 | struct wpa_bigtk bigtk_wnm_sleep; | |
38 | ||
39 | struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ | |
40 | ||
41 | struct rsn_pmksa_cache *pmksa; /* PMKSA cache */ | |
42 | struct rsn_pmksa_cache_entry *cur_pmksa; /* current PMKSA entry */ | |
43 | struct dl_list pmksa_candidates; | |
44 | ||
45 | struct l2_packet_data *l2_preauth; | |
46 | struct l2_packet_data *l2_preauth_br; | |
47 | struct l2_packet_data *l2_tdls; | |
48 | u8 preauth_bssid[ETH_ALEN]; /* current RSN pre-auth peer or | |
49 | * 00:00:00:00:00:00 if no pre-auth is | |
50 | * in progress */ | |
51 | struct eapol_sm *preauth_eapol; | |
52 | ||
53 | struct wpa_sm_ctx *ctx; | |
54 | ||
55 | void *scard_ctx; /* context for smartcard callbacks */ | |
56 | int fast_reauth; /* whether EAP fast re-authentication is enabled */ | |
57 | ||
58 | void *network_ctx; | |
59 | int allowed_pairwise_cipher; /* bitfield of WPA_CIPHER_* */ | |
60 | int proactive_key_caching; | |
61 | int eap_workaround; | |
62 | void *eap_conf_ctx; | |
63 | u8 ssid[32]; | |
64 | size_t ssid_len; | |
65 | int wpa_ptk_rekey; | |
66 | int wpa_deny_ptk0_rekey:1; | |
67 | int p2p; | |
68 | int wpa_rsc_relaxation; | |
69 | int owe_ptk_workaround; | |
70 | int beacon_prot; | |
71 | int ext_key_id; /* whether Extended Key ID is enabled */ | |
72 | int use_ext_key_id; /* whether Extended Key ID has been detected | |
73 | * to be used */ | |
74 | int keyidx_active; /* Key ID for the active TK */ | |
75 | ||
76 | u8 own_addr[ETH_ALEN]; | |
77 | const char *ifname; | |
78 | const char *bridge_ifname; | |
79 | u8 bssid[ETH_ALEN]; | |
80 | ||
81 | unsigned int dot11RSNAConfigPMKLifetime; | |
82 | unsigned int dot11RSNAConfigPMKReauthThreshold; | |
83 | unsigned int dot11RSNAConfigSATimeout; | |
84 | ||
85 | unsigned int dot11RSNA4WayHandshakeFailures; | |
86 | ||
87 | /* Selected configuration (based on Beacon/ProbeResp WPA IE) */ | |
88 | unsigned int proto; | |
89 | unsigned int pairwise_cipher; | |
90 | unsigned int group_cipher; | |
91 | unsigned int key_mgmt; | |
92 | unsigned int mgmt_group_cipher; | |
93 | ||
94 | int rsn_enabled; /* Whether RSN is enabled in configuration */ | |
95 | int mfp; /* 0 = disabled, 1 = optional, 2 = mandatory */ | |
96 | int ocv; /* Operating Channel Validation */ | |
97 | int sae_pwe; /* SAE PWE generation options */ | |
98 | ||
99 | u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */ | |
100 | size_t assoc_wpa_ie_len; | |
101 | u8 *assoc_rsnxe; /* Own RSNXE from (Re)AssocReq */ | |
102 | size_t assoc_rsnxe_len; | |
103 | u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe; | |
104 | size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len; | |
105 | ||
106 | #ifdef CONFIG_TDLS | |
107 | struct wpa_tdls_peer *tdls; | |
108 | int tdls_prohibited; | |
109 | int tdls_chan_switch_prohibited; | |
110 | int tdls_disabled; | |
111 | ||
112 | /* The driver supports TDLS */ | |
113 | int tdls_supported; | |
114 | ||
115 | /* | |
116 | * The driver requires explicit discovery/setup/teardown frames sent | |
117 | * to it via tdls_mgmt. | |
118 | */ | |
119 | int tdls_external_setup; | |
120 | ||
121 | /* The driver supports TDLS channel switching */ | |
122 | int tdls_chan_switch; | |
123 | #endif /* CONFIG_TDLS */ | |
124 | ||
125 | #ifdef CONFIG_IEEE80211R | |
126 | u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the | |
127 | * first 384 bits of MSK */ | |
128 | size_t xxkey_len; | |
129 | u8 pmk_r0[PMK_LEN_MAX]; | |
130 | size_t pmk_r0_len; | |
131 | u8 pmk_r0_name[WPA_PMK_NAME_LEN]; | |
132 | u8 pmk_r1[PMK_LEN_MAX]; | |
133 | size_t pmk_r1_len; | |
134 | u8 pmk_r1_name[WPA_PMK_NAME_LEN]; | |
135 | u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; | |
136 | u8 r0kh_id[FT_R0KH_ID_MAX_LEN]; | |
137 | size_t r0kh_id_len; | |
138 | u8 r1kh_id[FT_R1KH_ID_LEN]; | |
139 | unsigned int ft_completed:1; | |
140 | unsigned int ft_reassoc_completed:1; | |
141 | unsigned int ft_protocol:1; | |
142 | int over_the_ds_in_progress; | |
143 | u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ | |
144 | int set_ptk_after_assoc; | |
145 | u8 mdie_ft_capab; /* FT Capability and Policy from target AP MDIE */ | |
146 | u8 *assoc_resp_ies; /* MDIE and FTIE from (Re)Association Response */ | |
147 | size_t assoc_resp_ies_len; | |
148 | #endif /* CONFIG_IEEE80211R */ | |
149 | ||
150 | #ifdef CONFIG_P2P | |
151 | u8 p2p_ip_addr[3 * 4]; | |
152 | #endif /* CONFIG_P2P */ | |
153 | ||
154 | #ifdef CONFIG_TESTING_OPTIONS | |
155 | struct wpabuf *test_assoc_ie; | |
156 | #endif /* CONFIG_TESTING_OPTIONS */ | |
157 | ||
158 | #ifdef CONFIG_FILS | |
159 | u8 fils_nonce[FILS_NONCE_LEN]; | |
160 | u8 fils_session[FILS_SESSION_LEN]; | |
161 | u8 fils_anonce[FILS_NONCE_LEN]; | |
162 | u8 fils_key_auth_ap[FILS_MAX_KEY_AUTH_LEN]; | |
163 | u8 fils_key_auth_sta[FILS_MAX_KEY_AUTH_LEN]; | |
164 | size_t fils_key_auth_len; | |
165 | unsigned int fils_completed:1; | |
166 | unsigned int fils_erp_pmkid_set:1; | |
167 | unsigned int fils_cache_id_set:1; | |
168 | u8 fils_erp_pmkid[PMKID_LEN]; | |
169 | u8 fils_cache_id[FILS_CACHE_ID_LEN]; | |
170 | struct crypto_ecdh *fils_ecdh; | |
171 | int fils_dh_group; | |
172 | size_t fils_dh_elem_len; | |
173 | struct wpabuf *fils_ft_ies; | |
174 | u8 fils_ft[FILS_FT_MAX_LEN]; | |
175 | size_t fils_ft_len; | |
176 | #endif /* CONFIG_FILS */ | |
177 | ||
178 | #ifdef CONFIG_OWE | |
179 | struct crypto_ecdh *owe_ecdh; | |
180 | u16 owe_group; | |
181 | #endif /* CONFIG_OWE */ | |
182 | ||
183 | #ifdef CONFIG_DPP2 | |
184 | struct wpabuf *dpp_z; | |
185 | #endif /* CONFIG_DPP2 */ | |
186 | }; | |
187 | ||
188 | ||
189 | static inline void wpa_sm_set_state(struct wpa_sm *sm, enum wpa_states state) | |
190 | { | |
191 | WPA_ASSERT(sm->ctx->set_state); | |
192 | sm->ctx->set_state(sm->ctx->ctx, state); | |
193 | } | |
194 | ||
195 | static inline enum wpa_states wpa_sm_get_state(struct wpa_sm *sm) | |
196 | { | |
197 | WPA_ASSERT(sm->ctx->get_state); | |
198 | return sm->ctx->get_state(sm->ctx->ctx); | |
199 | } | |
200 | ||
201 | static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, u16 reason_code) | |
202 | { | |
203 | WPA_ASSERT(sm->ctx->deauthenticate); | |
204 | sm->ctx->deauthenticate(sm->ctx->ctx, reason_code); | |
205 | } | |
206 | ||
207 | static inline int wpa_sm_set_key(struct wpa_sm *sm, enum wpa_alg alg, | |
208 | const u8 *addr, int key_idx, int set_tx, | |
209 | const u8 *seq, size_t seq_len, | |
210 | const u8 *key, size_t key_len, | |
211 | enum key_flag key_flag) | |
212 | { | |
213 | WPA_ASSERT(sm->ctx->set_key); | |
214 | return sm->ctx->set_key(sm->ctx->ctx, alg, addr, key_idx, set_tx, | |
215 | seq, seq_len, key, key_len, key_flag); | |
216 | } | |
217 | ||
218 | static inline void wpa_sm_reconnect(struct wpa_sm *sm) | |
219 | { | |
220 | WPA_ASSERT(sm->ctx->reconnect); | |
221 | sm->ctx->reconnect(sm->ctx->ctx); | |
222 | } | |
223 | ||
224 | static inline void * wpa_sm_get_network_ctx(struct wpa_sm *sm) | |
225 | { | |
226 | WPA_ASSERT(sm->ctx->get_network_ctx); | |
227 | return sm->ctx->get_network_ctx(sm->ctx->ctx); | |
228 | } | |
229 | ||
230 | static inline int wpa_sm_get_bssid(struct wpa_sm *sm, u8 *bssid) | |
231 | { | |
232 | WPA_ASSERT(sm->ctx->get_bssid); | |
233 | return sm->ctx->get_bssid(sm->ctx->ctx, bssid); | |
234 | } | |
235 | ||
236 | static inline int wpa_sm_ether_send(struct wpa_sm *sm, const u8 *dest, | |
237 | u16 proto, const u8 *buf, size_t len) | |
238 | { | |
239 | WPA_ASSERT(sm->ctx->ether_send); | |
240 | return sm->ctx->ether_send(sm->ctx->ctx, dest, proto, buf, len); | |
241 | } | |
242 | ||
243 | static inline int wpa_sm_get_beacon_ie(struct wpa_sm *sm) | |
244 | { | |
245 | WPA_ASSERT(sm->ctx->get_beacon_ie); | |
246 | return sm->ctx->get_beacon_ie(sm->ctx->ctx); | |
247 | } | |
248 | ||
249 | static inline void wpa_sm_cancel_auth_timeout(struct wpa_sm *sm) | |
250 | { | |
251 | WPA_ASSERT(sm->ctx->cancel_auth_timeout); | |
252 | sm->ctx->cancel_auth_timeout(sm->ctx->ctx); | |
253 | } | |
254 | ||
255 | static inline u8 * wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, | |
256 | const void *data, u16 data_len, | |
257 | size_t *msg_len, void **data_pos) | |
258 | { | |
259 | WPA_ASSERT(sm->ctx->alloc_eapol); | |
260 | return sm->ctx->alloc_eapol(sm->ctx->ctx, type, data, data_len, | |
261 | msg_len, data_pos); | |
262 | } | |
263 | ||
264 | static inline int wpa_sm_add_pmkid(struct wpa_sm *sm, void *network_ctx, | |
265 | const u8 *bssid, const u8 *pmkid, | |
266 | const u8 *cache_id, const u8 *pmk, | |
267 | size_t pmk_len) | |
268 | { | |
269 | WPA_ASSERT(sm->ctx->add_pmkid); | |
270 | return sm->ctx->add_pmkid(sm->ctx->ctx, network_ctx, bssid, pmkid, | |
271 | cache_id, pmk, pmk_len); | |
272 | } | |
273 | ||
274 | static inline int wpa_sm_remove_pmkid(struct wpa_sm *sm, void *network_ctx, | |
275 | const u8 *bssid, const u8 *pmkid, | |
276 | const u8 *cache_id) | |
277 | { | |
278 | WPA_ASSERT(sm->ctx->remove_pmkid); | |
279 | return sm->ctx->remove_pmkid(sm->ctx->ctx, network_ctx, bssid, pmkid, | |
280 | cache_id); | |
281 | } | |
282 | ||
283 | static inline int wpa_sm_mlme_setprotection(struct wpa_sm *sm, const u8 *addr, | |
284 | int protect_type, int key_type) | |
285 | { | |
286 | WPA_ASSERT(sm->ctx->mlme_setprotection); | |
287 | return sm->ctx->mlme_setprotection(sm->ctx->ctx, addr, protect_type, | |
288 | key_type); | |
289 | } | |
290 | ||
291 | static inline int wpa_sm_update_ft_ies(struct wpa_sm *sm, const u8 *md, | |
292 | const u8 *ies, size_t ies_len) | |
293 | { | |
294 | if (sm->ctx->update_ft_ies) | |
295 | return sm->ctx->update_ft_ies(sm->ctx->ctx, md, ies, ies_len); | |
296 | return -1; | |
297 | } | |
298 | ||
299 | static inline int wpa_sm_send_ft_action(struct wpa_sm *sm, u8 action, | |
300 | const u8 *target_ap, | |
301 | const u8 *ies, size_t ies_len) | |
302 | { | |
303 | if (sm->ctx->send_ft_action) | |
304 | return sm->ctx->send_ft_action(sm->ctx->ctx, action, target_ap, | |
305 | ies, ies_len); | |
306 | return -1; | |
307 | } | |
308 | ||
309 | static inline int wpa_sm_mark_authenticated(struct wpa_sm *sm, | |
310 | const u8 *target_ap) | |
311 | { | |
312 | if (sm->ctx->mark_authenticated) | |
313 | return sm->ctx->mark_authenticated(sm->ctx->ctx, target_ap); | |
314 | return -1; | |
315 | } | |
316 | ||
317 | static inline void wpa_sm_set_rekey_offload(struct wpa_sm *sm) | |
318 | { | |
319 | if (!sm->ctx->set_rekey_offload) | |
320 | return; | |
321 | sm->ctx->set_rekey_offload(sm->ctx->ctx, sm->ptk.kek, sm->ptk.kek_len, | |
322 | sm->ptk.kck, sm->ptk.kck_len, | |
323 | sm->rx_replay_counter); | |
324 | } | |
325 | ||
326 | #ifdef CONFIG_TDLS | |
327 | static inline int wpa_sm_tdls_get_capa(struct wpa_sm *sm, | |
328 | int *tdls_supported, | |
329 | int *tdls_ext_setup, | |
330 | int *tdls_chan_switch) | |
331 | { | |
332 | if (sm->ctx->tdls_get_capa) | |
333 | return sm->ctx->tdls_get_capa(sm->ctx->ctx, tdls_supported, | |
334 | tdls_ext_setup, tdls_chan_switch); | |
335 | return -1; | |
336 | } | |
337 | ||
338 | static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst, | |
339 | u8 action_code, u8 dialog_token, | |
340 | u16 status_code, u32 peer_capab, | |
341 | int initiator, const u8 *buf, | |
342 | size_t len) | |
343 | { | |
344 | if (sm->ctx->send_tdls_mgmt) | |
345 | return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code, | |
346 | dialog_token, status_code, | |
347 | peer_capab, initiator, buf, | |
348 | len); | |
349 | return -1; | |
350 | } | |
351 | ||
352 | static inline int wpa_sm_tdls_oper(struct wpa_sm *sm, int oper, | |
353 | const u8 *peer) | |
354 | { | |
355 | if (sm->ctx->tdls_oper) | |
356 | return sm->ctx->tdls_oper(sm->ctx->ctx, oper, peer); | |
357 | return -1; | |
358 | } | |
359 | ||
360 | static inline int | |
361 | wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, | |
362 | u16 aid, u16 capability, const u8 *supp_rates, | |
363 | size_t supp_rates_len, | |
364 | const struct ieee80211_ht_capabilities *ht_capab, | |
365 | const struct ieee80211_vht_capabilities *vht_capab, | |
366 | u8 qosinfo, int wmm, const u8 *ext_capab, | |
367 | size_t ext_capab_len, const u8 *supp_channels, | |
368 | size_t supp_channels_len, const u8 *supp_oper_classes, | |
369 | size_t supp_oper_classes_len) | |
370 | { | |
371 | if (sm->ctx->tdls_peer_addset) | |
372 | return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add, | |
373 | aid, capability, supp_rates, | |
374 | supp_rates_len, ht_capab, | |
375 | vht_capab, qosinfo, wmm, | |
376 | ext_capab, ext_capab_len, | |
377 | supp_channels, | |
378 | supp_channels_len, | |
379 | supp_oper_classes, | |
380 | supp_oper_classes_len); | |
381 | return -1; | |
382 | } | |
383 | ||
384 | static inline int | |
385 | wpa_sm_tdls_enable_channel_switch(struct wpa_sm *sm, const u8 *addr, | |
386 | u8 oper_class, | |
387 | const struct hostapd_freq_params *freq_params) | |
388 | { | |
389 | if (sm->ctx->tdls_enable_channel_switch) | |
390 | return sm->ctx->tdls_enable_channel_switch(sm->ctx->ctx, addr, | |
391 | oper_class, | |
392 | freq_params); | |
393 | return -1; | |
394 | } | |
395 | ||
396 | static inline int | |
397 | wpa_sm_tdls_disable_channel_switch(struct wpa_sm *sm, const u8 *addr) | |
398 | { | |
399 | if (sm->ctx->tdls_disable_channel_switch) | |
400 | return sm->ctx->tdls_disable_channel_switch(sm->ctx->ctx, addr); | |
401 | return -1; | |
402 | } | |
403 | #endif /* CONFIG_TDLS */ | |
404 | ||
405 | static inline int wpa_sm_key_mgmt_set_pmk(struct wpa_sm *sm, | |
406 | const u8 *pmk, size_t pmk_len) | |
407 | { | |
408 | if (!sm->ctx->key_mgmt_set_pmk) | |
409 | return -1; | |
410 | return sm->ctx->key_mgmt_set_pmk(sm->ctx->ctx, pmk, pmk_len); | |
411 | } | |
412 | ||
413 | static inline void wpa_sm_fils_hlp_rx(struct wpa_sm *sm, | |
414 | const u8 *dst, const u8 *src, | |
415 | const u8 *pkt, size_t pkt_len) | |
416 | { | |
417 | if (sm->ctx->fils_hlp_rx) | |
418 | sm->ctx->fils_hlp_rx(sm->ctx->ctx, dst, src, pkt, pkt_len); | |
419 | } | |
420 | ||
421 | static inline int wpa_sm_channel_info(struct wpa_sm *sm, | |
422 | struct wpa_channel_info *ci) | |
423 | { | |
424 | if (!sm->ctx->channel_info) | |
425 | return -1; | |
426 | return sm->ctx->channel_info(sm->ctx->ctx, ci); | |
427 | } | |
428 | ||
429 | static inline void wpa_sm_transition_disable(struct wpa_sm *sm, u8 bitmap) | |
430 | { | |
431 | if (sm->ctx->transition_disable) | |
432 | sm->ctx->transition_disable(sm->ctx->ctx, bitmap); | |
433 | } | |
434 | ||
435 | ||
436 | int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, | |
437 | int ver, const u8 *dest, u16 proto, | |
438 | u8 *msg, size_t msg_len, u8 *key_mic); | |
439 | int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, | |
440 | const struct wpa_eapol_key *key, | |
441 | int ver, const u8 *nonce, | |
442 | const u8 *wpa_ie, size_t wpa_ie_len, | |
443 | struct wpa_ptk *ptk); | |
444 | int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst, | |
445 | const struct wpa_eapol_key *key, | |
446 | u16 ver, u16 key_info, | |
447 | struct wpa_ptk *ptk); | |
448 | ||
449 | int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, | |
450 | const struct wpa_eapol_key *key, struct wpa_ptk *ptk); | |
451 | ||
452 | void wpa_tdls_assoc(struct wpa_sm *sm); | |
453 | void wpa_tdls_disassoc(struct wpa_sm *sm); | |
454 | ||
455 | #endif /* WPA_I_H */ |