/src/hostap/src/pasn/pasn_common.h
Line | Count | Source |
1 | | /* |
2 | | * PASN info for initiator and responder |
3 | | * |
4 | | * Copyright (C) 2019, Intel Corporation |
5 | | * Copyright (c) 2022, Jouni Malinen <j@w1.fi> |
6 | | * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. |
7 | | * |
8 | | * This software may be distributed under the terms of the BSD license. |
9 | | * See README for more details. |
10 | | */ |
11 | | |
12 | | #ifndef PASN_COMMON_H |
13 | | #define PASN_COMMON_H |
14 | | |
15 | | #include "common/wpa_common.h" |
16 | | #ifdef CONFIG_SAE |
17 | | #include "common/sae.h" |
18 | | #endif /* CONFIG_SAE */ |
19 | | |
20 | | #ifdef __cplusplus |
21 | | extern "C" { |
22 | | #endif |
23 | | |
24 | | /* Maximum number of ECC groups supported for PASN */ |
25 | | #define MAX_NUM_OF_PASN_GROUPS 10 |
26 | | |
27 | | enum pasn_fils_state { |
28 | | PASN_FILS_STATE_NONE = 0, |
29 | | PASN_FILS_STATE_PENDING_AS, |
30 | | PASN_FILS_STATE_COMPLETE |
31 | | }; |
32 | | |
33 | | struct pasn_fils { |
34 | | u8 state; |
35 | | u8 nonce[NONCE_LEN]; |
36 | | u8 anonce[NONCE_LEN]; |
37 | | u8 session[FILS_SESSION_LEN]; |
38 | | u8 erp_pmkid[PMKID_LEN]; |
39 | | bool completed; |
40 | | struct wpabuf *erp_resp; |
41 | | }; |
42 | | |
43 | | struct pasn_data { |
44 | | /* External modules access below variables using setter and getter |
45 | | * functions */ |
46 | | int akmp; |
47 | | int cipher; |
48 | | u8 own_addr[ETH_ALEN]; |
49 | | u8 peer_addr[ETH_ALEN]; |
50 | | u8 bssid[ETH_ALEN]; |
51 | | struct rsn_pmksa_cache *pmksa; |
52 | | bool derive_kdk; |
53 | | size_t kdk_len; |
54 | | void *cb_ctx; |
55 | | unsigned int auth_alg; |
56 | | u8 mld_addr[ETH_ALEN]; |
57 | | bool is_ml_peer; |
58 | | int group_cipher; |
59 | | int group_mgmt_cipher; |
60 | | u16 rsn_capab; |
61 | | |
62 | | #ifdef CONFIG_SAE |
63 | | struct sae_pt *pt; |
64 | | #endif /* CONFIG_SAE */ |
65 | | |
66 | | /* Responder */ |
67 | | int wpa_key_mgmt; |
68 | | int rsn_pairwise; |
69 | | u64 rsnxe_capab; |
70 | | u8 *rsnxe_ie; |
71 | | bool custom_pmkid_valid; |
72 | | u8 custom_pmkid[PMKID_LEN]; |
73 | | enum mfp_options ieee80211w; |
74 | | |
75 | | /* Counter from the decrypted password identifier blob (set when |
76 | | * get_pt_for_pw_id() resolves an encrypted identifier) */ |
77 | | unsigned int sae_pw_id_counter; |
78 | | /* Decrypted (real) password identifier resolved from an encrypted |
79 | | * identifier blob; NULL for plaintext identifiers. Owned by pasn_data |
80 | | * and freed by pasn_data_deinit(). */ |
81 | | u8 *dec_pw_id; |
82 | | size_t dec_pw_id_len; |
83 | | |
84 | | /* |
85 | | * Extra elements to add into Authentication frames. These can be used, |
86 | | * e.g., for Wi-Fi Aware use cases. |
87 | | */ |
88 | | const u8 *extra_ies; |
89 | | size_t extra_ies_len; |
90 | | |
91 | | /* Security Profile element to include in PASN Auth frame 1 only. */ |
92 | | struct wpabuf *security_profile; |
93 | | |
94 | | /* External modules do not access below variables */ |
95 | | bool derive_kek; |
96 | | size_t kek_len; |
97 | | u16 group; |
98 | | u16 rejected_groups[MAX_NUM_OF_PASN_GROUPS]; |
99 | | unsigned int rejected_group_idx; |
100 | | u16 ap_supported_groups[MAX_NUM_OF_PASN_GROUPS]; |
101 | | unsigned int ap_supported_group_idx; |
102 | | bool secure_ltf; |
103 | | int freq; |
104 | | |
105 | | u8 trans_seq; |
106 | | u8 status; |
107 | | |
108 | | size_t pmk_len; |
109 | | u8 pmk[PMK_LEN_MAX]; |
110 | | bool using_pmksa; |
111 | | enum rsn_hash_alg hash_alg; |
112 | | |
113 | | struct wpabuf *auth1; |
114 | | |
115 | | struct wpabuf *beacon_rsne_rsnxe; |
116 | | struct wpa_ptk ptk; |
117 | | struct crypto_ecdh *ecdh; |
118 | | |
119 | | struct wpabuf *comeback; |
120 | | u16 comeback_after; |
121 | | |
122 | | #ifdef CONFIG_SAE |
123 | | struct sae_data sae; |
124 | | #endif /* CONFIG_SAE */ |
125 | | |
126 | | #ifdef CONFIG_FILS |
127 | | bool fils_eapol; |
128 | | bool fils_wd_valid; |
129 | | struct pasn_fils fils; |
130 | | #endif /* CONFIG_FILS */ |
131 | | |
132 | | #ifdef CONFIG_IEEE80211R |
133 | | u8 pmk_r1[PMK_LEN_MAX]; |
134 | | size_t pmk_r1_len; |
135 | | u8 pmk_r1_name[WPA_PMK_NAME_LEN]; |
136 | | #endif /* CONFIG_IEEE80211R */ |
137 | | /* Note that this pointers to RSN PMKSA cache are actually defined |
138 | | * differently for the PASN initiator (using RSN Supplicant |
139 | | * implementation) and PASN responser (using RSN Authenticator |
140 | | * implementation). Functions cannot be mixed between those cases. */ |
141 | | struct rsn_pmksa_cache_entry *pmksa_entry; |
142 | | struct eapol_sm *eapol; |
143 | | int fast_reauth; |
144 | | #ifdef CONFIG_TESTING_OPTIONS |
145 | | int corrupt_mic; |
146 | | /* |
147 | | * Override Supported Groups element in the second PASN Authentication |
148 | | * frame for group negotiation testing. |
149 | | */ |
150 | | const int *pasn_test_groups; |
151 | | |
152 | | /* |
153 | | * Number of random PMKIDs to inject into the RSNE when no valid |
154 | | * PMKSA is available. |
155 | | */ |
156 | | unsigned int test_random_pmkid_count; |
157 | | #endif /* CONFIG_TESTING_OPTIONS */ |
158 | | int network_id; |
159 | | void *network_ctx; |
160 | | |
161 | | u8 wrapped_data_format; |
162 | | struct wpabuf *secret; |
163 | | |
164 | | /* Responder */ |
165 | | bool noauth; /* Whether PASN without mutual authentication is enabled */ |
166 | | #ifdef CONFIG_ENC_ASSOC |
167 | | bool eppke_unauth; /* Whether unauthenticated EPPKE is enabled */ |
168 | | #endif /* CONFIG_ENC_ASSOC */ |
169 | | int disable_pmksa_caching; |
170 | | int *pasn_groups; |
171 | | int use_anti_clogging; |
172 | | u8 *rsn_ie; |
173 | | size_t rsn_ie_len; |
174 | | |
175 | | u8 *comeback_key; |
176 | | struct os_reltime last_comeback_key_update; |
177 | | u16 comeback_idx; |
178 | | u16 *comeback_pending_idx; |
179 | | struct wpabuf *frame; |
180 | | #ifdef CONFIG_ENC_ASSOC |
181 | | bool authorized; |
182 | | bool tk_configured; |
183 | | #endif /* CONFIG_ENC_ASSOC */ |
184 | | #ifdef CONFIG_PMKSA_PRIVACY |
185 | | bool pmksa_caching_privacy; |
186 | | u8 epp_pmkid_cur[PMKID_LEN]; |
187 | | #endif /* CONFIG_PMKSA_PRIVACY */ |
188 | | |
189 | | bool sec_prof_enabled; |
190 | | bool sec_prof_used; |
191 | | |
192 | | /** |
193 | | * send_mgmt - Function handler to transmit a Management frame |
194 | | * @ctx: Callback context from cb_ctx |
195 | | * @frame_buf : Frame to transmit |
196 | | * @frame_len: Length of frame to transmit |
197 | | * @freq: Frequency in MHz for the channel on which to transmit |
198 | | * @wait_dur: How many milliseconds to wait for a response frame |
199 | | * Returns: 0 on success, -1 on failure |
200 | | */ |
201 | | int (*send_mgmt)(void *ctx, const u8 *data, size_t data_len, int noack, |
202 | | unsigned int freq, unsigned int wait); |
203 | | /** |
204 | | * validate_custom_pmkid - Handler to validate vendor specific PMKID |
205 | | * @ctx: Callback context from cb_ctx |
206 | | * @addr : MAC address of the peer |
207 | | * @pmkid: Custom PMKID |
208 | | * Returns: 0 on success (valid PMKID), -1 on failure |
209 | | */ |
210 | | int (*validate_custom_pmkid)(void *ctx, const u8 *addr, |
211 | | const u8 *pmkid); |
212 | | |
213 | | int (*prepare_data_element)(void *ctx, const u8 *peer_addr); |
214 | | |
215 | | int (*parse_data_element)(void *ctx, const u8 *data, size_t len); |
216 | | #ifdef CONFIG_ENC_ASSOC |
217 | | int (*eppke_set_key)(void *ctx, enum wpa_alg alg, const u8 *addr, |
218 | | int vlan_id, const u8 *key, size_t key_len); |
219 | | #endif /* CONFIG_ENC_ASSOC */ |
220 | | struct rsn_pmksa_cache_entry * |
221 | | (*pmksa_cache_search)(void *ctx, const u8 *spa, const u8 *pmkid, |
222 | | bool is_ml); |
223 | | #ifdef CONFIG_SAE |
224 | | /** |
225 | | * get_pt_for_pw_id - Look up SAE PT for a given password identifier |
226 | | * @ctx: Callback context from cb_ctx |
227 | | * @pw_id: Password identifier received in the SAE commit frame |
228 | | * @pw_id_len: Length of the password identifier |
229 | | * @group: SAE group being used |
230 | | * @password: Output pointer to the matching password string |
231 | | * @counter: Output counter value from the decrypted identifier blob |
232 | | * (set to 0 for plaintext identifiers) |
233 | | * @dec_pw_id: Output pointer to the decrypted (real) password |
234 | | * identifier for encrypted blobs; set to NULL for plaintext |
235 | | * identifiers. The caller takes ownership and must free with |
236 | | * os_free(). |
237 | | * @dec_pw_id_len: Output length of the decrypted password identifier |
238 | | * Returns: SAE PT on success, NULL if not found |
239 | | * |
240 | | * This callback is invoked by the PASN responder when processing an |
241 | | * SAE commit frame that contains a password identifier, allowing the |
242 | | * AP to look up the correct PT at commit-processing time rather than |
243 | | * at PASN-setup time. |
244 | | */ |
245 | | struct sae_pt * (*get_pt_for_pw_id)(void *ctx, |
246 | | const u8 *pw_id, size_t pw_id_len, |
247 | | int group, |
248 | | const char **password, |
249 | | unsigned int *counter, |
250 | | u8 **dec_pw_id, |
251 | | size_t *dec_pw_id_len); |
252 | | #endif /* CONFIG_SAE */ |
253 | | }; |
254 | | |
255 | | /* Initiator */ |
256 | | void wpa_pasn_reset(struct pasn_data *pasn); |
257 | | int wpas_pasn_start(struct pasn_data *pasn, const u8 *own_addr, |
258 | | const u8 *peer_addr, const u8 *bssid, |
259 | | int akmp, int cipher, u16 group, |
260 | | int freq, const u8 *beacon_rsne, u8 beacon_rsne_len, |
261 | | const u8 *beacon_rsnxe, u8 beacon_rsnxe_len, |
262 | | const struct wpabuf *comeback); |
263 | | struct wpabuf * wpas_pasn_build_auth_1(struct pasn_data *pasn, |
264 | | const struct wpabuf *comeback, |
265 | | bool verify, bool full_hdr); |
266 | | struct wpabuf * wpas_pasn_build_auth_3(struct pasn_data *pasn, bool full_hdr); |
267 | | int wpa_pasn_verify(struct pasn_data *pasn, const u8 *own_addr, |
268 | | const u8 *peer_addr, const u8 *bssid, |
269 | | int akmp, int cipher, u16 group, |
270 | | int freq, const u8 *beacon_rsne, u8 beacon_rsne_len, |
271 | | const u8 *beacon_rsnxe, u8 beacon_rsnxe_len, |
272 | | const struct wpabuf *comeback); |
273 | | int wpa_pasn_auth_rx(struct pasn_data *pasn, const u8 *data, size_t len, |
274 | | struct wpa_pasn_params_data *pasn_params); |
275 | | int wpa_pasn_auth_tx_status(struct pasn_data *pasn, |
276 | | const u8 *data, size_t data_len, u8 acked); |
277 | | int wpas_parse_pasn_frame(struct pasn_data *pasn, u16 auth_type, |
278 | | u16 auth_transaction, u16 status_code, |
279 | | const u8 *frame_data, size_t frame_data_len, |
280 | | struct wpa_pasn_params_data *pasn_params); |
281 | | |
282 | | /* Responder */ |
283 | | int handle_auth_pasn_1(struct pasn_data *pasn, |
284 | | const u8 *own_addr, const u8 *peer_addr, |
285 | | const struct ieee80211_mgmt *mgmt, size_t len, |
286 | | bool reject); |
287 | | int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr, |
288 | | const u8 *peer_addr, |
289 | | const struct ieee80211_mgmt *mgmt, size_t len); |
290 | | int handle_auth_pasn_resp(struct pasn_data *pasn, const u8 *own_addr, |
291 | | const u8 *peer_addr, |
292 | | struct rsn_pmksa_cache_entry *pmksa, u16 status); |
293 | | |
294 | | struct pasn_data * pasn_data_init(void); |
295 | | void pasn_data_deinit(struct pasn_data *pasn); |
296 | | void pasn_register_callbacks(struct pasn_data *pasn, void *cb_ctx, |
297 | | int (*send_mgmt)(void *ctx, const u8 *data, |
298 | | size_t data_len, int noack, |
299 | | unsigned int freq, |
300 | | unsigned int wait), |
301 | | int (*validate_custom_pmkid)(void *ctx, |
302 | | const u8 *addr, |
303 | | const u8 *pmkid), |
304 | | int (*eppke_set_key)(void *ctx, enum wpa_alg alg, |
305 | | const u8 *addr, int vlan_id, |
306 | | const u8 *key, |
307 | | size_t key_len), |
308 | | struct rsn_pmksa_cache_entry * |
309 | | (*pmksa_cache_search)(void *ctx, const u8 *spa, |
310 | | const u8 *pmkid, |
311 | | bool is_ml)); |
312 | | |
313 | | void pasn_enable_kdk_derivation(struct pasn_data *pasn); |
314 | | void pasn_disable_kdk_derivation(struct pasn_data *pasn); |
315 | | |
316 | | void pasn_set_akmp(struct pasn_data *pasn, int akmp); |
317 | | void pasn_set_cipher(struct pasn_data *pasn, int cipher); |
318 | | void pasn_set_own_addr(struct pasn_data *pasn, const u8 *addr); |
319 | | void pasn_set_own_mld_addr(struct pasn_data *pasn, const u8 *addr); |
320 | | void pasn_set_peer_addr(struct pasn_data *pasn, const u8 *addr); |
321 | | void pasn_set_bssid(struct pasn_data *pasn, const u8 *addr); |
322 | | void pasn_set_initiator_pmksa(struct pasn_data *pasn, |
323 | | struct rsn_pmksa_cache *pmksa); |
324 | | void pasn_set_responder_pmksa(struct pasn_data *pasn, |
325 | | struct rsn_pmksa_cache *pmksa); |
326 | | int pasn_set_pt(struct pasn_data *pasn, struct sae_pt *pt); |
327 | | struct rsn_pmksa_cache * pasn_initiator_pmksa_cache_init(void); |
328 | | void pasn_initiator_pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa); |
329 | | int pasn_initiator_pmksa_cache_add(struct rsn_pmksa_cache *pmksa, |
330 | | const u8 *own_addr, const u8 *bssid, |
331 | | const u8 *pmk, size_t pmk_len, |
332 | | const u8 *pmkid, int akmp); |
333 | | int pasn_initiator_pmksa_cache_get(struct rsn_pmksa_cache *pmksa, |
334 | | const u8 *bssid, u8 *pmkid, u8 *pmk, |
335 | | size_t *pmk_len); |
336 | | void pasn_initiator_pmksa_cache_remove(struct rsn_pmksa_cache *pmksa, |
337 | | const u8 *bssid); |
338 | | void pasn_initiator_pmksa_cache_flush(struct rsn_pmksa_cache *pmksa); |
339 | | |
340 | | /* Responder */ |
341 | | void pasn_set_noauth(struct pasn_data *pasn, bool noauth); |
342 | | void pasn_set_wpa_key_mgmt(struct pasn_data *pasn, int key_mgmt); |
343 | | void pasn_set_rsn_pairwise(struct pasn_data *pasn, int rsn_pairwise); |
344 | | void pasn_set_rsne(struct pasn_data *pasn, const u8 *rsne); |
345 | | void pasn_set_rsnxe_caps(struct pasn_data *pasn, u64 rsnxe_capab); |
346 | | void pasn_set_rsnxe_ie(struct pasn_data *pasn, const u8 *rsnxe_ie); |
347 | | void pasn_set_custom_pmkid(struct pasn_data *pasn, const u8 *pmkid); |
348 | | int pasn_set_extra_ies(struct pasn_data *pasn, const u8 *extra_ies, |
349 | | size_t extra_ies_len); |
350 | | int pasn_set_security_profile(struct pasn_data *pasn, const u8 *sp, |
351 | | size_t sp_len); |
352 | | void pasn_set_mfp(struct pasn_data *pasn, enum mfp_options mfp); |
353 | | |
354 | | struct rsn_pmksa_cache * pasn_responder_pmksa_cache_init(void); |
355 | | void pasn_responder_pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa); |
356 | | int pasn_responder_pmksa_cache_add(struct rsn_pmksa_cache *pmksa, |
357 | | const u8 *own_addr, const u8 *bssid, |
358 | | const u8 *pmk, size_t pmk_len, |
359 | | const u8 *pmkid, int akmp); |
360 | | int pasn_responder_pmksa_cache_get(struct rsn_pmksa_cache *pmksa, |
361 | | const u8 *bssid, u8 *pmkid, u8 *pmk, |
362 | | size_t *pmk_len); |
363 | | void pasn_responder_pmksa_cache_remove(struct rsn_pmksa_cache *pmksa, |
364 | | const u8 *bssid); |
365 | | void pasn_responder_pmksa_cache_flush(struct rsn_pmksa_cache *pmksa); |
366 | | |
367 | | int pasn_get_akmp(struct pasn_data *pasn); |
368 | | int pasn_get_cipher(struct pasn_data *pasn); |
369 | | size_t pasn_get_pmk_len(struct pasn_data *pasn); |
370 | | u8 * pasn_get_pmk(struct pasn_data *pasn); |
371 | | struct wpa_ptk * pasn_get_ptk(struct pasn_data *pasn); |
372 | | int pasn_add_encrypted_data(struct pasn_data *pasn, struct wpabuf *buf, |
373 | | const u8 *data, size_t data_len); |
374 | | int pasn_parse_encrypted_data(struct pasn_data *pasn, const u8 *data, |
375 | | size_t len); |
376 | | |
377 | | static inline unsigned int pasn_get_test_random_pmkid(struct pasn_data *pasn) |
378 | 0 | { |
379 | 0 | #ifdef CONFIG_TESTING_OPTIONS |
380 | 0 | return pasn ? pasn->test_random_pmkid_count : 0; |
381 | 0 | #else /* CONFIG_TESTING_OPTIONS */ |
382 | 0 | return 0; |
383 | 0 | #endif /* CONFIG_TESTING_OPTIONS */ |
384 | 0 | } Unexecuted instantiation: pasn_common.c:pasn_get_test_random_pmkid Unexecuted instantiation: pasn_responder.c:pasn_get_test_random_pmkid Unexecuted instantiation: pasn-resp.c:pasn_get_test_random_pmkid |
385 | | |
386 | | #ifdef __cplusplus |
387 | | } |
388 | | #endif |
389 | | #endif /* PASN_COMMON_H */ |