blob: 65e257a939aceafc67b032c85f4cd1dd9610f81c [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * WPA Supplicant - WPA state machine and EAPOL-Key processing
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003 * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004 * Copyright(c) 2015 Intel Deutschland GmbH
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08006 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07008 */
9
10#include "includes.h"
11
12#include "common.h"
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080013#include "crypto/aes.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070014#include "crypto/aes_wrap.h"
15#include "crypto/crypto.h"
16#include "crypto/random.h"
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080017#include "crypto/aes_siv.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070018#include "common/ieee802_11_defs.h"
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080019#include "common/ieee802_11_common.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070020#include "eapol_supp/eapol_supp_sm.h"
21#include "wpa.h"
22#include "eloop.h"
23#include "preauth.h"
24#include "pmksa_cache.h"
25#include "wpa_i.h"
26#include "wpa_ie.h"
27#include "peerkey.h"
28
29
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080030static const u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
31
32
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070033/**
34 * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message
35 * @sm: Pointer to WPA state machine data from wpa_sm_init()
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080036 * @ptk: PTK for Key Confirmation/Encryption Key
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070037 * @ver: Version field from Key Info
38 * @dest: Destination address for the frame
39 * @proto: Ethertype (usually ETH_P_EAPOL)
40 * @msg: EAPOL-Key message
41 * @msg_len: Length of message
42 * @key_mic: Pointer to the buffer to which the EAPOL-Key MIC is written
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080043 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070044 */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080045int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080046 int ver, const u8 *dest, u16 proto,
47 u8 *msg, size_t msg_len, u8 *key_mic)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070048{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080049 int ret = -1;
Dmitry Shmidt807291d2015-01-27 13:40:23 -080050 size_t mic_len = wpa_mic_len(sm->key_mgmt);
51
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070052 if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
53 /*
54 * Association event was not yet received; try to fetch
55 * BSSID from the driver.
56 */
57 if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
58 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
59 "WPA: Failed to read BSSID for "
60 "EAPOL-Key destination address");
61 } else {
62 dest = sm->bssid;
63 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
64 "WPA: Use BSSID (" MACSTR
65 ") as the destination for EAPOL-Key",
66 MAC2STR(dest));
67 }
68 }
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080069
70 if (mic_len) {
71 if (key_mic && (!ptk || !ptk->kck_len))
72 goto out;
73
74 if (key_mic &&
75 wpa_eapol_key_mic(ptk->kck, ptk->kck_len, sm->key_mgmt, ver,
76 msg, msg_len, key_mic)) {
77 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
78 "WPA: Failed to generate EAPOL-Key version %d key_mgmt 0x%x MIC",
79 ver, sm->key_mgmt);
80 goto out;
81 }
82 wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", ptk->kck, ptk->kck_len);
83 wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC",
84 key_mic, mic_len);
85 } else {
86#ifdef CONFIG_FILS
87 /* AEAD cipher - Key MIC field not used */
88 struct ieee802_1x_hdr *s_hdr, *hdr;
89 struct wpa_eapol_key *s_key, *key;
90 u8 *buf, *s_key_data, *key_data;
91 size_t buf_len = msg_len + AES_BLOCK_SIZE;
92 size_t key_data_len;
93 u16 eapol_len;
94 const u8 *aad[1];
95 size_t aad_len[1];
96
97 if (!ptk || !ptk->kek_len)
98 goto out;
99
100 key_data_len = msg_len - sizeof(struct ieee802_1x_hdr) -
101 sizeof(struct wpa_eapol_key) - 2;
102
103 buf = os_malloc(buf_len);
104 if (!buf)
105 goto out;
106
107 os_memcpy(buf, msg, msg_len);
108 hdr = (struct ieee802_1x_hdr *) buf;
109 key = (struct wpa_eapol_key *) (hdr + 1);
110 key_data = ((u8 *) (key + 1)) + 2;
111
112 /* Update EAPOL header to include AES-SIV overhead */
113 eapol_len = be_to_host16(hdr->length);
114 eapol_len += AES_BLOCK_SIZE;
115 hdr->length = host_to_be16(eapol_len);
116
117 /* Update Key Data Length field to include AES-SIV overhead */
118 WPA_PUT_BE16((u8 *) (key + 1), AES_BLOCK_SIZE + key_data_len);
119
120 s_hdr = (struct ieee802_1x_hdr *) msg;
121 s_key = (struct wpa_eapol_key *) (s_hdr + 1);
122 s_key_data = ((u8 *) (s_key + 1)) + 2;
123
124 wpa_hexdump_key(MSG_DEBUG, "WPA: Plaintext Key Data",
125 s_key_data, key_data_len);
126
127 wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
128 /* AES-SIV AAD from EAPOL protocol version field (inclusive) to
129 * to Key Data (exclusive). */
130 aad[0] = buf;
131 aad_len[0] = key_data - buf;
132 if (aes_siv_encrypt(ptk->kek, ptk->kek_len,
133 s_key_data, key_data_len,
134 1, aad, aad_len, key_data) < 0) {
135 os_free(buf);
136 goto out;
137 }
138
139 wpa_hexdump(MSG_DEBUG, "WPA: Encrypted Key Data from SIV",
140 key_data, AES_BLOCK_SIZE + key_data_len);
141
142 os_free(msg);
143 msg = buf;
144 msg_len = buf_len;
145#else /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700146 goto out;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800147#endif /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700148 }
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800149
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700150 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800151 ret = wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700152 eapol_sm_notify_tx_eapol_key(sm->eapol);
153out:
154 os_free(msg);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800155 return ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700156}
157
158
159/**
160 * wpa_sm_key_request - Send EAPOL-Key Request
161 * @sm: Pointer to WPA state machine data from wpa_sm_init()
162 * @error: Indicate whether this is an Michael MIC error report
163 * @pairwise: 1 = error report for pairwise packet, 0 = for group packet
164 *
165 * Send an EAPOL-Key Request to the current authenticator. This function is
166 * used to request rekeying and it is usually called when a local Michael MIC
167 * failure is detected.
168 */
169void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
170{
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800171 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700172 struct wpa_eapol_key *reply;
173 int key_info, ver;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800174 u8 bssid[ETH_ALEN], *rbuf, *key_mic, *mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700175
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800176 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
177 wpa_key_mgmt_suite_b(sm->key_mgmt))
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800178 ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
179 else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
180 wpa_key_mgmt_sha256(sm->key_mgmt))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700181 ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700182 else if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700183 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
184 else
185 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
186
187 if (wpa_sm_get_bssid(sm, bssid) < 0) {
188 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
189 "Failed to read BSSID for EAPOL-Key request");
190 return;
191 }
192
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800193 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800194 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700195 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800196 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700197 if (rbuf == NULL)
198 return;
199
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800200 reply->type = (sm->proto == WPA_PROTO_RSN ||
201 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700202 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
203 key_info = WPA_KEY_INFO_REQUEST | ver;
204 if (sm->ptk_set)
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800205 key_info |= WPA_KEY_INFO_SECURE;
206 if (sm->ptk_set && mic_len)
207 key_info |= WPA_KEY_INFO_MIC;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700208 if (error)
209 key_info |= WPA_KEY_INFO_ERROR;
210 if (pairwise)
211 key_info |= WPA_KEY_INFO_KEY_TYPE;
212 WPA_PUT_BE16(reply->key_info, key_info);
213 WPA_PUT_BE16(reply->key_length, 0);
214 os_memcpy(reply->replay_counter, sm->request_counter,
215 WPA_REPLAY_COUNTER_LEN);
216 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
217
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800218 mic = (u8 *) (reply + 1);
219 WPA_PUT_BE16(mic + mic_len, 0);
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800220 if (!(key_info & WPA_KEY_INFO_MIC))
221 key_mic = NULL;
222 else
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800223 key_mic = mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700224
225 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
226 "WPA: Sending EAPOL-Key Request (error=%d "
227 "pairwise=%d ptk_set=%d len=%lu)",
228 error, pairwise, sm->ptk_set, (unsigned long) rlen);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800229 wpa_eapol_key_send(sm, &sm->ptk, ver, bssid, ETH_P_EAPOL, rbuf, rlen,
230 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700231}
232
233
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800234static void wpa_supplicant_key_mgmt_set_pmk(struct wpa_sm *sm)
235{
236#ifdef CONFIG_IEEE80211R
237 if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
238 if (wpa_sm_key_mgmt_set_pmk(sm, sm->xxkey, sm->xxkey_len))
239 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
240 "RSN: Cannot set low order 256 bits of MSK for key management offload");
241 } else {
242#endif /* CONFIG_IEEE80211R */
243 if (wpa_sm_key_mgmt_set_pmk(sm, sm->pmk, sm->pmk_len))
244 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
245 "RSN: Cannot set PMK for key management offload");
246#ifdef CONFIG_IEEE80211R
247 }
248#endif /* CONFIG_IEEE80211R */
249}
250
251
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700252static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
253 const unsigned char *src_addr,
254 const u8 *pmkid)
255{
256 int abort_cached = 0;
257
258 if (pmkid && !sm->cur_pmksa) {
259 /* When using drivers that generate RSN IE, wpa_supplicant may
260 * not have enough time to get the association information
261 * event before receiving this 1/4 message, so try to find a
262 * matching PMKSA cache entry here. */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800263 sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
264 NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700265 if (sm->cur_pmksa) {
266 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
267 "RSN: found matching PMKID from PMKSA cache");
268 } else {
269 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
270 "RSN: no matching PMKID found");
271 abort_cached = 1;
272 }
273 }
274
275 if (pmkid && sm->cur_pmksa &&
Dmitry Shmidtc2817022014-07-02 10:32:10 -0700276 os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700277 wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
278 wpa_sm_set_pmk_from_pmksa(sm);
279 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
280 sm->pmk, sm->pmk_len);
281 eapol_sm_notify_cached(sm->eapol);
282#ifdef CONFIG_IEEE80211R
283 sm->xxkey_len = 0;
284#endif /* CONFIG_IEEE80211R */
285 } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
286 int res, pmk_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800287
288 if (sm->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
289 pmk_len = PMK_LEN_SUITE_B_192;
290 else
291 pmk_len = PMK_LEN;
292 res = eapol_sm_get_key(sm->eapol, sm->pmk, pmk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700293 if (res) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800294 if (pmk_len == PMK_LEN) {
295 /*
296 * EAP-LEAP is an exception from other EAP
297 * methods: it uses only 16-byte PMK.
298 */
299 res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
300 pmk_len = 16;
301 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700302 } else {
303#ifdef CONFIG_IEEE80211R
304 u8 buf[2 * PMK_LEN];
305 if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
306 {
307 os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
308 sm->xxkey_len = PMK_LEN;
309 os_memset(buf, 0, sizeof(buf));
310 }
311#endif /* CONFIG_IEEE80211R */
312 }
313 if (res == 0) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700314 struct rsn_pmksa_cache_entry *sa = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700315 wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
316 "machines", sm->pmk, pmk_len);
317 sm->pmk_len = pmk_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800318 wpa_supplicant_key_mgmt_set_pmk(sm);
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700319 if (sm->proto == WPA_PROTO_RSN &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800320 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700321 !wpa_key_mgmt_ft(sm->key_mgmt)) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700322 sa = pmksa_cache_add(sm->pmksa,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800323 sm->pmk, pmk_len, NULL,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800324 NULL, 0,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700325 src_addr, sm->own_addr,
326 sm->network_ctx,
327 sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700328 }
329 if (!sm->cur_pmksa && pmkid &&
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800330 pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
331 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700332 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
333 "RSN: the new PMK matches with the "
334 "PMKID");
335 abort_cached = 0;
Jouni Malinen6ec30382015-07-08 20:48:18 +0300336 } else if (sa && !sm->cur_pmksa && pmkid) {
337 /*
338 * It looks like the authentication server
339 * derived mismatching MSK. This should not
340 * really happen, but bugs happen.. There is not
341 * much we can do here without knowing what
342 * exactly caused the server to misbehave.
343 */
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -0800344 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
Jouni Malinen6ec30382015-07-08 20:48:18 +0300345 "RSN: PMKID mismatch - authentication server may have derived different MSK?!");
346 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700347 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700348
349 if (!sm->cur_pmksa)
350 sm->cur_pmksa = sa;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700351 } else {
352 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
353 "WPA: Failed to get master session key from "
354 "EAPOL state machines - key handshake "
355 "aborted");
356 if (sm->cur_pmksa) {
357 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
358 "RSN: Cancelled PMKSA caching "
359 "attempt");
360 sm->cur_pmksa = NULL;
361 abort_cached = 1;
362 } else if (!abort_cached) {
363 return -1;
364 }
365 }
366 }
367
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700368 if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800369 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800370 !wpa_key_mgmt_ft(sm->key_mgmt) && sm->key_mgmt != WPA_KEY_MGMT_OSEN)
371 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700372 /* Send EAPOL-Start to trigger full EAP authentication. */
373 u8 *buf;
374 size_t buflen;
375
376 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
377 "RSN: no PMKSA entry found - trigger "
378 "full EAP authentication");
379 buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
380 NULL, 0, &buflen, NULL);
381 if (buf) {
382 wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
383 buf, buflen);
384 os_free(buf);
385 return -2;
386 }
387
388 return -1;
389 }
390
391 return 0;
392}
393
394
395/**
396 * wpa_supplicant_send_2_of_4 - Send message 2 of WPA/RSN 4-Way Handshake
397 * @sm: Pointer to WPA state machine data from wpa_sm_init()
398 * @dst: Destination address for the frame
399 * @key: Pointer to the EAPOL-Key frame header
400 * @ver: Version bits from EAPOL-Key Key Info
401 * @nonce: Nonce value for the EAPOL-Key frame
402 * @wpa_ie: WPA/RSN IE
403 * @wpa_ie_len: Length of the WPA/RSN IE
404 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800405 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700406 */
407int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
408 const struct wpa_eapol_key *key,
409 int ver, const u8 *nonce,
410 const u8 *wpa_ie, size_t wpa_ie_len,
411 struct wpa_ptk *ptk)
412{
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800413 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700414 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800415 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700416 u8 *rsn_ie_buf = NULL;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800417 u16 key_info;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700418
419 if (wpa_ie == NULL) {
420 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No wpa_ie set - "
421 "cannot generate msg 2/4");
422 return -1;
423 }
424
425#ifdef CONFIG_IEEE80211R
426 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
427 int res;
428
429 /*
430 * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
431 * FTIE from (Re)Association Response.
432 */
433 rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
434 sm->assoc_resp_ies_len);
435 if (rsn_ie_buf == NULL)
436 return -1;
437 os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800438 res = wpa_insert_pmkid(rsn_ie_buf, &wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700439 sm->pmk_r1_name);
440 if (res < 0) {
441 os_free(rsn_ie_buf);
442 return -1;
443 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700444
445 if (sm->assoc_resp_ies) {
446 os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
447 sm->assoc_resp_ies_len);
448 wpa_ie_len += sm->assoc_resp_ies_len;
449 }
450
451 wpa_ie = rsn_ie_buf;
452 }
453#endif /* CONFIG_IEEE80211R */
454
455 wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
456
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800457 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800458 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700459 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800460 NULL, hdrlen + wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700461 &rlen, (void *) &reply);
462 if (rbuf == NULL) {
463 os_free(rsn_ie_buf);
464 return -1;
465 }
466
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800467 reply->type = (sm->proto == WPA_PROTO_RSN ||
468 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700469 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800470 key_info = ver | WPA_KEY_INFO_KEY_TYPE;
471 if (mic_len)
472 key_info |= WPA_KEY_INFO_MIC;
473 else
474 key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
475 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800476 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700477 WPA_PUT_BE16(reply->key_length, 0);
478 else
479 os_memcpy(reply->key_length, key->key_length, 2);
480 os_memcpy(reply->replay_counter, key->replay_counter,
481 WPA_REPLAY_COUNTER_LEN);
482 wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
483 WPA_REPLAY_COUNTER_LEN);
484
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800485 key_mic = (u8 *) (reply + 1);
486 WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len); /* Key Data Length */
487 os_memcpy(key_mic + mic_len + 2, wpa_ie, wpa_ie_len); /* Key Data */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700488 os_free(rsn_ie_buf);
489
490 os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
491
492 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800493 return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen,
494 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700495}
496
497
498static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800499 const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700500{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700501#ifdef CONFIG_IEEE80211R
502 if (wpa_key_mgmt_ft(sm->key_mgmt))
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800503 return wpa_derive_ptk_ft(sm, src_addr, key, ptk);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700504#endif /* CONFIG_IEEE80211R */
505
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800506 return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
507 sm->own_addr, sm->bssid, sm->snonce,
508 key->key_nonce, ptk, sm->key_mgmt,
509 sm->pairwise_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700510}
511
512
513static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
514 const unsigned char *src_addr,
515 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700516 u16 ver, const u8 *key_data,
517 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700518{
519 struct wpa_eapol_ie_parse ie;
520 struct wpa_ptk *ptk;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700521 int res;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800522 u8 *kde, *kde_buf = NULL;
523 size_t kde_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700524
525 if (wpa_sm_get_network_ctx(sm) == NULL) {
526 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
527 "found (msg 1 of 4)");
528 return;
529 }
530
531 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
532 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
533 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
534
535 os_memset(&ie, 0, sizeof(ie));
536
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800537 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700538 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700539 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
540 key_data, key_data_len);
541 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800542 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700543 if (ie.pmkid) {
544 wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
545 "Authenticator", ie.pmkid, PMKID_LEN);
546 }
547 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700548
549 res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
550 if (res == -2) {
551 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
552 "msg 1/4 - requesting full EAP authentication");
553 return;
554 }
555 if (res)
556 goto failed;
557
558 if (sm->renew_snonce) {
559 if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
560 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
561 "WPA: Failed to get random data for SNonce");
562 goto failed;
563 }
564 sm->renew_snonce = 0;
565 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
566 sm->snonce, WPA_NONCE_LEN);
567 }
568
569 /* Calculate PTK which will be stored as a temporary PTK until it has
570 * been verified when processing message 3/4. */
571 ptk = &sm->tptk;
572 wpa_derive_ptk(sm, src_addr, key, ptk);
Dmitry Shmidt98660862014-03-11 17:26:21 -0700573 if (sm->pairwise_cipher == WPA_CIPHER_TKIP) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700574 u8 buf[8];
Dmitry Shmidt98660862014-03-11 17:26:21 -0700575 /* Supplicant: swap tx/rx Mic keys */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800576 os_memcpy(buf, &ptk->tk[16], 8);
577 os_memcpy(&ptk->tk[16], &ptk->tk[24], 8);
578 os_memcpy(&ptk->tk[24], buf, 8);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700579 os_memset(buf, 0, sizeof(buf));
Dmitry Shmidt98660862014-03-11 17:26:21 -0700580 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700581 sm->tptk_set = 1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800582 sm->tk_to_set = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700583
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800584 kde = sm->assoc_wpa_ie;
585 kde_len = sm->assoc_wpa_ie_len;
586
587#ifdef CONFIG_P2P
588 if (sm->p2p) {
589 kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
590 if (kde_buf) {
591 u8 *pos;
592 wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
593 "into EAPOL-Key 2/4");
594 os_memcpy(kde_buf, kde, kde_len);
595 kde = kde_buf;
596 pos = kde + kde_len;
597 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
598 *pos++ = RSN_SELECTOR_LEN + 1;
599 RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ);
600 pos += RSN_SELECTOR_LEN;
601 *pos++ = 0x01;
602 kde_len = pos - kde;
603 }
604 }
605#endif /* CONFIG_P2P */
606
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700607 if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800608 kde, kde_len, ptk) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700609 goto failed;
610
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800611 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700612 os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
613 return;
614
615failed:
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800616 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700617 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
618}
619
620
621static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
622{
623 struct wpa_sm *sm = eloop_ctx;
624 rsn_preauth_candidate_process(sm);
625}
626
627
628static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
629 const u8 *addr, int secure)
630{
631 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
632 "WPA: Key negotiation completed with "
633 MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
634 wpa_cipher_txt(sm->pairwise_cipher),
635 wpa_cipher_txt(sm->group_cipher));
636 wpa_sm_cancel_auth_timeout(sm);
637 wpa_sm_set_state(sm, WPA_COMPLETED);
638
639 if (secure) {
640 wpa_sm_mlme_setprotection(
641 sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
642 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
643 eapol_sm_notify_portValid(sm->eapol, TRUE);
644 if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
645 eapol_sm_notify_eap_success(sm->eapol, TRUE);
646 /*
647 * Start preauthentication after a short wait to avoid a
648 * possible race condition between the data receive and key
649 * configuration after the 4-Way Handshake. This increases the
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800650 * likelihood of the first preauth EAPOL-Start frame getting to
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700651 * the target AP.
652 */
653 eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
654 }
655
656 if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {
657 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
658 "RSN: Authenticator accepted "
659 "opportunistic PMKSA entry - marking it valid");
660 sm->cur_pmksa->opportunistic = 0;
661 }
662
663#ifdef CONFIG_IEEE80211R
664 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
665 /* Prepare for the next transition */
666 wpa_ft_prepare_auth_request(sm, NULL);
667 }
668#endif /* CONFIG_IEEE80211R */
669}
670
671
672static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
673{
674 struct wpa_sm *sm = eloop_ctx;
675 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Request PTK rekeying");
676 wpa_sm_key_request(sm, 0, 1);
677}
678
679
680static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
681 const struct wpa_eapol_key *key)
682{
683 int keylen, rsclen;
684 enum wpa_alg alg;
685 const u8 *key_rsc;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800686
687 if (!sm->tk_to_set) {
688 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
689 "WPA: Do not re-install same PTK to the driver");
690 return 0;
691 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700692
693 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
694 "WPA: Installing PTK to the driver");
695
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700696 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700697 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Pairwise Cipher "
698 "Suite: NONE - do not use pairwise keys");
699 return 0;
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700700 }
701
702 if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700703 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
704 "WPA: Unsupported pairwise cipher %d",
705 sm->pairwise_cipher);
706 return -1;
707 }
708
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700709 alg = wpa_cipher_to_alg(sm->pairwise_cipher);
710 keylen = wpa_cipher_key_len(sm->pairwise_cipher);
711 rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
712
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800713 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700714 key_rsc = null_rsc;
715 } else {
716 key_rsc = key->key_rsc;
717 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
718 }
719
720 if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800721 sm->ptk.tk, keylen) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700722 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
723 "WPA: Failed to set PTK to the "
724 "driver (alg=%d keylen=%d bssid=" MACSTR ")",
725 alg, keylen, MAC2STR(sm->bssid));
726 return -1;
727 }
728
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800729 /* TK is not needed anymore in supplicant */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800730 os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800731 sm->tk_to_set = 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800732
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700733 if (sm->wpa_ptk_rekey) {
734 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
735 eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
736 sm, NULL);
737 }
738
739 return 0;
740}
741
742
743static int wpa_supplicant_check_group_cipher(struct wpa_sm *sm,
744 int group_cipher,
745 int keylen, int maxkeylen,
746 int *key_rsc_len,
747 enum wpa_alg *alg)
748{
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700749 int klen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700750
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700751 *alg = wpa_cipher_to_alg(group_cipher);
752 if (*alg == WPA_ALG_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700753 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
754 "WPA: Unsupported Group Cipher %d",
755 group_cipher);
756 return -1;
757 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700758 *key_rsc_len = wpa_cipher_rsc_len(group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700759
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700760 klen = wpa_cipher_key_len(group_cipher);
761 if (keylen != klen || maxkeylen < klen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700762 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
763 "WPA: Unsupported %s Group Cipher key length %d (%d)",
764 wpa_cipher_txt(group_cipher), keylen, maxkeylen);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700765 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700766 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700767 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700768}
769
770
771struct wpa_gtk_data {
772 enum wpa_alg alg;
773 int tx, key_rsc_len, keyidx;
774 u8 gtk[32];
775 int gtk_len;
776};
777
778
779static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
780 const struct wpa_gtk_data *gd,
781 const u8 *key_rsc)
782{
783 const u8 *_gtk = gd->gtk;
784 u8 gtk_buf[32];
785
786 wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
787 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
788 "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
789 gd->keyidx, gd->tx, gd->gtk_len);
790 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
791 if (sm->group_cipher == WPA_CIPHER_TKIP) {
792 /* Swap Tx/Rx keys for Michael MIC */
793 os_memcpy(gtk_buf, gd->gtk, 16);
794 os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
795 os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
796 _gtk = gtk_buf;
797 }
798 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
799 if (wpa_sm_set_key(sm, gd->alg, NULL,
800 gd->keyidx, 1, key_rsc, gd->key_rsc_len,
801 _gtk, gd->gtk_len) < 0) {
802 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
803 "WPA: Failed to set GTK to the driver "
804 "(Group only)");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700805 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700806 return -1;
807 }
808 } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
809 gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
810 _gtk, gd->gtk_len) < 0) {
811 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
812 "WPA: Failed to set GTK to "
813 "the driver (alg=%d keylen=%d keyidx=%d)",
814 gd->alg, gd->gtk_len, gd->keyidx);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700815 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700816 return -1;
817 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700818 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700819
820 return 0;
821}
822
823
824static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
825 int tx)
826{
827 if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
828 /* Ignore Tx bit for GTK if a pairwise key is used. One AP
829 * seemed to set this bit (incorrectly, since Tx is only when
830 * doing Group Key only APs) and without this workaround, the
831 * data connection does not work because wpa_supplicant
832 * configured non-zero keyidx to be used for unicast. */
833 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
834 "WPA: Tx bit set for GTK, but pairwise "
835 "keys are used - ignore Tx bit");
836 return 0;
837 }
838 return tx;
839}
840
841
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800842static int wpa_supplicant_rsc_relaxation(const struct wpa_sm *sm,
843 const u8 *rsc)
844{
845 int rsclen;
846
847 if (!sm->wpa_rsc_relaxation)
848 return 0;
849
850 rsclen = wpa_cipher_rsc_len(sm->group_cipher);
851
852 /*
853 * Try to detect RSC (endian) corruption issue where the AP sends
854 * the RSC bytes in EAPOL-Key message in the wrong order, both if
855 * it's actually a 6-byte field (as it should be) and if it treats
856 * it as an 8-byte field.
857 * An AP model known to have this bug is the Sapido RB-1632.
858 */
859 if (rsclen == 6 && ((rsc[5] && !rsc[0]) || rsc[6] || rsc[7])) {
860 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
861 "RSC %02x%02x%02x%02x%02x%02x%02x%02x is likely bogus, using 0",
862 rsc[0], rsc[1], rsc[2], rsc[3],
863 rsc[4], rsc[5], rsc[6], rsc[7]);
864
865 return 1;
866 }
867
868 return 0;
869}
870
871
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700872static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
873 const struct wpa_eapol_key *key,
874 const u8 *gtk, size_t gtk_len,
875 int key_info)
876{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700877 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800878 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700879
880 /*
881 * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
882 * GTK KDE format:
883 * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]
884 * Reserved [bits 0-7]
885 * GTK
886 */
887
888 os_memset(&gd, 0, sizeof(gd));
889 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
890 gtk, gtk_len);
891
892 if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
893 return -1;
894
895 gd.keyidx = gtk[0] & 0x3;
896 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
897 !!(gtk[0] & BIT(2)));
898 gtk += 2;
899 gtk_len -= 2;
900
901 os_memcpy(gd.gtk, gtk, gtk_len);
902 gd.gtk_len = gtk_len;
903
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800904 key_rsc = key->key_rsc;
905 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
906 key_rsc = null_rsc;
907
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800908 if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED &&
909 (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
910 gtk_len, gtk_len,
911 &gd.key_rsc_len, &gd.alg) ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800912 wpa_supplicant_install_gtk(sm, &gd, key_rsc))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700913 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
914 "RSN: Failed to install GTK");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700915 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700916 return -1;
917 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700918 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700919
920 wpa_supplicant_key_neg_complete(sm, sm->bssid,
921 key_info & WPA_KEY_INFO_SECURE);
922 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700923}
924
925
926static int ieee80211w_set_keys(struct wpa_sm *sm,
927 struct wpa_eapol_ie_parse *ie)
928{
929#ifdef CONFIG_IEEE80211W
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700930 if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700931 return 0;
932
933 if (ie->igtk) {
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700934 size_t len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700935 const struct wpa_igtk_kde *igtk;
936 u16 keyidx;
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700937 len = wpa_cipher_key_len(sm->mgmt_group_cipher);
938 if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700939 return -1;
940 igtk = (const struct wpa_igtk_kde *) ie->igtk;
941 keyidx = WPA_GET_LE16(igtk->keyid);
942 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d "
943 "pn %02x%02x%02x%02x%02x%02x",
944 keyidx, MAC2STR(igtk->pn));
945 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700946 igtk->igtk, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700947 if (keyidx > 4095) {
948 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
949 "WPA: Invalid IGTK KeyID %d", keyidx);
950 return -1;
951 }
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700952 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
953 broadcast_ether_addr,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700954 keyidx, 0, igtk->pn, sizeof(igtk->pn),
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700955 igtk->igtk, len) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700956 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
957 "WPA: Failed to configure IGTK to the driver");
958 return -1;
959 }
960 }
961
962 return 0;
963#else /* CONFIG_IEEE80211W */
964 return 0;
965#endif /* CONFIG_IEEE80211W */
966}
967
968
969static void wpa_report_ie_mismatch(struct wpa_sm *sm,
970 const char *reason, const u8 *src_addr,
971 const u8 *wpa_ie, size_t wpa_ie_len,
972 const u8 *rsn_ie, size_t rsn_ie_len)
973{
974 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",
975 reason, MAC2STR(src_addr));
976
977 if (sm->ap_wpa_ie) {
978 wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
979 sm->ap_wpa_ie, sm->ap_wpa_ie_len);
980 }
981 if (wpa_ie) {
982 if (!sm->ap_wpa_ie) {
983 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
984 "WPA: No WPA IE in Beacon/ProbeResp");
985 }
986 wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
987 wpa_ie, wpa_ie_len);
988 }
989
990 if (sm->ap_rsn_ie) {
991 wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
992 sm->ap_rsn_ie, sm->ap_rsn_ie_len);
993 }
994 if (rsn_ie) {
995 if (!sm->ap_rsn_ie) {
996 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
997 "WPA: No RSN IE in Beacon/ProbeResp");
998 }
999 wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
1000 rsn_ie, rsn_ie_len);
1001 }
1002
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001003 wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001004}
1005
1006
1007#ifdef CONFIG_IEEE80211R
1008
1009static int ft_validate_mdie(struct wpa_sm *sm,
1010 const unsigned char *src_addr,
1011 struct wpa_eapol_ie_parse *ie,
1012 const u8 *assoc_resp_mdie)
1013{
1014 struct rsn_mdie *mdie;
1015
1016 mdie = (struct rsn_mdie *) (ie->mdie + 2);
1017 if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
1018 os_memcmp(mdie->mobility_domain, sm->mobility_domain,
1019 MOBILITY_DOMAIN_ID_LEN) != 0) {
1020 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did "
1021 "not match with the current mobility domain");
1022 return -1;
1023 }
1024
1025 if (assoc_resp_mdie &&
1026 (assoc_resp_mdie[1] != ie->mdie[1] ||
1027 os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
1028 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch");
1029 wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
1030 ie->mdie, 2 + ie->mdie[1]);
1031 wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
1032 assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
1033 return -1;
1034 }
1035
1036 return 0;
1037}
1038
1039
1040static int ft_validate_ftie(struct wpa_sm *sm,
1041 const unsigned char *src_addr,
1042 struct wpa_eapol_ie_parse *ie,
1043 const u8 *assoc_resp_ftie)
1044{
1045 if (ie->ftie == NULL) {
1046 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1047 "FT: No FTIE in EAPOL-Key msg 3/4");
1048 return -1;
1049 }
1050
1051 if (assoc_resp_ftie == NULL)
1052 return 0;
1053
1054 if (assoc_resp_ftie[1] != ie->ftie[1] ||
1055 os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
1056 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch");
1057 wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
1058 ie->ftie, 2 + ie->ftie[1]);
1059 wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
1060 assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
1061 return -1;
1062 }
1063
1064 return 0;
1065}
1066
1067
1068static int ft_validate_rsnie(struct wpa_sm *sm,
1069 const unsigned char *src_addr,
1070 struct wpa_eapol_ie_parse *ie)
1071{
1072 struct wpa_ie_data rsn;
1073
1074 if (!ie->rsn_ie)
1075 return 0;
1076
1077 /*
1078 * Verify that PMKR1Name from EAPOL-Key message 3/4
1079 * matches with the value we derived.
1080 */
1081 if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
1082 rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
1083 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in "
1084 "FT 4-way handshake message 3/4");
1085 return -1;
1086 }
1087
Dmitry Shmidtc2817022014-07-02 10:32:10 -07001088 if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
1089 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001090 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1091 "FT: PMKR1Name mismatch in "
1092 "FT 4-way handshake message 3/4");
1093 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
1094 rsn.pmkid, WPA_PMK_NAME_LEN);
1095 wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
1096 sm->pmk_r1_name, WPA_PMK_NAME_LEN);
1097 return -1;
1098 }
1099
1100 return 0;
1101}
1102
1103
1104static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
1105 const unsigned char *src_addr,
1106 struct wpa_eapol_ie_parse *ie)
1107{
1108 const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
1109
1110 if (sm->assoc_resp_ies) {
1111 pos = sm->assoc_resp_ies;
1112 end = pos + sm->assoc_resp_ies_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001113 while (end - pos > 2) {
1114 if (2 + pos[1] > end - pos)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001115 break;
1116 switch (*pos) {
1117 case WLAN_EID_MOBILITY_DOMAIN:
1118 mdie = pos;
1119 break;
1120 case WLAN_EID_FAST_BSS_TRANSITION:
1121 ftie = pos;
1122 break;
1123 }
1124 pos += 2 + pos[1];
1125 }
1126 }
1127
1128 if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
1129 ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
1130 ft_validate_rsnie(sm, src_addr, ie) < 0)
1131 return -1;
1132
1133 return 0;
1134}
1135
1136#endif /* CONFIG_IEEE80211R */
1137
1138
1139static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
1140 const unsigned char *src_addr,
1141 struct wpa_eapol_ie_parse *ie)
1142{
1143 if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {
1144 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1145 "WPA: No WPA/RSN IE for this AP known. "
1146 "Trying to get from scan results");
1147 if (wpa_sm_get_beacon_ie(sm) < 0) {
1148 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1149 "WPA: Could not find AP from "
1150 "the scan results");
1151 } else {
1152 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
1153 "WPA: Found the current AP from "
1154 "updated scan results");
1155 }
1156 }
1157
1158 if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
1159 (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
1160 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1161 "with IE in Beacon/ProbeResp (no IE?)",
1162 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1163 ie->rsn_ie, ie->rsn_ie_len);
1164 return -1;
1165 }
1166
1167 if ((ie->wpa_ie && sm->ap_wpa_ie &&
1168 (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
1169 os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
1170 (ie->rsn_ie && sm->ap_rsn_ie &&
1171 wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
1172 sm->ap_rsn_ie, sm->ap_rsn_ie_len,
1173 ie->rsn_ie, ie->rsn_ie_len))) {
1174 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1175 "with IE in Beacon/ProbeResp",
1176 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1177 ie->rsn_ie, ie->rsn_ie_len);
1178 return -1;
1179 }
1180
1181 if (sm->proto == WPA_PROTO_WPA &&
1182 ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
1183 wpa_report_ie_mismatch(sm, "Possible downgrade attack "
1184 "detected - RSN was enabled and RSN IE "
1185 "was in msg 3/4, but not in "
1186 "Beacon/ProbeResp",
1187 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1188 ie->rsn_ie, ie->rsn_ie_len);
1189 return -1;
1190 }
1191
1192#ifdef CONFIG_IEEE80211R
1193 if (wpa_key_mgmt_ft(sm->key_mgmt) &&
1194 wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
1195 return -1;
1196#endif /* CONFIG_IEEE80211R */
1197
1198 return 0;
1199}
1200
1201
1202/**
1203 * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake
1204 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1205 * @dst: Destination address for the frame
1206 * @key: Pointer to the EAPOL-Key frame header
1207 * @ver: Version bits from EAPOL-Key Key Info
1208 * @key_info: Key Info
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001209 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001210 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001211 */
1212int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
1213 const struct wpa_eapol_key *key,
1214 u16 ver, u16 key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001215 struct wpa_ptk *ptk)
1216{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001217 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001218 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001219 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001220
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001221 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001222 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001223 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001224 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001225 if (rbuf == NULL)
1226 return -1;
1227
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001228 reply->type = (sm->proto == WPA_PROTO_RSN ||
1229 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001230 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1231 key_info &= WPA_KEY_INFO_SECURE;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001232 key_info |= ver | WPA_KEY_INFO_KEY_TYPE;
1233 if (mic_len)
1234 key_info |= WPA_KEY_INFO_MIC;
1235 else
1236 key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001237 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001238 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001239 WPA_PUT_BE16(reply->key_length, 0);
1240 else
1241 os_memcpy(reply->key_length, key->key_length, 2);
1242 os_memcpy(reply->replay_counter, key->replay_counter,
1243 WPA_REPLAY_COUNTER_LEN);
1244
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001245 key_mic = (u8 *) (reply + 1);
1246 WPA_PUT_BE16(key_mic + mic_len, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001247
1248 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001249 return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen,
1250 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001251}
1252
1253
1254static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
1255 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001256 u16 ver, const u8 *key_data,
1257 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001258{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001259 u16 key_info, keylen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001260 struct wpa_eapol_ie_parse ie;
1261
1262 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
1263 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 3 of 4-Way "
1264 "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
1265
1266 key_info = WPA_GET_BE16(key->key_info);
1267
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001268 wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", key_data, key_data_len);
1269 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001270 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001271 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1272 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1273 "WPA: GTK IE in unencrypted key data");
1274 goto failed;
1275 }
1276#ifdef CONFIG_IEEE80211W
1277 if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1278 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1279 "WPA: IGTK KDE in unencrypted key data");
1280 goto failed;
1281 }
1282
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07001283 if (ie.igtk &&
1284 wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) &&
1285 ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN +
1286 (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001287 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1288 "WPA: Invalid IGTK KDE length %lu",
1289 (unsigned long) ie.igtk_len);
1290 goto failed;
1291 }
1292#endif /* CONFIG_IEEE80211W */
1293
1294 if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
1295 goto failed;
1296
1297 if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
1298 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1299 "WPA: ANonce from message 1 of 4-Way Handshake "
1300 "differs from 3 of 4-Way Handshake - drop packet (src="
1301 MACSTR ")", MAC2STR(sm->bssid));
1302 goto failed;
1303 }
1304
1305 keylen = WPA_GET_BE16(key->key_length);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07001306 if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) {
1307 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1308 "WPA: Invalid %s key length %d (src=" MACSTR
1309 ")", wpa_cipher_txt(sm->pairwise_cipher), keylen,
1310 MAC2STR(sm->bssid));
1311 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001312 }
1313
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08001314#ifdef CONFIG_P2P
1315 if (ie.ip_addr_alloc) {
1316 os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4);
1317 wpa_hexdump(MSG_DEBUG, "P2P: IP address info",
1318 sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr));
1319 }
1320#endif /* CONFIG_P2P */
1321
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001322 if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001323 &sm->ptk) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001324 goto failed;
1325 }
1326
1327 /* SNonce was successfully used in msg 3/4, so mark it to be renewed
1328 * for the next 4-Way Handshake. If msg 3 is received again, the old
1329 * SNonce will still be used to avoid changing PTK. */
1330 sm->renew_snonce = 1;
1331
1332 if (key_info & WPA_KEY_INFO_INSTALL) {
1333 if (wpa_supplicant_install_ptk(sm, key))
1334 goto failed;
1335 }
1336
1337 if (key_info & WPA_KEY_INFO_SECURE) {
1338 wpa_sm_mlme_setprotection(
1339 sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
1340 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1341 eapol_sm_notify_portValid(sm->eapol, TRUE);
1342 }
1343 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1344
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001345 if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) {
1346 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1347 key_info & WPA_KEY_INFO_SECURE);
1348 } else if (ie.gtk &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001349 wpa_supplicant_pairwise_gtk(sm, key,
1350 ie.gtk, ie.gtk_len, key_info) < 0) {
1351 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1352 "RSN: Failed to configure GTK");
1353 goto failed;
1354 }
1355
1356 if (ieee80211w_set_keys(sm, &ie) < 0) {
1357 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1358 "RSN: Failed to configure IGTK");
1359 goto failed;
1360 }
1361
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001362 if (ie.gtk)
1363 wpa_sm_set_rekey_offload(sm);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001364
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001365 if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) {
1366 struct rsn_pmksa_cache_entry *sa;
1367
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001368 sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001369 sm->ptk.kck, sm->ptk.kck_len,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001370 sm->bssid, sm->own_addr,
1371 sm->network_ctx, sm->key_mgmt);
1372 if (!sm->cur_pmksa)
1373 sm->cur_pmksa = sa;
1374 }
1375
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001376 sm->msg_3_of_4_ok = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001377 return;
1378
1379failed:
1380 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1381}
1382
1383
1384static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
1385 const u8 *keydata,
1386 size_t keydatalen,
1387 u16 key_info,
1388 struct wpa_gtk_data *gd)
1389{
1390 int maxkeylen;
1391 struct wpa_eapol_ie_parse ie;
1392
1393 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001394 if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0)
1395 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001396 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1397 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1398 "WPA: GTK IE in unencrypted key data");
1399 return -1;
1400 }
1401 if (ie.gtk == NULL) {
1402 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1403 "WPA: No GTK IE in Group Key msg 1/2");
1404 return -1;
1405 }
1406 maxkeylen = gd->gtk_len = ie.gtk_len - 2;
1407
1408 if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1409 gd->gtk_len, maxkeylen,
1410 &gd->key_rsc_len, &gd->alg))
1411 return -1;
1412
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001413 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in group key handshake",
1414 ie.gtk, ie.gtk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001415 gd->keyidx = ie.gtk[0] & 0x3;
1416 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
1417 !!(ie.gtk[0] & BIT(2)));
1418 if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
1419 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1420 "RSN: Too long GTK in GTK IE (len=%lu)",
1421 (unsigned long) ie.gtk_len - 2);
1422 return -1;
1423 }
1424 os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
1425
1426 if (ieee80211w_set_keys(sm, &ie) < 0)
1427 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1428 "RSN: Failed to configure IGTK");
1429
1430 return 0;
1431}
1432
1433
1434static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
1435 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001436 const u8 *key_data,
1437 size_t key_data_len, u16 key_info,
1438 u16 ver, struct wpa_gtk_data *gd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001439{
1440 size_t maxkeylen;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001441 u16 gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001442
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001443 gtk_len = WPA_GET_BE16(key->key_length);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001444 maxkeylen = key_data_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001445 if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1446 if (maxkeylen < 8) {
1447 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1448 "WPA: Too short maxkeylen (%lu)",
1449 (unsigned long) maxkeylen);
1450 return -1;
1451 }
1452 maxkeylen -= 8;
1453 }
1454
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001455 if (gtk_len > maxkeylen ||
1456 wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1457 gtk_len, maxkeylen,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001458 &gd->key_rsc_len, &gd->alg))
1459 return -1;
1460
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001461 gd->gtk_len = gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001462 gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1463 WPA_KEY_INFO_KEY_INDEX_SHIFT;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001464 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001465#ifdef CONFIG_NO_RC4
1466 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1467 "WPA: RC4 not supported in the build");
1468 return -1;
1469#else /* CONFIG_NO_RC4 */
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001470 u8 ek[32];
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001471 if (key_data_len > sizeof(gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001472 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1473 "WPA: RC4 key data too long (%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001474 (unsigned long) key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001475 return -1;
1476 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001477 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001478 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001479 os_memcpy(gd->gtk, key_data, key_data_len);
1480 if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001481 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001482 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1483 "WPA: RC4 failed");
1484 return -1;
1485 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001486 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001487#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001488 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001489 if (maxkeylen % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001490 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1491 "WPA: Unsupported AES-WRAP len %lu",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001492 (unsigned long) maxkeylen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001493 return -1;
1494 }
1495 if (maxkeylen > sizeof(gd->gtk)) {
1496 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1497 "WPA: AES-WRAP key data "
1498 "too long (keydatalen=%lu maxkeylen=%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001499 (unsigned long) key_data_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001500 (unsigned long) maxkeylen);
1501 return -1;
1502 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001503 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, maxkeylen / 8,
1504 key_data, gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001505 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1506 "WPA: AES unwrap failed - could not decrypt "
1507 "GTK");
1508 return -1;
1509 }
1510 } else {
1511 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1512 "WPA: Unsupported key_info type %d", ver);
1513 return -1;
1514 }
1515 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
1516 sm, !!(key_info & WPA_KEY_INFO_TXRX));
1517 return 0;
1518}
1519
1520
1521static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
1522 const struct wpa_eapol_key *key,
1523 int ver, u16 key_info)
1524{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001525 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001526 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001527 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001528
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001529 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001530 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001531 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001532 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001533 if (rbuf == NULL)
1534 return -1;
1535
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001536 reply->type = (sm->proto == WPA_PROTO_RSN ||
1537 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001538 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1539 key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001540 key_info |= ver | WPA_KEY_INFO_SECURE;
1541 if (mic_len)
1542 key_info |= WPA_KEY_INFO_MIC;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001543 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001544 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001545 WPA_PUT_BE16(reply->key_length, 0);
1546 else
1547 os_memcpy(reply->key_length, key->key_length, 2);
1548 os_memcpy(reply->replay_counter, key->replay_counter,
1549 WPA_REPLAY_COUNTER_LEN);
1550
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001551 key_mic = (u8 *) (reply + 1);
1552 WPA_PUT_BE16(key_mic + mic_len, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001553
1554 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001555 return wpa_eapol_key_send(sm, &sm->ptk, ver, sm->bssid, ETH_P_EAPOL,
1556 rbuf, rlen, key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001557}
1558
1559
1560static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
1561 const unsigned char *src_addr,
1562 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001563 const u8 *key_data,
1564 size_t key_data_len, u16 ver)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001565{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001566 u16 key_info;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001567 int rekey, ret;
1568 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001569 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001570
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001571 if (!sm->msg_3_of_4_ok) {
1572 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1573 "WPA: Group Key Handshake started prior to completion of 4-way handshake");
1574 goto failed;
1575 }
1576
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001577 os_memset(&gd, 0, sizeof(gd));
1578
1579 rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
1580 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of Group Key "
1581 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1582
1583 key_info = WPA_GET_BE16(key->key_info);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001584
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001585 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001586 ret = wpa_supplicant_process_1_of_2_rsn(sm, key_data,
1587 key_data_len, key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001588 &gd);
1589 } else {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001590 ret = wpa_supplicant_process_1_of_2_wpa(sm, key, key_data,
1591 key_data_len,
1592 key_info, ver, &gd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001593 }
1594
1595 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1596
1597 if (ret)
1598 goto failed;
1599
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001600 key_rsc = key->key_rsc;
1601 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
1602 key_rsc = null_rsc;
1603
1604 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc) ||
1605 wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001606 goto failed;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001607 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001608
1609 if (rekey) {
1610 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
1611 "completed with " MACSTR " [GTK=%s]",
1612 MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
1613 wpa_sm_cancel_auth_timeout(sm);
1614 wpa_sm_set_state(sm, WPA_COMPLETED);
1615 } else {
1616 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1617 key_info &
1618 WPA_KEY_INFO_SECURE);
1619 }
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001620
1621 wpa_sm_set_rekey_offload(sm);
1622
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001623 return;
1624
1625failed:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001626 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001627 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1628}
1629
1630
1631static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001632 struct wpa_eapol_key *key,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001633 u16 ver,
1634 const u8 *buf, size_t len)
1635{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001636 u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001637 int ok = 0;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001638 size_t mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001639
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001640 os_memcpy(mic, key + 1, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001641 if (sm->tptk_set) {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001642 os_memset(key + 1, 0, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001643 wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len, sm->key_mgmt,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001644 ver, buf, len, (u8 *) (key + 1));
1645 if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001646 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1647 "WPA: Invalid EAPOL-Key MIC "
1648 "when using TPTK - ignoring TPTK");
1649 } else {
1650 ok = 1;
1651 sm->tptk_set = 0;
1652 sm->ptk_set = 1;
1653 os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001654 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001655 }
1656 }
1657
1658 if (!ok && sm->ptk_set) {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001659 os_memset(key + 1, 0, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001660 wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len, sm->key_mgmt,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001661 ver, buf, len, (u8 *) (key + 1));
1662 if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001663 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1664 "WPA: Invalid EAPOL-Key MIC - "
1665 "dropping packet");
1666 return -1;
1667 }
1668 ok = 1;
1669 }
1670
1671 if (!ok) {
1672 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1673 "WPA: Could not verify EAPOL-Key MIC - "
1674 "dropping packet");
1675 return -1;
1676 }
1677
1678 os_memcpy(sm->rx_replay_counter, key->replay_counter,
1679 WPA_REPLAY_COUNTER_LEN);
1680 sm->rx_replay_counter_set = 1;
1681 return 0;
1682}
1683
1684
1685/* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
1686static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001687 struct wpa_eapol_key *key,
1688 size_t mic_len, u16 ver,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001689 u8 *key_data, size_t *key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001690{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001691 wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001692 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001693 if (!sm->ptk_set) {
1694 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1695 "WPA: PTK not available, cannot decrypt EAPOL-Key Key "
1696 "Data");
1697 return -1;
1698 }
1699
1700 /* Decrypt key data here so that this operation does not need
1701 * to be implemented separately for each message type. */
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001702 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001703#ifdef CONFIG_NO_RC4
1704 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1705 "WPA: RC4 not supported in the build");
1706 return -1;
1707#else /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001708 u8 ek[32];
1709 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001710 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001711 if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001712 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001713 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1714 "WPA: RC4 failed");
1715 return -1;
1716 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001717 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001718#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001719 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001720 ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001721 sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
1722 wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001723 u8 *buf;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001724 if (*key_data_len < 8 || *key_data_len % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001725 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001726 "WPA: Unsupported AES-WRAP len %u",
1727 (unsigned int) *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001728 return -1;
1729 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001730 *key_data_len -= 8; /* AES-WRAP adds 8 bytes */
1731 buf = os_malloc(*key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001732 if (buf == NULL) {
1733 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1734 "WPA: No memory for AES-UNWRAP buffer");
1735 return -1;
1736 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001737 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, *key_data_len / 8,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001738 key_data, buf)) {
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001739 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001740 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1741 "WPA: AES unwrap failed - "
1742 "could not decrypt EAPOL-Key key data");
1743 return -1;
1744 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001745 os_memcpy(key_data, buf, *key_data_len);
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001746 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001747 WPA_PUT_BE16(((u8 *) (key + 1)) + mic_len, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001748 } else {
1749 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1750 "WPA: Unsupported key_info type %d", ver);
1751 return -1;
1752 }
1753 wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001754 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001755 return 0;
1756}
1757
1758
1759/**
1760 * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted
1761 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1762 */
1763void wpa_sm_aborted_cached(struct wpa_sm *sm)
1764{
1765 if (sm && sm->cur_pmksa) {
1766 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1767 "RSN: Cancelling PMKSA caching attempt");
1768 sm->cur_pmksa = NULL;
1769 }
1770}
1771
1772
1773static void wpa_eapol_key_dump(struct wpa_sm *sm,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001774 const struct wpa_eapol_key *key,
1775 unsigned int key_data_len,
1776 const u8 *mic, unsigned int mic_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001777{
1778#ifndef CONFIG_NO_STDOUT_DEBUG
1779 u16 key_info = WPA_GET_BE16(key->key_info);
1780
1781 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, " EAPOL-Key type=%d", key->type);
1782 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1783 " key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s%s%s%s%s%s%s%s)",
1784 key_info, key_info & WPA_KEY_INFO_TYPE_MASK,
1785 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1786 WPA_KEY_INFO_KEY_INDEX_SHIFT,
1787 (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,
1788 key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",
1789 key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",
1790 key_info & WPA_KEY_INFO_ACK ? " Ack" : "",
1791 key_info & WPA_KEY_INFO_MIC ? " MIC" : "",
1792 key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",
1793 key_info & WPA_KEY_INFO_ERROR ? " Error" : "",
1794 key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",
1795 key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
1796 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1797 " key_length=%u key_data_length=%u",
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001798 WPA_GET_BE16(key->key_length), key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001799 wpa_hexdump(MSG_DEBUG, " replay_counter",
1800 key->replay_counter, WPA_REPLAY_COUNTER_LEN);
1801 wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN);
1802 wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16);
1803 wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8);
1804 wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001805 wpa_hexdump(MSG_DEBUG, " key_mic", mic, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001806#endif /* CONFIG_NO_STDOUT_DEBUG */
1807}
1808
1809
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001810#ifdef CONFIG_FILS
1811static int wpa_supp_aead_decrypt(struct wpa_sm *sm, u8 *buf, size_t buf_len,
1812 size_t *key_data_len)
1813{
1814 struct wpa_ptk *ptk;
1815 struct ieee802_1x_hdr *hdr;
1816 struct wpa_eapol_key *key;
1817 u8 *pos, *tmp;
1818 const u8 *aad[1];
1819 size_t aad_len[1];
1820
1821 if (*key_data_len < AES_BLOCK_SIZE) {
1822 wpa_printf(MSG_INFO, "No room for AES-SIV data in the frame");
1823 return -1;
1824 }
1825
1826 if (sm->tptk_set)
1827 ptk = &sm->tptk;
1828 else if (sm->ptk_set)
1829 ptk = &sm->ptk;
1830 else
1831 return -1;
1832
1833 hdr = (struct ieee802_1x_hdr *) buf;
1834 key = (struct wpa_eapol_key *) (hdr + 1);
1835 pos = (u8 *) (key + 1);
1836 pos += 2; /* Pointing at the Encrypted Key Data field */
1837
1838 tmp = os_malloc(*key_data_len);
1839 if (!tmp)
1840 return -1;
1841
1842 /* AES-SIV AAD from EAPOL protocol version field (inclusive) to
1843 * to Key Data (exclusive). */
1844 aad[0] = buf;
1845 aad_len[0] = pos - buf;
1846 if (aes_siv_decrypt(ptk->kek, ptk->kek_len, pos, *key_data_len,
1847 1, aad, aad_len, tmp) < 0) {
1848 wpa_printf(MSG_INFO, "Invalid AES-SIV data in the frame");
1849 bin_clear_free(tmp, *key_data_len);
1850 return -1;
1851 }
1852
1853 /* AEAD decryption and validation completed successfully */
1854 (*key_data_len) -= AES_BLOCK_SIZE;
1855 wpa_hexdump_key(MSG_DEBUG, "WPA: Decrypted Key Data",
1856 tmp, *key_data_len);
1857
1858 /* Replace Key Data field with the decrypted version */
1859 os_memcpy(pos, tmp, *key_data_len);
1860 pos -= 2; /* Key Data Length field */
1861 WPA_PUT_BE16(pos, *key_data_len);
1862 bin_clear_free(tmp, *key_data_len);
1863
1864 if (sm->tptk_set) {
1865 sm->tptk_set = 0;
1866 sm->ptk_set = 1;
1867 os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
1868 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
1869 }
1870
1871 os_memcpy(sm->rx_replay_counter, key->replay_counter,
1872 WPA_REPLAY_COUNTER_LEN);
1873 sm->rx_replay_counter_set = 1;
1874
1875 return 0;
1876}
1877#endif /* CONFIG_FILS */
1878
1879
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001880/**
1881 * wpa_sm_rx_eapol - Process received WPA EAPOL frames
1882 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1883 * @src_addr: Source MAC address of the EAPOL packet
1884 * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
1885 * @len: Length of the EAPOL frame
1886 * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
1887 *
1888 * This function is called for each received EAPOL frame. Other than EAPOL-Key
1889 * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
1890 * only processing WPA and WPA2 EAPOL-Key frames.
1891 *
1892 * The received EAPOL-Key packets are validated and valid packets are replied
1893 * to. In addition, key material (PTK, GTK) is configured at the end of a
1894 * successful key handshake.
1895 */
1896int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
1897 const u8 *buf, size_t len)
1898{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001899 size_t plen, data_len, key_data_len;
1900 const struct ieee802_1x_hdr *hdr;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001901 struct wpa_eapol_key *key;
1902 u16 key_info, ver;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001903 u8 *tmp = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001904 int ret = -1;
1905 struct wpa_peerkey *peerkey = NULL;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001906 u8 *mic, *key_data;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001907 size_t mic_len, keyhdrlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001908
1909#ifdef CONFIG_IEEE80211R
1910 sm->ft_completed = 0;
1911#endif /* CONFIG_IEEE80211R */
1912
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001913 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001914 keyhdrlen = sizeof(*key) + mic_len + 2;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001915
1916 if (len < sizeof(*hdr) + keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001917 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1918 "WPA: EAPOL frame too short to be a WPA "
1919 "EAPOL-Key (len %lu, expecting at least %lu)",
1920 (unsigned long) len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001921 (unsigned long) sizeof(*hdr) + keyhdrlen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001922 return 0;
1923 }
1924
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001925 hdr = (const struct ieee802_1x_hdr *) buf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001926 plen = be_to_host16(hdr->length);
1927 data_len = plen + sizeof(*hdr);
1928 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1929 "IEEE 802.1X RX: version=%d type=%d length=%lu",
1930 hdr->version, hdr->type, (unsigned long) plen);
1931
1932 if (hdr->version < EAPOL_VERSION) {
1933 /* TODO: backwards compatibility */
1934 }
1935 if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
1936 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1937 "WPA: EAPOL frame (type %u) discarded, "
1938 "not a Key frame", hdr->type);
1939 ret = 0;
1940 goto out;
1941 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001942 wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001943 if (plen > len - sizeof(*hdr) || plen < keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001944 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1945 "WPA: EAPOL frame payload size %lu "
1946 "invalid (frame size %lu)",
1947 (unsigned long) plen, (unsigned long) len);
1948 ret = 0;
1949 goto out;
1950 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001951 if (data_len < len) {
1952 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1953 "WPA: ignoring %lu bytes after the IEEE 802.1X data",
1954 (unsigned long) len - data_len);
1955 }
1956
1957 /*
1958 * Make a copy of the frame since we need to modify the buffer during
1959 * MAC validation and Key Data decryption.
1960 */
1961 tmp = os_malloc(data_len);
1962 if (tmp == NULL)
1963 goto out;
1964 os_memcpy(tmp, buf, data_len);
1965 key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr));
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001966 mic = (u8 *) (key + 1);
1967 key_data = mic + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001968
1969 if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
1970 {
1971 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1972 "WPA: EAPOL-Key type (%d) unknown, discarded",
1973 key->type);
1974 ret = 0;
1975 goto out;
1976 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001977
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001978 key_data_len = WPA_GET_BE16(mic + mic_len);
1979 wpa_eapol_key_dump(sm, key, key_data_len, mic, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001980
1981 if (key_data_len > plen - keyhdrlen) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001982 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
1983 "frame - key_data overflow (%u > %u)",
1984 (unsigned int) key_data_len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001985 (unsigned int) (plen - keyhdrlen));
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001986 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001987 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001988
1989 eapol_sm_notify_lower_layer_success(sm->eapol, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001990 key_info = WPA_GET_BE16(key->key_info);
1991 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1992 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1993#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
1994 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
1995#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001996 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001997 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001998 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001999 sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002000 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2001 "WPA: Unsupported EAPOL-Key descriptor version %d",
2002 ver);
2003 goto out;
2004 }
2005
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002006 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN &&
2007 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
2008 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2009 "OSEN: Unsupported EAPOL-Key descriptor version %d",
2010 ver);
2011 goto out;
2012 }
2013
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002014 if ((wpa_key_mgmt_suite_b(sm->key_mgmt) ||
2015 wpa_key_mgmt_fils(sm->key_mgmt)) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002016 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
2017 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2018 "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)",
2019 ver);
2020 goto out;
2021 }
2022
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002023#ifdef CONFIG_IEEE80211R
2024 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
2025 /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
2026 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
2027 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2028 "FT: AP did not use AES-128-CMAC");
2029 goto out;
2030 }
2031 } else
2032#endif /* CONFIG_IEEE80211R */
2033#ifdef CONFIG_IEEE80211W
2034 if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002035 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002036 sm->key_mgmt != WPA_KEY_MGMT_OSEN &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002037 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002038 !wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002039 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2040 "WPA: AP did not use the "
2041 "negotiated AES-128-CMAC");
2042 goto out;
2043 }
2044 } else
2045#endif /* CONFIG_IEEE80211W */
2046 if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002047 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002048 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002049 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
2050 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2051 "WPA: CCMP is used, but EAPOL-Key "
2052 "descriptor version (%d) is not 2", ver);
2053 if (sm->group_cipher != WPA_CIPHER_CCMP &&
2054 !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
2055 /* Earlier versions of IEEE 802.11i did not explicitly
2056 * require version 2 descriptor for all EAPOL-Key
2057 * packets, so allow group keys to use version 1 if
2058 * CCMP is not used for them. */
2059 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2060 "WPA: Backwards compatibility: allow invalid "
2061 "version for non-CCMP group keys");
Jouni Malinen658fb4a2014-11-14 20:57:05 +02002062 } else if (ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
2063 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2064 "WPA: Interoperability workaround: allow incorrect (should have been HMAC-SHA1), but stronger (is AES-128-CMAC), descriptor version to be used");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002065 } else
2066 goto out;
Dmitry Shmidt71757432014-06-02 13:50:35 -07002067 } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002068 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt71757432014-06-02 13:50:35 -07002069 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002070 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2071 "WPA: GCMP is used, but EAPOL-Key "
2072 "descriptor version (%d) is not 2", ver);
2073 goto out;
2074 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002075
2076#ifdef CONFIG_PEERKEY
2077 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
2078 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
2079 break;
2080 }
2081
2082 if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
2083 if (!peerkey->initiator && peerkey->replay_counter_set &&
2084 os_memcmp(key->replay_counter, peerkey->replay_counter,
2085 WPA_REPLAY_COUNTER_LEN) <= 0) {
2086 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2087 "RSN: EAPOL-Key Replay Counter did not "
2088 "increase (STK) - dropping packet");
2089 goto out;
2090 } else if (peerkey->initiator) {
2091 u8 _tmp[WPA_REPLAY_COUNTER_LEN];
2092 os_memcpy(_tmp, key->replay_counter,
2093 WPA_REPLAY_COUNTER_LEN);
2094 inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
2095 if (os_memcmp(_tmp, peerkey->replay_counter,
2096 WPA_REPLAY_COUNTER_LEN) != 0) {
2097 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2098 "RSN: EAPOL-Key Replay "
2099 "Counter did not match (STK) - "
2100 "dropping packet");
2101 goto out;
2102 }
2103 }
2104 }
2105
2106 if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
2107 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2108 "RSN: Ack bit in key_info from STK peer");
2109 goto out;
2110 }
2111#endif /* CONFIG_PEERKEY */
2112
2113 if (!peerkey && sm->rx_replay_counter_set &&
2114 os_memcmp(key->replay_counter, sm->rx_replay_counter,
2115 WPA_REPLAY_COUNTER_LEN) <= 0) {
2116 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2117 "WPA: EAPOL-Key Replay Counter did not increase - "
2118 "dropping packet");
2119 goto out;
2120 }
2121
2122 if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
2123#ifdef CONFIG_PEERKEY
2124 && (peerkey == NULL || !peerkey->initiator)
2125#endif /* CONFIG_PEERKEY */
2126 ) {
2127 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2128 "WPA: No Ack bit in key_info");
2129 goto out;
2130 }
2131
2132 if (key_info & WPA_KEY_INFO_REQUEST) {
2133 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2134 "WPA: EAPOL-Key with Request bit - dropped");
2135 goto out;
2136 }
2137
2138 if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002139 wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002140 goto out;
2141
2142#ifdef CONFIG_PEERKEY
2143 if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002144 peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002145 data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002146 goto out;
2147#endif /* CONFIG_PEERKEY */
2148
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002149#ifdef CONFIG_FILS
2150 if (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
2151 if (wpa_supp_aead_decrypt(sm, tmp, data_len, &key_data_len))
2152 goto out;
2153 }
2154#endif /* CONFIG_FILS */
2155
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002156 if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002157 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) && mic_len) {
2158 if (wpa_supplicant_decrypt_key_data(sm, key, mic_len,
2159 ver, key_data,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002160 &key_data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002161 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002162 }
2163
2164 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
2165 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
2166 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2167 "WPA: Ignored EAPOL-Key (Pairwise) with "
2168 "non-zero key index");
2169 goto out;
2170 }
2171 if (peerkey) {
2172 /* PeerKey 4-Way Handshake */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07002173 peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
2174 key_data, key_data_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002175 } else if (key_info & (WPA_KEY_INFO_MIC |
2176 WPA_KEY_INFO_ENCR_KEY_DATA)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002177 /* 3/4 4-Way Handshake */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002178 wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
2179 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002180 } else {
2181 /* 1/4 4-Way Handshake */
2182 wpa_supplicant_process_1_of_4(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002183 ver, key_data,
2184 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002185 }
2186 } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
2187 /* PeerKey SMK Handshake */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002188 peerkey_rx_eapol_smk(sm, src_addr, key, key_data_len, key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002189 ver);
2190 } else {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002191 if ((mic_len && (key_info & WPA_KEY_INFO_MIC)) ||
2192 (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002193 /* 1/2 Group Key Handshake */
2194 wpa_supplicant_process_1_of_2(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002195 key_data, key_data_len,
2196 ver);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002197 } else {
2198 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002199 "WPA: EAPOL-Key (Group) without Mic/Encr bit - "
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002200 "dropped");
2201 }
2202 }
2203
2204 ret = 1;
2205
2206out:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002207 bin_clear_free(tmp, data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002208 return ret;
2209}
2210
2211
2212#ifdef CONFIG_CTRL_IFACE
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002213static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
2214{
2215 switch (sm->key_mgmt) {
2216 case WPA_KEY_MGMT_IEEE8021X:
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002217 return ((sm->proto == WPA_PROTO_RSN ||
2218 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002219 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
2220 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
2221 case WPA_KEY_MGMT_PSK:
2222 return (sm->proto == WPA_PROTO_RSN ?
2223 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
2224 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
2225#ifdef CONFIG_IEEE80211R
2226 case WPA_KEY_MGMT_FT_IEEE8021X:
2227 return RSN_AUTH_KEY_MGMT_FT_802_1X;
2228 case WPA_KEY_MGMT_FT_PSK:
2229 return RSN_AUTH_KEY_MGMT_FT_PSK;
2230#endif /* CONFIG_IEEE80211R */
2231#ifdef CONFIG_IEEE80211W
2232 case WPA_KEY_MGMT_IEEE8021X_SHA256:
2233 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
2234 case WPA_KEY_MGMT_PSK_SHA256:
2235 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
2236#endif /* CONFIG_IEEE80211W */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002237 case WPA_KEY_MGMT_CCKM:
2238 return (sm->proto == WPA_PROTO_RSN ?
2239 RSN_AUTH_KEY_MGMT_CCKM:
2240 WPA_AUTH_KEY_MGMT_CCKM);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002241 case WPA_KEY_MGMT_WPA_NONE:
2242 return WPA_AUTH_KEY_MGMT_NONE;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002243 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
2244 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002245 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
2246 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002247 default:
2248 return 0;
2249 }
2250}
2251
2252
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002253#define RSN_SUITE "%02x-%02x-%02x-%d"
2254#define RSN_SUITE_ARG(s) \
2255((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
2256
2257/**
2258 * wpa_sm_get_mib - Dump text list of MIB entries
2259 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2260 * @buf: Buffer for the list
2261 * @buflen: Length of the buffer
2262 * Returns: Number of bytes written to buffer
2263 *
2264 * This function is used fetch dot11 MIB variables.
2265 */
2266int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
2267{
2268 char pmkid_txt[PMKID_LEN * 2 + 1];
2269 int rsna, ret;
2270 size_t len;
2271
2272 if (sm->cur_pmksa) {
2273 wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
2274 sm->cur_pmksa->pmkid, PMKID_LEN);
2275 } else
2276 pmkid_txt[0] = '\0';
2277
2278 if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
2279 wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
2280 sm->proto == WPA_PROTO_RSN)
2281 rsna = 1;
2282 else
2283 rsna = 0;
2284
2285 ret = os_snprintf(buf, buflen,
2286 "dot11RSNAOptionImplemented=TRUE\n"
2287 "dot11RSNAPreauthenticationImplemented=TRUE\n"
2288 "dot11RSNAEnabled=%s\n"
2289 "dot11RSNAPreauthenticationEnabled=%s\n"
2290 "dot11RSNAConfigVersion=%d\n"
2291 "dot11RSNAConfigPairwiseKeysSupported=5\n"
2292 "dot11RSNAConfigGroupCipherSize=%d\n"
2293 "dot11RSNAConfigPMKLifetime=%d\n"
2294 "dot11RSNAConfigPMKReauthThreshold=%d\n"
2295 "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
2296 "dot11RSNAConfigSATimeout=%d\n",
2297 rsna ? "TRUE" : "FALSE",
2298 rsna ? "TRUE" : "FALSE",
2299 RSN_VERSION,
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002300 wpa_cipher_key_len(sm->group_cipher) * 8,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002301 sm->dot11RSNAConfigPMKLifetime,
2302 sm->dot11RSNAConfigPMKReauthThreshold,
2303 sm->dot11RSNAConfigSATimeout);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002304 if (os_snprintf_error(buflen, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002305 return 0;
2306 len = ret;
2307
2308 ret = os_snprintf(
2309 buf + len, buflen - len,
2310 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
2311 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
2312 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
2313 "dot11RSNAPMKIDUsed=%s\n"
2314 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
2315 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
2316 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
2317 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
2318 "dot11RSNA4WayHandshakeFailures=%u\n",
2319 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002320 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2321 sm->pairwise_cipher)),
2322 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2323 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002324 pmkid_txt,
2325 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002326 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2327 sm->pairwise_cipher)),
2328 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2329 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002330 sm->dot11RSNA4WayHandshakeFailures);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002331 if (!os_snprintf_error(buflen - len, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002332 len += ret;
2333
2334 return (int) len;
2335}
2336#endif /* CONFIG_CTRL_IFACE */
2337
2338
2339static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002340 void *ctx, enum pmksa_free_reason reason)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002341{
2342 struct wpa_sm *sm = ctx;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002343 int deauth = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002344
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002345 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: "
2346 MACSTR " reason=%d", MAC2STR(entry->aa), reason);
2347
2348 if (sm->cur_pmksa == entry) {
2349 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2350 "RSN: %s current PMKSA entry",
2351 reason == PMKSA_REPLACE ? "replaced" : "removed");
2352 pmksa_cache_clear_current(sm);
2353
2354 /*
2355 * If an entry is simply being replaced, there's no need to
2356 * deauthenticate because it will be immediately re-added.
2357 * This happens when EAP authentication is completed again
2358 * (reauth or failed PMKSA caching attempt).
2359 */
2360 if (reason != PMKSA_REPLACE)
2361 deauth = 1;
2362 }
2363
2364 if (reason == PMKSA_EXPIRE &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002365 (sm->pmk_len == entry->pmk_len &&
2366 os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
2367 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002368 "RSN: deauthenticating due to expired PMK");
2369 pmksa_cache_clear_current(sm);
2370 deauth = 1;
2371 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002372
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002373 if (deauth) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002374 os_memset(sm->pmk, 0, sizeof(sm->pmk));
2375 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
2376 }
2377}
2378
2379
2380/**
2381 * wpa_sm_init - Initialize WPA state machine
2382 * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
2383 * Returns: Pointer to the allocated WPA state machine data
2384 *
2385 * This function is used to allocate a new WPA state machine and the returned
2386 * value is passed to all WPA state machine calls.
2387 */
2388struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
2389{
2390 struct wpa_sm *sm;
2391
2392 sm = os_zalloc(sizeof(*sm));
2393 if (sm == NULL)
2394 return NULL;
2395 dl_list_init(&sm->pmksa_candidates);
2396 sm->renew_snonce = 1;
2397 sm->ctx = ctx;
2398
2399 sm->dot11RSNAConfigPMKLifetime = 43200;
2400 sm->dot11RSNAConfigPMKReauthThreshold = 70;
2401 sm->dot11RSNAConfigSATimeout = 60;
2402
2403 sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
2404 if (sm->pmksa == NULL) {
2405 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
2406 "RSN: PMKSA cache initialization failed");
2407 os_free(sm);
2408 return NULL;
2409 }
2410
2411 return sm;
2412}
2413
2414
2415/**
2416 * wpa_sm_deinit - Deinitialize WPA state machine
2417 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2418 */
2419void wpa_sm_deinit(struct wpa_sm *sm)
2420{
2421 if (sm == NULL)
2422 return;
2423 pmksa_cache_deinit(sm->pmksa);
2424 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2425 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
2426 os_free(sm->assoc_wpa_ie);
2427 os_free(sm->ap_wpa_ie);
2428 os_free(sm->ap_rsn_ie);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002429 wpa_sm_drop_sa(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002430 os_free(sm->ctx);
2431 peerkey_deinit(sm);
2432#ifdef CONFIG_IEEE80211R
2433 os_free(sm->assoc_resp_ies);
2434#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002435#ifdef CONFIG_TESTING_OPTIONS
2436 wpabuf_free(sm->test_assoc_ie);
2437#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002438 os_free(sm);
2439}
2440
2441
2442/**
2443 * wpa_sm_notify_assoc - Notify WPA state machine about association
2444 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2445 * @bssid: The BSSID of the new association
2446 *
2447 * This function is called to let WPA state machine know that the connection
2448 * was established.
2449 */
2450void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
2451{
2452 int clear_ptk = 1;
2453
2454 if (sm == NULL)
2455 return;
2456
2457 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2458 "WPA: Association event - clear replay counter");
2459 os_memcpy(sm->bssid, bssid, ETH_ALEN);
2460 os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
2461 sm->rx_replay_counter_set = 0;
2462 sm->renew_snonce = 1;
2463 if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
2464 rsn_preauth_deinit(sm);
2465
2466#ifdef CONFIG_IEEE80211R
2467 if (wpa_ft_is_completed(sm)) {
2468 /*
2469 * Clear portValid to kick EAPOL state machine to re-enter
2470 * AUTHENTICATED state to get the EAPOL port Authorized.
2471 */
2472 eapol_sm_notify_portValid(sm->eapol, FALSE);
2473 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
2474
2475 /* Prepare for the next transition */
2476 wpa_ft_prepare_auth_request(sm, NULL);
2477
2478 clear_ptk = 0;
2479 }
2480#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002481#ifdef CONFIG_FILS
2482 if (sm->fils_completed) {
2483 /*
2484 * Clear portValid to kick EAPOL state machine to re-enter
2485 * AUTHENTICATED state to get the EAPOL port Authorized.
2486 */
2487 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
2488 clear_ptk = 0;
2489 }
2490#endif /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002491
2492 if (clear_ptk) {
2493 /*
2494 * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
2495 * this is not part of a Fast BSS Transition.
2496 */
2497 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
2498 sm->ptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002499 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002500 sm->tptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002501 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002502 }
2503
2504#ifdef CONFIG_TDLS
2505 wpa_tdls_assoc(sm);
2506#endif /* CONFIG_TDLS */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002507
2508#ifdef CONFIG_P2P
2509 os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
2510#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002511}
2512
2513
2514/**
2515 * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation
2516 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2517 *
2518 * This function is called to let WPA state machine know that the connection
2519 * was lost. This will abort any existing pre-authentication session.
2520 */
2521void wpa_sm_notify_disassoc(struct wpa_sm *sm)
2522{
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002523 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2524 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002525 peerkey_deinit(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002526 rsn_preauth_deinit(sm);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002527 pmksa_cache_clear_current(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002528 if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
2529 sm->dot11RSNA4WayHandshakeFailures++;
2530#ifdef CONFIG_TDLS
2531 wpa_tdls_disassoc(sm);
2532#endif /* CONFIG_TDLS */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002533#ifdef CONFIG_FILS
2534 sm->fils_completed = 0;
2535#endif /* CONFIG_FILS */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002536
2537 /* Keys are not needed in the WPA state machine anymore */
2538 wpa_sm_drop_sa(sm);
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002539
2540 sm->msg_3_of_4_ok = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002541}
2542
2543
2544/**
2545 * wpa_sm_set_pmk - Set PMK
2546 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2547 * @pmk: The new PMK
2548 * @pmk_len: The length of the new PMK in bytes
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002549 * @pmkid: Calculated PMKID
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002550 * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002551 *
2552 * Configure the PMK for WPA state machine.
2553 */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002554void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002555 const u8 *pmkid, const u8 *bssid)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002556{
2557 if (sm == NULL)
2558 return;
2559
2560 sm->pmk_len = pmk_len;
2561 os_memcpy(sm->pmk, pmk, pmk_len);
2562
2563#ifdef CONFIG_IEEE80211R
2564 /* Set XXKey to be PSK for FT key derivation */
2565 sm->xxkey_len = pmk_len;
2566 os_memcpy(sm->xxkey, pmk, pmk_len);
2567#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002568
2569 if (bssid) {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002570 pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002571 bssid, sm->own_addr,
2572 sm->network_ctx, sm->key_mgmt);
2573 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002574}
2575
2576
2577/**
2578 * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA
2579 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2580 *
2581 * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK
2582 * will be cleared.
2583 */
2584void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
2585{
2586 if (sm == NULL)
2587 return;
2588
2589 if (sm->cur_pmksa) {
2590 sm->pmk_len = sm->cur_pmksa->pmk_len;
2591 os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
2592 } else {
2593 sm->pmk_len = PMK_LEN;
2594 os_memset(sm->pmk, 0, PMK_LEN);
2595 }
2596}
2597
2598
2599/**
2600 * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled
2601 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2602 * @fast_reauth: Whether fast reauthentication (EAP) is allowed
2603 */
2604void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
2605{
2606 if (sm)
2607 sm->fast_reauth = fast_reauth;
2608}
2609
2610
2611/**
2612 * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks
2613 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2614 * @scard_ctx: Context pointer for smartcard related callback functions
2615 */
2616void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
2617{
2618 if (sm == NULL)
2619 return;
2620 sm->scard_ctx = scard_ctx;
2621 if (sm->preauth_eapol)
2622 eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
2623}
2624
2625
2626/**
2627 * wpa_sm_set_config - Notification of current configration change
2628 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2629 * @config: Pointer to current network configuration
2630 *
2631 * Notify WPA state machine that configuration has changed. config will be
2632 * stored as a backpointer to network configuration. This can be %NULL to clear
2633 * the stored pointed.
2634 */
2635void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
2636{
2637 if (!sm)
2638 return;
2639
2640 if (config) {
2641 sm->network_ctx = config->network_ctx;
2642 sm->peerkey_enabled = config->peerkey_enabled;
2643 sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
2644 sm->proactive_key_caching = config->proactive_key_caching;
2645 sm->eap_workaround = config->eap_workaround;
2646 sm->eap_conf_ctx = config->eap_conf_ctx;
2647 if (config->ssid) {
2648 os_memcpy(sm->ssid, config->ssid, config->ssid_len);
2649 sm->ssid_len = config->ssid_len;
2650 } else
2651 sm->ssid_len = 0;
2652 sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002653 sm->p2p = config->p2p;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002654 sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002655 } else {
2656 sm->network_ctx = NULL;
2657 sm->peerkey_enabled = 0;
2658 sm->allowed_pairwise_cipher = 0;
2659 sm->proactive_key_caching = 0;
2660 sm->eap_workaround = 0;
2661 sm->eap_conf_ctx = NULL;
2662 sm->ssid_len = 0;
2663 sm->wpa_ptk_rekey = 0;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002664 sm->p2p = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002665 sm->wpa_rsc_relaxation = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002666 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002667}
2668
2669
2670/**
2671 * wpa_sm_set_own_addr - Set own MAC address
2672 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2673 * @addr: Own MAC address
2674 */
2675void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
2676{
2677 if (sm)
2678 os_memcpy(sm->own_addr, addr, ETH_ALEN);
2679}
2680
2681
2682/**
2683 * wpa_sm_set_ifname - Set network interface name
2684 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2685 * @ifname: Interface name
2686 * @bridge_ifname: Optional bridge interface name (for pre-auth)
2687 */
2688void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
2689 const char *bridge_ifname)
2690{
2691 if (sm) {
2692 sm->ifname = ifname;
2693 sm->bridge_ifname = bridge_ifname;
2694 }
2695}
2696
2697
2698/**
2699 * wpa_sm_set_eapol - Set EAPOL state machine pointer
2700 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2701 * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init()
2702 */
2703void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
2704{
2705 if (sm)
2706 sm->eapol = eapol;
2707}
2708
2709
2710/**
2711 * wpa_sm_set_param - Set WPA state machine parameters
2712 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2713 * @param: Parameter field
2714 * @value: Parameter value
2715 * Returns: 0 on success, -1 on failure
2716 */
2717int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
2718 unsigned int value)
2719{
2720 int ret = 0;
2721
2722 if (sm == NULL)
2723 return -1;
2724
2725 switch (param) {
2726 case RSNA_PMK_LIFETIME:
2727 if (value > 0)
2728 sm->dot11RSNAConfigPMKLifetime = value;
2729 else
2730 ret = -1;
2731 break;
2732 case RSNA_PMK_REAUTH_THRESHOLD:
2733 if (value > 0 && value <= 100)
2734 sm->dot11RSNAConfigPMKReauthThreshold = value;
2735 else
2736 ret = -1;
2737 break;
2738 case RSNA_SA_TIMEOUT:
2739 if (value > 0)
2740 sm->dot11RSNAConfigSATimeout = value;
2741 else
2742 ret = -1;
2743 break;
2744 case WPA_PARAM_PROTO:
2745 sm->proto = value;
2746 break;
2747 case WPA_PARAM_PAIRWISE:
2748 sm->pairwise_cipher = value;
2749 break;
2750 case WPA_PARAM_GROUP:
2751 sm->group_cipher = value;
2752 break;
2753 case WPA_PARAM_KEY_MGMT:
2754 sm->key_mgmt = value;
2755 break;
2756#ifdef CONFIG_IEEE80211W
2757 case WPA_PARAM_MGMT_GROUP:
2758 sm->mgmt_group_cipher = value;
2759 break;
2760#endif /* CONFIG_IEEE80211W */
2761 case WPA_PARAM_RSN_ENABLED:
2762 sm->rsn_enabled = value;
2763 break;
2764 case WPA_PARAM_MFP:
2765 sm->mfp = value;
2766 break;
2767 default:
2768 break;
2769 }
2770
2771 return ret;
2772}
2773
2774
2775/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002776 * wpa_sm_get_status - Get WPA state machine
2777 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2778 * @buf: Buffer for status information
2779 * @buflen: Maximum buffer length
2780 * @verbose: Whether to include verbose status information
2781 * Returns: Number of bytes written to buf.
2782 *
2783 * Query WPA state machine for status information. This function fills in
2784 * a text area with current status information. If the buffer (buf) is not
2785 * large enough, status information will be truncated to fit the buffer.
2786 */
2787int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
2788 int verbose)
2789{
2790 char *pos = buf, *end = buf + buflen;
2791 int ret;
2792
2793 ret = os_snprintf(pos, end - pos,
2794 "pairwise_cipher=%s\n"
2795 "group_cipher=%s\n"
2796 "key_mgmt=%s\n",
2797 wpa_cipher_txt(sm->pairwise_cipher),
2798 wpa_cipher_txt(sm->group_cipher),
2799 wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002800 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002801 return pos - buf;
2802 pos += ret;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002803
2804 if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
2805 struct wpa_ie_data rsn;
2806 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
2807 >= 0 &&
2808 rsn.capabilities & (WPA_CAPABILITY_MFPR |
2809 WPA_CAPABILITY_MFPC)) {
2810 ret = os_snprintf(pos, end - pos, "pmf=%d\n",
2811 (rsn.capabilities &
2812 WPA_CAPABILITY_MFPR) ? 2 : 1);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002813 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002814 return pos - buf;
2815 pos += ret;
2816 }
2817 }
2818
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002819 return pos - buf;
2820}
2821
2822
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07002823int wpa_sm_pmf_enabled(struct wpa_sm *sm)
2824{
2825 struct wpa_ie_data rsn;
2826
2827 if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
2828 return 0;
2829
2830 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
2831 rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
2832 return 1;
2833
2834 return 0;
2835}
2836
2837
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002838/**
2839 * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration
2840 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2841 * @wpa_ie: Pointer to buffer for WPA/RSN IE
2842 * @wpa_ie_len: Pointer to the length of the wpa_ie buffer
2843 * Returns: 0 on success, -1 on failure
2844 */
2845int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
2846 size_t *wpa_ie_len)
2847{
2848 int res;
2849
2850 if (sm == NULL)
2851 return -1;
2852
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002853#ifdef CONFIG_TESTING_OPTIONS
2854 if (sm->test_assoc_ie) {
2855 wpa_printf(MSG_DEBUG,
2856 "TESTING: Replace association WPA/RSN IE");
2857 if (*wpa_ie_len < wpabuf_len(sm->test_assoc_ie))
2858 return -1;
2859 os_memcpy(wpa_ie, wpabuf_head(sm->test_assoc_ie),
2860 wpabuf_len(sm->test_assoc_ie));
2861 res = wpabuf_len(sm->test_assoc_ie);
2862 } else
2863#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002864 res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
2865 if (res < 0)
2866 return -1;
2867 *wpa_ie_len = res;
2868
2869 wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
2870 wpa_ie, *wpa_ie_len);
2871
2872 if (sm->assoc_wpa_ie == NULL) {
2873 /*
2874 * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
2875 * the correct version of the IE even if PMKSA caching is
2876 * aborted (which would remove PMKID from IE generation).
2877 */
2878 sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
2879 if (sm->assoc_wpa_ie == NULL)
2880 return -1;
2881
2882 os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
2883 sm->assoc_wpa_ie_len = *wpa_ie_len;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002884 } else {
2885 wpa_hexdump(MSG_DEBUG,
2886 "WPA: Leave previously set WPA IE default",
2887 sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002888 }
2889
2890 return 0;
2891}
2892
2893
2894/**
2895 * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq
2896 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2897 * @ie: Pointer to IE data (starting from id)
2898 * @len: IE length
2899 * Returns: 0 on success, -1 on failure
2900 *
2901 * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
2902 * Request frame. The IE will be used to override the default value generated
2903 * with wpa_sm_set_assoc_wpa_ie_default().
2904 */
2905int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2906{
2907 if (sm == NULL)
2908 return -1;
2909
2910 os_free(sm->assoc_wpa_ie);
2911 if (ie == NULL || len == 0) {
2912 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2913 "WPA: clearing own WPA/RSN IE");
2914 sm->assoc_wpa_ie = NULL;
2915 sm->assoc_wpa_ie_len = 0;
2916 } else {
2917 wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
2918 sm->assoc_wpa_ie = os_malloc(len);
2919 if (sm->assoc_wpa_ie == NULL)
2920 return -1;
2921
2922 os_memcpy(sm->assoc_wpa_ie, ie, len);
2923 sm->assoc_wpa_ie_len = len;
2924 }
2925
2926 return 0;
2927}
2928
2929
2930/**
2931 * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
2932 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2933 * @ie: Pointer to IE data (starting from id)
2934 * @len: IE length
2935 * Returns: 0 on success, -1 on failure
2936 *
2937 * Inform WPA state machine about the WPA IE used in Beacon / Probe Response
2938 * frame.
2939 */
2940int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2941{
2942 if (sm == NULL)
2943 return -1;
2944
2945 os_free(sm->ap_wpa_ie);
2946 if (ie == NULL || len == 0) {
2947 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2948 "WPA: clearing AP WPA IE");
2949 sm->ap_wpa_ie = NULL;
2950 sm->ap_wpa_ie_len = 0;
2951 } else {
2952 wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
2953 sm->ap_wpa_ie = os_malloc(len);
2954 if (sm->ap_wpa_ie == NULL)
2955 return -1;
2956
2957 os_memcpy(sm->ap_wpa_ie, ie, len);
2958 sm->ap_wpa_ie_len = len;
2959 }
2960
2961 return 0;
2962}
2963
2964
2965/**
2966 * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
2967 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2968 * @ie: Pointer to IE data (starting from id)
2969 * @len: IE length
2970 * Returns: 0 on success, -1 on failure
2971 *
2972 * Inform WPA state machine about the RSN IE used in Beacon / Probe Response
2973 * frame.
2974 */
2975int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2976{
2977 if (sm == NULL)
2978 return -1;
2979
2980 os_free(sm->ap_rsn_ie);
2981 if (ie == NULL || len == 0) {
2982 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2983 "WPA: clearing AP RSN IE");
2984 sm->ap_rsn_ie = NULL;
2985 sm->ap_rsn_ie_len = 0;
2986 } else {
2987 wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
2988 sm->ap_rsn_ie = os_malloc(len);
2989 if (sm->ap_rsn_ie == NULL)
2990 return -1;
2991
2992 os_memcpy(sm->ap_rsn_ie, ie, len);
2993 sm->ap_rsn_ie_len = len;
2994 }
2995
2996 return 0;
2997}
2998
2999
3000/**
3001 * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
3002 * @sm: Pointer to WPA state machine data from wpa_sm_init()
3003 * @data: Pointer to data area for parsing results
3004 * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure
3005 *
3006 * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the
3007 * parsed data into data.
3008 */
3009int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
3010{
3011 if (sm == NULL)
3012 return -1;
3013
3014 if (sm->assoc_wpa_ie == NULL) {
3015 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
3016 "WPA: No WPA/RSN IE available from association info");
3017 return -1;
3018 }
3019 if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
3020 return -2;
3021 return 0;
3022}
3023
3024
3025int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
3026{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003027 return pmksa_cache_list(sm->pmksa, buf, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003028}
3029
3030
3031void wpa_sm_drop_sa(struct wpa_sm *sm)
3032{
3033 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
3034 sm->ptk_set = 0;
3035 sm->tptk_set = 0;
3036 os_memset(sm->pmk, 0, sizeof(sm->pmk));
3037 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
3038 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003039#ifdef CONFIG_IEEE80211R
3040 os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
3041 os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
3042 os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1));
3043#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003044}
3045
3046
3047int wpa_sm_has_ptk(struct wpa_sm *sm)
3048{
3049 if (sm == NULL)
3050 return 0;
3051 return sm->ptk_set;
3052}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003053
3054
3055void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
3056{
3057 os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
3058}
3059
3060
3061void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
3062{
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07003063 pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003064}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003065
3066
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003067#ifdef CONFIG_WNM
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003068int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
3069{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003070 u16 keyinfo;
3071 u8 keylen; /* plaintext key len */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003072 u8 *key_rsc;
3073
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003074 if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003075 struct wpa_gtk_data gd;
3076
3077 os_memset(&gd, 0, sizeof(gd));
3078 keylen = wpa_cipher_key_len(sm->group_cipher);
3079 gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
3080 gd.alg = wpa_cipher_to_alg(sm->group_cipher);
3081 if (gd.alg == WPA_ALG_NONE) {
3082 wpa_printf(MSG_DEBUG, "Unsupported group cipher suite");
3083 return -1;
3084 }
3085
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003086 key_rsc = buf + 5;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003087 keyinfo = WPA_GET_LE16(buf + 2);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003088 gd.gtk_len = keylen;
3089 if (gd.gtk_len != buf[4]) {
3090 wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
3091 gd.gtk_len, buf[4]);
3092 return -1;
3093 }
3094 gd.keyidx = keyinfo & 0x03; /* B0 - B1 */
3095 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
3096 sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
3097
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003098 os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003099
3100 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
3101 gd.gtk, gd.gtk_len);
3102 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003103 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003104 wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
3105 "WNM mode");
3106 return -1;
3107 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003108 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003109#ifdef CONFIG_IEEE80211W
3110 } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003111 struct wpa_igtk_kde igd;
3112 u16 keyidx;
3113
3114 os_memset(&igd, 0, sizeof(igd));
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003115 keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003116 os_memcpy(igd.keyid, buf + 2, 2);
3117 os_memcpy(igd.pn, buf + 4, 6);
3118
3119 keyidx = WPA_GET_LE16(igd.keyid);
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003120 os_memcpy(igd.igtk, buf + 10, keylen);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003121
3122 wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003123 igd.igtk, keylen);
3124 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
3125 broadcast_ether_addr,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003126 keyidx, 0, igd.pn, sizeof(igd.pn),
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003127 igd.igtk, keylen) < 0) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003128 wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
3129 "WNM mode");
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003130 os_memset(&igd, 0, sizeof(igd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003131 return -1;
3132 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003133 os_memset(&igd, 0, sizeof(igd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003134#endif /* CONFIG_IEEE80211W */
3135 } else {
3136 wpa_printf(MSG_DEBUG, "Unknown element id");
3137 return -1;
3138 }
3139
3140 return 0;
3141}
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003142#endif /* CONFIG_WNM */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003143
3144
3145#ifdef CONFIG_PEERKEY
3146int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
3147 const u8 *buf, size_t len)
3148{
3149 struct wpa_peerkey *peerkey;
3150
3151 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
3152 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
3153 break;
3154 }
3155
3156 if (!peerkey)
3157 return 0;
3158
3159 wpa_sm_rx_eapol(sm, src_addr, buf, len);
3160
3161 return 1;
3162}
3163#endif /* CONFIG_PEERKEY */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08003164
3165
3166#ifdef CONFIG_P2P
3167
3168int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)
3169{
3170 if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0)
3171 return -1;
3172 os_memcpy(buf, sm->p2p_ip_addr, 3 * 4);
3173 return 0;
3174}
3175
3176#endif /* CONFIG_P2P */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003177
3178
3179void wpa_sm_set_rx_replay_ctr(struct wpa_sm *sm, const u8 *rx_replay_counter)
3180{
3181 if (rx_replay_counter == NULL)
3182 return;
3183
3184 os_memcpy(sm->rx_replay_counter, rx_replay_counter,
3185 WPA_REPLAY_COUNTER_LEN);
3186 sm->rx_replay_counter_set = 1;
3187 wpa_printf(MSG_DEBUG, "Updated key replay counter");
3188}
3189
3190
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003191void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
3192 const u8 *ptk_kck, size_t ptk_kck_len,
3193 const u8 *ptk_kek, size_t ptk_kek_len)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003194{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003195 if (ptk_kck && ptk_kck_len <= WPA_KCK_MAX_LEN) {
3196 os_memcpy(sm->ptk.kck, ptk_kck, ptk_kck_len);
3197 sm->ptk.kck_len = ptk_kck_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003198 wpa_printf(MSG_DEBUG, "Updated PTK KCK");
3199 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003200 if (ptk_kek && ptk_kek_len <= WPA_KEK_MAX_LEN) {
3201 os_memcpy(sm->ptk.kek, ptk_kek, ptk_kek_len);
3202 sm->ptk.kek_len = ptk_kek_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003203 wpa_printf(MSG_DEBUG, "Updated PTK KEK");
3204 }
3205 sm->ptk_set = 1;
3206}
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08003207
3208
3209#ifdef CONFIG_TESTING_OPTIONS
3210void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf)
3211{
3212 wpabuf_free(sm->test_assoc_ie);
3213 sm->test_assoc_ie = buf;
3214}
3215#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003216
3217
3218#ifdef CONFIG_FILS
3219
3220struct wpabuf * fils_build_auth(struct wpa_sm *sm)
3221{
3222 struct wpabuf *buf = NULL;
3223 struct wpabuf *erp_msg;
3224
3225 erp_msg = eapol_sm_build_erp_reauth_start(sm->eapol);
3226 if (!erp_msg && !sm->cur_pmksa) {
3227 wpa_printf(MSG_DEBUG,
3228 "FILS: Neither ERP EAP-Initiate/Re-auth nor PMKSA cache entry is available - skip FILS");
3229 goto fail;
3230 }
3231
3232 wpa_printf(MSG_DEBUG, "FILS: Try to use FILS (erp=%d pmksa_cache=%d)",
3233 erp_msg != NULL, sm->cur_pmksa != NULL);
3234
3235 sm->fils_completed = 0;
3236
3237 if (!sm->assoc_wpa_ie) {
3238 wpa_printf(MSG_INFO, "FILS: No own RSN IE set for FILS");
3239 goto fail;
3240 }
3241
3242 if (random_get_bytes(sm->fils_nonce, FILS_NONCE_LEN) < 0 ||
3243 random_get_bytes(sm->fils_session, FILS_SESSION_LEN) < 0)
3244 goto fail;
3245
3246 wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Nonce",
3247 sm->fils_nonce, FILS_NONCE_LEN);
3248 wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Session",
3249 sm->fils_session, FILS_SESSION_LEN);
3250
3251 buf = wpabuf_alloc(1000 + sm->assoc_wpa_ie_len);
3252 if (!buf)
3253 goto fail;
3254
3255 /* Fields following the Authentication algorithm number field */
3256
3257 /* Authentication Transaction seq# */
3258 wpabuf_put_le16(buf, 1);
3259
3260 /* Status Code */
3261 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
3262
3263 /* TODO: Finite Cyclic Group when using PK or PFS */
3264 /* TODO: Element when using PK or PFS */
3265
3266 /* RSNE */
3267 wpa_hexdump(MSG_DEBUG, "FILS: RSNE in FILS Authentication frame",
3268 sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
3269 wpabuf_put_data(buf, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
3270
3271 /* TODO: MDE when using FILS for FT initial association */
3272 /* TODO: FTE when using FILS for FT initial association */
3273
3274 /* FILS Nonce */
3275 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3276 wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN); /* Length */
3277 /* Element ID Extension */
3278 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
3279 wpabuf_put_data(buf, sm->fils_nonce, FILS_NONCE_LEN);
3280
3281 /* FILS Session */
3282 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3283 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
3284 /* Element ID Extension */
3285 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
3286 wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
3287
3288 /* FILS Wrapped Data */
3289 if (erp_msg) {
3290 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3291 wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg)); /* Length */
3292 /* Element ID Extension */
3293 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_WRAPPED_DATA);
3294 wpabuf_put_buf(buf, erp_msg);
3295 }
3296
3297 wpa_hexdump_buf(MSG_DEBUG, "RSN: FILS fields for Authentication frame",
3298 buf);
3299
3300fail:
3301 wpabuf_free(erp_msg);
3302 return buf;
3303}
3304
3305
3306int fils_process_auth(struct wpa_sm *sm, const u8 *data, size_t len)
3307{
3308 const u8 *pos, *end;
3309 struct ieee802_11_elems elems;
3310 struct wpa_ie_data rsn;
3311 int pmkid_match = 0;
3312 u8 ick[FILS_ICK_MAX_LEN];
3313 size_t ick_len;
3314 int res;
3315
3316 wpa_hexdump(MSG_DEBUG, "FILS: Authentication frame fields",
3317 data, len);
3318 pos = data;
3319 end = data + len;
3320
3321 /* TODO: Finite Cyclic Group when using PK or PFS */
3322 /* TODO: Element when using PK or PFS */
3323
3324 wpa_hexdump(MSG_DEBUG, "FILS: Remaining IEs", pos, end - pos);
3325 if (ieee802_11_parse_elems(pos, end - pos, &elems, 1) == ParseFailed) {
3326 wpa_printf(MSG_DEBUG, "FILS: Could not parse elements");
3327 return -1;
3328 }
3329
3330 /* RSNE */
3331 wpa_hexdump(MSG_DEBUG, "FILS: RSN element", elems.rsn_ie,
3332 elems.rsn_ie_len);
3333 if (!elems.rsn_ie ||
3334 wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
3335 &rsn) < 0) {
3336 wpa_printf(MSG_DEBUG, "FILS: No RSN element");
3337 return -1;
3338 }
3339
3340 if (!elems.fils_nonce) {
3341 wpa_printf(MSG_DEBUG, "FILS: No FILS Nonce field");
3342 return -1;
3343 }
3344 os_memcpy(sm->fils_anonce, elems.fils_nonce, FILS_NONCE_LEN);
3345 wpa_hexdump(MSG_DEBUG, "FILS: ANonce", sm->fils_anonce, FILS_NONCE_LEN);
3346
3347 /* TODO: MDE when using FILS+FT */
3348 /* TODO: FTE when using FILS+FT */
3349
3350 /* PMKID List */
3351 if (rsn.pmkid && rsn.num_pmkid > 0) {
3352 wpa_hexdump(MSG_DEBUG, "FILS: PMKID List",
3353 rsn.pmkid, rsn.num_pmkid * PMKID_LEN);
3354
3355 if (rsn.num_pmkid != 1) {
3356 wpa_printf(MSG_DEBUG, "FILS: Invalid PMKID selection");
3357 return -1;
3358 }
3359 wpa_hexdump(MSG_DEBUG, "FILS: PMKID", rsn.pmkid, PMKID_LEN);
3360 if (os_memcmp(sm->cur_pmksa->pmkid, rsn.pmkid, PMKID_LEN) != 0)
3361 {
3362 wpa_printf(MSG_DEBUG, "FILS: PMKID mismatch");
3363 wpa_hexdump(MSG_DEBUG, "FILS: Expected PMKID",
3364 sm->cur_pmksa->pmkid, PMKID_LEN);
3365 return -1;
3366 }
3367 wpa_printf(MSG_DEBUG,
3368 "FILS: Matching PMKID - continue using PMKSA caching");
3369 pmkid_match = 1;
3370 }
3371 if (!pmkid_match && sm->cur_pmksa) {
3372 wpa_printf(MSG_DEBUG,
3373 "FILS: No PMKID match - cannot use cached PMKSA entry");
3374 sm->cur_pmksa = NULL;
3375 }
3376
3377 /* FILS Session */
3378 if (!elems.fils_session) {
3379 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
3380 return -1;
3381 }
3382 wpa_hexdump(MSG_DEBUG, "FILS: FILS Session", elems.fils_session,
3383 FILS_SESSION_LEN);
3384 if (os_memcmp(sm->fils_session, elems.fils_session, FILS_SESSION_LEN)
3385 != 0) {
3386 wpa_printf(MSG_DEBUG, "FILS: Session mismatch");
3387 wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
3388 sm->fils_session, FILS_SESSION_LEN);
3389 return -1;
3390 }
3391
3392 /* FILS Wrapped Data */
3393 if (!sm->cur_pmksa && elems.fils_wrapped_data) {
3394 wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
3395 elems.fils_wrapped_data,
3396 elems.fils_wrapped_data_len);
3397 eapol_sm_process_erp_finish(sm->eapol, elems.fils_wrapped_data,
3398 elems.fils_wrapped_data_len);
3399 if (eapol_sm_failed(sm->eapol))
3400 return -1;
3401
3402 res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);
3403 if (res)
3404 return -1;
3405
3406 wpa_printf(MSG_DEBUG, "FILS: ERP processing succeeded - add PMKSA cache entry for the result");
3407 sm->cur_pmksa = pmksa_cache_add(sm->pmksa, sm->pmk, PMK_LEN,
3408 NULL, NULL, 0, sm->bssid,
3409 sm->own_addr,
3410 sm->network_ctx, sm->key_mgmt);
3411 }
3412
3413 if (!sm->cur_pmksa) {
3414 wpa_printf(MSG_DEBUG,
3415 "FILS: No remaining options to continue FILS authentication");
3416 return -1;
3417 }
3418
3419 if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
3420 sm->fils_nonce, sm->fils_anonce, &sm->ptk,
3421 ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher) <
3422 0) {
3423 wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
3424 return -1;
3425 }
3426 sm->ptk_set = 1;
3427 sm->tptk_set = 0;
3428 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
3429
3430 res = fils_key_auth_sk(ick, ick_len, sm->fils_nonce,
3431 sm->fils_anonce, sm->own_addr, sm->bssid,
3432 NULL, 0, NULL, 0, /* TODO: SK+PFS */
3433 sm->key_mgmt, sm->fils_key_auth_sta,
3434 sm->fils_key_auth_ap,
3435 &sm->fils_key_auth_len);
3436 os_memset(ick, 0, sizeof(ick));
3437 return res;
3438}
3439
3440
3441struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek,
3442 size_t *kek_len, const u8 **snonce,
3443 const u8 **anonce)
3444{
3445 struct wpabuf *buf;
3446
3447 buf = wpabuf_alloc(1000);
3448 if (!buf)
3449 return NULL;
3450
3451 /* FILS Session */
3452 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3453 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
3454 /* Element ID Extension */
3455 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
3456 wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
3457
3458 /* Everything after FILS Session element gets encrypted in the driver
3459 * with KEK. The buffer returned from here is the plaintext version. */
3460
3461 /* TODO: FILS Public Key */
3462
3463 /* FILS Key Confirm */
3464 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3465 wpabuf_put_u8(buf, 1 + sm->fils_key_auth_len); /* Length */
3466 /* Element ID Extension */
3467 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_KEY_CONFIRM);
3468 wpabuf_put_data(buf, sm->fils_key_auth_sta, sm->fils_key_auth_len);
3469
3470 /* TODO: FILS HLP Container */
3471
3472 /* TODO: FILS IP Address Assignment */
3473
3474 wpa_hexdump_buf(MSG_DEBUG, "FILS: Association Request plaintext", buf);
3475
3476 *kek = sm->ptk.kek;
3477 *kek_len = sm->ptk.kek_len;
3478 wpa_hexdump_key(MSG_DEBUG, "FILS: KEK for AEAD", *kek, *kek_len);
3479 *snonce = sm->fils_nonce;
3480 wpa_hexdump(MSG_DEBUG, "FILS: SNonce for AEAD AAD",
3481 *snonce, FILS_NONCE_LEN);
3482 *anonce = sm->fils_anonce;
3483 wpa_hexdump(MSG_DEBUG, "FILS: ANonce for AEAD AAD",
3484 *anonce, FILS_NONCE_LEN);
3485
3486 return buf;
3487}
3488
3489
3490int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
3491{
3492 const struct ieee80211_mgmt *mgmt;
3493 const u8 *end, *ie_start;
3494 struct ieee802_11_elems elems;
3495 int keylen, rsclen;
3496 enum wpa_alg alg;
3497 struct wpa_gtk_data gd;
3498 int maxkeylen;
3499 struct wpa_eapol_ie_parse kde;
3500
3501 if (!sm || !sm->ptk_set) {
3502 wpa_printf(MSG_DEBUG, "FILS: No KEK available");
3503 return -1;
3504 }
3505
3506 if (!wpa_key_mgmt_fils(sm->key_mgmt)) {
3507 wpa_printf(MSG_DEBUG, "FILS: Not a FILS AKM");
3508 return -1;
3509 }
3510
3511 wpa_hexdump(MSG_DEBUG, "FILS: (Re)Association Response frame",
3512 resp, len);
3513
3514 mgmt = (const struct ieee80211_mgmt *) resp;
3515 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_resp))
3516 return -1;
3517
3518 end = resp + len;
3519 /* Same offset for Association Response and Reassociation Response */
3520 ie_start = mgmt->u.assoc_resp.variable;
3521
3522 if (ieee802_11_parse_elems(ie_start, end - ie_start, &elems, 1) ==
3523 ParseFailed) {
3524 wpa_printf(MSG_DEBUG,
3525 "FILS: Failed to parse decrypted elements");
3526 goto fail;
3527 }
3528
3529 if (!elems.fils_session) {
3530 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
3531 return -1;
3532 }
3533 if (os_memcmp(elems.fils_session, sm->fils_session,
3534 FILS_SESSION_LEN) != 0) {
3535 wpa_printf(MSG_DEBUG, "FILS: FILS Session mismatch");
3536 wpa_hexdump(MSG_DEBUG, "FILS: Received FILS Session",
3537 elems.fils_session, FILS_SESSION_LEN);
3538 wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
3539 sm->fils_session, FILS_SESSION_LEN);
3540 }
3541
3542 /* TODO: FILS Public Key */
3543
3544 if (!elems.fils_key_confirm) {
3545 wpa_printf(MSG_DEBUG, "FILS: No FILS Key Confirm element");
3546 goto fail;
3547 }
3548 if (elems.fils_key_confirm_len != sm->fils_key_auth_len) {
3549 wpa_printf(MSG_DEBUG,
3550 "FILS: Unexpected Key-Auth length %d (expected %d)",
3551 elems.fils_key_confirm_len,
3552 (int) sm->fils_key_auth_len);
3553 goto fail;
3554 }
3555 if (os_memcmp(elems.fils_key_confirm, sm->fils_key_auth_ap,
3556 sm->fils_key_auth_len) != 0) {
3557 wpa_printf(MSG_DEBUG, "FILS: Key-Auth mismatch");
3558 wpa_hexdump(MSG_DEBUG, "FILS: Received Key-Auth",
3559 elems.fils_key_confirm,
3560 elems.fils_key_confirm_len);
3561 wpa_hexdump(MSG_DEBUG, "FILS: Expected Key-Auth",
3562 sm->fils_key_auth_ap, sm->fils_key_auth_len);
3563 goto fail;
3564 }
3565
3566 /* Key Delivery */
3567 if (!elems.key_delivery) {
3568 wpa_printf(MSG_DEBUG, "FILS: No Key Delivery element");
3569 goto fail;
3570 }
3571
3572 /* Parse GTK and set the key to the driver */
3573 os_memset(&gd, 0, sizeof(gd));
3574 if (wpa_supplicant_parse_ies(elems.key_delivery + WPA_KEY_RSC_LEN,
3575 elems.key_delivery_len - WPA_KEY_RSC_LEN,
3576 &kde) < 0) {
3577 wpa_printf(MSG_DEBUG, "FILS: Failed to parse KDEs");
3578 goto fail;
3579 }
3580 if (!kde.gtk) {
3581 wpa_printf(MSG_DEBUG, "FILS: No GTK KDE");
3582 goto fail;
3583 }
3584 maxkeylen = gd.gtk_len = kde.gtk_len - 2;
3585 if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
3586 gd.gtk_len, maxkeylen,
3587 &gd.key_rsc_len, &gd.alg))
3588 goto fail;
3589
3590 wpa_hexdump_key(MSG_DEBUG, "FILS: Received GTK", kde.gtk, kde.gtk_len);
3591 gd.keyidx = kde.gtk[0] & 0x3;
3592 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
3593 !!(kde.gtk[0] & BIT(2)));
3594 if (kde.gtk_len - 2 > sizeof(gd.gtk)) {
3595 wpa_printf(MSG_DEBUG, "FILS: Too long GTK in GTK KDE (len=%lu)",
3596 (unsigned long) kde.gtk_len - 2);
3597 goto fail;
3598 }
3599 os_memcpy(gd.gtk, kde.gtk + 2, kde.gtk_len - 2);
3600
3601 wpa_printf(MSG_DEBUG, "FILS: Set GTK to driver");
3602 if (wpa_supplicant_install_gtk(sm, &gd, elems.key_delivery) < 0) {
3603 wpa_printf(MSG_DEBUG, "FILS: Failed to set GTK");
3604 goto fail;
3605 }
3606
3607 if (ieee80211w_set_keys(sm, &kde) < 0) {
3608 wpa_printf(MSG_DEBUG, "FILS: Failed to set IGTK");
3609 goto fail;
3610 }
3611
3612 alg = wpa_cipher_to_alg(sm->pairwise_cipher);
3613 keylen = wpa_cipher_key_len(sm->pairwise_cipher);
3614 rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
3615 wpa_hexdump_key(MSG_DEBUG, "FILS: Set TK to driver",
3616 sm->ptk.tk, keylen);
3617 if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, null_rsc, rsclen,
3618 sm->ptk.tk, keylen) < 0) {
3619 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
3620 "FILS: Failed to set PTK to the driver (alg=%d keylen=%d bssid="
3621 MACSTR ")",
3622 alg, keylen, MAC2STR(sm->bssid));
3623 goto fail;
3624 }
3625
3626 /* TODO: TK could be cleared after auth frame exchange now that driver
3627 * takes care of association frame encryption/decryption. */
3628 /* TK is not needed anymore in supplicant */
3629 os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
3630
3631 /* TODO: FILS HLP Container */
3632
3633 /* TODO: FILS IP Address Assignment */
3634
3635 wpa_printf(MSG_DEBUG, "FILS: Auth+Assoc completed successfully");
3636 sm->fils_completed = 1;
3637
3638 return 0;
3639fail:
3640 return -1;
3641}
3642
3643#endif /* CONFIG_FILS */
3644
3645
3646int wpa_fils_is_completed(struct wpa_sm *sm)
3647{
3648#ifdef CONFIG_FILS
3649 return sm && sm->fils_completed;
3650#else /* CONFIG_FILS */
3651 return 0;
3652#endif /* CONFIG_FILS */
3653}