Branch data Line data Source code
1 : : /*
2 : : * WPA Supplicant - WPA state machine and EAPOL-Key processing
3 : : * Copyright (c) 2003-2012, 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 : : #include "includes.h"
10 : :
11 : : #include "common.h"
12 : : #include "crypto/aes_wrap.h"
13 : : #include "crypto/crypto.h"
14 : : #include "crypto/random.h"
15 : : #include "common/ieee802_11_defs.h"
16 : : #include "eapol_supp/eapol_supp_sm.h"
17 : : #include "wpa.h"
18 : : #include "eloop.h"
19 : : #include "preauth.h"
20 : : #include "pmksa_cache.h"
21 : : #include "wpa_i.h"
22 : : #include "wpa_ie.h"
23 : : #include "peerkey.h"
24 : :
25 : :
26 : : /**
27 : : * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message
28 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
29 : : * @kck: Key Confirmation Key (KCK, part of PTK)
30 : : * @ver: Version field from Key Info
31 : : * @dest: Destination address for the frame
32 : : * @proto: Ethertype (usually ETH_P_EAPOL)
33 : : * @msg: EAPOL-Key message
34 : : * @msg_len: Length of message
35 : : * @key_mic: Pointer to the buffer to which the EAPOL-Key MIC is written
36 : : */
37 : 477 : void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck,
38 : : int ver, const u8 *dest, u16 proto,
39 : : u8 *msg, size_t msg_len, u8 *key_mic)
40 : : {
41 [ - + ][ # # ]: 477 : if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
42 : : /*
43 : : * Association event was not yet received; try to fetch
44 : : * BSSID from the driver.
45 : : */
46 [ # # ]: 0 : if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
47 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
48 : : "WPA: Failed to read BSSID for "
49 : : "EAPOL-Key destination address");
50 : : } else {
51 : 0 : dest = sm->bssid;
52 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
53 : : "WPA: Use BSSID (" MACSTR
54 : : ") as the destination for EAPOL-Key",
55 : : MAC2STR(dest));
56 : : }
57 : : }
58 [ + + - + ]: 953 : if (key_mic &&
59 : 476 : wpa_eapol_key_mic(kck, ver, msg, msg_len, key_mic)) {
60 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
61 : : "WPA: Failed to generate EAPOL-Key "
62 : : "version %d MIC", ver);
63 : 0 : goto out;
64 : : }
65 : 477 : wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", kck, 16);
66 : 477 : wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC", key_mic, 16);
67 : 477 : wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
68 : 477 : wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
69 : 477 : eapol_sm_notify_tx_eapol_key(sm->eapol);
70 : : out:
71 : 477 : os_free(msg);
72 : 477 : }
73 : :
74 : :
75 : : /**
76 : : * wpa_sm_key_request - Send EAPOL-Key Request
77 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
78 : : * @error: Indicate whether this is an Michael MIC error report
79 : : * @pairwise: 1 = error report for pairwise packet, 0 = for group packet
80 : : *
81 : : * Send an EAPOL-Key Request to the current authenticator. This function is
82 : : * used to request rekeying and it is usually called when a local Michael MIC
83 : : * failure is detected.
84 : : */
85 : 0 : void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
86 : : {
87 : : size_t rlen;
88 : : struct wpa_eapol_key *reply;
89 : : int key_info, ver;
90 : : u8 bssid[ETH_ALEN], *rbuf;
91 : :
92 [ # # ][ # # ]: 0 : if (wpa_key_mgmt_ft(sm->key_mgmt) || wpa_key_mgmt_sha256(sm->key_mgmt))
93 : 0 : ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
94 [ # # ]: 0 : else if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
95 : 0 : ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
96 : : else
97 : 0 : ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
98 : :
99 [ # # ]: 0 : if (wpa_sm_get_bssid(sm, bssid) < 0) {
100 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
101 : : "Failed to read BSSID for EAPOL-Key request");
102 : 0 : return;
103 : : }
104 : :
105 : 0 : rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
106 : : sizeof(*reply), &rlen, (void *) &reply);
107 [ # # ]: 0 : if (rbuf == NULL)
108 : 0 : return;
109 : :
110 [ # # ]: 0 : reply->type = sm->proto == WPA_PROTO_RSN ?
111 : : EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
112 : 0 : key_info = WPA_KEY_INFO_REQUEST | ver;
113 [ # # ]: 0 : if (sm->ptk_set)
114 : 0 : key_info |= WPA_KEY_INFO_MIC;
115 [ # # ]: 0 : if (error)
116 : 0 : key_info |= WPA_KEY_INFO_ERROR;
117 [ # # ]: 0 : if (pairwise)
118 : 0 : key_info |= WPA_KEY_INFO_KEY_TYPE;
119 : 0 : WPA_PUT_BE16(reply->key_info, key_info);
120 : 0 : WPA_PUT_BE16(reply->key_length, 0);
121 : 0 : os_memcpy(reply->replay_counter, sm->request_counter,
122 : : WPA_REPLAY_COUNTER_LEN);
123 : 0 : inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
124 : :
125 : 0 : WPA_PUT_BE16(reply->key_data_length, 0);
126 : :
127 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
128 : : "WPA: Sending EAPOL-Key Request (error=%d "
129 : : "pairwise=%d ptk_set=%d len=%lu)",
130 : : error, pairwise, sm->ptk_set, (unsigned long) rlen);
131 [ # # ]: 0 : wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
132 : 0 : rbuf, rlen, key_info & WPA_KEY_INFO_MIC ?
133 : 0 : reply->key_mic : NULL);
134 : : }
135 : :
136 : :
137 : 242 : static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
138 : : const unsigned char *src_addr,
139 : : const u8 *pmkid)
140 : : {
141 : 242 : int abort_cached = 0;
142 : :
143 [ + + ][ + + ]: 242 : if (pmkid && !sm->cur_pmksa) {
144 : : /* When using drivers that generate RSN IE, wpa_supplicant may
145 : : * not have enough time to get the association information
146 : : * event before receiving this 1/4 message, so try to find a
147 : : * matching PMKSA cache entry here. */
148 : 69 : sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
149 : : NULL);
150 [ - + ]: 69 : if (sm->cur_pmksa) {
151 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
152 : : "RSN: found matching PMKID from PMKSA cache");
153 : : } else {
154 : 69 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
155 : : "RSN: no matching PMKID found");
156 : 69 : abort_cached = 1;
157 : : }
158 : : }
159 : :
160 [ + + ][ + + ]: 242 : if (pmkid && sm->cur_pmksa &&
[ + - ]
161 : 1 : os_memcmp(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
162 : 1 : wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
163 : 1 : wpa_sm_set_pmk_from_pmksa(sm);
164 : 1 : wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
165 : 1 : sm->pmk, sm->pmk_len);
166 : 1 : eapol_sm_notify_cached(sm->eapol);
167 : : #ifdef CONFIG_IEEE80211R
168 : 1 : sm->xxkey_len = 0;
169 : : #endif /* CONFIG_IEEE80211R */
170 [ + + ][ + - ]: 241 : } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
171 : : int res, pmk_len;
172 : 71 : pmk_len = PMK_LEN;
173 : 71 : res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);
174 [ - + ]: 71 : if (res) {
175 : : /*
176 : : * EAP-LEAP is an exception from other EAP methods: it
177 : : * uses only 16-byte PMK.
178 : : */
179 : 0 : res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
180 : 0 : pmk_len = 16;
181 : : } else {
182 : : #ifdef CONFIG_IEEE80211R
183 : : u8 buf[2 * PMK_LEN];
184 [ + - ]: 71 : if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
185 : : {
186 : 71 : os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
187 : 71 : sm->xxkey_len = PMK_LEN;
188 : 71 : os_memset(buf, 0, sizeof(buf));
189 : : }
190 : : #endif /* CONFIG_IEEE80211R */
191 : : }
192 [ + - ]: 71 : if (res == 0) {
193 : 71 : struct rsn_pmksa_cache_entry *sa = NULL;
194 : 71 : wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
195 : 71 : "machines", sm->pmk, pmk_len);
196 : 71 : sm->pmk_len = pmk_len;
197 [ + + + + ]: 140 : if (sm->proto == WPA_PROTO_RSN &&
198 : 69 : !wpa_key_mgmt_ft(sm->key_mgmt)) {
199 : 68 : sa = pmksa_cache_add(sm->pmksa,
200 : 68 : sm->pmk, pmk_len,
201 : 68 : src_addr, sm->own_addr,
202 : : sm->network_ctx,
203 : 68 : sm->key_mgmt);
204 : : }
205 [ + - ]: 140 : if (!sm->cur_pmksa && pmkid &&
[ + + + + ]
206 : 69 : pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
207 : : {
208 : 68 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
209 : : "RSN: the new PMK matches with the "
210 : : "PMKID");
211 : 68 : abort_cached = 0;
212 : : }
213 : :
214 [ + - ]: 71 : if (!sm->cur_pmksa)
215 : 71 : sm->cur_pmksa = sa;
216 : : } else {
217 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
218 : : "WPA: Failed to get master session key from "
219 : : "EAPOL state machines - key handshake "
220 : : "aborted");
221 [ # # ]: 0 : if (sm->cur_pmksa) {
222 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
223 : : "RSN: Cancelled PMKSA caching "
224 : : "attempt");
225 : 0 : sm->cur_pmksa = NULL;
226 : 0 : abort_cached = 1;
227 [ # # ]: 0 : } else if (!abort_cached) {
228 : 0 : return -1;
229 : : }
230 : : }
231 : : }
232 : :
233 [ + + ]: 243 : if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) &&
[ + - - + ]
234 : 1 : !wpa_key_mgmt_ft(sm->key_mgmt)) {
235 : : /* Send EAPOL-Start to trigger full EAP authentication. */
236 : : u8 *buf;
237 : : size_t buflen;
238 : :
239 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
240 : : "RSN: no PMKSA entry found - trigger "
241 : : "full EAP authentication");
242 : 0 : buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
243 : : NULL, 0, &buflen, NULL);
244 [ # # ]: 0 : if (buf) {
245 : 0 : wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
246 : : buf, buflen);
247 : 0 : os_free(buf);
248 : 0 : return -2;
249 : : }
250 : :
251 : 0 : return -1;
252 : : }
253 : :
254 : 242 : return 0;
255 : : }
256 : :
257 : :
258 : : /**
259 : : * wpa_supplicant_send_2_of_4 - Send message 2 of WPA/RSN 4-Way Handshake
260 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
261 : : * @dst: Destination address for the frame
262 : : * @key: Pointer to the EAPOL-Key frame header
263 : : * @ver: Version bits from EAPOL-Key Key Info
264 : : * @nonce: Nonce value for the EAPOL-Key frame
265 : : * @wpa_ie: WPA/RSN IE
266 : : * @wpa_ie_len: Length of the WPA/RSN IE
267 : : * @ptk: PTK to use for keyed hash and encryption
268 : : * Returns: 0 on success, -1 on failure
269 : : */
270 : 243 : int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
271 : : const struct wpa_eapol_key *key,
272 : : int ver, const u8 *nonce,
273 : : const u8 *wpa_ie, size_t wpa_ie_len,
274 : : struct wpa_ptk *ptk)
275 : : {
276 : : size_t rlen;
277 : : struct wpa_eapol_key *reply;
278 : : u8 *rbuf;
279 : 243 : u8 *rsn_ie_buf = NULL;
280 : :
281 [ - + ]: 243 : if (wpa_ie == NULL) {
282 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No wpa_ie set - "
283 : : "cannot generate msg 2/4");
284 : 0 : return -1;
285 : : }
286 : :
287 : : #ifdef CONFIG_IEEE80211R
288 [ + + ]: 243 : if (wpa_key_mgmt_ft(sm->key_mgmt)) {
289 : : int res;
290 : :
291 : : /*
292 : : * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
293 : : * FTIE from (Re)Association Response.
294 : : */
295 : 8 : rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
296 : 8 : sm->assoc_resp_ies_len);
297 [ - + ]: 8 : if (rsn_ie_buf == NULL)
298 : 0 : return -1;
299 : 8 : os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
300 : 8 : res = wpa_insert_pmkid(rsn_ie_buf, wpa_ie_len,
301 : 8 : sm->pmk_r1_name);
302 [ - + ]: 8 : if (res < 0) {
303 : 0 : os_free(rsn_ie_buf);
304 : 0 : return -1;
305 : : }
306 : 8 : wpa_ie_len += res;
307 : :
308 [ + - ]: 8 : if (sm->assoc_resp_ies) {
309 : 8 : os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
310 : : sm->assoc_resp_ies_len);
311 : 8 : wpa_ie_len += sm->assoc_resp_ies_len;
312 : : }
313 : :
314 : 8 : wpa_ie = rsn_ie_buf;
315 : : }
316 : : #endif /* CONFIG_IEEE80211R */
317 : :
318 : 243 : wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
319 : :
320 : 243 : rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
321 : : NULL, sizeof(*reply) + wpa_ie_len,
322 : : &rlen, (void *) &reply);
323 [ - + ]: 243 : if (rbuf == NULL) {
324 : 0 : os_free(rsn_ie_buf);
325 : 0 : return -1;
326 : : }
327 : :
328 [ + + ]: 243 : reply->type = sm->proto == WPA_PROTO_RSN ?
329 : : EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
330 : 243 : WPA_PUT_BE16(reply->key_info,
331 : : ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
332 [ + + ]: 243 : if (sm->proto == WPA_PROTO_RSN)
333 : 237 : WPA_PUT_BE16(reply->key_length, 0);
334 : : else
335 : 6 : os_memcpy(reply->key_length, key->key_length, 2);
336 : 243 : os_memcpy(reply->replay_counter, key->replay_counter,
337 : : WPA_REPLAY_COUNTER_LEN);
338 : 243 : wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
339 : : WPA_REPLAY_COUNTER_LEN);
340 : :
341 : 243 : WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
342 : 243 : os_memcpy(reply + 1, wpa_ie, wpa_ie_len);
343 : 243 : os_free(rsn_ie_buf);
344 : :
345 : 243 : os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
346 : :
347 : 243 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
348 : 243 : wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,
349 : 243 : rbuf, rlen, reply->key_mic);
350 : :
351 : 243 : return 0;
352 : : }
353 : :
354 : :
355 : 242 : static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
356 : : const struct wpa_eapol_key *key,
357 : : struct wpa_ptk *ptk)
358 : : {
359 [ + + ]: 242 : size_t ptk_len = sm->pairwise_cipher != WPA_CIPHER_TKIP ? 48 : 64;
360 : : #ifdef CONFIG_IEEE80211R
361 [ + + ]: 242 : if (wpa_key_mgmt_ft(sm->key_mgmt))
362 : 8 : return wpa_derive_ptk_ft(sm, src_addr, key, ptk, ptk_len);
363 : : #endif /* CONFIG_IEEE80211R */
364 : :
365 : 234 : wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
366 : 234 : sm->own_addr, sm->bssid, sm->snonce, key->key_nonce,
367 : : (u8 *) ptk, ptk_len,
368 : 234 : wpa_key_mgmt_sha256(sm->key_mgmt));
369 : 242 : return 0;
370 : : }
371 : :
372 : :
373 : 242 : static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
374 : : const unsigned char *src_addr,
375 : : const struct wpa_eapol_key *key,
376 : : u16 ver)
377 : : {
378 : : struct wpa_eapol_ie_parse ie;
379 : : struct wpa_ptk *ptk;
380 : : u8 buf[8];
381 : : int res;
382 : :
383 [ - + ]: 242 : if (wpa_sm_get_network_ctx(sm) == NULL) {
384 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
385 : : "found (msg 1 of 4)");
386 : 0 : return;
387 : : }
388 : :
389 : 242 : wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
390 : 242 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
391 : : "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
392 : :
393 : 242 : os_memset(&ie, 0, sizeof(ie));
394 : :
395 [ + + ]: 242 : if (sm->proto == WPA_PROTO_RSN) {
396 : : /* RSN: msg 1/4 should contain PMKID for the selected PMK */
397 : 236 : const u8 *_buf = (const u8 *) (key + 1);
398 : 236 : size_t len = WPA_GET_BE16(key->key_data_length);
399 : 236 : wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", _buf, len);
400 [ - + ]: 236 : if (wpa_supplicant_parse_ies(_buf, len, &ie) < 0)
401 : 0 : goto failed;
402 [ + + ]: 236 : if (ie.pmkid) {
403 : 70 : wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
404 : 70 : "Authenticator", ie.pmkid, PMKID_LEN);
405 : : }
406 : : }
407 : :
408 : 242 : res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
409 [ - + ]: 242 : if (res == -2) {
410 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
411 : : "msg 1/4 - requesting full EAP authentication");
412 : 0 : return;
413 : : }
414 [ - + ]: 242 : if (res)
415 : 0 : goto failed;
416 : :
417 [ + + ]: 242 : if (sm->renew_snonce) {
418 [ - + ]: 227 : if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
419 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
420 : : "WPA: Failed to get random data for SNonce");
421 : 0 : goto failed;
422 : : }
423 : 227 : sm->renew_snonce = 0;
424 : 227 : wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
425 : 227 : sm->snonce, WPA_NONCE_LEN);
426 : : }
427 : :
428 : : /* Calculate PTK which will be stored as a temporary PTK until it has
429 : : * been verified when processing message 3/4. */
430 : 242 : ptk = &sm->tptk;
431 : 242 : wpa_derive_ptk(sm, src_addr, key, ptk);
432 : : /* Supplicant: swap tx/rx Mic keys */
433 : 242 : os_memcpy(buf, ptk->u.auth.tx_mic_key, 8);
434 : 242 : os_memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
435 : 242 : os_memcpy(ptk->u.auth.rx_mic_key, buf, 8);
436 : 242 : sm->tptk_set = 1;
437 : :
438 [ - + ]: 242 : if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
439 : 242 : sm->assoc_wpa_ie, sm->assoc_wpa_ie_len,
440 : : ptk))
441 : 0 : goto failed;
442 : :
443 : 242 : os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
444 : 242 : return;
445 : :
446 : : failed:
447 : 242 : wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
448 : : }
449 : :
450 : :
451 : 227 : static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
452 : : {
453 : 227 : struct wpa_sm *sm = eloop_ctx;
454 : 227 : rsn_preauth_candidate_process(sm);
455 : 227 : }
456 : :
457 : :
458 : 236 : static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
459 : : const u8 *addr, int secure)
460 : : {
461 : 236 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
462 : : "WPA: Key negotiation completed with "
463 : 1416 : MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
464 : 236 : wpa_cipher_txt(sm->pairwise_cipher),
465 : 236 : wpa_cipher_txt(sm->group_cipher));
466 : 236 : wpa_sm_cancel_auth_timeout(sm);
467 : 236 : wpa_sm_set_state(sm, WPA_COMPLETED);
468 : :
469 [ + - ]: 236 : if (secure) {
470 : 236 : wpa_sm_mlme_setprotection(
471 : : sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
472 : : MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
473 : 236 : eapol_sm_notify_portValid(sm->eapol, TRUE);
474 [ + + ]: 236 : if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
475 : 162 : eapol_sm_notify_eap_success(sm->eapol, TRUE);
476 : : /*
477 : : * Start preauthentication after a short wait to avoid a
478 : : * possible race condition between the data receive and key
479 : : * configuration after the 4-Way Handshake. This increases the
480 : : * likelihood of the first preauth EAPOL-Start frame getting to
481 : : * the target AP.
482 : : */
483 : 236 : eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
484 : : }
485 : :
486 [ + + ][ - + ]: 236 : if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {
487 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
488 : : "RSN: Authenticator accepted "
489 : : "opportunistic PMKSA entry - marking it valid");
490 : 0 : sm->cur_pmksa->opportunistic = 0;
491 : : }
492 : :
493 : : #ifdef CONFIG_IEEE80211R
494 [ + + ]: 236 : if (wpa_key_mgmt_ft(sm->key_mgmt)) {
495 : : /* Prepare for the next transition */
496 : 22 : wpa_ft_prepare_auth_request(sm, NULL);
497 : : }
498 : : #endif /* CONFIG_IEEE80211R */
499 : 236 : }
500 : :
501 : :
502 : 0 : static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
503 : : {
504 : 0 : struct wpa_sm *sm = eloop_ctx;
505 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Request PTK rekeying");
506 : 0 : wpa_sm_key_request(sm, 0, 1);
507 : 0 : }
508 : :
509 : :
510 : 222 : static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
511 : : const struct wpa_eapol_key *key)
512 : : {
513 : : int keylen, rsclen;
514 : : enum wpa_alg alg;
515 : : const u8 *key_rsc;
516 : 222 : u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
517 : :
518 : 222 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
519 : : "WPA: Installing PTK to the driver");
520 : :
521 [ - + ]: 222 : if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
522 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Pairwise Cipher "
523 : : "Suite: NONE - do not use pairwise keys");
524 : 0 : return 0;
525 : : }
526 : :
527 [ - + ]: 222 : if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
528 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
529 : : "WPA: Unsupported pairwise cipher %d",
530 : : sm->pairwise_cipher);
531 : 0 : return -1;
532 : : }
533 : :
534 : 222 : alg = wpa_cipher_to_alg(sm->pairwise_cipher);
535 : 222 : keylen = wpa_cipher_key_len(sm->pairwise_cipher);
536 : 222 : rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
537 : :
538 [ + + ]: 222 : if (sm->proto == WPA_PROTO_RSN) {
539 : 216 : key_rsc = null_rsc;
540 : : } else {
541 : 6 : key_rsc = key->key_rsc;
542 : 6 : wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
543 : : }
544 : :
545 [ - + ]: 222 : if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
546 : 222 : (u8 *) sm->ptk.tk1, keylen) < 0) {
547 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
548 : : "WPA: Failed to set PTK to the "
549 : : "driver (alg=%d keylen=%d bssid=" MACSTR ")",
550 : 0 : alg, keylen, MAC2STR(sm->bssid));
551 : 0 : return -1;
552 : : }
553 : :
554 [ - + ]: 222 : if (sm->wpa_ptk_rekey) {
555 : 0 : eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
556 : 0 : eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
557 : : sm, NULL);
558 : : }
559 : :
560 : 222 : return 0;
561 : : }
562 : :
563 : :
564 : 223 : static int wpa_supplicant_check_group_cipher(struct wpa_sm *sm,
565 : : int group_cipher,
566 : : int keylen, int maxkeylen,
567 : : int *key_rsc_len,
568 : : enum wpa_alg *alg)
569 : : {
570 : : int klen;
571 : :
572 : 223 : *alg = wpa_cipher_to_alg(group_cipher);
573 [ - + ]: 223 : if (*alg == WPA_ALG_NONE) {
574 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
575 : : "WPA: Unsupported Group Cipher %d",
576 : : group_cipher);
577 : 0 : return -1;
578 : : }
579 : 223 : *key_rsc_len = wpa_cipher_rsc_len(group_cipher);
580 : :
581 : 223 : klen = wpa_cipher_key_len(group_cipher);
582 [ + - ][ - + ]: 223 : if (keylen != klen || maxkeylen < klen) {
583 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
584 : : "WPA: Unsupported %s Group Cipher key length %d (%d)",
585 : : wpa_cipher_txt(group_cipher), keylen, maxkeylen);
586 : 0 : return -1;
587 : : }
588 : 223 : return 0;
589 : : }
590 : :
591 : :
592 : : struct wpa_gtk_data {
593 : : enum wpa_alg alg;
594 : : int tx, key_rsc_len, keyidx;
595 : : u8 gtk[32];
596 : : int gtk_len;
597 : : };
598 : :
599 : :
600 : 224 : static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
601 : : const struct wpa_gtk_data *gd,
602 : : const u8 *key_rsc)
603 : : {
604 : 224 : const u8 *_gtk = gd->gtk;
605 : : u8 gtk_buf[32];
606 : :
607 : 224 : wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
608 : 224 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
609 : : "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
610 : : gd->keyidx, gd->tx, gd->gtk_len);
611 : 224 : wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
612 [ + + ]: 224 : if (sm->group_cipher == WPA_CIPHER_TKIP) {
613 : : /* Swap Tx/Rx keys for Michael MIC */
614 : 13 : os_memcpy(gtk_buf, gd->gtk, 16);
615 : 13 : os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
616 : 13 : os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
617 : 13 : _gtk = gtk_buf;
618 : : }
619 [ - + ]: 224 : if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
620 [ # # ]: 0 : if (wpa_sm_set_key(sm, gd->alg, NULL,
621 : 0 : gd->keyidx, 1, key_rsc, gd->key_rsc_len,
622 : 0 : _gtk, gd->gtk_len) < 0) {
623 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
624 : : "WPA: Failed to set GTK to the driver "
625 : : "(Group only)");
626 : 0 : return -1;
627 : : }
628 [ - + ]: 224 : } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
629 : 224 : gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
630 : 224 : _gtk, gd->gtk_len) < 0) {
631 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
632 : : "WPA: Failed to set GTK to "
633 : : "the driver (alg=%d keylen=%d keyidx=%d)",
634 : 0 : gd->alg, gd->gtk_len, gd->keyidx);
635 : 0 : return -1;
636 : : }
637 : :
638 : 224 : return 0;
639 : : }
640 : :
641 : :
642 : 224 : static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
643 : : int tx)
644 : : {
645 [ - + ][ # # ]: 224 : if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
646 : : /* Ignore Tx bit for GTK if a pairwise key is used. One AP
647 : : * seemed to set this bit (incorrectly, since Tx is only when
648 : : * doing Group Key only APs) and without this workaround, the
649 : : * data connection does not work because wpa_supplicant
650 : : * configured non-zero keyidx to be used for unicast. */
651 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
652 : : "WPA: Tx bit set for GTK, but pairwise "
653 : : "keys are used - ignore Tx bit");
654 : 0 : return 0;
655 : : }
656 : 224 : return tx;
657 : : }
658 : :
659 : :
660 : 216 : static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
661 : : const struct wpa_eapol_key *key,
662 : : const u8 *gtk, size_t gtk_len,
663 : : int key_info)
664 : : {
665 : : struct wpa_gtk_data gd;
666 : :
667 : : /*
668 : : * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
669 : : * GTK KDE format:
670 : : * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]
671 : : * Reserved [bits 0-7]
672 : : * GTK
673 : : */
674 : :
675 : 216 : os_memset(&gd, 0, sizeof(gd));
676 : 216 : wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
677 : : gtk, gtk_len);
678 : :
679 [ + - ][ - + ]: 216 : if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
680 : 0 : return -1;
681 : :
682 : 216 : gd.keyidx = gtk[0] & 0x3;
683 : 216 : gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
684 : 216 : !!(gtk[0] & BIT(2)));
685 : 216 : gtk += 2;
686 : 216 : gtk_len -= 2;
687 : :
688 : 216 : os_memcpy(gd.gtk, gtk, gtk_len);
689 : 216 : gd.gtk_len = gtk_len;
690 : :
691 [ + - + - ]: 432 : if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED &&
692 : 216 : (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
693 : : gtk_len, gtk_len,
694 [ - + ]: 216 : &gd.key_rsc_len, &gd.alg) ||
695 : 216 : wpa_supplicant_install_gtk(sm, &gd, key->key_rsc))) {
696 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
697 : : "RSN: Failed to install GTK");
698 : 0 : return -1;
699 : : }
700 : :
701 : 216 : wpa_supplicant_key_neg_complete(sm, sm->bssid,
702 : : key_info & WPA_KEY_INFO_SECURE);
703 : 216 : return 0;
704 : : }
705 : :
706 : :
707 : 223 : static int ieee80211w_set_keys(struct wpa_sm *sm,
708 : : struct wpa_eapol_ie_parse *ie)
709 : : {
710 : : #ifdef CONFIG_IEEE80211W
711 [ + + ]: 223 : if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)
712 : 211 : return 0;
713 : :
714 [ + - ]: 12 : if (ie->igtk) {
715 : : const struct wpa_igtk_kde *igtk;
716 : : u16 keyidx;
717 [ - + ]: 12 : if (ie->igtk_len != sizeof(*igtk))
718 : 0 : return -1;
719 : 12 : igtk = (const struct wpa_igtk_kde *) ie->igtk;
720 : 12 : keyidx = WPA_GET_LE16(igtk->keyid);
721 : 12 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d "
722 : : "pn %02x%02x%02x%02x%02x%02x",
723 : : keyidx, MAC2STR(igtk->pn));
724 : 12 : wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
725 : 12 : igtk->igtk, WPA_IGTK_LEN);
726 [ - + ]: 12 : if (keyidx > 4095) {
727 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
728 : : "WPA: Invalid IGTK KeyID %d", keyidx);
729 : 0 : return -1;
730 : : }
731 [ - + ]: 12 : if (wpa_sm_set_key(sm, WPA_ALG_IGTK, broadcast_ether_addr,
732 : 12 : keyidx, 0, igtk->pn, sizeof(igtk->pn),
733 : 12 : igtk->igtk, WPA_IGTK_LEN) < 0) {
734 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
735 : : "WPA: Failed to configure IGTK to the driver");
736 : 0 : return -1;
737 : : }
738 : : }
739 : :
740 : 223 : return 0;
741 : : #else /* CONFIG_IEEE80211W */
742 : : return 0;
743 : : #endif /* CONFIG_IEEE80211W */
744 : : }
745 : :
746 : :
747 : 0 : static void wpa_report_ie_mismatch(struct wpa_sm *sm,
748 : : const char *reason, const u8 *src_addr,
749 : : const u8 *wpa_ie, size_t wpa_ie_len,
750 : : const u8 *rsn_ie, size_t rsn_ie_len)
751 : : {
752 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",
753 : 0 : reason, MAC2STR(src_addr));
754 : :
755 [ # # ]: 0 : if (sm->ap_wpa_ie) {
756 : 0 : wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
757 : 0 : sm->ap_wpa_ie, sm->ap_wpa_ie_len);
758 : : }
759 [ # # ]: 0 : if (wpa_ie) {
760 [ # # ]: 0 : if (!sm->ap_wpa_ie) {
761 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
762 : : "WPA: No WPA IE in Beacon/ProbeResp");
763 : : }
764 : 0 : wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
765 : : wpa_ie, wpa_ie_len);
766 : : }
767 : :
768 [ # # ]: 0 : if (sm->ap_rsn_ie) {
769 : 0 : wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
770 : 0 : sm->ap_rsn_ie, sm->ap_rsn_ie_len);
771 : : }
772 [ # # ]: 0 : if (rsn_ie) {
773 [ # # ]: 0 : if (!sm->ap_rsn_ie) {
774 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
775 : : "WPA: No RSN IE in Beacon/ProbeResp");
776 : : }
777 : 0 : wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
778 : : rsn_ie, rsn_ie_len);
779 : : }
780 : :
781 : 0 : wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
782 : 0 : }
783 : :
784 : :
785 : : #ifdef CONFIG_IEEE80211R
786 : :
787 : 8 : static int ft_validate_mdie(struct wpa_sm *sm,
788 : : const unsigned char *src_addr,
789 : : struct wpa_eapol_ie_parse *ie,
790 : : const u8 *assoc_resp_mdie)
791 : : {
792 : : struct rsn_mdie *mdie;
793 : :
794 : 8 : mdie = (struct rsn_mdie *) (ie->mdie + 2);
795 [ + - ][ + - ]: 8 : if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
[ - + ]
796 : 8 : os_memcmp(mdie->mobility_domain, sm->mobility_domain,
797 : : MOBILITY_DOMAIN_ID_LEN) != 0) {
798 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did "
799 : : "not match with the current mobility domain");
800 : 0 : return -1;
801 : : }
802 : :
803 [ + - ][ + - ]: 8 : if (assoc_resp_mdie &&
804 [ - + ]: 8 : (assoc_resp_mdie[1] != ie->mdie[1] ||
805 : 8 : os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
806 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch");
807 : 0 : wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
808 : 0 : ie->mdie, 2 + ie->mdie[1]);
809 : 0 : wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
810 : 0 : assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
811 : 0 : return -1;
812 : : }
813 : :
814 : 8 : return 0;
815 : : }
816 : :
817 : :
818 : 8 : static int ft_validate_ftie(struct wpa_sm *sm,
819 : : const unsigned char *src_addr,
820 : : struct wpa_eapol_ie_parse *ie,
821 : : const u8 *assoc_resp_ftie)
822 : : {
823 [ - + ]: 8 : if (ie->ftie == NULL) {
824 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
825 : : "FT: No FTIE in EAPOL-Key msg 3/4");
826 : 0 : return -1;
827 : : }
828 : :
829 [ - + ]: 8 : if (assoc_resp_ftie == NULL)
830 : 0 : return 0;
831 : :
832 [ + - ][ - + ]: 8 : if (assoc_resp_ftie[1] != ie->ftie[1] ||
833 : 8 : os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
834 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch");
835 : 0 : wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
836 : 0 : ie->ftie, 2 + ie->ftie[1]);
837 : 0 : wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
838 : 0 : assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
839 : 0 : return -1;
840 : : }
841 : :
842 : 8 : return 0;
843 : : }
844 : :
845 : :
846 : 8 : static int ft_validate_rsnie(struct wpa_sm *sm,
847 : : const unsigned char *src_addr,
848 : : struct wpa_eapol_ie_parse *ie)
849 : : {
850 : : struct wpa_ie_data rsn;
851 : :
852 [ - + ]: 8 : if (!ie->rsn_ie)
853 : 0 : return 0;
854 : :
855 : : /*
856 : : * Verify that PMKR1Name from EAPOL-Key message 3/4
857 : : * matches with the value we derived.
858 : : */
859 [ + - ][ + - ]: 8 : if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
860 [ - + ]: 8 : rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
861 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in "
862 : : "FT 4-way handshake message 3/4");
863 : 0 : return -1;
864 : : }
865 : :
866 [ - + ]: 8 : if (os_memcmp(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0) {
867 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
868 : : "FT: PMKR1Name mismatch in "
869 : : "FT 4-way handshake message 3/4");
870 : 0 : wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
871 : 0 : rsn.pmkid, WPA_PMK_NAME_LEN);
872 : 0 : wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
873 : 0 : sm->pmk_r1_name, WPA_PMK_NAME_LEN);
874 : 0 : return -1;
875 : : }
876 : :
877 : 8 : return 0;
878 : : }
879 : :
880 : :
881 : 8 : static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
882 : : const unsigned char *src_addr,
883 : : struct wpa_eapol_ie_parse *ie)
884 : : {
885 : 8 : const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
886 : :
887 [ + - ]: 8 : if (sm->assoc_resp_ies) {
888 : 8 : pos = sm->assoc_resp_ies;
889 : 8 : end = pos + sm->assoc_resp_ies_len;
890 [ + + ]: 24 : while (pos + 2 < end) {
891 [ - + ]: 16 : if (pos + 2 + pos[1] > end)
892 : 0 : break;
893 [ + + - ]: 16 : switch (*pos) {
894 : : case WLAN_EID_MOBILITY_DOMAIN:
895 : 8 : mdie = pos;
896 : 8 : break;
897 : : case WLAN_EID_FAST_BSS_TRANSITION:
898 : 8 : ftie = pos;
899 : 8 : break;
900 : : }
901 : 16 : pos += 2 + pos[1];
902 : : }
903 : : }
904 : :
905 [ + - + - ]: 16 : if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
906 [ - + ]: 16 : ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
907 : 8 : ft_validate_rsnie(sm, src_addr, ie) < 0)
908 : 0 : return -1;
909 : :
910 : 8 : return 0;
911 : : }
912 : :
913 : : #endif /* CONFIG_IEEE80211R */
914 : :
915 : :
916 : 222 : static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
917 : : const unsigned char *src_addr,
918 : : struct wpa_eapol_ie_parse *ie)
919 : : {
920 [ + + ][ + + ]: 222 : if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {
921 : 6 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
922 : : "WPA: No WPA/RSN IE for this AP known. "
923 : : "Trying to get from scan results");
924 [ - + ]: 6 : if (wpa_sm_get_beacon_ie(sm) < 0) {
925 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
926 : : "WPA: Could not find AP from "
927 : : "the scan results");
928 : : } else {
929 : 6 : wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
930 : : "WPA: Found the current AP from "
931 : : "updated scan results");
932 : : }
933 : : }
934 : :
935 [ + + ][ - + ]: 222 : if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
[ # # ]
936 [ # # ]: 0 : (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
937 : 0 : wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
938 : : "with IE in Beacon/ProbeResp (no IE?)",
939 : : src_addr, ie->wpa_ie, ie->wpa_ie_len,
940 : : ie->rsn_ie, ie->rsn_ie_len);
941 : 0 : return -1;
942 : : }
943 : :
944 [ + + ][ + - ]: 222 : if ((ie->wpa_ie && sm->ap_wpa_ie &&
[ + - ]
945 [ + - ]: 12 : (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
946 [ + + ]: 222 : os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
947 [ + - - + ]: 432 : (ie->rsn_ie && sm->ap_rsn_ie &&
948 : 216 : wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
949 : 216 : sm->ap_rsn_ie, sm->ap_rsn_ie_len,
950 : : ie->rsn_ie, ie->rsn_ie_len))) {
951 : 0 : wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
952 : : "with IE in Beacon/ProbeResp",
953 : : src_addr, ie->wpa_ie, ie->wpa_ie_len,
954 : : ie->rsn_ie, ie->rsn_ie_len);
955 : 0 : return -1;
956 : : }
957 : :
958 [ + + ][ - + ]: 222 : if (sm->proto == WPA_PROTO_WPA &&
959 [ # # ][ # # ]: 0 : ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
960 : 0 : wpa_report_ie_mismatch(sm, "Possible downgrade attack "
961 : : "detected - RSN was enabled and RSN IE "
962 : : "was in msg 3/4, but not in "
963 : : "Beacon/ProbeResp",
964 : : src_addr, ie->wpa_ie, ie->wpa_ie_len,
965 : : ie->rsn_ie, ie->rsn_ie_len);
966 : 0 : return -1;
967 : : }
968 : :
969 : : #ifdef CONFIG_IEEE80211R
970 [ + + - + ]: 230 : if (wpa_key_mgmt_ft(sm->key_mgmt) &&
971 : 8 : wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
972 : 0 : return -1;
973 : : #endif /* CONFIG_IEEE80211R */
974 : :
975 : 222 : return 0;
976 : : }
977 : :
978 : :
979 : : /**
980 : : * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake
981 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
982 : : * @dst: Destination address for the frame
983 : : * @key: Pointer to the EAPOL-Key frame header
984 : : * @ver: Version bits from EAPOL-Key Key Info
985 : : * @key_info: Key Info
986 : : * @kde: KDEs to include the EAPOL-Key frame
987 : : * @kde_len: Length of KDEs
988 : : * @ptk: PTK to use for keyed hash and encryption
989 : : * Returns: 0 on success, -1 on failure
990 : : */
991 : 223 : int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
992 : : const struct wpa_eapol_key *key,
993 : : u16 ver, u16 key_info,
994 : : const u8 *kde, size_t kde_len,
995 : : struct wpa_ptk *ptk)
996 : : {
997 : : size_t rlen;
998 : : struct wpa_eapol_key *reply;
999 : : u8 *rbuf;
1000 : :
1001 [ - + ]: 223 : if (kde)
1002 : 0 : wpa_hexdump(MSG_DEBUG, "WPA: KDE for msg 4/4", kde, kde_len);
1003 : :
1004 : 223 : rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
1005 : : sizeof(*reply) + kde_len,
1006 : : &rlen, (void *) &reply);
1007 [ - + ]: 223 : if (rbuf == NULL)
1008 : 0 : return -1;
1009 : :
1010 [ + + ]: 223 : reply->type = sm->proto == WPA_PROTO_RSN ?
1011 : : EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1012 : 223 : key_info &= WPA_KEY_INFO_SECURE;
1013 : 223 : key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC;
1014 : 223 : WPA_PUT_BE16(reply->key_info, key_info);
1015 [ + + ]: 223 : if (sm->proto == WPA_PROTO_RSN)
1016 : 217 : WPA_PUT_BE16(reply->key_length, 0);
1017 : : else
1018 : 6 : os_memcpy(reply->key_length, key->key_length, 2);
1019 : 223 : os_memcpy(reply->replay_counter, key->replay_counter,
1020 : : WPA_REPLAY_COUNTER_LEN);
1021 : :
1022 : 223 : WPA_PUT_BE16(reply->key_data_length, kde_len);
1023 [ - + ]: 223 : if (kde)
1024 : 0 : os_memcpy(reply + 1, kde, kde_len);
1025 : :
1026 : 223 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
1027 : 223 : wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,
1028 : 223 : rbuf, rlen, reply->key_mic);
1029 : :
1030 : 223 : return 0;
1031 : : }
1032 : :
1033 : :
1034 : 222 : static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
1035 : : const struct wpa_eapol_key *key,
1036 : : u16 ver)
1037 : : {
1038 : : u16 key_info, keylen, len;
1039 : : const u8 *pos;
1040 : : struct wpa_eapol_ie_parse ie;
1041 : :
1042 : 222 : wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
1043 : 222 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 3 of 4-Way "
1044 : : "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
1045 : :
1046 : 222 : key_info = WPA_GET_BE16(key->key_info);
1047 : :
1048 : 222 : pos = (const u8 *) (key + 1);
1049 : 222 : len = WPA_GET_BE16(key->key_data_length);
1050 : 222 : wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", pos, len);
1051 [ - + ]: 222 : if (wpa_supplicant_parse_ies(pos, len, &ie) < 0)
1052 : 0 : goto failed;
1053 [ + + ][ - + ]: 222 : if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1054 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1055 : : "WPA: GTK IE in unencrypted key data");
1056 : 0 : goto failed;
1057 : : }
1058 : : #ifdef CONFIG_IEEE80211W
1059 [ + + ][ - + ]: 222 : if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1060 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1061 : : "WPA: IGTK KDE in unencrypted key data");
1062 : 0 : goto failed;
1063 : : }
1064 : :
1065 [ + + ][ - + ]: 222 : if (ie.igtk && ie.igtk_len != sizeof(struct wpa_igtk_kde)) {
1066 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1067 : : "WPA: Invalid IGTK KDE length %lu",
1068 : : (unsigned long) ie.igtk_len);
1069 : 0 : goto failed;
1070 : : }
1071 : : #endif /* CONFIG_IEEE80211W */
1072 : :
1073 [ - + ]: 222 : if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
1074 : 0 : goto failed;
1075 : :
1076 [ - + ]: 222 : if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
1077 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1078 : : "WPA: ANonce from message 1 of 4-Way Handshake "
1079 : : "differs from 3 of 4-Way Handshake - drop packet (src="
1080 : 0 : MACSTR ")", MAC2STR(sm->bssid));
1081 : 0 : goto failed;
1082 : : }
1083 : :
1084 : 222 : keylen = WPA_GET_BE16(key->key_length);
1085 [ - + ]: 222 : if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) {
1086 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1087 : : "WPA: Invalid %s key length %d (src=" MACSTR
1088 : 0 : ")", wpa_cipher_txt(sm->pairwise_cipher), keylen,
1089 : 0 : MAC2STR(sm->bssid));
1090 : 0 : goto failed;
1091 : : }
1092 : :
1093 [ - + ]: 222 : if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
1094 : : NULL, 0, &sm->ptk)) {
1095 : 0 : goto failed;
1096 : : }
1097 : :
1098 : : /* SNonce was successfully used in msg 3/4, so mark it to be renewed
1099 : : * for the next 4-Way Handshake. If msg 3 is received again, the old
1100 : : * SNonce will still be used to avoid changing PTK. */
1101 : 222 : sm->renew_snonce = 1;
1102 : :
1103 [ + - ]: 222 : if (key_info & WPA_KEY_INFO_INSTALL) {
1104 [ - + ]: 222 : if (wpa_supplicant_install_ptk(sm, key))
1105 : 0 : goto failed;
1106 : : }
1107 : :
1108 [ + + ]: 222 : if (key_info & WPA_KEY_INFO_SECURE) {
1109 : 216 : wpa_sm_mlme_setprotection(
1110 : 216 : sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
1111 : : MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1112 : 216 : eapol_sm_notify_portValid(sm->eapol, TRUE);
1113 : : }
1114 : 222 : wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1115 : :
1116 [ - + ]: 222 : if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) {
1117 : 0 : wpa_supplicant_key_neg_complete(sm, sm->bssid,
1118 : : key_info & WPA_KEY_INFO_SECURE);
1119 [ + + - + ]: 438 : } else if (ie.gtk &&
1120 : 216 : wpa_supplicant_pairwise_gtk(sm, key,
1121 : : ie.gtk, ie.gtk_len, key_info) < 0) {
1122 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1123 : : "RSN: Failed to configure GTK");
1124 : 0 : goto failed;
1125 : : }
1126 : :
1127 [ - + ]: 222 : if (ieee80211w_set_keys(sm, &ie) < 0) {
1128 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1129 : : "RSN: Failed to configure IGTK");
1130 : 0 : goto failed;
1131 : : }
1132 : :
1133 [ + + ]: 222 : if (ie.gtk)
1134 : 216 : wpa_sm_set_rekey_offload(sm);
1135 : :
1136 : 222 : return;
1137 : :
1138 : : failed:
1139 : 0 : wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1140 : : }
1141 : :
1142 : :
1143 : 1 : static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
1144 : : const u8 *keydata,
1145 : : size_t keydatalen,
1146 : : u16 key_info,
1147 : : struct wpa_gtk_data *gd)
1148 : : {
1149 : : int maxkeylen;
1150 : : struct wpa_eapol_ie_parse ie;
1151 : :
1152 : 1 : wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);
1153 [ - + ]: 1 : if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0)
1154 : 0 : return -1;
1155 [ + - ][ - + ]: 1 : if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1156 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1157 : : "WPA: GTK IE in unencrypted key data");
1158 : 0 : return -1;
1159 : : }
1160 [ - + ]: 1 : if (ie.gtk == NULL) {
1161 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1162 : : "WPA: No GTK IE in Group Key msg 1/2");
1163 : 0 : return -1;
1164 : : }
1165 : 1 : maxkeylen = gd->gtk_len = ie.gtk_len - 2;
1166 : :
1167 [ - + ]: 1 : if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1168 : : gd->gtk_len, maxkeylen,
1169 : : &gd->key_rsc_len, &gd->alg))
1170 : 0 : return -1;
1171 : :
1172 : 1 : wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake",
1173 : 1 : ie.gtk, ie.gtk_len);
1174 : 1 : gd->keyidx = ie.gtk[0] & 0x3;
1175 : 1 : gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
1176 : 1 : !!(ie.gtk[0] & BIT(2)));
1177 [ - + ]: 1 : if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
1178 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1179 : : "RSN: Too long GTK in GTK IE (len=%lu)",
1180 : 0 : (unsigned long) ie.gtk_len - 2);
1181 : 0 : return -1;
1182 : : }
1183 : 1 : os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
1184 : :
1185 [ - + ]: 1 : if (ieee80211w_set_keys(sm, &ie) < 0)
1186 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1187 : : "RSN: Failed to configure IGTK");
1188 : :
1189 : 1 : return 0;
1190 : : }
1191 : :
1192 : :
1193 : 6 : static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
1194 : : const struct wpa_eapol_key *key,
1195 : : size_t keydatalen, int key_info,
1196 : : size_t extra_len, u16 ver,
1197 : : struct wpa_gtk_data *gd)
1198 : : {
1199 : : size_t maxkeylen;
1200 : : u8 ek[32];
1201 : :
1202 : 6 : gd->gtk_len = WPA_GET_BE16(key->key_length);
1203 : 6 : maxkeylen = keydatalen;
1204 [ - + ]: 6 : if (keydatalen > extra_len) {
1205 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1206 : : "WPA: Truncated EAPOL-Key packet: "
1207 : : "key_data_length=%lu > extra_len=%lu",
1208 : : (unsigned long) keydatalen, (unsigned long) extra_len);
1209 : 0 : return -1;
1210 : : }
1211 [ - + ]: 6 : if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1212 [ # # ]: 0 : if (maxkeylen < 8) {
1213 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1214 : : "WPA: Too short maxkeylen (%lu)",
1215 : : (unsigned long) maxkeylen);
1216 : 0 : return -1;
1217 : : }
1218 : 0 : maxkeylen -= 8;
1219 : : }
1220 : :
1221 [ - + ]: 6 : if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1222 : : gd->gtk_len, maxkeylen,
1223 : : &gd->key_rsc_len, &gd->alg))
1224 : 0 : return -1;
1225 : :
1226 : 6 : gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1227 : : WPA_KEY_INFO_KEY_INDEX_SHIFT;
1228 [ + - ]: 6 : if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
1229 : 6 : os_memcpy(ek, key->key_iv, 16);
1230 : 6 : os_memcpy(ek + 16, sm->ptk.kek, 16);
1231 [ - + ]: 6 : if (keydatalen > sizeof(gd->gtk)) {
1232 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1233 : : "WPA: RC4 key data too long (%lu)",
1234 : : (unsigned long) keydatalen);
1235 : 0 : return -1;
1236 : : }
1237 : 6 : os_memcpy(gd->gtk, key + 1, keydatalen);
1238 [ - + ]: 6 : if (rc4_skip(ek, 32, 256, gd->gtk, keydatalen)) {
1239 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1240 : : "WPA: RC4 failed");
1241 : 0 : return -1;
1242 : : }
1243 [ # # ]: 0 : } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1244 [ # # ]: 0 : if (keydatalen % 8) {
1245 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1246 : : "WPA: Unsupported AES-WRAP len %lu",
1247 : : (unsigned long) keydatalen);
1248 : 0 : return -1;
1249 : : }
1250 [ # # ]: 0 : if (maxkeylen > sizeof(gd->gtk)) {
1251 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1252 : : "WPA: AES-WRAP key data "
1253 : : "too long (keydatalen=%lu maxkeylen=%lu)",
1254 : : (unsigned long) keydatalen,
1255 : : (unsigned long) maxkeylen);
1256 : 0 : return -1;
1257 : : }
1258 [ # # ]: 0 : if (aes_unwrap(sm->ptk.kek, maxkeylen / 8,
1259 : 0 : (const u8 *) (key + 1), gd->gtk)) {
1260 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1261 : : "WPA: AES unwrap failed - could not decrypt "
1262 : : "GTK");
1263 : 0 : return -1;
1264 : : }
1265 : : } else {
1266 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1267 : : "WPA: Unsupported key_info type %d", ver);
1268 : 0 : return -1;
1269 : : }
1270 : 6 : gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
1271 : 6 : sm, !!(key_info & WPA_KEY_INFO_TXRX));
1272 : 6 : return 0;
1273 : : }
1274 : :
1275 : :
1276 : 7 : static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
1277 : : const struct wpa_eapol_key *key,
1278 : : int ver, u16 key_info)
1279 : : {
1280 : : size_t rlen;
1281 : : struct wpa_eapol_key *reply;
1282 : : u8 *rbuf;
1283 : :
1284 : 7 : rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
1285 : : sizeof(*reply), &rlen, (void *) &reply);
1286 [ - + ]: 7 : if (rbuf == NULL)
1287 : 0 : return -1;
1288 : :
1289 [ + + ]: 7 : reply->type = sm->proto == WPA_PROTO_RSN ?
1290 : : EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1291 : 7 : key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
1292 : 7 : key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
1293 : 7 : WPA_PUT_BE16(reply->key_info, key_info);
1294 [ + + ]: 7 : if (sm->proto == WPA_PROTO_RSN)
1295 : 1 : WPA_PUT_BE16(reply->key_length, 0);
1296 : : else
1297 : 6 : os_memcpy(reply->key_length, key->key_length, 2);
1298 : 7 : os_memcpy(reply->replay_counter, key->replay_counter,
1299 : : WPA_REPLAY_COUNTER_LEN);
1300 : :
1301 : 7 : WPA_PUT_BE16(reply->key_data_length, 0);
1302 : :
1303 : 7 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
1304 : 7 : wpa_eapol_key_send(sm, sm->ptk.kck, ver, sm->bssid, ETH_P_EAPOL,
1305 : 7 : rbuf, rlen, reply->key_mic);
1306 : :
1307 : 7 : return 0;
1308 : : }
1309 : :
1310 : :
1311 : 7 : static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
1312 : : const unsigned char *src_addr,
1313 : : const struct wpa_eapol_key *key,
1314 : : int extra_len, u16 ver)
1315 : : {
1316 : : u16 key_info, keydatalen;
1317 : : int rekey, ret;
1318 : : struct wpa_gtk_data gd;
1319 : :
1320 : 7 : os_memset(&gd, 0, sizeof(gd));
1321 : :
1322 : 7 : rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
1323 : 7 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of Group Key "
1324 : : "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1325 : :
1326 : 7 : key_info = WPA_GET_BE16(key->key_info);
1327 : 7 : keydatalen = WPA_GET_BE16(key->key_data_length);
1328 : :
1329 [ + + ]: 7 : if (sm->proto == WPA_PROTO_RSN) {
1330 : 1 : ret = wpa_supplicant_process_1_of_2_rsn(sm,
1331 : : (const u8 *) (key + 1),
1332 : : keydatalen, key_info,
1333 : : &gd);
1334 : : } else {
1335 : 6 : ret = wpa_supplicant_process_1_of_2_wpa(sm, key, keydatalen,
1336 : : key_info, extra_len,
1337 : : ver, &gd);
1338 : : }
1339 : :
1340 : 7 : wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1341 : :
1342 [ - + ]: 7 : if (ret)
1343 : 0 : goto failed;
1344 : :
1345 [ + - + - ]: 14 : if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) ||
1346 : 7 : wpa_supplicant_send_2_of_2(sm, key, ver, key_info))
1347 : : goto failed;
1348 : :
1349 [ + + ]: 7 : if (rekey) {
1350 : 1 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
1351 : : "completed with " MACSTR " [GTK=%s]",
1352 : 7 : MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
1353 : 1 : wpa_sm_cancel_auth_timeout(sm);
1354 : 1 : wpa_sm_set_state(sm, WPA_COMPLETED);
1355 : : } else {
1356 : 6 : wpa_supplicant_key_neg_complete(sm, sm->bssid,
1357 : : key_info &
1358 : : WPA_KEY_INFO_SECURE);
1359 : : }
1360 : :
1361 : 7 : wpa_sm_set_rekey_offload(sm);
1362 : :
1363 : 7 : return;
1364 : :
1365 : : failed:
1366 : 0 : wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1367 : : }
1368 : :
1369 : :
1370 : 232 : static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
1371 : : struct wpa_eapol_key *key,
1372 : : u16 ver,
1373 : : const u8 *buf, size_t len)
1374 : : {
1375 : : u8 mic[16];
1376 : 232 : int ok = 0;
1377 : :
1378 : 232 : os_memcpy(mic, key->key_mic, 16);
1379 [ + + ]: 232 : if (sm->tptk_set) {
1380 : 222 : os_memset(key->key_mic, 0, 16);
1381 : 222 : wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len,
1382 : 222 : key->key_mic);
1383 [ - + ]: 222 : if (os_memcmp(mic, key->key_mic, 16) != 0) {
1384 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1385 : : "WPA: Invalid EAPOL-Key MIC "
1386 : : "when using TPTK - ignoring TPTK");
1387 : : } else {
1388 : 222 : ok = 1;
1389 : 222 : sm->tptk_set = 0;
1390 : 222 : sm->ptk_set = 1;
1391 : 222 : os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
1392 : : }
1393 : : }
1394 : :
1395 [ + + ][ + - ]: 232 : if (!ok && sm->ptk_set) {
1396 : 10 : os_memset(key->key_mic, 0, 16);
1397 : 10 : wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len,
1398 : 10 : key->key_mic);
1399 [ - + ]: 10 : if (os_memcmp(mic, key->key_mic, 16) != 0) {
1400 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1401 : : "WPA: Invalid EAPOL-Key MIC - "
1402 : : "dropping packet");
1403 : 0 : return -1;
1404 : : }
1405 : 10 : ok = 1;
1406 : : }
1407 : :
1408 [ - + ]: 232 : if (!ok) {
1409 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1410 : : "WPA: Could not verify EAPOL-Key MIC - "
1411 : : "dropping packet");
1412 : 0 : return -1;
1413 : : }
1414 : :
1415 : 232 : os_memcpy(sm->rx_replay_counter, key->replay_counter,
1416 : : WPA_REPLAY_COUNTER_LEN);
1417 : 232 : sm->rx_replay_counter_set = 1;
1418 : 232 : return 0;
1419 : : }
1420 : :
1421 : :
1422 : : /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
1423 : 219 : static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
1424 : : struct wpa_eapol_key *key, u16 ver)
1425 : : {
1426 : 219 : u16 keydatalen = WPA_GET_BE16(key->key_data_length);
1427 : :
1428 : 219 : wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
1429 : : (u8 *) (key + 1), keydatalen);
1430 [ - + ]: 219 : if (!sm->ptk_set) {
1431 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1432 : : "WPA: PTK not available, cannot decrypt EAPOL-Key Key "
1433 : : "Data");
1434 : 0 : return -1;
1435 : : }
1436 : :
1437 : : /* Decrypt key data here so that this operation does not need
1438 : : * to be implemented separately for each message type. */
1439 [ + + ]: 219 : if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
1440 : : u8 ek[32];
1441 : 1 : os_memcpy(ek, key->key_iv, 16);
1442 : 1 : os_memcpy(ek + 16, sm->ptk.kek, 16);
1443 [ - + ]: 1 : if (rc4_skip(ek, 32, 256, (u8 *) (key + 1), keydatalen)) {
1444 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1445 : : "WPA: RC4 failed");
1446 : 0 : return -1;
1447 : : }
1448 [ + + ][ + - ]: 218 : } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
1449 : 218 : ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
1450 : : u8 *buf;
1451 [ - + ]: 218 : if (keydatalen % 8) {
1452 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1453 : : "WPA: Unsupported AES-WRAP len %d",
1454 : : keydatalen);
1455 : 0 : return -1;
1456 : : }
1457 : 218 : keydatalen -= 8; /* AES-WRAP adds 8 bytes */
1458 : 218 : buf = os_malloc(keydatalen);
1459 [ - + ]: 218 : if (buf == NULL) {
1460 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1461 : : "WPA: No memory for AES-UNWRAP buffer");
1462 : 0 : return -1;
1463 : : }
1464 [ - + ]: 218 : if (aes_unwrap(sm->ptk.kek, keydatalen / 8,
1465 : : (u8 *) (key + 1), buf)) {
1466 : 0 : os_free(buf);
1467 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1468 : : "WPA: AES unwrap failed - "
1469 : : "could not decrypt EAPOL-Key key data");
1470 : 0 : return -1;
1471 : : }
1472 : 218 : os_memcpy(key + 1, buf, keydatalen);
1473 : 218 : os_free(buf);
1474 : 218 : WPA_PUT_BE16(key->key_data_length, keydatalen);
1475 : : } else {
1476 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1477 : : "WPA: Unsupported key_info type %d", ver);
1478 : 0 : return -1;
1479 : : }
1480 : 219 : wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
1481 : : (u8 *) (key + 1), keydatalen);
1482 : 219 : return 0;
1483 : : }
1484 : :
1485 : :
1486 : : /**
1487 : : * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted
1488 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
1489 : : */
1490 : 1 : void wpa_sm_aborted_cached(struct wpa_sm *sm)
1491 : : {
1492 [ + - ][ - + ]: 1 : if (sm && sm->cur_pmksa) {
1493 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1494 : : "RSN: Cancelling PMKSA caching attempt");
1495 : 0 : sm->cur_pmksa = NULL;
1496 : : }
1497 : 1 : }
1498 : :
1499 : :
1500 : 478 : static void wpa_eapol_key_dump(struct wpa_sm *sm,
1501 : : const struct wpa_eapol_key *key)
1502 : : {
1503 : : #ifndef CONFIG_NO_STDOUT_DEBUG
1504 : 478 : u16 key_info = WPA_GET_BE16(key->key_info);
1505 : :
1506 : 478 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, " EAPOL-Key type=%d", key->type);
1507 [ + + ][ - + ]: 478 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
[ - + ][ + + ]
[ + + ][ + + ]
[ + + ][ + + ]
1508 : : " key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s%s%s%s%s%s%s%s)",
1509 : : key_info, key_info & WPA_KEY_INFO_TYPE_MASK,
1510 : : (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1511 : : WPA_KEY_INFO_KEY_INDEX_SHIFT,
1512 : : (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,
1513 : : key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",
1514 : : key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",
1515 : : key_info & WPA_KEY_INFO_ACK ? " Ack" : "",
1516 : : key_info & WPA_KEY_INFO_MIC ? " MIC" : "",
1517 : : key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",
1518 : : key_info & WPA_KEY_INFO_ERROR ? " Error" : "",
1519 : : key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",
1520 : : key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
1521 : 478 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1522 : : " key_length=%u key_data_length=%u",
1523 : : WPA_GET_BE16(key->key_length),
1524 : : WPA_GET_BE16(key->key_data_length));
1525 : 478 : wpa_hexdump(MSG_DEBUG, " replay_counter",
1526 : 478 : key->replay_counter, WPA_REPLAY_COUNTER_LEN);
1527 : 478 : wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN);
1528 : 478 : wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16);
1529 : 478 : wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8);
1530 : 478 : wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8);
1531 : 478 : wpa_hexdump(MSG_DEBUG, " key_mic", key->key_mic, 16);
1532 : : #endif /* CONFIG_NO_STDOUT_DEBUG */
1533 : 478 : }
1534 : :
1535 : :
1536 : : /**
1537 : : * wpa_sm_rx_eapol - Process received WPA EAPOL frames
1538 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
1539 : : * @src_addr: Source MAC address of the EAPOL packet
1540 : : * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
1541 : : * @len: Length of the EAPOL frame
1542 : : * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
1543 : : *
1544 : : * This function is called for each received EAPOL frame. Other than EAPOL-Key
1545 : : * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
1546 : : * only processing WPA and WPA2 EAPOL-Key frames.
1547 : : *
1548 : : * The received EAPOL-Key packets are validated and valid packets are replied
1549 : : * to. In addition, key material (PTK, GTK) is configured at the end of a
1550 : : * successful key handshake.
1551 : : */
1552 : 478 : int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
1553 : : const u8 *buf, size_t len)
1554 : : {
1555 : : size_t plen, data_len, extra_len;
1556 : : struct ieee802_1x_hdr *hdr;
1557 : : struct wpa_eapol_key *key;
1558 : : u16 key_info, ver;
1559 : : u8 *tmp;
1560 : 478 : int ret = -1;
1561 : 478 : struct wpa_peerkey *peerkey = NULL;
1562 : :
1563 : : #ifdef CONFIG_IEEE80211R
1564 : 478 : sm->ft_completed = 0;
1565 : : #endif /* CONFIG_IEEE80211R */
1566 : :
1567 [ - + ]: 478 : if (len < sizeof(*hdr) + sizeof(*key)) {
1568 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1569 : : "WPA: EAPOL frame too short to be a WPA "
1570 : : "EAPOL-Key (len %lu, expecting at least %lu)",
1571 : : (unsigned long) len,
1572 : : (unsigned long) sizeof(*hdr) + sizeof(*key));
1573 : 0 : return 0;
1574 : : }
1575 : :
1576 : 478 : tmp = os_malloc(len);
1577 [ - + ]: 478 : if (tmp == NULL)
1578 : 0 : return -1;
1579 : 478 : os_memcpy(tmp, buf, len);
1580 : :
1581 : 478 : hdr = (struct ieee802_1x_hdr *) tmp;
1582 : 478 : key = (struct wpa_eapol_key *) (hdr + 1);
1583 : 478 : plen = be_to_host16(hdr->length);
1584 : 478 : data_len = plen + sizeof(*hdr);
1585 : 478 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1586 : : "IEEE 802.1X RX: version=%d type=%d length=%lu",
1587 : : hdr->version, hdr->type, (unsigned long) plen);
1588 : :
1589 : 478 : if (hdr->version < EAPOL_VERSION) {
1590 : : /* TODO: backwards compatibility */
1591 : : }
1592 [ - + ]: 478 : if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
1593 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1594 : : "WPA: EAPOL frame (type %u) discarded, "
1595 : : "not a Key frame", hdr->type);
1596 : 0 : ret = 0;
1597 : 0 : goto out;
1598 : : }
1599 [ + - ][ - + ]: 478 : if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) {
1600 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1601 : : "WPA: EAPOL frame payload size %lu "
1602 : : "invalid (frame size %lu)",
1603 : : (unsigned long) plen, (unsigned long) len);
1604 : 0 : ret = 0;
1605 : 0 : goto out;
1606 : : }
1607 : :
1608 [ + + ][ - + ]: 478 : if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
1609 : : {
1610 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1611 : : "WPA: EAPOL-Key type (%d) unknown, discarded",
1612 : : key->type);
1613 : 0 : ret = 0;
1614 : 0 : goto out;
1615 : : }
1616 : 478 : wpa_eapol_key_dump(sm, key);
1617 : :
1618 : 478 : eapol_sm_notify_lower_layer_success(sm->eapol, 0);
1619 : 478 : wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", tmp, len);
1620 [ - + ]: 478 : if (data_len < len) {
1621 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1622 : : "WPA: ignoring %lu bytes after the IEEE 802.1X data",
1623 : : (unsigned long) len - data_len);
1624 : : }
1625 : 478 : key_info = WPA_GET_BE16(key->key_info);
1626 : 478 : ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1627 [ + + ][ + + ]: 478 : if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1628 : : #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
1629 [ - + ]: 426 : ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
1630 : : #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
1631 : : ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1632 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1633 : : "WPA: Unsupported EAPOL-Key descriptor version %d",
1634 : : ver);
1635 : 0 : goto out;
1636 : : }
1637 : :
1638 : : #ifdef CONFIG_IEEE80211R
1639 [ + + ]: 478 : if (wpa_key_mgmt_ft(sm->key_mgmt)) {
1640 : : /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
1641 [ - + ]: 16 : if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
1642 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1643 : : "FT: AP did not use AES-128-CMAC");
1644 : 0 : goto out;
1645 : : }
1646 : : } else
1647 : : #endif /* CONFIG_IEEE80211R */
1648 : : #ifdef CONFIG_IEEE80211W
1649 [ + + ]: 462 : if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
1650 [ - + ]: 16 : if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
1651 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1652 : : "WPA: AP did not use the "
1653 : : "negotiated AES-128-CMAC");
1654 : 0 : goto out;
1655 : : }
1656 : : } else
1657 : : #endif /* CONFIG_IEEE80211W */
1658 [ + + ][ - + ]: 446 : if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
1659 : : ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1660 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1661 : : "WPA: CCMP is used, but EAPOL-Key "
1662 : : "descriptor version (%d) is not 2", ver);
1663 [ # # ][ # # ]: 0 : if (sm->group_cipher != WPA_CIPHER_CCMP &&
1664 : 0 : !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
1665 : : /* Earlier versions of IEEE 802.11i did not explicitly
1666 : : * require version 2 descriptor for all EAPOL-Key
1667 : : * packets, so allow group keys to use version 1 if
1668 : : * CCMP is not used for them. */
1669 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1670 : : "WPA: Backwards compatibility: allow invalid "
1671 : : "version for non-CCMP group keys");
1672 : : } else
1673 : : goto out;
1674 : : }
1675 [ + + ][ - + ]: 478 : if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
1676 : : ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1677 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1678 : : "WPA: GCMP is used, but EAPOL-Key "
1679 : : "descriptor version (%d) is not 2", ver);
1680 : 0 : goto out;
1681 : : }
1682 : :
1683 : : #ifdef CONFIG_PEERKEY
1684 [ + + ]: 480 : for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
1685 [ + + ]: 6 : if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
1686 : 4 : break;
1687 : : }
1688 : :
1689 [ + + ][ + + ]: 478 : if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
1690 [ + + ][ - + ]: 4 : if (!peerkey->initiator && peerkey->replay_counter_set &&
[ # # ]
1691 : 0 : os_memcmp(key->replay_counter, peerkey->replay_counter,
1692 : : WPA_REPLAY_COUNTER_LEN) <= 0) {
1693 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1694 : : "RSN: EAPOL-Key Replay Counter did not "
1695 : : "increase (STK) - dropping packet");
1696 : 0 : goto out;
1697 [ + + ]: 4 : } else if (peerkey->initiator) {
1698 : : u8 _tmp[WPA_REPLAY_COUNTER_LEN];
1699 : 2 : os_memcpy(_tmp, key->replay_counter,
1700 : : WPA_REPLAY_COUNTER_LEN);
1701 : 2 : inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
1702 [ - + ]: 2 : if (os_memcmp(_tmp, peerkey->replay_counter,
1703 : : WPA_REPLAY_COUNTER_LEN) != 0) {
1704 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1705 : : "RSN: EAPOL-Key Replay "
1706 : : "Counter did not match (STK) - "
1707 : : "dropping packet");
1708 : 0 : goto out;
1709 : : }
1710 : : }
1711 : : }
1712 : :
1713 [ + + ][ + + ]: 478 : if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
[ - + ]
1714 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1715 : : "RSN: Ack bit in key_info from STK peer");
1716 : 0 : goto out;
1717 : : }
1718 : : #endif /* CONFIG_PEERKEY */
1719 : :
1720 [ + + ][ + + ]: 478 : if (!peerkey && sm->rx_replay_counter_set &&
[ - + ]
1721 : 52 : os_memcmp(key->replay_counter, sm->rx_replay_counter,
1722 : : WPA_REPLAY_COUNTER_LEN) <= 0) {
1723 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1724 : : "WPA: EAPOL-Key Replay Counter did not increase - "
1725 : : "dropping packet");
1726 : 0 : goto out;
1727 : : }
1728 : :
1729 [ + + ]: 478 : if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
1730 : : #ifdef CONFIG_PEERKEY
1731 [ + - ][ - + ]: 2 : && (peerkey == NULL || !peerkey->initiator)
1732 : : #endif /* CONFIG_PEERKEY */
1733 : : ) {
1734 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1735 : : "WPA: No Ack bit in key_info");
1736 : 0 : goto out;
1737 : : }
1738 : :
1739 [ - + ]: 478 : if (key_info & WPA_KEY_INFO_REQUEST) {
1740 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1741 : : "WPA: EAPOL-Key with Request bit - dropped");
1742 : 0 : goto out;
1743 : : }
1744 : :
1745 [ + + ]: 710 : if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
[ + + - + ]
1746 : 232 : wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
1747 : 0 : goto out;
1748 : :
1749 : : #ifdef CONFIG_PEERKEY
1750 [ + + ]: 481 : if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
[ + + - + ]
1751 : 3 : peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp, data_len))
1752 : 0 : goto out;
1753 : : #endif /* CONFIG_PEERKEY */
1754 : :
1755 : 478 : extra_len = data_len - sizeof(*hdr) - sizeof(*key);
1756 : :
1757 [ - + ]: 478 : if (WPA_GET_BE16(key->key_data_length) > extra_len) {
1758 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
1759 : : "frame - key_data overflow (%d > %lu)",
1760 : 0 : WPA_GET_BE16(key->key_data_length),
1761 : : (unsigned long) extra_len);
1762 : 0 : goto out;
1763 : : }
1764 : 478 : extra_len = WPA_GET_BE16(key->key_data_length);
1765 : :
1766 [ + + ][ + + ]: 478 : if (sm->proto == WPA_PROTO_RSN &&
1767 : 460 : (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1768 [ - + ]: 219 : if (wpa_supplicant_decrypt_key_data(sm, key, ver))
1769 : 0 : goto out;
1770 : 219 : extra_len = WPA_GET_BE16(key->key_data_length);
1771 : : }
1772 : :
1773 [ + + ]: 478 : if (key_info & WPA_KEY_INFO_KEY_TYPE) {
1774 [ - + ]: 468 : if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
1775 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1776 : : "WPA: Ignored EAPOL-Key (Pairwise) with "
1777 : : "non-zero key index");
1778 : 0 : goto out;
1779 : : }
1780 [ + + ]: 468 : if (peerkey) {
1781 : : /* PeerKey 4-Way Handshake */
1782 : 4 : peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver);
1783 [ + + ]: 464 : } else if (key_info & WPA_KEY_INFO_MIC) {
1784 : : /* 3/4 4-Way Handshake */
1785 : 222 : wpa_supplicant_process_3_of_4(sm, key, ver);
1786 : : } else {
1787 : : /* 1/4 4-Way Handshake */
1788 : 242 : wpa_supplicant_process_1_of_4(sm, src_addr, key,
1789 : : ver);
1790 : : }
1791 [ + + ]: 10 : } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
1792 : : /* PeerKey SMK Handshake */
1793 : 3 : peerkey_rx_eapol_smk(sm, src_addr, key, extra_len, key_info,
1794 : : ver);
1795 : : } else {
1796 [ + - ]: 7 : if (key_info & WPA_KEY_INFO_MIC) {
1797 : : /* 1/2 Group Key Handshake */
1798 : 7 : wpa_supplicant_process_1_of_2(sm, src_addr, key,
1799 : : extra_len, ver);
1800 : : } else {
1801 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1802 : : "WPA: EAPOL-Key (Group) without Mic bit - "
1803 : : "dropped");
1804 : : }
1805 : : }
1806 : :
1807 : 478 : ret = 1;
1808 : :
1809 : : out:
1810 : 478 : os_free(tmp);
1811 : 478 : return ret;
1812 : : }
1813 : :
1814 : :
1815 : : #ifdef CONFIG_CTRL_IFACE
1816 : 0 : static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
1817 : : {
1818 [ # # # # : 0 : switch (sm->key_mgmt) {
# # # #
# ]
1819 : : case WPA_KEY_MGMT_IEEE8021X:
1820 : 0 : return (sm->proto == WPA_PROTO_RSN ?
1821 [ # # ]: 0 : RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
1822 : : WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
1823 : : case WPA_KEY_MGMT_PSK:
1824 : 0 : return (sm->proto == WPA_PROTO_RSN ?
1825 [ # # ]: 0 : RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
1826 : : WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
1827 : : #ifdef CONFIG_IEEE80211R
1828 : : case WPA_KEY_MGMT_FT_IEEE8021X:
1829 : 0 : return RSN_AUTH_KEY_MGMT_FT_802_1X;
1830 : : case WPA_KEY_MGMT_FT_PSK:
1831 : 0 : return RSN_AUTH_KEY_MGMT_FT_PSK;
1832 : : #endif /* CONFIG_IEEE80211R */
1833 : : #ifdef CONFIG_IEEE80211W
1834 : : case WPA_KEY_MGMT_IEEE8021X_SHA256:
1835 : 0 : return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
1836 : : case WPA_KEY_MGMT_PSK_SHA256:
1837 : 0 : return RSN_AUTH_KEY_MGMT_PSK_SHA256;
1838 : : #endif /* CONFIG_IEEE80211W */
1839 : : case WPA_KEY_MGMT_CCKM:
1840 : 0 : return (sm->proto == WPA_PROTO_RSN ?
1841 : : RSN_AUTH_KEY_MGMT_CCKM:
1842 : : WPA_AUTH_KEY_MGMT_CCKM);
1843 : : case WPA_KEY_MGMT_WPA_NONE:
1844 : 0 : return WPA_AUTH_KEY_MGMT_NONE;
1845 : : default:
1846 : 0 : return 0;
1847 : : }
1848 : : }
1849 : :
1850 : :
1851 : : #define RSN_SUITE "%02x-%02x-%02x-%d"
1852 : : #define RSN_SUITE_ARG(s) \
1853 : : ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
1854 : :
1855 : : /**
1856 : : * wpa_sm_get_mib - Dump text list of MIB entries
1857 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
1858 : : * @buf: Buffer for the list
1859 : : * @buflen: Length of the buffer
1860 : : * Returns: Number of bytes written to buffer
1861 : : *
1862 : : * This function is used fetch dot11 MIB variables.
1863 : : */
1864 : 0 : int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
1865 : : {
1866 : : char pmkid_txt[PMKID_LEN * 2 + 1];
1867 : : int rsna, ret;
1868 : : size_t len;
1869 : :
1870 [ # # ]: 0 : if (sm->cur_pmksa) {
1871 : 0 : wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
1872 : 0 : sm->cur_pmksa->pmkid, PMKID_LEN);
1873 : : } else
1874 : 0 : pmkid_txt[0] = '\0';
1875 : :
1876 [ # # # # ]: 0 : if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
1877 [ # # ]: 0 : wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
1878 : 0 : sm->proto == WPA_PROTO_RSN)
1879 : 0 : rsna = 1;
1880 : : else
1881 : 0 : rsna = 0;
1882 : :
1883 [ # # ][ # # ]: 0 : ret = os_snprintf(buf, buflen,
1884 : : "dot11RSNAOptionImplemented=TRUE\n"
1885 : : "dot11RSNAPreauthenticationImplemented=TRUE\n"
1886 : : "dot11RSNAEnabled=%s\n"
1887 : : "dot11RSNAPreauthenticationEnabled=%s\n"
1888 : : "dot11RSNAConfigVersion=%d\n"
1889 : : "dot11RSNAConfigPairwiseKeysSupported=5\n"
1890 : : "dot11RSNAConfigGroupCipherSize=%d\n"
1891 : : "dot11RSNAConfigPMKLifetime=%d\n"
1892 : : "dot11RSNAConfigPMKReauthThreshold=%d\n"
1893 : : "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
1894 : : "dot11RSNAConfigSATimeout=%d\n",
1895 : : rsna ? "TRUE" : "FALSE",
1896 : : rsna ? "TRUE" : "FALSE",
1897 : : RSN_VERSION,
1898 : 0 : wpa_cipher_key_len(sm->group_cipher) * 8,
1899 : : sm->dot11RSNAConfigPMKLifetime,
1900 : : sm->dot11RSNAConfigPMKReauthThreshold,
1901 : : sm->dot11RSNAConfigSATimeout);
1902 [ # # ][ # # ]: 0 : if (ret < 0 || (size_t) ret >= buflen)
1903 : 0 : return 0;
1904 : 0 : len = ret;
1905 : :
1906 : 0 : ret = os_snprintf(
1907 : : buf + len, buflen - len,
1908 : : "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
1909 : : "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
1910 : : "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
1911 : : "dot11RSNAPMKIDUsed=%s\n"
1912 : : "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
1913 : : "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
1914 : : "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
1915 : : "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
1916 : : "dot11RSNA4WayHandshakeFailures=%u\n",
1917 : 0 : RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
1918 : 0 : RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
1919 : : sm->pairwise_cipher)),
1920 : 0 : RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
1921 : : sm->group_cipher)),
1922 : : pmkid_txt,
1923 : 0 : RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
1924 : 0 : RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
1925 : : sm->pairwise_cipher)),
1926 : 0 : RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
1927 : : sm->group_cipher)),
1928 : : sm->dot11RSNA4WayHandshakeFailures);
1929 [ # # ][ # # ]: 0 : if (ret >= 0 && (size_t) ret < buflen)
1930 : 0 : len += ret;
1931 : :
1932 : 0 : return (int) len;
1933 : : }
1934 : : #endif /* CONFIG_CTRL_IFACE */
1935 : :
1936 : :
1937 : 68 : static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
1938 : : void *ctx, enum pmksa_free_reason reason)
1939 : : {
1940 : 68 : struct wpa_sm *sm = ctx;
1941 : 68 : int deauth = 0;
1942 : :
1943 : 68 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: "
1944 : : MACSTR " reason=%d", MAC2STR(entry->aa), reason);
1945 : :
1946 [ + + ]: 68 : if (sm->cur_pmksa == entry) {
1947 [ - + ]: 4 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1948 : : "RSN: %s current PMKSA entry",
1949 : : reason == PMKSA_REPLACE ? "replaced" : "removed");
1950 : 4 : pmksa_cache_clear_current(sm);
1951 : :
1952 : : /*
1953 : : * If an entry is simply being replaced, there's no need to
1954 : : * deauthenticate because it will be immediately re-added.
1955 : : * This happens when EAP authentication is completed again
1956 : : * (reauth or failed PMKSA caching attempt).
1957 : : */
1958 [ + - ]: 4 : if (reason != PMKSA_REPLACE)
1959 : 4 : deauth = 1;
1960 : : }
1961 : :
1962 [ - + ][ # # ]: 68 : if (reason == PMKSA_EXPIRE &&
1963 [ # # ]: 0 : (sm->pmk_len == entry->pmk_len &&
1964 : 0 : os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
1965 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1966 : : "RSN: deauthenticating due to expired PMK");
1967 : 0 : pmksa_cache_clear_current(sm);
1968 : 0 : deauth = 1;
1969 : : }
1970 : :
1971 [ + + ]: 68 : if (deauth) {
1972 : 4 : os_memset(sm->pmk, 0, sizeof(sm->pmk));
1973 : 4 : wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1974 : : }
1975 : 68 : }
1976 : :
1977 : :
1978 : : /**
1979 : : * wpa_sm_init - Initialize WPA state machine
1980 : : * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
1981 : : * Returns: Pointer to the allocated WPA state machine data
1982 : : *
1983 : : * This function is used to allocate a new WPA state machine and the returned
1984 : : * value is passed to all WPA state machine calls.
1985 : : */
1986 : 28 : struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
1987 : : {
1988 : : struct wpa_sm *sm;
1989 : :
1990 : 28 : sm = os_zalloc(sizeof(*sm));
1991 [ - + ]: 28 : if (sm == NULL)
1992 : 0 : return NULL;
1993 : 28 : dl_list_init(&sm->pmksa_candidates);
1994 : 28 : sm->renew_snonce = 1;
1995 : 28 : sm->ctx = ctx;
1996 : :
1997 : 28 : sm->dot11RSNAConfigPMKLifetime = 43200;
1998 : 28 : sm->dot11RSNAConfigPMKReauthThreshold = 70;
1999 : 28 : sm->dot11RSNAConfigSATimeout = 60;
2000 : :
2001 : 28 : sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
2002 [ - + ]: 28 : if (sm->pmksa == NULL) {
2003 : 0 : wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
2004 : : "RSN: PMKSA cache initialization failed");
2005 : 0 : os_free(sm);
2006 : 0 : return NULL;
2007 : : }
2008 : :
2009 : 28 : return sm;
2010 : : }
2011 : :
2012 : :
2013 : : /**
2014 : : * wpa_sm_deinit - Deinitialize WPA state machine
2015 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2016 : : */
2017 : 28 : void wpa_sm_deinit(struct wpa_sm *sm)
2018 : : {
2019 [ - + ]: 28 : if (sm == NULL)
2020 : 28 : return;
2021 : 28 : pmksa_cache_deinit(sm->pmksa);
2022 : 28 : eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2023 : 28 : eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
2024 : 28 : os_free(sm->assoc_wpa_ie);
2025 : 28 : os_free(sm->ap_wpa_ie);
2026 : 28 : os_free(sm->ap_rsn_ie);
2027 : 28 : os_free(sm->ctx);
2028 : 28 : peerkey_deinit(sm);
2029 : : #ifdef CONFIG_IEEE80211R
2030 : 28 : os_free(sm->assoc_resp_ies);
2031 : : #endif /* CONFIG_IEEE80211R */
2032 : 28 : os_free(sm);
2033 : : }
2034 : :
2035 : :
2036 : : /**
2037 : : * wpa_sm_notify_assoc - Notify WPA state machine about association
2038 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2039 : : * @bssid: The BSSID of the new association
2040 : : *
2041 : : * This function is called to let WPA state machine know that the connection
2042 : : * was established.
2043 : : */
2044 : 368 : void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
2045 : : {
2046 : 368 : int clear_ptk = 1;
2047 : :
2048 [ - + ]: 368 : if (sm == NULL)
2049 : 368 : return;
2050 : :
2051 : 368 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2052 : : "WPA: Association event - clear replay counter");
2053 : 368 : os_memcpy(sm->bssid, bssid, ETH_ALEN);
2054 : 368 : os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
2055 : 368 : sm->rx_replay_counter_set = 0;
2056 : 368 : sm->renew_snonce = 1;
2057 [ - + ]: 368 : if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
2058 : 0 : rsn_preauth_deinit(sm);
2059 : :
2060 : : #ifdef CONFIG_IEEE80211R
2061 [ + + ]: 368 : if (wpa_ft_is_completed(sm)) {
2062 : : /*
2063 : : * Clear portValid to kick EAPOL state machine to re-enter
2064 : : * AUTHENTICATED state to get the EAPOL port Authorized.
2065 : : */
2066 : 14 : eapol_sm_notify_portValid(sm->eapol, FALSE);
2067 : 14 : wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
2068 : :
2069 : : /* Prepare for the next transition */
2070 : 14 : wpa_ft_prepare_auth_request(sm, NULL);
2071 : :
2072 : 14 : clear_ptk = 0;
2073 : : }
2074 : : #endif /* CONFIG_IEEE80211R */
2075 : :
2076 [ + + ]: 368 : if (clear_ptk) {
2077 : : /*
2078 : : * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
2079 : : * this is not part of a Fast BSS Transition.
2080 : : */
2081 : 354 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
2082 : 354 : sm->ptk_set = 0;
2083 : 354 : sm->tptk_set = 0;
2084 : : }
2085 : :
2086 : : #ifdef CONFIG_TDLS
2087 : 368 : wpa_tdls_assoc(sm);
2088 : : #endif /* CONFIG_TDLS */
2089 : : }
2090 : :
2091 : :
2092 : : /**
2093 : : * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation
2094 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2095 : : *
2096 : : * This function is called to let WPA state machine know that the connection
2097 : : * was lost. This will abort any existing pre-authentication session.
2098 : : */
2099 : 663 : void wpa_sm_notify_disassoc(struct wpa_sm *sm)
2100 : : {
2101 : 663 : peerkey_deinit(sm);
2102 : 663 : rsn_preauth_deinit(sm);
2103 : 663 : pmksa_cache_clear_current(sm);
2104 [ + + ]: 663 : if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
2105 : 5 : sm->dot11RSNA4WayHandshakeFailures++;
2106 : : #ifdef CONFIG_TDLS
2107 : 663 : wpa_tdls_disassoc(sm);
2108 : : #endif /* CONFIG_TDLS */
2109 : 663 : }
2110 : :
2111 : :
2112 : : /**
2113 : : * wpa_sm_set_pmk - Set PMK
2114 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2115 : : * @pmk: The new PMK
2116 : : * @pmk_len: The length of the new PMK in bytes
2117 : : *
2118 : : * Configure the PMK for WPA state machine.
2119 : : */
2120 : 200 : void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len)
2121 : : {
2122 [ - + ]: 200 : if (sm == NULL)
2123 : 200 : return;
2124 : :
2125 : 200 : sm->pmk_len = pmk_len;
2126 : 200 : os_memcpy(sm->pmk, pmk, pmk_len);
2127 : :
2128 : : #ifdef CONFIG_IEEE80211R
2129 : : /* Set XXKey to be PSK for FT key derivation */
2130 : 200 : sm->xxkey_len = pmk_len;
2131 : 200 : os_memcpy(sm->xxkey, pmk, pmk_len);
2132 : : #endif /* CONFIG_IEEE80211R */
2133 : : }
2134 : :
2135 : :
2136 : : /**
2137 : : * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA
2138 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2139 : : *
2140 : : * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK
2141 : : * will be cleared.
2142 : : */
2143 : 59 : void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
2144 : : {
2145 [ - + ]: 59 : if (sm == NULL)
2146 : 59 : return;
2147 : :
2148 [ + + ]: 59 : if (sm->cur_pmksa) {
2149 : 2 : sm->pmk_len = sm->cur_pmksa->pmk_len;
2150 : 2 : os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
2151 : : } else {
2152 : 57 : sm->pmk_len = PMK_LEN;
2153 : 57 : os_memset(sm->pmk, 0, PMK_LEN);
2154 : : }
2155 : : }
2156 : :
2157 : :
2158 : : /**
2159 : : * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled
2160 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2161 : : * @fast_reauth: Whether fast reauthentication (EAP) is allowed
2162 : : */
2163 : 22 : void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
2164 : : {
2165 [ + - ]: 22 : if (sm)
2166 : 22 : sm->fast_reauth = fast_reauth;
2167 : 22 : }
2168 : :
2169 : :
2170 : : /**
2171 : : * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks
2172 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2173 : : * @scard_ctx: Context pointer for smartcard related callback functions
2174 : : */
2175 : 22 : void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
2176 : : {
2177 [ - + ]: 22 : if (sm == NULL)
2178 : 22 : return;
2179 : 22 : sm->scard_ctx = scard_ctx;
2180 [ - + ]: 22 : if (sm->preauth_eapol)
2181 : 0 : eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
2182 : : }
2183 : :
2184 : :
2185 : : /**
2186 : : * wpa_sm_set_config - Notification of current configration change
2187 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2188 : : * @config: Pointer to current network configuration
2189 : : *
2190 : : * Notify WPA state machine that configuration has changed. config will be
2191 : : * stored as a backpointer to network configuration. This can be %NULL to clear
2192 : : * the stored pointed.
2193 : : */
2194 : 915 : void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
2195 : : {
2196 [ - + ]: 915 : if (!sm)
2197 : 915 : return;
2198 : :
2199 [ + + ]: 915 : if (config) {
2200 : 379 : sm->network_ctx = config->network_ctx;
2201 : 379 : sm->peerkey_enabled = config->peerkey_enabled;
2202 : 379 : sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
2203 : 379 : sm->proactive_key_caching = config->proactive_key_caching;
2204 : 379 : sm->eap_workaround = config->eap_workaround;
2205 : 379 : sm->eap_conf_ctx = config->eap_conf_ctx;
2206 [ + + ]: 379 : if (config->ssid) {
2207 : 359 : os_memcpy(sm->ssid, config->ssid, config->ssid_len);
2208 : 359 : sm->ssid_len = config->ssid_len;
2209 : : } else
2210 : 20 : sm->ssid_len = 0;
2211 : 379 : sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
2212 : : } else {
2213 : 536 : sm->network_ctx = NULL;
2214 : 536 : sm->peerkey_enabled = 0;
2215 : 536 : sm->allowed_pairwise_cipher = 0;
2216 : 536 : sm->proactive_key_caching = 0;
2217 : 536 : sm->eap_workaround = 0;
2218 : 536 : sm->eap_conf_ctx = NULL;
2219 : 536 : sm->ssid_len = 0;
2220 : 536 : sm->wpa_ptk_rekey = 0;
2221 : : }
2222 : : }
2223 : :
2224 : :
2225 : : /**
2226 : : * wpa_sm_set_own_addr - Set own MAC address
2227 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2228 : : * @addr: Own MAC address
2229 : : */
2230 : 28 : void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
2231 : : {
2232 [ + - ]: 28 : if (sm)
2233 : 28 : os_memcpy(sm->own_addr, addr, ETH_ALEN);
2234 : 28 : }
2235 : :
2236 : :
2237 : : /**
2238 : : * wpa_sm_set_ifname - Set network interface name
2239 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2240 : : * @ifname: Interface name
2241 : : * @bridge_ifname: Optional bridge interface name (for pre-auth)
2242 : : */
2243 : 22 : void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
2244 : : const char *bridge_ifname)
2245 : : {
2246 [ + - ]: 22 : if (sm) {
2247 : 22 : sm->ifname = ifname;
2248 : 22 : sm->bridge_ifname = bridge_ifname;
2249 : : }
2250 : 22 : }
2251 : :
2252 : :
2253 : : /**
2254 : : * wpa_sm_set_eapol - Set EAPOL state machine pointer
2255 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2256 : : * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init()
2257 : : */
2258 : 44 : void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
2259 : : {
2260 [ + - ]: 44 : if (sm)
2261 : 44 : sm->eapol = eapol;
2262 : 44 : }
2263 : :
2264 : :
2265 : : /**
2266 : : * wpa_sm_set_param - Set WPA state machine parameters
2267 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2268 : : * @param: Parameter field
2269 : : * @value: Parameter value
2270 : : * Returns: 0 on success, -1 on failure
2271 : : */
2272 : 2401 : int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
2273 : : unsigned int value)
2274 : : {
2275 : 2401 : int ret = 0;
2276 : :
2277 [ - + ]: 2401 : if (sm == NULL)
2278 : 0 : return -1;
2279 : :
2280 [ - - - + : 2401 : switch (param) {
+ + + + +
+ - ]
2281 : : case RSNA_PMK_LIFETIME:
2282 [ # # ]: 0 : if (value > 0)
2283 : 0 : sm->dot11RSNAConfigPMKLifetime = value;
2284 : : else
2285 : 0 : ret = -1;
2286 : 0 : break;
2287 : : case RSNA_PMK_REAUTH_THRESHOLD:
2288 [ # # ][ # # ]: 0 : if (value > 0 && value <= 100)
2289 : 0 : sm->dot11RSNAConfigPMKReauthThreshold = value;
2290 : : else
2291 : 0 : ret = -1;
2292 : 0 : break;
2293 : : case RSNA_SA_TIMEOUT:
2294 [ # # ]: 0 : if (value > 0)
2295 : 0 : sm->dot11RSNAConfigSATimeout = value;
2296 : : else
2297 : 0 : ret = -1;
2298 : 0 : break;
2299 : : case WPA_PARAM_PROTO:
2300 : 244 : sm->proto = value;
2301 : 244 : break;
2302 : : case WPA_PARAM_PAIRWISE:
2303 : 385 : sm->pairwise_cipher = value;
2304 : 385 : break;
2305 : : case WPA_PARAM_GROUP:
2306 : 385 : sm->group_cipher = value;
2307 : 385 : break;
2308 : : case WPA_PARAM_KEY_MGMT:
2309 : 385 : sm->key_mgmt = value;
2310 : 385 : break;
2311 : : #ifdef CONFIG_IEEE80211W
2312 : : case WPA_PARAM_MGMT_GROUP:
2313 : 379 : sm->mgmt_group_cipher = value;
2314 : 379 : break;
2315 : : #endif /* CONFIG_IEEE80211W */
2316 : : case WPA_PARAM_RSN_ENABLED:
2317 : 385 : sm->rsn_enabled = value;
2318 : 385 : break;
2319 : : case WPA_PARAM_MFP:
2320 : 238 : sm->mfp = value;
2321 : 238 : break;
2322 : : default:
2323 : 0 : break;
2324 : : }
2325 : :
2326 : 2401 : return ret;
2327 : : }
2328 : :
2329 : :
2330 : : /**
2331 : : * wpa_sm_get_param - Get WPA state machine parameters
2332 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2333 : : * @param: Parameter field
2334 : : * Returns: Parameter value
2335 : : */
2336 : 0 : unsigned int wpa_sm_get_param(struct wpa_sm *sm, enum wpa_sm_conf_params param)
2337 : : {
2338 [ # # ]: 0 : if (sm == NULL)
2339 : 0 : return 0;
2340 : :
2341 [ # # # # : 0 : switch (param) {
# # # # #
# ]
2342 : : case RSNA_PMK_LIFETIME:
2343 : 0 : return sm->dot11RSNAConfigPMKLifetime;
2344 : : case RSNA_PMK_REAUTH_THRESHOLD:
2345 : 0 : return sm->dot11RSNAConfigPMKReauthThreshold;
2346 : : case RSNA_SA_TIMEOUT:
2347 : 0 : return sm->dot11RSNAConfigSATimeout;
2348 : : case WPA_PARAM_PROTO:
2349 : 0 : return sm->proto;
2350 : : case WPA_PARAM_PAIRWISE:
2351 : 0 : return sm->pairwise_cipher;
2352 : : case WPA_PARAM_GROUP:
2353 : 0 : return sm->group_cipher;
2354 : : case WPA_PARAM_KEY_MGMT:
2355 : 0 : return sm->key_mgmt;
2356 : : #ifdef CONFIG_IEEE80211W
2357 : : case WPA_PARAM_MGMT_GROUP:
2358 : 0 : return sm->mgmt_group_cipher;
2359 : : #endif /* CONFIG_IEEE80211W */
2360 : : case WPA_PARAM_RSN_ENABLED:
2361 : 0 : return sm->rsn_enabled;
2362 : : default:
2363 : 0 : return 0;
2364 : : }
2365 : : }
2366 : :
2367 : :
2368 : : /**
2369 : : * wpa_sm_get_status - Get WPA state machine
2370 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2371 : : * @buf: Buffer for status information
2372 : : * @buflen: Maximum buffer length
2373 : : * @verbose: Whether to include verbose status information
2374 : : * Returns: Number of bytes written to buf.
2375 : : *
2376 : : * Query WPA state machine for status information. This function fills in
2377 : : * a text area with current status information. If the buffer (buf) is not
2378 : : * large enough, status information will be truncated to fit the buffer.
2379 : : */
2380 : 240 : int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
2381 : : int verbose)
2382 : : {
2383 : 240 : char *pos = buf, *end = buf + buflen;
2384 : : int ret;
2385 : :
2386 : 240 : ret = os_snprintf(pos, end - pos,
2387 : : "pairwise_cipher=%s\n"
2388 : : "group_cipher=%s\n"
2389 : : "key_mgmt=%s\n",
2390 : 240 : wpa_cipher_txt(sm->pairwise_cipher),
2391 : 240 : wpa_cipher_txt(sm->group_cipher),
2392 : 480 : wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
2393 [ + - ][ - + ]: 240 : if (ret < 0 || ret >= end - pos)
2394 : 0 : return pos - buf;
2395 : 240 : pos += ret;
2396 : :
2397 [ + + ][ + + ]: 240 : if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
2398 : : struct wpa_ie_data rsn;
2399 [ + - ]: 76 : if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
2400 [ + + ]: 76 : >= 0 &&
2401 : 76 : rsn.capabilities & (WPA_CAPABILITY_MFPR |
2402 : : WPA_CAPABILITY_MFPC)) {
2403 [ + + ]: 20 : ret = os_snprintf(pos, end - pos, "pmf=%d\n",
2404 : 20 : (rsn.capabilities &
2405 : : WPA_CAPABILITY_MFPR) ? 2 : 1);
2406 [ + - ][ - + ]: 20 : if (ret < 0 || ret >= end - pos)
2407 : 0 : return pos - buf;
2408 : 20 : pos += ret;
2409 : : }
2410 : : }
2411 : :
2412 : 240 : return pos - buf;
2413 : : }
2414 : :
2415 : :
2416 : 2 : int wpa_sm_pmf_enabled(struct wpa_sm *sm)
2417 : : {
2418 : : struct wpa_ie_data rsn;
2419 : :
2420 [ + + ][ - + ]: 2 : if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
2421 : 1 : return 0;
2422 : :
2423 [ + - ][ + - ]: 1 : if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
2424 : 1 : rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
2425 : 1 : return 1;
2426 : :
2427 : 2 : return 0;
2428 : : }
2429 : :
2430 : :
2431 : : /**
2432 : : * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration
2433 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2434 : : * @wpa_ie: Pointer to buffer for WPA/RSN IE
2435 : : * @wpa_ie_len: Pointer to the length of the wpa_ie buffer
2436 : : * Returns: 0 on success, -1 on failure
2437 : : */
2438 : 244 : int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
2439 : : size_t *wpa_ie_len)
2440 : : {
2441 : : int res;
2442 : :
2443 [ - + ]: 244 : if (sm == NULL)
2444 : 0 : return -1;
2445 : :
2446 : 244 : res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
2447 [ - + ]: 244 : if (res < 0)
2448 : 0 : return -1;
2449 : 244 : *wpa_ie_len = res;
2450 : :
2451 : 244 : wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
2452 : : wpa_ie, *wpa_ie_len);
2453 : :
2454 [ + + ]: 244 : if (sm->assoc_wpa_ie == NULL) {
2455 : : /*
2456 : : * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
2457 : : * the correct version of the IE even if PMKSA caching is
2458 : : * aborted (which would remove PMKID from IE generation).
2459 : : */
2460 : 88 : sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
2461 [ - + ]: 88 : if (sm->assoc_wpa_ie == NULL)
2462 : 0 : return -1;
2463 : :
2464 : 88 : os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
2465 : 88 : sm->assoc_wpa_ie_len = *wpa_ie_len;
2466 : : }
2467 : :
2468 : 244 : return 0;
2469 : : }
2470 : :
2471 : :
2472 : : /**
2473 : : * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq
2474 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2475 : : * @ie: Pointer to IE data (starting from id)
2476 : : * @len: IE length
2477 : : * Returns: 0 on success, -1 on failure
2478 : : *
2479 : : * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
2480 : : * Request frame. The IE will be used to override the default value generated
2481 : : * with wpa_sm_set_assoc_wpa_ie_default().
2482 : : */
2483 : 504 : int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2484 : : {
2485 [ - + ]: 504 : if (sm == NULL)
2486 : 0 : return -1;
2487 : :
2488 : 504 : os_free(sm->assoc_wpa_ie);
2489 [ + + ][ - + ]: 504 : if (ie == NULL || len == 0) {
2490 : 288 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2491 : : "WPA: clearing own WPA/RSN IE");
2492 : 288 : sm->assoc_wpa_ie = NULL;
2493 : 288 : sm->assoc_wpa_ie_len = 0;
2494 : : } else {
2495 : 216 : wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
2496 : 216 : sm->assoc_wpa_ie = os_malloc(len);
2497 [ - + ]: 216 : if (sm->assoc_wpa_ie == NULL)
2498 : 0 : return -1;
2499 : :
2500 : 216 : os_memcpy(sm->assoc_wpa_ie, ie, len);
2501 : 216 : sm->assoc_wpa_ie_len = len;
2502 : : }
2503 : :
2504 : 504 : return 0;
2505 : : }
2506 : :
2507 : :
2508 : : /**
2509 : : * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
2510 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2511 : : * @ie: Pointer to IE data (starting from id)
2512 : : * @len: IE length
2513 : : * Returns: 0 on success, -1 on failure
2514 : : *
2515 : : * Inform WPA state machine about the WPA IE used in Beacon / Probe Response
2516 : : * frame.
2517 : : */
2518 : 379 : int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2519 : : {
2520 [ - + ]: 379 : if (sm == NULL)
2521 : 0 : return -1;
2522 : :
2523 : 379 : os_free(sm->ap_wpa_ie);
2524 [ + + ][ - + ]: 379 : if (ie == NULL || len == 0) {
2525 : 366 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2526 : : "WPA: clearing AP WPA IE");
2527 : 366 : sm->ap_wpa_ie = NULL;
2528 : 366 : sm->ap_wpa_ie_len = 0;
2529 : : } else {
2530 : 13 : wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
2531 : 13 : sm->ap_wpa_ie = os_malloc(len);
2532 [ - + ]: 13 : if (sm->ap_wpa_ie == NULL)
2533 : 0 : return -1;
2534 : :
2535 : 13 : os_memcpy(sm->ap_wpa_ie, ie, len);
2536 : 13 : sm->ap_wpa_ie_len = len;
2537 : : }
2538 : :
2539 : 379 : return 0;
2540 : : }
2541 : :
2542 : :
2543 : : /**
2544 : : * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
2545 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2546 : : * @ie: Pointer to IE data (starting from id)
2547 : : * @len: IE length
2548 : : * Returns: 0 on success, -1 on failure
2549 : : *
2550 : : * Inform WPA state machine about the RSN IE used in Beacon / Probe Response
2551 : : * frame.
2552 : : */
2553 : 385 : int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2554 : : {
2555 [ - + ]: 385 : if (sm == NULL)
2556 : 0 : return -1;
2557 : :
2558 : 385 : os_free(sm->ap_rsn_ie);
2559 [ + + ][ - + ]: 385 : if (ie == NULL || len == 0) {
2560 : 151 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2561 : : "WPA: clearing AP RSN IE");
2562 : 151 : sm->ap_rsn_ie = NULL;
2563 : 151 : sm->ap_rsn_ie_len = 0;
2564 : : } else {
2565 : 234 : wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
2566 : 234 : sm->ap_rsn_ie = os_malloc(len);
2567 [ - + ]: 234 : if (sm->ap_rsn_ie == NULL)
2568 : 0 : return -1;
2569 : :
2570 : 234 : os_memcpy(sm->ap_rsn_ie, ie, len);
2571 : 234 : sm->ap_rsn_ie_len = len;
2572 : : }
2573 : :
2574 : 385 : return 0;
2575 : : }
2576 : :
2577 : :
2578 : : /**
2579 : : * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
2580 : : * @sm: Pointer to WPA state machine data from wpa_sm_init()
2581 : : * @data: Pointer to data area for parsing results
2582 : : * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure
2583 : : *
2584 : : * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the
2585 : : * parsed data into data.
2586 : : */
2587 : 6 : int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
2588 : : {
2589 [ - + ]: 6 : if (sm == NULL)
2590 : 0 : return -1;
2591 : :
2592 [ + - ]: 6 : if (sm->assoc_wpa_ie == NULL) {
2593 : 6 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2594 : : "WPA: No WPA/RSN IE available from association info");
2595 : 6 : return -1;
2596 : : }
2597 [ # # ]: 0 : if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
2598 : 0 : return -2;
2599 : 6 : return 0;
2600 : : }
2601 : :
2602 : :
2603 : 0 : int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
2604 : : {
2605 : 0 : return pmksa_cache_list(sm->pmksa, buf, len);
2606 : : }
2607 : :
2608 : :
2609 : 0 : void wpa_sm_drop_sa(struct wpa_sm *sm)
2610 : : {
2611 : 0 : wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
2612 : 0 : sm->ptk_set = 0;
2613 : 0 : sm->tptk_set = 0;
2614 : 0 : os_memset(sm->pmk, 0, sizeof(sm->pmk));
2615 : 0 : os_memset(&sm->ptk, 0, sizeof(sm->ptk));
2616 : 0 : os_memset(&sm->tptk, 0, sizeof(sm->tptk));
2617 : 0 : }
2618 : :
2619 : :
2620 : 10 : int wpa_sm_has_ptk(struct wpa_sm *sm)
2621 : : {
2622 [ - + ]: 10 : if (sm == NULL)
2623 : 0 : return 0;
2624 : 10 : return sm->ptk_set;
2625 : : }
2626 : :
2627 : :
2628 : 0 : void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
2629 : : {
2630 : 0 : os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
2631 : 0 : }
2632 : :
2633 : :
2634 : 1117 : void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
2635 : : {
2636 : 1117 : pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
2637 : 1117 : }
2638 : :
2639 : :
2640 : : #ifdef CONFIG_WNM
2641 : 2 : int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
2642 : : {
2643 : : struct wpa_gtk_data gd;
2644 : : #ifdef CONFIG_IEEE80211W
2645 : : struct wpa_igtk_kde igd;
2646 : : u16 keyidx;
2647 : : #endif /* CONFIG_IEEE80211W */
2648 : : u16 keyinfo;
2649 : : u8 keylen; /* plaintext key len */
2650 : : u8 *key_rsc;
2651 : :
2652 : 2 : os_memset(&gd, 0, sizeof(gd));
2653 : : #ifdef CONFIG_IEEE80211W
2654 : 2 : os_memset(&igd, 0, sizeof(igd));
2655 : : #endif /* CONFIG_IEEE80211W */
2656 : :
2657 : 2 : keylen = wpa_cipher_key_len(sm->group_cipher);
2658 : 2 : gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
2659 : 2 : gd.alg = wpa_cipher_to_alg(sm->group_cipher);
2660 [ - + ]: 2 : if (gd.alg == WPA_ALG_NONE) {
2661 : 0 : wpa_printf(MSG_DEBUG, "Unsupported group cipher suite");
2662 : 0 : return -1;
2663 : : }
2664 : :
2665 [ + + ]: 2 : if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
2666 : 1 : key_rsc = buf + 5;
2667 : 1 : keyinfo = WPA_GET_LE16(buf + 2);
2668 : 1 : gd.gtk_len = keylen;
2669 [ - + ]: 1 : if (gd.gtk_len != buf[4]) {
2670 : 0 : wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
2671 : 0 : gd.gtk_len, buf[4]);
2672 : 0 : return -1;
2673 : : }
2674 : 1 : gd.keyidx = keyinfo & 0x03; /* B0 - B1 */
2675 : 1 : gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
2676 : 1 : sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
2677 : :
2678 : 1 : os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
2679 : :
2680 : 1 : wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
2681 : 1 : gd.gtk, gd.gtk_len);
2682 [ - + ]: 1 : if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
2683 : 0 : wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
2684 : : "WNM mode");
2685 : 0 : return -1;
2686 : : }
2687 : : #ifdef CONFIG_IEEE80211W
2688 [ + - ]: 1 : } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
2689 : 1 : os_memcpy(igd.keyid, buf + 2, 2);
2690 : 1 : os_memcpy(igd.pn, buf + 4, 6);
2691 : :
2692 : 1 : keyidx = WPA_GET_LE16(igd.keyid);
2693 : 1 : os_memcpy(igd.igtk, buf + 10, WPA_IGTK_LEN);
2694 : :
2695 : 1 : wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
2696 : : igd.igtk, WPA_IGTK_LEN);
2697 [ - + ]: 1 : if (wpa_sm_set_key(sm, WPA_ALG_IGTK, broadcast_ether_addr,
2698 : : keyidx, 0, igd.pn, sizeof(igd.pn),
2699 : : igd.igtk, WPA_IGTK_LEN) < 0) {
2700 : 0 : wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
2701 : : "WNM mode");
2702 : 0 : return -1;
2703 : : }
2704 : : #endif /* CONFIG_IEEE80211W */
2705 : : } else {
2706 : 0 : wpa_printf(MSG_DEBUG, "Unknown element id");
2707 : 0 : return -1;
2708 : : }
2709 : :
2710 : 2 : return 0;
2711 : : }
2712 : : #endif /* CONFIG_WNM */
2713 : :
2714 : :
2715 : : #ifdef CONFIG_PEERKEY
2716 : 9 : int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
2717 : : const u8 *buf, size_t len)
2718 : : {
2719 : : struct wpa_peerkey *peerkey;
2720 : :
2721 [ + + ]: 11 : for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
2722 [ + + ]: 6 : if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
2723 : 4 : break;
2724 : : }
2725 : :
2726 [ + + ]: 9 : if (!peerkey)
2727 : 5 : return 0;
2728 : :
2729 : 4 : wpa_sm_rx_eapol(sm, src_addr, buf, len);
2730 : :
2731 : 9 : return 1;
2732 : : }
2733 : : #endif /* CONFIG_PEERKEY */
|