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