blob: 365845f7cba8cda72aaed4a039c3a8c8c4e3881a [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 }
Dmitry Shmidt29333592017-01-09 12:27:11 -080082 if (ptk)
83 wpa_hexdump_key(MSG_DEBUG, "WPA: KCK",
84 ptk->kck, ptk->kck_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080085 wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC",
86 key_mic, mic_len);
87 } else {
88#ifdef CONFIG_FILS
89 /* AEAD cipher - Key MIC field not used */
90 struct ieee802_1x_hdr *s_hdr, *hdr;
91 struct wpa_eapol_key *s_key, *key;
92 u8 *buf, *s_key_data, *key_data;
93 size_t buf_len = msg_len + AES_BLOCK_SIZE;
94 size_t key_data_len;
95 u16 eapol_len;
96 const u8 *aad[1];
97 size_t aad_len[1];
98
99 if (!ptk || !ptk->kek_len)
100 goto out;
101
102 key_data_len = msg_len - sizeof(struct ieee802_1x_hdr) -
103 sizeof(struct wpa_eapol_key) - 2;
104
105 buf = os_malloc(buf_len);
106 if (!buf)
107 goto out;
108
109 os_memcpy(buf, msg, msg_len);
110 hdr = (struct ieee802_1x_hdr *) buf;
111 key = (struct wpa_eapol_key *) (hdr + 1);
112 key_data = ((u8 *) (key + 1)) + 2;
113
114 /* Update EAPOL header to include AES-SIV overhead */
115 eapol_len = be_to_host16(hdr->length);
116 eapol_len += AES_BLOCK_SIZE;
117 hdr->length = host_to_be16(eapol_len);
118
119 /* Update Key Data Length field to include AES-SIV overhead */
120 WPA_PUT_BE16((u8 *) (key + 1), AES_BLOCK_SIZE + key_data_len);
121
122 s_hdr = (struct ieee802_1x_hdr *) msg;
123 s_key = (struct wpa_eapol_key *) (s_hdr + 1);
124 s_key_data = ((u8 *) (s_key + 1)) + 2;
125
126 wpa_hexdump_key(MSG_DEBUG, "WPA: Plaintext Key Data",
127 s_key_data, key_data_len);
128
129 wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
130 /* AES-SIV AAD from EAPOL protocol version field (inclusive) to
131 * to Key Data (exclusive). */
132 aad[0] = buf;
133 aad_len[0] = key_data - buf;
134 if (aes_siv_encrypt(ptk->kek, ptk->kek_len,
135 s_key_data, key_data_len,
136 1, aad, aad_len, key_data) < 0) {
137 os_free(buf);
138 goto out;
139 }
140
141 wpa_hexdump(MSG_DEBUG, "WPA: Encrypted Key Data from SIV",
142 key_data, AES_BLOCK_SIZE + key_data_len);
143
144 os_free(msg);
145 msg = buf;
146 msg_len = buf_len;
147#else /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700148 goto out;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800149#endif /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700150 }
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800151
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700152 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800153 ret = wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700154 eapol_sm_notify_tx_eapol_key(sm->eapol);
155out:
156 os_free(msg);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800157 return ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700158}
159
160
161/**
162 * wpa_sm_key_request - Send EAPOL-Key Request
163 * @sm: Pointer to WPA state machine data from wpa_sm_init()
164 * @error: Indicate whether this is an Michael MIC error report
165 * @pairwise: 1 = error report for pairwise packet, 0 = for group packet
166 *
167 * Send an EAPOL-Key Request to the current authenticator. This function is
168 * used to request rekeying and it is usually called when a local Michael MIC
169 * failure is detected.
170 */
171void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
172{
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800173 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700174 struct wpa_eapol_key *reply;
175 int key_info, ver;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800176 u8 bssid[ETH_ALEN], *rbuf, *key_mic, *mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700177
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800178 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
179 wpa_key_mgmt_suite_b(sm->key_mgmt))
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800180 ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
181 else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
182 wpa_key_mgmt_sha256(sm->key_mgmt))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700183 ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700184 else if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700185 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
186 else
187 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
188
189 if (wpa_sm_get_bssid(sm, bssid) < 0) {
190 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
191 "Failed to read BSSID for EAPOL-Key request");
192 return;
193 }
194
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800195 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800196 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700197 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800198 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700199 if (rbuf == NULL)
200 return;
201
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800202 reply->type = (sm->proto == WPA_PROTO_RSN ||
203 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700204 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
205 key_info = WPA_KEY_INFO_REQUEST | ver;
206 if (sm->ptk_set)
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800207 key_info |= WPA_KEY_INFO_SECURE;
208 if (sm->ptk_set && mic_len)
209 key_info |= WPA_KEY_INFO_MIC;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700210 if (error)
211 key_info |= WPA_KEY_INFO_ERROR;
212 if (pairwise)
213 key_info |= WPA_KEY_INFO_KEY_TYPE;
214 WPA_PUT_BE16(reply->key_info, key_info);
215 WPA_PUT_BE16(reply->key_length, 0);
216 os_memcpy(reply->replay_counter, sm->request_counter,
217 WPA_REPLAY_COUNTER_LEN);
218 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
219
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800220 mic = (u8 *) (reply + 1);
221 WPA_PUT_BE16(mic + mic_len, 0);
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800222 if (!(key_info & WPA_KEY_INFO_MIC))
223 key_mic = NULL;
224 else
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800225 key_mic = mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700226
227 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
228 "WPA: Sending EAPOL-Key Request (error=%d "
229 "pairwise=%d ptk_set=%d len=%lu)",
230 error, pairwise, sm->ptk_set, (unsigned long) rlen);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800231 wpa_eapol_key_send(sm, &sm->ptk, ver, bssid, ETH_P_EAPOL, rbuf, rlen,
232 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700233}
234
235
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800236static void wpa_supplicant_key_mgmt_set_pmk(struct wpa_sm *sm)
237{
238#ifdef CONFIG_IEEE80211R
239 if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
240 if (wpa_sm_key_mgmt_set_pmk(sm, sm->xxkey, sm->xxkey_len))
241 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
242 "RSN: Cannot set low order 256 bits of MSK for key management offload");
243 } else {
244#endif /* CONFIG_IEEE80211R */
245 if (wpa_sm_key_mgmt_set_pmk(sm, sm->pmk, sm->pmk_len))
246 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
247 "RSN: Cannot set PMK for key management offload");
248#ifdef CONFIG_IEEE80211R
249 }
250#endif /* CONFIG_IEEE80211R */
251}
252
253
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700254static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
255 const unsigned char *src_addr,
256 const u8 *pmkid)
257{
258 int abort_cached = 0;
259
260 if (pmkid && !sm->cur_pmksa) {
261 /* When using drivers that generate RSN IE, wpa_supplicant may
262 * not have enough time to get the association information
263 * event before receiving this 1/4 message, so try to find a
264 * matching PMKSA cache entry here. */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800265 sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
266 NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700267 if (sm->cur_pmksa) {
268 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
269 "RSN: found matching PMKID from PMKSA cache");
270 } else {
271 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
272 "RSN: no matching PMKID found");
273 abort_cached = 1;
274 }
275 }
276
277 if (pmkid && sm->cur_pmksa &&
Dmitry Shmidtc2817022014-07-02 10:32:10 -0700278 os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700279 wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
280 wpa_sm_set_pmk_from_pmksa(sm);
281 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
282 sm->pmk, sm->pmk_len);
283 eapol_sm_notify_cached(sm->eapol);
284#ifdef CONFIG_IEEE80211R
285 sm->xxkey_len = 0;
286#endif /* CONFIG_IEEE80211R */
287 } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
288 int res, pmk_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800289
290 if (sm->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
291 pmk_len = PMK_LEN_SUITE_B_192;
292 else
293 pmk_len = PMK_LEN;
294 res = eapol_sm_get_key(sm->eapol, sm->pmk, pmk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700295 if (res) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800296 if (pmk_len == PMK_LEN) {
297 /*
298 * EAP-LEAP is an exception from other EAP
299 * methods: it uses only 16-byte PMK.
300 */
301 res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
302 pmk_len = 16;
303 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700304 } else {
305#ifdef CONFIG_IEEE80211R
306 u8 buf[2 * PMK_LEN];
307 if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
308 {
309 os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
310 sm->xxkey_len = PMK_LEN;
311 os_memset(buf, 0, sizeof(buf));
312 }
313#endif /* CONFIG_IEEE80211R */
314 }
315 if (res == 0) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700316 struct rsn_pmksa_cache_entry *sa = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700317 wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
318 "machines", sm->pmk, pmk_len);
319 sm->pmk_len = pmk_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800320 wpa_supplicant_key_mgmt_set_pmk(sm);
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700321 if (sm->proto == WPA_PROTO_RSN &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800322 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700323 !wpa_key_mgmt_ft(sm->key_mgmt)) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700324 sa = pmksa_cache_add(sm->pmksa,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800325 sm->pmk, pmk_len, NULL,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800326 NULL, 0,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700327 src_addr, sm->own_addr,
328 sm->network_ctx,
329 sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700330 }
331 if (!sm->cur_pmksa && pmkid &&
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800332 pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
333 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700334 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
335 "RSN: the new PMK matches with the "
336 "PMKID");
337 abort_cached = 0;
Jouni Malinen6ec30382015-07-08 20:48:18 +0300338 } else if (sa && !sm->cur_pmksa && pmkid) {
339 /*
340 * It looks like the authentication server
341 * derived mismatching MSK. This should not
342 * really happen, but bugs happen.. There is not
343 * much we can do here without knowing what
344 * exactly caused the server to misbehave.
345 */
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -0800346 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
Jouni Malinen6ec30382015-07-08 20:48:18 +0300347 "RSN: PMKID mismatch - authentication server may have derived different MSK?!");
348 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700349 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700350
351 if (!sm->cur_pmksa)
352 sm->cur_pmksa = sa;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700353 } else {
354 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
355 "WPA: Failed to get master session key from "
356 "EAPOL state machines - key handshake "
357 "aborted");
358 if (sm->cur_pmksa) {
359 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
360 "RSN: Cancelled PMKSA caching "
361 "attempt");
362 sm->cur_pmksa = NULL;
363 abort_cached = 1;
364 } else if (!abort_cached) {
365 return -1;
366 }
367 }
368 }
369
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700370 if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800371 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800372 !wpa_key_mgmt_ft(sm->key_mgmt) && sm->key_mgmt != WPA_KEY_MGMT_OSEN)
373 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700374 /* Send EAPOL-Start to trigger full EAP authentication. */
375 u8 *buf;
376 size_t buflen;
377
378 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
379 "RSN: no PMKSA entry found - trigger "
380 "full EAP authentication");
381 buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
382 NULL, 0, &buflen, NULL);
383 if (buf) {
384 wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
385 buf, buflen);
386 os_free(buf);
387 return -2;
388 }
389
390 return -1;
391 }
392
393 return 0;
394}
395
396
397/**
398 * wpa_supplicant_send_2_of_4 - Send message 2 of WPA/RSN 4-Way Handshake
399 * @sm: Pointer to WPA state machine data from wpa_sm_init()
400 * @dst: Destination address for the frame
401 * @key: Pointer to the EAPOL-Key frame header
402 * @ver: Version bits from EAPOL-Key Key Info
403 * @nonce: Nonce value for the EAPOL-Key frame
404 * @wpa_ie: WPA/RSN IE
405 * @wpa_ie_len: Length of the WPA/RSN IE
406 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800407 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700408 */
409int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
410 const struct wpa_eapol_key *key,
411 int ver, const u8 *nonce,
412 const u8 *wpa_ie, size_t wpa_ie_len,
413 struct wpa_ptk *ptk)
414{
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800415 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700416 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800417 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700418 u8 *rsn_ie_buf = NULL;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800419 u16 key_info;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700420
421 if (wpa_ie == NULL) {
422 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No wpa_ie set - "
423 "cannot generate msg 2/4");
424 return -1;
425 }
426
427#ifdef CONFIG_IEEE80211R
428 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
429 int res;
430
431 /*
432 * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
433 * FTIE from (Re)Association Response.
434 */
435 rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
436 sm->assoc_resp_ies_len);
437 if (rsn_ie_buf == NULL)
438 return -1;
439 os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800440 res = wpa_insert_pmkid(rsn_ie_buf, &wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700441 sm->pmk_r1_name);
442 if (res < 0) {
443 os_free(rsn_ie_buf);
444 return -1;
445 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700446
447 if (sm->assoc_resp_ies) {
448 os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
449 sm->assoc_resp_ies_len);
450 wpa_ie_len += sm->assoc_resp_ies_len;
451 }
452
453 wpa_ie = rsn_ie_buf;
454 }
455#endif /* CONFIG_IEEE80211R */
456
457 wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
458
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800459 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800460 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700461 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800462 NULL, hdrlen + wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700463 &rlen, (void *) &reply);
464 if (rbuf == NULL) {
465 os_free(rsn_ie_buf);
466 return -1;
467 }
468
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800469 reply->type = (sm->proto == WPA_PROTO_RSN ||
470 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700471 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800472 key_info = ver | WPA_KEY_INFO_KEY_TYPE;
473 if (mic_len)
474 key_info |= WPA_KEY_INFO_MIC;
475 else
476 key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
477 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800478 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700479 WPA_PUT_BE16(reply->key_length, 0);
480 else
481 os_memcpy(reply->key_length, key->key_length, 2);
482 os_memcpy(reply->replay_counter, key->replay_counter,
483 WPA_REPLAY_COUNTER_LEN);
484 wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
485 WPA_REPLAY_COUNTER_LEN);
486
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800487 key_mic = (u8 *) (reply + 1);
488 WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len); /* Key Data Length */
489 os_memcpy(key_mic + mic_len + 2, wpa_ie, wpa_ie_len); /* Key Data */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700490 os_free(rsn_ie_buf);
491
492 os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
493
494 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800495 return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen,
496 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700497}
498
499
500static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800501 const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700502{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700503#ifdef CONFIG_IEEE80211R
504 if (wpa_key_mgmt_ft(sm->key_mgmt))
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800505 return wpa_derive_ptk_ft(sm, src_addr, key, ptk);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700506#endif /* CONFIG_IEEE80211R */
507
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800508 return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
509 sm->own_addr, sm->bssid, sm->snonce,
510 key->key_nonce, ptk, sm->key_mgmt,
511 sm->pairwise_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700512}
513
514
515static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
516 const unsigned char *src_addr,
517 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700518 u16 ver, const u8 *key_data,
519 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700520{
521 struct wpa_eapol_ie_parse ie;
522 struct wpa_ptk *ptk;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700523 int res;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800524 u8 *kde, *kde_buf = NULL;
525 size_t kde_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700526
527 if (wpa_sm_get_network_ctx(sm) == NULL) {
528 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
529 "found (msg 1 of 4)");
530 return;
531 }
532
533 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
534 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
535 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
536
537 os_memset(&ie, 0, sizeof(ie));
538
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800539 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700540 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700541 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
542 key_data, key_data_len);
543 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800544 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700545 if (ie.pmkid) {
546 wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
547 "Authenticator", ie.pmkid, PMKID_LEN);
548 }
549 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700550
551 res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
552 if (res == -2) {
553 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
554 "msg 1/4 - requesting full EAP authentication");
555 return;
556 }
557 if (res)
558 goto failed;
559
560 if (sm->renew_snonce) {
561 if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
562 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
563 "WPA: Failed to get random data for SNonce");
564 goto failed;
565 }
566 sm->renew_snonce = 0;
567 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
568 sm->snonce, WPA_NONCE_LEN);
569 }
570
571 /* Calculate PTK which will be stored as a temporary PTK until it has
572 * been verified when processing message 3/4. */
573 ptk = &sm->tptk;
574 wpa_derive_ptk(sm, src_addr, key, ptk);
Dmitry Shmidt98660862014-03-11 17:26:21 -0700575 if (sm->pairwise_cipher == WPA_CIPHER_TKIP) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700576 u8 buf[8];
Dmitry Shmidt98660862014-03-11 17:26:21 -0700577 /* Supplicant: swap tx/rx Mic keys */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800578 os_memcpy(buf, &ptk->tk[16], 8);
579 os_memcpy(&ptk->tk[16], &ptk->tk[24], 8);
580 os_memcpy(&ptk->tk[24], buf, 8);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700581 os_memset(buf, 0, sizeof(buf));
Dmitry Shmidt98660862014-03-11 17:26:21 -0700582 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700583 sm->tptk_set = 1;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800584 sm->tk_to_set = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700585
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800586 kde = sm->assoc_wpa_ie;
587 kde_len = sm->assoc_wpa_ie_len;
588
589#ifdef CONFIG_P2P
590 if (sm->p2p) {
591 kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
592 if (kde_buf) {
593 u8 *pos;
594 wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
595 "into EAPOL-Key 2/4");
596 os_memcpy(kde_buf, kde, kde_len);
597 kde = kde_buf;
598 pos = kde + kde_len;
599 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
600 *pos++ = RSN_SELECTOR_LEN + 1;
601 RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ);
602 pos += RSN_SELECTOR_LEN;
603 *pos++ = 0x01;
604 kde_len = pos - kde;
605 }
606 }
607#endif /* CONFIG_P2P */
608
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700609 if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800610 kde, kde_len, ptk) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700611 goto failed;
612
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800613 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700614 os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
615 return;
616
617failed:
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800618 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700619 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
620}
621
622
623static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
624{
625 struct wpa_sm *sm = eloop_ctx;
626 rsn_preauth_candidate_process(sm);
627}
628
629
630static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
631 const u8 *addr, int secure)
632{
633 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
634 "WPA: Key negotiation completed with "
635 MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
636 wpa_cipher_txt(sm->pairwise_cipher),
637 wpa_cipher_txt(sm->group_cipher));
638 wpa_sm_cancel_auth_timeout(sm);
639 wpa_sm_set_state(sm, WPA_COMPLETED);
640
641 if (secure) {
642 wpa_sm_mlme_setprotection(
643 sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
644 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
645 eapol_sm_notify_portValid(sm->eapol, TRUE);
646 if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
647 eapol_sm_notify_eap_success(sm->eapol, TRUE);
648 /*
649 * Start preauthentication after a short wait to avoid a
650 * possible race condition between the data receive and key
651 * configuration after the 4-Way Handshake. This increases the
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800652 * likelihood of the first preauth EAPOL-Start frame getting to
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700653 * the target AP.
654 */
655 eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
656 }
657
658 if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {
659 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
660 "RSN: Authenticator accepted "
661 "opportunistic PMKSA entry - marking it valid");
662 sm->cur_pmksa->opportunistic = 0;
663 }
664
665#ifdef CONFIG_IEEE80211R
666 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
667 /* Prepare for the next transition */
668 wpa_ft_prepare_auth_request(sm, NULL);
669 }
670#endif /* CONFIG_IEEE80211R */
671}
672
673
674static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
675{
676 struct wpa_sm *sm = eloop_ctx;
677 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Request PTK rekeying");
678 wpa_sm_key_request(sm, 0, 1);
679}
680
681
682static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
683 const struct wpa_eapol_key *key)
684{
685 int keylen, rsclen;
686 enum wpa_alg alg;
687 const u8 *key_rsc;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800688
689 if (!sm->tk_to_set) {
690 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
691 "WPA: Do not re-install same PTK to the driver");
692 return 0;
693 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700694
695 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
696 "WPA: Installing PTK to the driver");
697
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700698 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700699 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Pairwise Cipher "
700 "Suite: NONE - do not use pairwise keys");
701 return 0;
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700702 }
703
704 if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700705 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
706 "WPA: Unsupported pairwise cipher %d",
707 sm->pairwise_cipher);
708 return -1;
709 }
710
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700711 alg = wpa_cipher_to_alg(sm->pairwise_cipher);
712 keylen = wpa_cipher_key_len(sm->pairwise_cipher);
713 rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
714
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800715 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700716 key_rsc = null_rsc;
717 } else {
718 key_rsc = key->key_rsc;
719 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
720 }
721
722 if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800723 sm->ptk.tk, keylen) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700724 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
725 "WPA: Failed to set PTK to the "
726 "driver (alg=%d keylen=%d bssid=" MACSTR ")",
727 alg, keylen, MAC2STR(sm->bssid));
728 return -1;
729 }
730
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800731 /* TK is not needed anymore in supplicant */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800732 os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800733 sm->tk_to_set = 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800734
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700735 if (sm->wpa_ptk_rekey) {
736 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
737 eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
738 sm, NULL);
739 }
740
741 return 0;
742}
743
744
745static int wpa_supplicant_check_group_cipher(struct wpa_sm *sm,
746 int group_cipher,
747 int keylen, int maxkeylen,
748 int *key_rsc_len,
749 enum wpa_alg *alg)
750{
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700751 int klen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700752
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700753 *alg = wpa_cipher_to_alg(group_cipher);
754 if (*alg == WPA_ALG_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700755 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
756 "WPA: Unsupported Group Cipher %d",
757 group_cipher);
758 return -1;
759 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700760 *key_rsc_len = wpa_cipher_rsc_len(group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700761
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700762 klen = wpa_cipher_key_len(group_cipher);
763 if (keylen != klen || maxkeylen < klen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700764 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
765 "WPA: Unsupported %s Group Cipher key length %d (%d)",
766 wpa_cipher_txt(group_cipher), keylen, maxkeylen);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700767 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700768 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700769 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700770}
771
772
773struct wpa_gtk_data {
774 enum wpa_alg alg;
775 int tx, key_rsc_len, keyidx;
776 u8 gtk[32];
777 int gtk_len;
778};
779
780
781static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
782 const struct wpa_gtk_data *gd,
783 const u8 *key_rsc)
784{
785 const u8 *_gtk = gd->gtk;
786 u8 gtk_buf[32];
787
788 wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
789 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
790 "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
791 gd->keyidx, gd->tx, gd->gtk_len);
792 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
793 if (sm->group_cipher == WPA_CIPHER_TKIP) {
794 /* Swap Tx/Rx keys for Michael MIC */
795 os_memcpy(gtk_buf, gd->gtk, 16);
796 os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
797 os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
798 _gtk = gtk_buf;
799 }
800 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
801 if (wpa_sm_set_key(sm, gd->alg, NULL,
802 gd->keyidx, 1, key_rsc, gd->key_rsc_len,
803 _gtk, gd->gtk_len) < 0) {
804 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
805 "WPA: Failed to set GTK to the driver "
806 "(Group only)");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700807 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700808 return -1;
809 }
810 } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
811 gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
812 _gtk, gd->gtk_len) < 0) {
813 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
814 "WPA: Failed to set GTK to "
815 "the driver (alg=%d keylen=%d keyidx=%d)",
816 gd->alg, gd->gtk_len, gd->keyidx);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700817 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700818 return -1;
819 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700820 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700821
822 return 0;
823}
824
825
826static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
827 int tx)
828{
829 if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
830 /* Ignore Tx bit for GTK if a pairwise key is used. One AP
831 * seemed to set this bit (incorrectly, since Tx is only when
832 * doing Group Key only APs) and without this workaround, the
833 * data connection does not work because wpa_supplicant
834 * configured non-zero keyidx to be used for unicast. */
835 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
836 "WPA: Tx bit set for GTK, but pairwise "
837 "keys are used - ignore Tx bit");
838 return 0;
839 }
840 return tx;
841}
842
843
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800844static int wpa_supplicant_rsc_relaxation(const struct wpa_sm *sm,
845 const u8 *rsc)
846{
847 int rsclen;
848
849 if (!sm->wpa_rsc_relaxation)
850 return 0;
851
852 rsclen = wpa_cipher_rsc_len(sm->group_cipher);
853
854 /*
855 * Try to detect RSC (endian) corruption issue where the AP sends
856 * the RSC bytes in EAPOL-Key message in the wrong order, both if
857 * it's actually a 6-byte field (as it should be) and if it treats
858 * it as an 8-byte field.
859 * An AP model known to have this bug is the Sapido RB-1632.
860 */
861 if (rsclen == 6 && ((rsc[5] && !rsc[0]) || rsc[6] || rsc[7])) {
862 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
863 "RSC %02x%02x%02x%02x%02x%02x%02x%02x is likely bogus, using 0",
864 rsc[0], rsc[1], rsc[2], rsc[3],
865 rsc[4], rsc[5], rsc[6], rsc[7]);
866
867 return 1;
868 }
869
870 return 0;
871}
872
873
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700874static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
875 const struct wpa_eapol_key *key,
876 const u8 *gtk, size_t gtk_len,
877 int key_info)
878{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700879 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800880 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700881
882 /*
883 * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
884 * GTK KDE format:
885 * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]
886 * Reserved [bits 0-7]
887 * GTK
888 */
889
890 os_memset(&gd, 0, sizeof(gd));
891 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
892 gtk, gtk_len);
893
894 if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
895 return -1;
896
897 gd.keyidx = gtk[0] & 0x3;
898 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
899 !!(gtk[0] & BIT(2)));
900 gtk += 2;
901 gtk_len -= 2;
902
903 os_memcpy(gd.gtk, gtk, gtk_len);
904 gd.gtk_len = gtk_len;
905
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800906 key_rsc = key->key_rsc;
907 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
908 key_rsc = null_rsc;
909
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800910 if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED &&
911 (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
912 gtk_len, gtk_len,
913 &gd.key_rsc_len, &gd.alg) ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800914 wpa_supplicant_install_gtk(sm, &gd, key_rsc))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700915 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
916 "RSN: Failed to install GTK");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700917 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700918 return -1;
919 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700920 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700921
922 wpa_supplicant_key_neg_complete(sm, sm->bssid,
923 key_info & WPA_KEY_INFO_SECURE);
924 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700925}
926
927
928static int ieee80211w_set_keys(struct wpa_sm *sm,
929 struct wpa_eapol_ie_parse *ie)
930{
931#ifdef CONFIG_IEEE80211W
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700932 if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700933 return 0;
934
935 if (ie->igtk) {
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700936 size_t len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700937 const struct wpa_igtk_kde *igtk;
938 u16 keyidx;
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700939 len = wpa_cipher_key_len(sm->mgmt_group_cipher);
940 if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700941 return -1;
942 igtk = (const struct wpa_igtk_kde *) ie->igtk;
943 keyidx = WPA_GET_LE16(igtk->keyid);
944 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d "
945 "pn %02x%02x%02x%02x%02x%02x",
946 keyidx, MAC2STR(igtk->pn));
947 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700948 igtk->igtk, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700949 if (keyidx > 4095) {
950 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
951 "WPA: Invalid IGTK KeyID %d", keyidx);
952 return -1;
953 }
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700954 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
955 broadcast_ether_addr,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700956 keyidx, 0, igtk->pn, sizeof(igtk->pn),
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700957 igtk->igtk, len) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700958 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
959 "WPA: Failed to configure IGTK to the driver");
960 return -1;
961 }
962 }
963
964 return 0;
965#else /* CONFIG_IEEE80211W */
966 return 0;
967#endif /* CONFIG_IEEE80211W */
968}
969
970
971static void wpa_report_ie_mismatch(struct wpa_sm *sm,
972 const char *reason, const u8 *src_addr,
973 const u8 *wpa_ie, size_t wpa_ie_len,
974 const u8 *rsn_ie, size_t rsn_ie_len)
975{
976 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",
977 reason, MAC2STR(src_addr));
978
979 if (sm->ap_wpa_ie) {
980 wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
981 sm->ap_wpa_ie, sm->ap_wpa_ie_len);
982 }
983 if (wpa_ie) {
984 if (!sm->ap_wpa_ie) {
985 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
986 "WPA: No WPA IE in Beacon/ProbeResp");
987 }
988 wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
989 wpa_ie, wpa_ie_len);
990 }
991
992 if (sm->ap_rsn_ie) {
993 wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
994 sm->ap_rsn_ie, sm->ap_rsn_ie_len);
995 }
996 if (rsn_ie) {
997 if (!sm->ap_rsn_ie) {
998 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
999 "WPA: No RSN IE in Beacon/ProbeResp");
1000 }
1001 wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
1002 rsn_ie, rsn_ie_len);
1003 }
1004
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001005 wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001006}
1007
1008
1009#ifdef CONFIG_IEEE80211R
1010
1011static int ft_validate_mdie(struct wpa_sm *sm,
1012 const unsigned char *src_addr,
1013 struct wpa_eapol_ie_parse *ie,
1014 const u8 *assoc_resp_mdie)
1015{
1016 struct rsn_mdie *mdie;
1017
1018 mdie = (struct rsn_mdie *) (ie->mdie + 2);
1019 if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
1020 os_memcmp(mdie->mobility_domain, sm->mobility_domain,
1021 MOBILITY_DOMAIN_ID_LEN) != 0) {
1022 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did "
1023 "not match with the current mobility domain");
1024 return -1;
1025 }
1026
1027 if (assoc_resp_mdie &&
1028 (assoc_resp_mdie[1] != ie->mdie[1] ||
1029 os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
1030 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch");
1031 wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
1032 ie->mdie, 2 + ie->mdie[1]);
1033 wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
1034 assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
1035 return -1;
1036 }
1037
1038 return 0;
1039}
1040
1041
1042static int ft_validate_ftie(struct wpa_sm *sm,
1043 const unsigned char *src_addr,
1044 struct wpa_eapol_ie_parse *ie,
1045 const u8 *assoc_resp_ftie)
1046{
1047 if (ie->ftie == NULL) {
1048 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1049 "FT: No FTIE in EAPOL-Key msg 3/4");
1050 return -1;
1051 }
1052
1053 if (assoc_resp_ftie == NULL)
1054 return 0;
1055
1056 if (assoc_resp_ftie[1] != ie->ftie[1] ||
1057 os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
1058 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch");
1059 wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
1060 ie->ftie, 2 + ie->ftie[1]);
1061 wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
1062 assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
1063 return -1;
1064 }
1065
1066 return 0;
1067}
1068
1069
1070static int ft_validate_rsnie(struct wpa_sm *sm,
1071 const unsigned char *src_addr,
1072 struct wpa_eapol_ie_parse *ie)
1073{
1074 struct wpa_ie_data rsn;
1075
1076 if (!ie->rsn_ie)
1077 return 0;
1078
1079 /*
1080 * Verify that PMKR1Name from EAPOL-Key message 3/4
1081 * matches with the value we derived.
1082 */
1083 if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
1084 rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
1085 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in "
1086 "FT 4-way handshake message 3/4");
1087 return -1;
1088 }
1089
Dmitry Shmidtc2817022014-07-02 10:32:10 -07001090 if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
1091 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001092 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1093 "FT: PMKR1Name mismatch in "
1094 "FT 4-way handshake message 3/4");
1095 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
1096 rsn.pmkid, WPA_PMK_NAME_LEN);
1097 wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
1098 sm->pmk_r1_name, WPA_PMK_NAME_LEN);
1099 return -1;
1100 }
1101
1102 return 0;
1103}
1104
1105
1106static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
1107 const unsigned char *src_addr,
1108 struct wpa_eapol_ie_parse *ie)
1109{
1110 const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
1111
1112 if (sm->assoc_resp_ies) {
1113 pos = sm->assoc_resp_ies;
1114 end = pos + sm->assoc_resp_ies_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001115 while (end - pos > 2) {
1116 if (2 + pos[1] > end - pos)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001117 break;
1118 switch (*pos) {
1119 case WLAN_EID_MOBILITY_DOMAIN:
1120 mdie = pos;
1121 break;
1122 case WLAN_EID_FAST_BSS_TRANSITION:
1123 ftie = pos;
1124 break;
1125 }
1126 pos += 2 + pos[1];
1127 }
1128 }
1129
1130 if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
1131 ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
1132 ft_validate_rsnie(sm, src_addr, ie) < 0)
1133 return -1;
1134
1135 return 0;
1136}
1137
1138#endif /* CONFIG_IEEE80211R */
1139
1140
1141static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
1142 const unsigned char *src_addr,
1143 struct wpa_eapol_ie_parse *ie)
1144{
1145 if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {
1146 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1147 "WPA: No WPA/RSN IE for this AP known. "
1148 "Trying to get from scan results");
1149 if (wpa_sm_get_beacon_ie(sm) < 0) {
1150 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1151 "WPA: Could not find AP from "
1152 "the scan results");
1153 } else {
1154 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
1155 "WPA: Found the current AP from "
1156 "updated scan results");
1157 }
1158 }
1159
1160 if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
1161 (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
1162 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1163 "with IE in Beacon/ProbeResp (no IE?)",
1164 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1165 ie->rsn_ie, ie->rsn_ie_len);
1166 return -1;
1167 }
1168
1169 if ((ie->wpa_ie && sm->ap_wpa_ie &&
1170 (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
1171 os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
1172 (ie->rsn_ie && sm->ap_rsn_ie &&
1173 wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
1174 sm->ap_rsn_ie, sm->ap_rsn_ie_len,
1175 ie->rsn_ie, ie->rsn_ie_len))) {
1176 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1177 "with IE in Beacon/ProbeResp",
1178 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1179 ie->rsn_ie, ie->rsn_ie_len);
1180 return -1;
1181 }
1182
1183 if (sm->proto == WPA_PROTO_WPA &&
1184 ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
1185 wpa_report_ie_mismatch(sm, "Possible downgrade attack "
1186 "detected - RSN was enabled and RSN IE "
1187 "was in msg 3/4, but not in "
1188 "Beacon/ProbeResp",
1189 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1190 ie->rsn_ie, ie->rsn_ie_len);
1191 return -1;
1192 }
1193
1194#ifdef CONFIG_IEEE80211R
1195 if (wpa_key_mgmt_ft(sm->key_mgmt) &&
1196 wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
1197 return -1;
1198#endif /* CONFIG_IEEE80211R */
1199
1200 return 0;
1201}
1202
1203
1204/**
1205 * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake
1206 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1207 * @dst: Destination address for the frame
1208 * @key: Pointer to the EAPOL-Key frame header
1209 * @ver: Version bits from EAPOL-Key Key Info
1210 * @key_info: Key Info
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001211 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001212 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001213 */
1214int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
1215 const struct wpa_eapol_key *key,
1216 u16 ver, u16 key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001217 struct wpa_ptk *ptk)
1218{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001219 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001220 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001221 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001222
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001223 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001224 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001225 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001226 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001227 if (rbuf == NULL)
1228 return -1;
1229
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001230 reply->type = (sm->proto == WPA_PROTO_RSN ||
1231 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001232 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1233 key_info &= WPA_KEY_INFO_SECURE;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001234 key_info |= ver | WPA_KEY_INFO_KEY_TYPE;
1235 if (mic_len)
1236 key_info |= WPA_KEY_INFO_MIC;
1237 else
1238 key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001239 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001240 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001241 WPA_PUT_BE16(reply->key_length, 0);
1242 else
1243 os_memcpy(reply->key_length, key->key_length, 2);
1244 os_memcpy(reply->replay_counter, key->replay_counter,
1245 WPA_REPLAY_COUNTER_LEN);
1246
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001247 key_mic = (u8 *) (reply + 1);
1248 WPA_PUT_BE16(key_mic + mic_len, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001249
1250 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001251 return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen,
1252 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001253}
1254
1255
1256static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
1257 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001258 u16 ver, const u8 *key_data,
1259 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001260{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001261 u16 key_info, keylen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001262 struct wpa_eapol_ie_parse ie;
1263
1264 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
1265 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 3 of 4-Way "
1266 "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
1267
1268 key_info = WPA_GET_BE16(key->key_info);
1269
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001270 wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", key_data, key_data_len);
1271 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001272 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001273 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1274 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1275 "WPA: GTK IE in unencrypted key data");
1276 goto failed;
1277 }
1278#ifdef CONFIG_IEEE80211W
1279 if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1280 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1281 "WPA: IGTK KDE in unencrypted key data");
1282 goto failed;
1283 }
1284
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07001285 if (ie.igtk &&
1286 wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) &&
1287 ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN +
1288 (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001289 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1290 "WPA: Invalid IGTK KDE length %lu",
1291 (unsigned long) ie.igtk_len);
1292 goto failed;
1293 }
1294#endif /* CONFIG_IEEE80211W */
1295
1296 if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
1297 goto failed;
1298
1299 if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
1300 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1301 "WPA: ANonce from message 1 of 4-Way Handshake "
1302 "differs from 3 of 4-Way Handshake - drop packet (src="
1303 MACSTR ")", MAC2STR(sm->bssid));
1304 goto failed;
1305 }
1306
1307 keylen = WPA_GET_BE16(key->key_length);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07001308 if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) {
1309 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1310 "WPA: Invalid %s key length %d (src=" MACSTR
1311 ")", wpa_cipher_txt(sm->pairwise_cipher), keylen,
1312 MAC2STR(sm->bssid));
1313 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001314 }
1315
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08001316#ifdef CONFIG_P2P
1317 if (ie.ip_addr_alloc) {
1318 os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4);
1319 wpa_hexdump(MSG_DEBUG, "P2P: IP address info",
1320 sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr));
1321 }
1322#endif /* CONFIG_P2P */
1323
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001324 if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001325 &sm->ptk) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001326 goto failed;
1327 }
1328
1329 /* SNonce was successfully used in msg 3/4, so mark it to be renewed
1330 * for the next 4-Way Handshake. If msg 3 is received again, the old
1331 * SNonce will still be used to avoid changing PTK. */
1332 sm->renew_snonce = 1;
1333
1334 if (key_info & WPA_KEY_INFO_INSTALL) {
1335 if (wpa_supplicant_install_ptk(sm, key))
1336 goto failed;
1337 }
1338
1339 if (key_info & WPA_KEY_INFO_SECURE) {
1340 wpa_sm_mlme_setprotection(
1341 sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
1342 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1343 eapol_sm_notify_portValid(sm->eapol, TRUE);
1344 }
1345 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1346
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001347 if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) {
1348 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1349 key_info & WPA_KEY_INFO_SECURE);
1350 } else if (ie.gtk &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001351 wpa_supplicant_pairwise_gtk(sm, key,
1352 ie.gtk, ie.gtk_len, key_info) < 0) {
1353 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1354 "RSN: Failed to configure GTK");
1355 goto failed;
1356 }
1357
1358 if (ieee80211w_set_keys(sm, &ie) < 0) {
1359 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1360 "RSN: Failed to configure IGTK");
1361 goto failed;
1362 }
1363
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001364 if (ie.gtk)
1365 wpa_sm_set_rekey_offload(sm);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001366
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001367 if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) {
1368 struct rsn_pmksa_cache_entry *sa;
1369
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001370 sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001371 sm->ptk.kck, sm->ptk.kck_len,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001372 sm->bssid, sm->own_addr,
1373 sm->network_ctx, sm->key_mgmt);
1374 if (!sm->cur_pmksa)
1375 sm->cur_pmksa = sa;
1376 }
1377
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001378 sm->msg_3_of_4_ok = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001379 return;
1380
1381failed:
1382 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1383}
1384
1385
1386static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
1387 const u8 *keydata,
1388 size_t keydatalen,
1389 u16 key_info,
1390 struct wpa_gtk_data *gd)
1391{
1392 int maxkeylen;
1393 struct wpa_eapol_ie_parse ie;
1394
1395 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001396 if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0)
1397 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001398 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1399 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1400 "WPA: GTK IE in unencrypted key data");
1401 return -1;
1402 }
1403 if (ie.gtk == NULL) {
1404 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1405 "WPA: No GTK IE in Group Key msg 1/2");
1406 return -1;
1407 }
1408 maxkeylen = gd->gtk_len = ie.gtk_len - 2;
1409
1410 if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1411 gd->gtk_len, maxkeylen,
1412 &gd->key_rsc_len, &gd->alg))
1413 return -1;
1414
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001415 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in group key handshake",
1416 ie.gtk, ie.gtk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001417 gd->keyidx = ie.gtk[0] & 0x3;
1418 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
1419 !!(ie.gtk[0] & BIT(2)));
1420 if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
1421 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1422 "RSN: Too long GTK in GTK IE (len=%lu)",
1423 (unsigned long) ie.gtk_len - 2);
1424 return -1;
1425 }
1426 os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
1427
1428 if (ieee80211w_set_keys(sm, &ie) < 0)
1429 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1430 "RSN: Failed to configure IGTK");
1431
1432 return 0;
1433}
1434
1435
1436static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
1437 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001438 const u8 *key_data,
1439 size_t key_data_len, u16 key_info,
1440 u16 ver, struct wpa_gtk_data *gd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001441{
1442 size_t maxkeylen;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001443 u16 gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001444
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001445 gtk_len = WPA_GET_BE16(key->key_length);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001446 maxkeylen = key_data_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001447 if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1448 if (maxkeylen < 8) {
1449 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1450 "WPA: Too short maxkeylen (%lu)",
1451 (unsigned long) maxkeylen);
1452 return -1;
1453 }
1454 maxkeylen -= 8;
1455 }
1456
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001457 if (gtk_len > maxkeylen ||
1458 wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1459 gtk_len, maxkeylen,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001460 &gd->key_rsc_len, &gd->alg))
1461 return -1;
1462
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001463 gd->gtk_len = gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001464 gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1465 WPA_KEY_INFO_KEY_INDEX_SHIFT;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001466 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001467#ifdef CONFIG_NO_RC4
1468 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1469 "WPA: RC4 not supported in the build");
1470 return -1;
1471#else /* CONFIG_NO_RC4 */
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001472 u8 ek[32];
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001473 if (key_data_len > sizeof(gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001474 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1475 "WPA: RC4 key data too long (%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001476 (unsigned long) key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001477 return -1;
1478 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001479 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001480 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001481 os_memcpy(gd->gtk, key_data, key_data_len);
1482 if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001483 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001484 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1485 "WPA: RC4 failed");
1486 return -1;
1487 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001488 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001489#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001490 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001491 if (maxkeylen % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001492 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1493 "WPA: Unsupported AES-WRAP len %lu",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001494 (unsigned long) maxkeylen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001495 return -1;
1496 }
1497 if (maxkeylen > sizeof(gd->gtk)) {
1498 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1499 "WPA: AES-WRAP key data "
1500 "too long (keydatalen=%lu maxkeylen=%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001501 (unsigned long) key_data_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001502 (unsigned long) maxkeylen);
1503 return -1;
1504 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001505 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, maxkeylen / 8,
1506 key_data, gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001507 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1508 "WPA: AES unwrap failed - could not decrypt "
1509 "GTK");
1510 return -1;
1511 }
1512 } else {
1513 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1514 "WPA: Unsupported key_info type %d", ver);
1515 return -1;
1516 }
1517 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
1518 sm, !!(key_info & WPA_KEY_INFO_TXRX));
1519 return 0;
1520}
1521
1522
1523static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
1524 const struct wpa_eapol_key *key,
1525 int ver, u16 key_info)
1526{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001527 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001528 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001529 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001530
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001531 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001532 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001533 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001534 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001535 if (rbuf == NULL)
1536 return -1;
1537
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001538 reply->type = (sm->proto == WPA_PROTO_RSN ||
1539 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001540 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1541 key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001542 key_info |= ver | WPA_KEY_INFO_SECURE;
1543 if (mic_len)
1544 key_info |= WPA_KEY_INFO_MIC;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001545 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001546 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001547 WPA_PUT_BE16(reply->key_length, 0);
1548 else
1549 os_memcpy(reply->key_length, key->key_length, 2);
1550 os_memcpy(reply->replay_counter, key->replay_counter,
1551 WPA_REPLAY_COUNTER_LEN);
1552
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001553 key_mic = (u8 *) (reply + 1);
1554 WPA_PUT_BE16(key_mic + mic_len, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001555
1556 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001557 return wpa_eapol_key_send(sm, &sm->ptk, ver, sm->bssid, ETH_P_EAPOL,
1558 rbuf, rlen, key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001559}
1560
1561
1562static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
1563 const unsigned char *src_addr,
1564 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001565 const u8 *key_data,
1566 size_t key_data_len, u16 ver)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001567{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001568 u16 key_info;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001569 int rekey, ret;
1570 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001571 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001572
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001573 if (!sm->msg_3_of_4_ok) {
1574 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1575 "WPA: Group Key Handshake started prior to completion of 4-way handshake");
1576 goto failed;
1577 }
1578
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001579 os_memset(&gd, 0, sizeof(gd));
1580
1581 rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
1582 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of Group Key "
1583 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1584
1585 key_info = WPA_GET_BE16(key->key_info);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001586
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001587 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001588 ret = wpa_supplicant_process_1_of_2_rsn(sm, key_data,
1589 key_data_len, key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001590 &gd);
1591 } else {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001592 ret = wpa_supplicant_process_1_of_2_wpa(sm, key, key_data,
1593 key_data_len,
1594 key_info, ver, &gd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001595 }
1596
1597 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1598
1599 if (ret)
1600 goto failed;
1601
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001602 key_rsc = key->key_rsc;
1603 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
1604 key_rsc = null_rsc;
1605
1606 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc) ||
1607 wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001608 goto failed;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001609 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001610
1611 if (rekey) {
1612 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
1613 "completed with " MACSTR " [GTK=%s]",
1614 MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
1615 wpa_sm_cancel_auth_timeout(sm);
1616 wpa_sm_set_state(sm, WPA_COMPLETED);
1617 } else {
1618 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1619 key_info &
1620 WPA_KEY_INFO_SECURE);
1621 }
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001622
1623 wpa_sm_set_rekey_offload(sm);
1624
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001625 return;
1626
1627failed:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001628 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001629 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1630}
1631
1632
1633static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001634 struct wpa_eapol_key *key,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001635 u16 ver,
1636 const u8 *buf, size_t len)
1637{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001638 u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001639 int ok = 0;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001640 size_t mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001641
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001642 os_memcpy(mic, key + 1, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001643 if (sm->tptk_set) {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001644 os_memset(key + 1, 0, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001645 wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len, sm->key_mgmt,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001646 ver, buf, len, (u8 *) (key + 1));
1647 if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001648 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1649 "WPA: Invalid EAPOL-Key MIC "
1650 "when using TPTK - ignoring TPTK");
1651 } else {
1652 ok = 1;
1653 sm->tptk_set = 0;
1654 sm->ptk_set = 1;
1655 os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001656 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001657 }
1658 }
1659
1660 if (!ok && sm->ptk_set) {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001661 os_memset(key + 1, 0, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001662 wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len, sm->key_mgmt,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001663 ver, buf, len, (u8 *) (key + 1));
1664 if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001665 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1666 "WPA: Invalid EAPOL-Key MIC - "
1667 "dropping packet");
1668 return -1;
1669 }
1670 ok = 1;
1671 }
1672
1673 if (!ok) {
1674 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1675 "WPA: Could not verify EAPOL-Key MIC - "
1676 "dropping packet");
1677 return -1;
1678 }
1679
1680 os_memcpy(sm->rx_replay_counter, key->replay_counter,
1681 WPA_REPLAY_COUNTER_LEN);
1682 sm->rx_replay_counter_set = 1;
1683 return 0;
1684}
1685
1686
1687/* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
1688static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001689 struct wpa_eapol_key *key,
1690 size_t mic_len, u16 ver,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001691 u8 *key_data, size_t *key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001692{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001693 wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001694 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001695 if (!sm->ptk_set) {
1696 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1697 "WPA: PTK not available, cannot decrypt EAPOL-Key Key "
1698 "Data");
1699 return -1;
1700 }
1701
1702 /* Decrypt key data here so that this operation does not need
1703 * to be implemented separately for each message type. */
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001704 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001705#ifdef CONFIG_NO_RC4
1706 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1707 "WPA: RC4 not supported in the build");
1708 return -1;
1709#else /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001710 u8 ek[32];
1711 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001712 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001713 if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001714 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001715 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1716 "WPA: RC4 failed");
1717 return -1;
1718 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001719 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001720#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001721 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001722 ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001723 sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
1724 wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001725 u8 *buf;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001726 if (*key_data_len < 8 || *key_data_len % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001727 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001728 "WPA: Unsupported AES-WRAP len %u",
1729 (unsigned int) *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001730 return -1;
1731 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001732 *key_data_len -= 8; /* AES-WRAP adds 8 bytes */
1733 buf = os_malloc(*key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001734 if (buf == NULL) {
1735 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1736 "WPA: No memory for AES-UNWRAP buffer");
1737 return -1;
1738 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001739 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, *key_data_len / 8,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001740 key_data, buf)) {
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001741 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001742 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1743 "WPA: AES unwrap failed - "
1744 "could not decrypt EAPOL-Key key data");
1745 return -1;
1746 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001747 os_memcpy(key_data, buf, *key_data_len);
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001748 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001749 WPA_PUT_BE16(((u8 *) (key + 1)) + mic_len, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001750 } else {
1751 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1752 "WPA: Unsupported key_info type %d", ver);
1753 return -1;
1754 }
1755 wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001756 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001757 return 0;
1758}
1759
1760
1761/**
1762 * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted
1763 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1764 */
1765void wpa_sm_aborted_cached(struct wpa_sm *sm)
1766{
1767 if (sm && sm->cur_pmksa) {
1768 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1769 "RSN: Cancelling PMKSA caching attempt");
1770 sm->cur_pmksa = NULL;
1771 }
1772}
1773
1774
1775static void wpa_eapol_key_dump(struct wpa_sm *sm,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001776 const struct wpa_eapol_key *key,
1777 unsigned int key_data_len,
1778 const u8 *mic, unsigned int mic_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001779{
1780#ifndef CONFIG_NO_STDOUT_DEBUG
1781 u16 key_info = WPA_GET_BE16(key->key_info);
1782
1783 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, " EAPOL-Key type=%d", key->type);
1784 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1785 " key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s%s%s%s%s%s%s%s)",
1786 key_info, key_info & WPA_KEY_INFO_TYPE_MASK,
1787 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1788 WPA_KEY_INFO_KEY_INDEX_SHIFT,
1789 (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,
1790 key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",
1791 key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",
1792 key_info & WPA_KEY_INFO_ACK ? " Ack" : "",
1793 key_info & WPA_KEY_INFO_MIC ? " MIC" : "",
1794 key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",
1795 key_info & WPA_KEY_INFO_ERROR ? " Error" : "",
1796 key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",
1797 key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
1798 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1799 " key_length=%u key_data_length=%u",
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001800 WPA_GET_BE16(key->key_length), key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001801 wpa_hexdump(MSG_DEBUG, " replay_counter",
1802 key->replay_counter, WPA_REPLAY_COUNTER_LEN);
1803 wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN);
1804 wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16);
1805 wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8);
1806 wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001807 wpa_hexdump(MSG_DEBUG, " key_mic", mic, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001808#endif /* CONFIG_NO_STDOUT_DEBUG */
1809}
1810
1811
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001812#ifdef CONFIG_FILS
1813static int wpa_supp_aead_decrypt(struct wpa_sm *sm, u8 *buf, size_t buf_len,
1814 size_t *key_data_len)
1815{
1816 struct wpa_ptk *ptk;
1817 struct ieee802_1x_hdr *hdr;
1818 struct wpa_eapol_key *key;
1819 u8 *pos, *tmp;
1820 const u8 *aad[1];
1821 size_t aad_len[1];
1822
1823 if (*key_data_len < AES_BLOCK_SIZE) {
1824 wpa_printf(MSG_INFO, "No room for AES-SIV data in the frame");
1825 return -1;
1826 }
1827
1828 if (sm->tptk_set)
1829 ptk = &sm->tptk;
1830 else if (sm->ptk_set)
1831 ptk = &sm->ptk;
1832 else
1833 return -1;
1834
1835 hdr = (struct ieee802_1x_hdr *) buf;
1836 key = (struct wpa_eapol_key *) (hdr + 1);
1837 pos = (u8 *) (key + 1);
1838 pos += 2; /* Pointing at the Encrypted Key Data field */
1839
1840 tmp = os_malloc(*key_data_len);
1841 if (!tmp)
1842 return -1;
1843
1844 /* AES-SIV AAD from EAPOL protocol version field (inclusive) to
1845 * to Key Data (exclusive). */
1846 aad[0] = buf;
1847 aad_len[0] = pos - buf;
1848 if (aes_siv_decrypt(ptk->kek, ptk->kek_len, pos, *key_data_len,
1849 1, aad, aad_len, tmp) < 0) {
1850 wpa_printf(MSG_INFO, "Invalid AES-SIV data in the frame");
1851 bin_clear_free(tmp, *key_data_len);
1852 return -1;
1853 }
1854
1855 /* AEAD decryption and validation completed successfully */
1856 (*key_data_len) -= AES_BLOCK_SIZE;
1857 wpa_hexdump_key(MSG_DEBUG, "WPA: Decrypted Key Data",
1858 tmp, *key_data_len);
1859
1860 /* Replace Key Data field with the decrypted version */
1861 os_memcpy(pos, tmp, *key_data_len);
1862 pos -= 2; /* Key Data Length field */
1863 WPA_PUT_BE16(pos, *key_data_len);
1864 bin_clear_free(tmp, *key_data_len);
1865
1866 if (sm->tptk_set) {
1867 sm->tptk_set = 0;
1868 sm->ptk_set = 1;
1869 os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
1870 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
1871 }
1872
1873 os_memcpy(sm->rx_replay_counter, key->replay_counter,
1874 WPA_REPLAY_COUNTER_LEN);
1875 sm->rx_replay_counter_set = 1;
1876
1877 return 0;
1878}
1879#endif /* CONFIG_FILS */
1880
1881
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001882/**
1883 * wpa_sm_rx_eapol - Process received WPA EAPOL frames
1884 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1885 * @src_addr: Source MAC address of the EAPOL packet
1886 * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
1887 * @len: Length of the EAPOL frame
1888 * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
1889 *
1890 * This function is called for each received EAPOL frame. Other than EAPOL-Key
1891 * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
1892 * only processing WPA and WPA2 EAPOL-Key frames.
1893 *
1894 * The received EAPOL-Key packets are validated and valid packets are replied
1895 * to. In addition, key material (PTK, GTK) is configured at the end of a
1896 * successful key handshake.
1897 */
1898int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
1899 const u8 *buf, size_t len)
1900{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001901 size_t plen, data_len, key_data_len;
1902 const struct ieee802_1x_hdr *hdr;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001903 struct wpa_eapol_key *key;
1904 u16 key_info, ver;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001905 u8 *tmp = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001906 int ret = -1;
1907 struct wpa_peerkey *peerkey = NULL;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001908 u8 *mic, *key_data;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001909 size_t mic_len, keyhdrlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001910
1911#ifdef CONFIG_IEEE80211R
1912 sm->ft_completed = 0;
1913#endif /* CONFIG_IEEE80211R */
1914
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001915 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001916 keyhdrlen = sizeof(*key) + mic_len + 2;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001917
1918 if (len < sizeof(*hdr) + keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001919 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1920 "WPA: EAPOL frame too short to be a WPA "
1921 "EAPOL-Key (len %lu, expecting at least %lu)",
1922 (unsigned long) len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001923 (unsigned long) sizeof(*hdr) + keyhdrlen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001924 return 0;
1925 }
1926
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001927 hdr = (const struct ieee802_1x_hdr *) buf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001928 plen = be_to_host16(hdr->length);
1929 data_len = plen + sizeof(*hdr);
1930 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1931 "IEEE 802.1X RX: version=%d type=%d length=%lu",
1932 hdr->version, hdr->type, (unsigned long) plen);
1933
1934 if (hdr->version < EAPOL_VERSION) {
1935 /* TODO: backwards compatibility */
1936 }
1937 if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
1938 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1939 "WPA: EAPOL frame (type %u) discarded, "
1940 "not a Key frame", hdr->type);
1941 ret = 0;
1942 goto out;
1943 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001944 wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001945 if (plen > len - sizeof(*hdr) || plen < keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001946 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1947 "WPA: EAPOL frame payload size %lu "
1948 "invalid (frame size %lu)",
1949 (unsigned long) plen, (unsigned long) len);
1950 ret = 0;
1951 goto out;
1952 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001953 if (data_len < len) {
1954 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1955 "WPA: ignoring %lu bytes after the IEEE 802.1X data",
1956 (unsigned long) len - data_len);
1957 }
1958
1959 /*
1960 * Make a copy of the frame since we need to modify the buffer during
1961 * MAC validation and Key Data decryption.
1962 */
1963 tmp = os_malloc(data_len);
1964 if (tmp == NULL)
1965 goto out;
1966 os_memcpy(tmp, buf, data_len);
1967 key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr));
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001968 mic = (u8 *) (key + 1);
1969 key_data = mic + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001970
1971 if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
1972 {
1973 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1974 "WPA: EAPOL-Key type (%d) unknown, discarded",
1975 key->type);
1976 ret = 0;
1977 goto out;
1978 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001979
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001980 key_data_len = WPA_GET_BE16(mic + mic_len);
1981 wpa_eapol_key_dump(sm, key, key_data_len, mic, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001982
1983 if (key_data_len > plen - keyhdrlen) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001984 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
1985 "frame - key_data overflow (%u > %u)",
1986 (unsigned int) key_data_len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001987 (unsigned int) (plen - keyhdrlen));
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001988 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001989 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001990
1991 eapol_sm_notify_lower_layer_success(sm->eapol, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001992 key_info = WPA_GET_BE16(key->key_info);
1993 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1994 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1995#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
1996 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
1997#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001998 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001999 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002000 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002001 sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002002 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2003 "WPA: Unsupported EAPOL-Key descriptor version %d",
2004 ver);
2005 goto out;
2006 }
2007
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002008 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN &&
2009 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
2010 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2011 "OSEN: Unsupported EAPOL-Key descriptor version %d",
2012 ver);
2013 goto out;
2014 }
2015
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002016 if ((wpa_key_mgmt_suite_b(sm->key_mgmt) ||
2017 wpa_key_mgmt_fils(sm->key_mgmt)) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002018 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
2019 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2020 "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)",
2021 ver);
2022 goto out;
2023 }
2024
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002025#ifdef CONFIG_IEEE80211R
2026 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
2027 /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
2028 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
2029 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2030 "FT: AP did not use AES-128-CMAC");
2031 goto out;
2032 }
2033 } else
2034#endif /* CONFIG_IEEE80211R */
2035#ifdef CONFIG_IEEE80211W
2036 if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002037 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002038 sm->key_mgmt != WPA_KEY_MGMT_OSEN &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002039 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002040 !wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002041 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2042 "WPA: AP did not use the "
2043 "negotiated AES-128-CMAC");
2044 goto out;
2045 }
2046 } else
2047#endif /* CONFIG_IEEE80211W */
2048 if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002049 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002050 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002051 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
2052 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2053 "WPA: CCMP is used, but EAPOL-Key "
2054 "descriptor version (%d) is not 2", ver);
2055 if (sm->group_cipher != WPA_CIPHER_CCMP &&
2056 !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
2057 /* Earlier versions of IEEE 802.11i did not explicitly
2058 * require version 2 descriptor for all EAPOL-Key
2059 * packets, so allow group keys to use version 1 if
2060 * CCMP is not used for them. */
2061 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2062 "WPA: Backwards compatibility: allow invalid "
2063 "version for non-CCMP group keys");
Jouni Malinen658fb4a2014-11-14 20:57:05 +02002064 } else if (ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
2065 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2066 "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 -07002067 } else
2068 goto out;
Dmitry Shmidt71757432014-06-02 13:50:35 -07002069 } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002070 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt71757432014-06-02 13:50:35 -07002071 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002072 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2073 "WPA: GCMP is used, but EAPOL-Key "
2074 "descriptor version (%d) is not 2", ver);
2075 goto out;
2076 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002077
2078#ifdef CONFIG_PEERKEY
2079 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
2080 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
2081 break;
2082 }
2083
2084 if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
2085 if (!peerkey->initiator && peerkey->replay_counter_set &&
2086 os_memcmp(key->replay_counter, peerkey->replay_counter,
2087 WPA_REPLAY_COUNTER_LEN) <= 0) {
2088 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2089 "RSN: EAPOL-Key Replay Counter did not "
2090 "increase (STK) - dropping packet");
2091 goto out;
2092 } else if (peerkey->initiator) {
2093 u8 _tmp[WPA_REPLAY_COUNTER_LEN];
2094 os_memcpy(_tmp, key->replay_counter,
2095 WPA_REPLAY_COUNTER_LEN);
2096 inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
2097 if (os_memcmp(_tmp, peerkey->replay_counter,
2098 WPA_REPLAY_COUNTER_LEN) != 0) {
2099 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2100 "RSN: EAPOL-Key Replay "
2101 "Counter did not match (STK) - "
2102 "dropping packet");
2103 goto out;
2104 }
2105 }
2106 }
2107
2108 if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
2109 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2110 "RSN: Ack bit in key_info from STK peer");
2111 goto out;
2112 }
2113#endif /* CONFIG_PEERKEY */
2114
2115 if (!peerkey && sm->rx_replay_counter_set &&
2116 os_memcmp(key->replay_counter, sm->rx_replay_counter,
2117 WPA_REPLAY_COUNTER_LEN) <= 0) {
2118 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2119 "WPA: EAPOL-Key Replay Counter did not increase - "
2120 "dropping packet");
2121 goto out;
2122 }
2123
2124 if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
2125#ifdef CONFIG_PEERKEY
2126 && (peerkey == NULL || !peerkey->initiator)
2127#endif /* CONFIG_PEERKEY */
2128 ) {
2129 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2130 "WPA: No Ack bit in key_info");
2131 goto out;
2132 }
2133
2134 if (key_info & WPA_KEY_INFO_REQUEST) {
2135 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2136 "WPA: EAPOL-Key with Request bit - dropped");
2137 goto out;
2138 }
2139
2140 if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002141 wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002142 goto out;
2143
2144#ifdef CONFIG_PEERKEY
2145 if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002146 peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002147 data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002148 goto out;
2149#endif /* CONFIG_PEERKEY */
2150
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002151#ifdef CONFIG_FILS
2152 if (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
2153 if (wpa_supp_aead_decrypt(sm, tmp, data_len, &key_data_len))
2154 goto out;
2155 }
2156#endif /* CONFIG_FILS */
2157
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002158 if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002159 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) && mic_len) {
2160 if (wpa_supplicant_decrypt_key_data(sm, key, mic_len,
2161 ver, key_data,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002162 &key_data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002163 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002164 }
2165
2166 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
2167 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
2168 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2169 "WPA: Ignored EAPOL-Key (Pairwise) with "
2170 "non-zero key index");
2171 goto out;
2172 }
2173 if (peerkey) {
2174 /* PeerKey 4-Way Handshake */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07002175 peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
2176 key_data, key_data_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002177 } else if (key_info & (WPA_KEY_INFO_MIC |
2178 WPA_KEY_INFO_ENCR_KEY_DATA)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002179 /* 3/4 4-Way Handshake */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002180 wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
2181 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002182 } else {
2183 /* 1/4 4-Way Handshake */
2184 wpa_supplicant_process_1_of_4(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002185 ver, key_data,
2186 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002187 }
2188 } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
2189 /* PeerKey SMK Handshake */
Dmitry Shmidt29333592017-01-09 12:27:11 -08002190 peerkey_rx_eapol_smk(sm, src_addr, key, key_data, key_data_len,
2191 key_info, ver);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002192 } else {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002193 if ((mic_len && (key_info & WPA_KEY_INFO_MIC)) ||
2194 (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002195 /* 1/2 Group Key Handshake */
2196 wpa_supplicant_process_1_of_2(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002197 key_data, key_data_len,
2198 ver);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002199 } else {
2200 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002201 "WPA: EAPOL-Key (Group) without Mic/Encr bit - "
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002202 "dropped");
2203 }
2204 }
2205
2206 ret = 1;
2207
2208out:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002209 bin_clear_free(tmp, data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002210 return ret;
2211}
2212
2213
2214#ifdef CONFIG_CTRL_IFACE
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002215static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
2216{
2217 switch (sm->key_mgmt) {
2218 case WPA_KEY_MGMT_IEEE8021X:
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002219 return ((sm->proto == WPA_PROTO_RSN ||
2220 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002221 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
2222 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
2223 case WPA_KEY_MGMT_PSK:
2224 return (sm->proto == WPA_PROTO_RSN ?
2225 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
2226 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
2227#ifdef CONFIG_IEEE80211R
2228 case WPA_KEY_MGMT_FT_IEEE8021X:
2229 return RSN_AUTH_KEY_MGMT_FT_802_1X;
2230 case WPA_KEY_MGMT_FT_PSK:
2231 return RSN_AUTH_KEY_MGMT_FT_PSK;
2232#endif /* CONFIG_IEEE80211R */
2233#ifdef CONFIG_IEEE80211W
2234 case WPA_KEY_MGMT_IEEE8021X_SHA256:
2235 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
2236 case WPA_KEY_MGMT_PSK_SHA256:
2237 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
2238#endif /* CONFIG_IEEE80211W */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002239 case WPA_KEY_MGMT_CCKM:
2240 return (sm->proto == WPA_PROTO_RSN ?
2241 RSN_AUTH_KEY_MGMT_CCKM:
2242 WPA_AUTH_KEY_MGMT_CCKM);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002243 case WPA_KEY_MGMT_WPA_NONE:
2244 return WPA_AUTH_KEY_MGMT_NONE;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002245 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
2246 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002247 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
2248 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002249 default:
2250 return 0;
2251 }
2252}
2253
2254
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002255#define RSN_SUITE "%02x-%02x-%02x-%d"
2256#define RSN_SUITE_ARG(s) \
2257((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
2258
2259/**
2260 * wpa_sm_get_mib - Dump text list of MIB entries
2261 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2262 * @buf: Buffer for the list
2263 * @buflen: Length of the buffer
2264 * Returns: Number of bytes written to buffer
2265 *
2266 * This function is used fetch dot11 MIB variables.
2267 */
2268int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
2269{
2270 char pmkid_txt[PMKID_LEN * 2 + 1];
2271 int rsna, ret;
2272 size_t len;
2273
2274 if (sm->cur_pmksa) {
2275 wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
2276 sm->cur_pmksa->pmkid, PMKID_LEN);
2277 } else
2278 pmkid_txt[0] = '\0';
2279
2280 if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
2281 wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
2282 sm->proto == WPA_PROTO_RSN)
2283 rsna = 1;
2284 else
2285 rsna = 0;
2286
2287 ret = os_snprintf(buf, buflen,
2288 "dot11RSNAOptionImplemented=TRUE\n"
2289 "dot11RSNAPreauthenticationImplemented=TRUE\n"
2290 "dot11RSNAEnabled=%s\n"
2291 "dot11RSNAPreauthenticationEnabled=%s\n"
2292 "dot11RSNAConfigVersion=%d\n"
2293 "dot11RSNAConfigPairwiseKeysSupported=5\n"
2294 "dot11RSNAConfigGroupCipherSize=%d\n"
2295 "dot11RSNAConfigPMKLifetime=%d\n"
2296 "dot11RSNAConfigPMKReauthThreshold=%d\n"
2297 "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
2298 "dot11RSNAConfigSATimeout=%d\n",
2299 rsna ? "TRUE" : "FALSE",
2300 rsna ? "TRUE" : "FALSE",
2301 RSN_VERSION,
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002302 wpa_cipher_key_len(sm->group_cipher) * 8,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002303 sm->dot11RSNAConfigPMKLifetime,
2304 sm->dot11RSNAConfigPMKReauthThreshold,
2305 sm->dot11RSNAConfigSATimeout);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002306 if (os_snprintf_error(buflen, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002307 return 0;
2308 len = ret;
2309
2310 ret = os_snprintf(
2311 buf + len, buflen - len,
2312 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
2313 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
2314 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
2315 "dot11RSNAPMKIDUsed=%s\n"
2316 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
2317 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
2318 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
2319 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
2320 "dot11RSNA4WayHandshakeFailures=%u\n",
2321 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002322 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2323 sm->pairwise_cipher)),
2324 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2325 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002326 pmkid_txt,
2327 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002328 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2329 sm->pairwise_cipher)),
2330 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2331 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002332 sm->dot11RSNA4WayHandshakeFailures);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002333 if (!os_snprintf_error(buflen - len, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002334 len += ret;
2335
2336 return (int) len;
2337}
2338#endif /* CONFIG_CTRL_IFACE */
2339
2340
2341static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002342 void *ctx, enum pmksa_free_reason reason)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002343{
2344 struct wpa_sm *sm = ctx;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002345 int deauth = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002346
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002347 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: "
2348 MACSTR " reason=%d", MAC2STR(entry->aa), reason);
2349
2350 if (sm->cur_pmksa == entry) {
2351 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2352 "RSN: %s current PMKSA entry",
2353 reason == PMKSA_REPLACE ? "replaced" : "removed");
2354 pmksa_cache_clear_current(sm);
2355
2356 /*
2357 * If an entry is simply being replaced, there's no need to
2358 * deauthenticate because it will be immediately re-added.
2359 * This happens when EAP authentication is completed again
2360 * (reauth or failed PMKSA caching attempt).
2361 */
2362 if (reason != PMKSA_REPLACE)
2363 deauth = 1;
2364 }
2365
2366 if (reason == PMKSA_EXPIRE &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002367 (sm->pmk_len == entry->pmk_len &&
2368 os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
2369 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002370 "RSN: deauthenticating due to expired PMK");
2371 pmksa_cache_clear_current(sm);
2372 deauth = 1;
2373 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002374
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002375 if (deauth) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002376 os_memset(sm->pmk, 0, sizeof(sm->pmk));
2377 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
2378 }
2379}
2380
2381
2382/**
2383 * wpa_sm_init - Initialize WPA state machine
2384 * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
2385 * Returns: Pointer to the allocated WPA state machine data
2386 *
2387 * This function is used to allocate a new WPA state machine and the returned
2388 * value is passed to all WPA state machine calls.
2389 */
2390struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
2391{
2392 struct wpa_sm *sm;
2393
2394 sm = os_zalloc(sizeof(*sm));
2395 if (sm == NULL)
2396 return NULL;
2397 dl_list_init(&sm->pmksa_candidates);
2398 sm->renew_snonce = 1;
2399 sm->ctx = ctx;
2400
2401 sm->dot11RSNAConfigPMKLifetime = 43200;
2402 sm->dot11RSNAConfigPMKReauthThreshold = 70;
2403 sm->dot11RSNAConfigSATimeout = 60;
2404
2405 sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
2406 if (sm->pmksa == NULL) {
2407 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
2408 "RSN: PMKSA cache initialization failed");
2409 os_free(sm);
2410 return NULL;
2411 }
2412
2413 return sm;
2414}
2415
2416
2417/**
2418 * wpa_sm_deinit - Deinitialize WPA state machine
2419 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2420 */
2421void wpa_sm_deinit(struct wpa_sm *sm)
2422{
2423 if (sm == NULL)
2424 return;
2425 pmksa_cache_deinit(sm->pmksa);
2426 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2427 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
2428 os_free(sm->assoc_wpa_ie);
2429 os_free(sm->ap_wpa_ie);
2430 os_free(sm->ap_rsn_ie);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002431 wpa_sm_drop_sa(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002432 os_free(sm->ctx);
2433 peerkey_deinit(sm);
2434#ifdef CONFIG_IEEE80211R
2435 os_free(sm->assoc_resp_ies);
2436#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002437#ifdef CONFIG_TESTING_OPTIONS
2438 wpabuf_free(sm->test_assoc_ie);
2439#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002440 os_free(sm);
2441}
2442
2443
2444/**
2445 * wpa_sm_notify_assoc - Notify WPA state machine about association
2446 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2447 * @bssid: The BSSID of the new association
2448 *
2449 * This function is called to let WPA state machine know that the connection
2450 * was established.
2451 */
2452void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
2453{
2454 int clear_ptk = 1;
2455
2456 if (sm == NULL)
2457 return;
2458
2459 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2460 "WPA: Association event - clear replay counter");
2461 os_memcpy(sm->bssid, bssid, ETH_ALEN);
2462 os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
2463 sm->rx_replay_counter_set = 0;
2464 sm->renew_snonce = 1;
2465 if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
2466 rsn_preauth_deinit(sm);
2467
2468#ifdef CONFIG_IEEE80211R
2469 if (wpa_ft_is_completed(sm)) {
2470 /*
2471 * Clear portValid to kick EAPOL state machine to re-enter
2472 * AUTHENTICATED state to get the EAPOL port Authorized.
2473 */
2474 eapol_sm_notify_portValid(sm->eapol, FALSE);
2475 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
2476
2477 /* Prepare for the next transition */
2478 wpa_ft_prepare_auth_request(sm, NULL);
2479
2480 clear_ptk = 0;
2481 }
2482#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002483#ifdef CONFIG_FILS
2484 if (sm->fils_completed) {
2485 /*
2486 * Clear portValid to kick EAPOL state machine to re-enter
2487 * AUTHENTICATED state to get the EAPOL port Authorized.
2488 */
2489 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
2490 clear_ptk = 0;
2491 }
2492#endif /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002493
2494 if (clear_ptk) {
2495 /*
2496 * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
2497 * this is not part of a Fast BSS Transition.
2498 */
2499 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
2500 sm->ptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002501 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002502 sm->tptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002503 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002504 }
2505
2506#ifdef CONFIG_TDLS
2507 wpa_tdls_assoc(sm);
2508#endif /* CONFIG_TDLS */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002509
2510#ifdef CONFIG_P2P
2511 os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
2512#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002513}
2514
2515
2516/**
2517 * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation
2518 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2519 *
2520 * This function is called to let WPA state machine know that the connection
2521 * was lost. This will abort any existing pre-authentication session.
2522 */
2523void wpa_sm_notify_disassoc(struct wpa_sm *sm)
2524{
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002525 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2526 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002527 peerkey_deinit(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002528 rsn_preauth_deinit(sm);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002529 pmksa_cache_clear_current(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002530 if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
2531 sm->dot11RSNA4WayHandshakeFailures++;
2532#ifdef CONFIG_TDLS
2533 wpa_tdls_disassoc(sm);
2534#endif /* CONFIG_TDLS */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002535#ifdef CONFIG_FILS
2536 sm->fils_completed = 0;
2537#endif /* CONFIG_FILS */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002538
2539 /* Keys are not needed in the WPA state machine anymore */
2540 wpa_sm_drop_sa(sm);
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002541
2542 sm->msg_3_of_4_ok = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002543}
2544
2545
2546/**
2547 * wpa_sm_set_pmk - Set PMK
2548 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2549 * @pmk: The new PMK
2550 * @pmk_len: The length of the new PMK in bytes
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002551 * @pmkid: Calculated PMKID
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002552 * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002553 *
2554 * Configure the PMK for WPA state machine.
2555 */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002556void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002557 const u8 *pmkid, const u8 *bssid)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002558{
2559 if (sm == NULL)
2560 return;
2561
2562 sm->pmk_len = pmk_len;
2563 os_memcpy(sm->pmk, pmk, pmk_len);
2564
2565#ifdef CONFIG_IEEE80211R
2566 /* Set XXKey to be PSK for FT key derivation */
2567 sm->xxkey_len = pmk_len;
2568 os_memcpy(sm->xxkey, pmk, pmk_len);
2569#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002570
2571 if (bssid) {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002572 pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002573 bssid, sm->own_addr,
2574 sm->network_ctx, sm->key_mgmt);
2575 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002576}
2577
2578
2579/**
2580 * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA
2581 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2582 *
2583 * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK
2584 * will be cleared.
2585 */
2586void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
2587{
2588 if (sm == NULL)
2589 return;
2590
2591 if (sm->cur_pmksa) {
2592 sm->pmk_len = sm->cur_pmksa->pmk_len;
2593 os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
2594 } else {
2595 sm->pmk_len = PMK_LEN;
2596 os_memset(sm->pmk, 0, PMK_LEN);
2597 }
2598}
2599
2600
2601/**
2602 * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled
2603 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2604 * @fast_reauth: Whether fast reauthentication (EAP) is allowed
2605 */
2606void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
2607{
2608 if (sm)
2609 sm->fast_reauth = fast_reauth;
2610}
2611
2612
2613/**
2614 * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks
2615 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2616 * @scard_ctx: Context pointer for smartcard related callback functions
2617 */
2618void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
2619{
2620 if (sm == NULL)
2621 return;
2622 sm->scard_ctx = scard_ctx;
2623 if (sm->preauth_eapol)
2624 eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
2625}
2626
2627
2628/**
2629 * wpa_sm_set_config - Notification of current configration change
2630 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2631 * @config: Pointer to current network configuration
2632 *
2633 * Notify WPA state machine that configuration has changed. config will be
2634 * stored as a backpointer to network configuration. This can be %NULL to clear
2635 * the stored pointed.
2636 */
2637void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
2638{
2639 if (!sm)
2640 return;
2641
2642 if (config) {
2643 sm->network_ctx = config->network_ctx;
2644 sm->peerkey_enabled = config->peerkey_enabled;
2645 sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
2646 sm->proactive_key_caching = config->proactive_key_caching;
2647 sm->eap_workaround = config->eap_workaround;
2648 sm->eap_conf_ctx = config->eap_conf_ctx;
2649 if (config->ssid) {
2650 os_memcpy(sm->ssid, config->ssid, config->ssid_len);
2651 sm->ssid_len = config->ssid_len;
2652 } else
2653 sm->ssid_len = 0;
2654 sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002655 sm->p2p = config->p2p;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002656 sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002657 } else {
2658 sm->network_ctx = NULL;
2659 sm->peerkey_enabled = 0;
2660 sm->allowed_pairwise_cipher = 0;
2661 sm->proactive_key_caching = 0;
2662 sm->eap_workaround = 0;
2663 sm->eap_conf_ctx = NULL;
2664 sm->ssid_len = 0;
2665 sm->wpa_ptk_rekey = 0;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002666 sm->p2p = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002667 sm->wpa_rsc_relaxation = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002668 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002669}
2670
2671
2672/**
2673 * wpa_sm_set_own_addr - Set own MAC address
2674 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2675 * @addr: Own MAC address
2676 */
2677void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
2678{
2679 if (sm)
2680 os_memcpy(sm->own_addr, addr, ETH_ALEN);
2681}
2682
2683
2684/**
2685 * wpa_sm_set_ifname - Set network interface name
2686 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2687 * @ifname: Interface name
2688 * @bridge_ifname: Optional bridge interface name (for pre-auth)
2689 */
2690void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
2691 const char *bridge_ifname)
2692{
2693 if (sm) {
2694 sm->ifname = ifname;
2695 sm->bridge_ifname = bridge_ifname;
2696 }
2697}
2698
2699
2700/**
2701 * wpa_sm_set_eapol - Set EAPOL state machine pointer
2702 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2703 * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init()
2704 */
2705void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
2706{
2707 if (sm)
2708 sm->eapol = eapol;
2709}
2710
2711
2712/**
2713 * wpa_sm_set_param - Set WPA state machine parameters
2714 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2715 * @param: Parameter field
2716 * @value: Parameter value
2717 * Returns: 0 on success, -1 on failure
2718 */
2719int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
2720 unsigned int value)
2721{
2722 int ret = 0;
2723
2724 if (sm == NULL)
2725 return -1;
2726
2727 switch (param) {
2728 case RSNA_PMK_LIFETIME:
2729 if (value > 0)
2730 sm->dot11RSNAConfigPMKLifetime = value;
2731 else
2732 ret = -1;
2733 break;
2734 case RSNA_PMK_REAUTH_THRESHOLD:
2735 if (value > 0 && value <= 100)
2736 sm->dot11RSNAConfigPMKReauthThreshold = value;
2737 else
2738 ret = -1;
2739 break;
2740 case RSNA_SA_TIMEOUT:
2741 if (value > 0)
2742 sm->dot11RSNAConfigSATimeout = value;
2743 else
2744 ret = -1;
2745 break;
2746 case WPA_PARAM_PROTO:
2747 sm->proto = value;
2748 break;
2749 case WPA_PARAM_PAIRWISE:
2750 sm->pairwise_cipher = value;
2751 break;
2752 case WPA_PARAM_GROUP:
2753 sm->group_cipher = value;
2754 break;
2755 case WPA_PARAM_KEY_MGMT:
2756 sm->key_mgmt = value;
2757 break;
2758#ifdef CONFIG_IEEE80211W
2759 case WPA_PARAM_MGMT_GROUP:
2760 sm->mgmt_group_cipher = value;
2761 break;
2762#endif /* CONFIG_IEEE80211W */
2763 case WPA_PARAM_RSN_ENABLED:
2764 sm->rsn_enabled = value;
2765 break;
2766 case WPA_PARAM_MFP:
2767 sm->mfp = value;
2768 break;
2769 default:
2770 break;
2771 }
2772
2773 return ret;
2774}
2775
2776
2777/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002778 * wpa_sm_get_status - Get WPA state machine
2779 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2780 * @buf: Buffer for status information
2781 * @buflen: Maximum buffer length
2782 * @verbose: Whether to include verbose status information
2783 * Returns: Number of bytes written to buf.
2784 *
2785 * Query WPA state machine for status information. This function fills in
2786 * a text area with current status information. If the buffer (buf) is not
2787 * large enough, status information will be truncated to fit the buffer.
2788 */
2789int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
2790 int verbose)
2791{
2792 char *pos = buf, *end = buf + buflen;
2793 int ret;
2794
2795 ret = os_snprintf(pos, end - pos,
2796 "pairwise_cipher=%s\n"
2797 "group_cipher=%s\n"
2798 "key_mgmt=%s\n",
2799 wpa_cipher_txt(sm->pairwise_cipher),
2800 wpa_cipher_txt(sm->group_cipher),
2801 wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002802 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002803 return pos - buf;
2804 pos += ret;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002805
2806 if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
2807 struct wpa_ie_data rsn;
2808 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
2809 >= 0 &&
2810 rsn.capabilities & (WPA_CAPABILITY_MFPR |
2811 WPA_CAPABILITY_MFPC)) {
2812 ret = os_snprintf(pos, end - pos, "pmf=%d\n",
2813 (rsn.capabilities &
2814 WPA_CAPABILITY_MFPR) ? 2 : 1);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002815 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002816 return pos - buf;
2817 pos += ret;
2818 }
2819 }
2820
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002821 return pos - buf;
2822}
2823
2824
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07002825int wpa_sm_pmf_enabled(struct wpa_sm *sm)
2826{
2827 struct wpa_ie_data rsn;
2828
2829 if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
2830 return 0;
2831
2832 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
2833 rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
2834 return 1;
2835
2836 return 0;
2837}
2838
2839
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002840/**
2841 * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration
2842 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2843 * @wpa_ie: Pointer to buffer for WPA/RSN IE
2844 * @wpa_ie_len: Pointer to the length of the wpa_ie buffer
2845 * Returns: 0 on success, -1 on failure
2846 */
2847int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
2848 size_t *wpa_ie_len)
2849{
2850 int res;
2851
2852 if (sm == NULL)
2853 return -1;
2854
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002855#ifdef CONFIG_TESTING_OPTIONS
2856 if (sm->test_assoc_ie) {
2857 wpa_printf(MSG_DEBUG,
2858 "TESTING: Replace association WPA/RSN IE");
2859 if (*wpa_ie_len < wpabuf_len(sm->test_assoc_ie))
2860 return -1;
2861 os_memcpy(wpa_ie, wpabuf_head(sm->test_assoc_ie),
2862 wpabuf_len(sm->test_assoc_ie));
2863 res = wpabuf_len(sm->test_assoc_ie);
2864 } else
2865#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002866 res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
2867 if (res < 0)
2868 return -1;
2869 *wpa_ie_len = res;
2870
2871 wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
2872 wpa_ie, *wpa_ie_len);
2873
2874 if (sm->assoc_wpa_ie == NULL) {
2875 /*
2876 * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
2877 * the correct version of the IE even if PMKSA caching is
2878 * aborted (which would remove PMKID from IE generation).
2879 */
2880 sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
2881 if (sm->assoc_wpa_ie == NULL)
2882 return -1;
2883
2884 os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
2885 sm->assoc_wpa_ie_len = *wpa_ie_len;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002886 } else {
2887 wpa_hexdump(MSG_DEBUG,
2888 "WPA: Leave previously set WPA IE default",
2889 sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002890 }
2891
2892 return 0;
2893}
2894
2895
2896/**
2897 * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq
2898 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2899 * @ie: Pointer to IE data (starting from id)
2900 * @len: IE length
2901 * Returns: 0 on success, -1 on failure
2902 *
2903 * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
2904 * Request frame. The IE will be used to override the default value generated
2905 * with wpa_sm_set_assoc_wpa_ie_default().
2906 */
2907int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2908{
2909 if (sm == NULL)
2910 return -1;
2911
2912 os_free(sm->assoc_wpa_ie);
2913 if (ie == NULL || len == 0) {
2914 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2915 "WPA: clearing own WPA/RSN IE");
2916 sm->assoc_wpa_ie = NULL;
2917 sm->assoc_wpa_ie_len = 0;
2918 } else {
2919 wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
2920 sm->assoc_wpa_ie = os_malloc(len);
2921 if (sm->assoc_wpa_ie == NULL)
2922 return -1;
2923
2924 os_memcpy(sm->assoc_wpa_ie, ie, len);
2925 sm->assoc_wpa_ie_len = len;
2926 }
2927
2928 return 0;
2929}
2930
2931
2932/**
2933 * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
2934 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2935 * @ie: Pointer to IE data (starting from id)
2936 * @len: IE length
2937 * Returns: 0 on success, -1 on failure
2938 *
2939 * Inform WPA state machine about the WPA IE used in Beacon / Probe Response
2940 * frame.
2941 */
2942int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2943{
2944 if (sm == NULL)
2945 return -1;
2946
2947 os_free(sm->ap_wpa_ie);
2948 if (ie == NULL || len == 0) {
2949 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2950 "WPA: clearing AP WPA IE");
2951 sm->ap_wpa_ie = NULL;
2952 sm->ap_wpa_ie_len = 0;
2953 } else {
2954 wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
2955 sm->ap_wpa_ie = os_malloc(len);
2956 if (sm->ap_wpa_ie == NULL)
2957 return -1;
2958
2959 os_memcpy(sm->ap_wpa_ie, ie, len);
2960 sm->ap_wpa_ie_len = len;
2961 }
2962
2963 return 0;
2964}
2965
2966
2967/**
2968 * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
2969 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2970 * @ie: Pointer to IE data (starting from id)
2971 * @len: IE length
2972 * Returns: 0 on success, -1 on failure
2973 *
2974 * Inform WPA state machine about the RSN IE used in Beacon / Probe Response
2975 * frame.
2976 */
2977int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2978{
2979 if (sm == NULL)
2980 return -1;
2981
2982 os_free(sm->ap_rsn_ie);
2983 if (ie == NULL || len == 0) {
2984 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2985 "WPA: clearing AP RSN IE");
2986 sm->ap_rsn_ie = NULL;
2987 sm->ap_rsn_ie_len = 0;
2988 } else {
2989 wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
2990 sm->ap_rsn_ie = os_malloc(len);
2991 if (sm->ap_rsn_ie == NULL)
2992 return -1;
2993
2994 os_memcpy(sm->ap_rsn_ie, ie, len);
2995 sm->ap_rsn_ie_len = len;
2996 }
2997
2998 return 0;
2999}
3000
3001
3002/**
3003 * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
3004 * @sm: Pointer to WPA state machine data from wpa_sm_init()
3005 * @data: Pointer to data area for parsing results
3006 * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure
3007 *
3008 * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the
3009 * parsed data into data.
3010 */
3011int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
3012{
3013 if (sm == NULL)
3014 return -1;
3015
3016 if (sm->assoc_wpa_ie == NULL) {
3017 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
3018 "WPA: No WPA/RSN IE available from association info");
3019 return -1;
3020 }
3021 if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
3022 return -2;
3023 return 0;
3024}
3025
3026
3027int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
3028{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003029 return pmksa_cache_list(sm->pmksa, buf, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003030}
3031
3032
Dmitry Shmidt29333592017-01-09 12:27:11 -08003033struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_head(struct wpa_sm *sm)
3034{
3035 return pmksa_cache_head(sm->pmksa);
3036}
3037
3038
3039struct rsn_pmksa_cache_entry *
3040wpa_sm_pmksa_cache_add_entry(struct wpa_sm *sm,
3041 struct rsn_pmksa_cache_entry * entry)
3042{
3043 return pmksa_cache_add_entry(sm->pmksa, entry);
3044}
3045
3046
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003047void wpa_sm_drop_sa(struct wpa_sm *sm)
3048{
3049 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
3050 sm->ptk_set = 0;
3051 sm->tptk_set = 0;
3052 os_memset(sm->pmk, 0, sizeof(sm->pmk));
3053 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
3054 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003055#ifdef CONFIG_IEEE80211R
3056 os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
3057 os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
3058 os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1));
3059#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003060}
3061
3062
3063int wpa_sm_has_ptk(struct wpa_sm *sm)
3064{
3065 if (sm == NULL)
3066 return 0;
3067 return sm->ptk_set;
3068}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003069
3070
3071void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
3072{
3073 os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
3074}
3075
3076
3077void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
3078{
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07003079 pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003080}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003081
3082
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003083#ifdef CONFIG_WNM
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003084int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
3085{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003086 u16 keyinfo;
3087 u8 keylen; /* plaintext key len */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003088 u8 *key_rsc;
3089
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003090 if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003091 struct wpa_gtk_data gd;
3092
3093 os_memset(&gd, 0, sizeof(gd));
3094 keylen = wpa_cipher_key_len(sm->group_cipher);
3095 gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
3096 gd.alg = wpa_cipher_to_alg(sm->group_cipher);
3097 if (gd.alg == WPA_ALG_NONE) {
3098 wpa_printf(MSG_DEBUG, "Unsupported group cipher suite");
3099 return -1;
3100 }
3101
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003102 key_rsc = buf + 5;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003103 keyinfo = WPA_GET_LE16(buf + 2);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003104 gd.gtk_len = keylen;
3105 if (gd.gtk_len != buf[4]) {
3106 wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
3107 gd.gtk_len, buf[4]);
3108 return -1;
3109 }
3110 gd.keyidx = keyinfo & 0x03; /* B0 - B1 */
3111 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
3112 sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
3113
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003114 os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003115
3116 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
3117 gd.gtk, gd.gtk_len);
3118 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003119 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003120 wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
3121 "WNM mode");
3122 return -1;
3123 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003124 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003125#ifdef CONFIG_IEEE80211W
3126 } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003127 struct wpa_igtk_kde igd;
3128 u16 keyidx;
3129
3130 os_memset(&igd, 0, sizeof(igd));
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003131 keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003132 os_memcpy(igd.keyid, buf + 2, 2);
3133 os_memcpy(igd.pn, buf + 4, 6);
3134
3135 keyidx = WPA_GET_LE16(igd.keyid);
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003136 os_memcpy(igd.igtk, buf + 10, keylen);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003137
3138 wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003139 igd.igtk, keylen);
3140 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
3141 broadcast_ether_addr,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003142 keyidx, 0, igd.pn, sizeof(igd.pn),
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07003143 igd.igtk, keylen) < 0) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003144 wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
3145 "WNM mode");
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003146 os_memset(&igd, 0, sizeof(igd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003147 return -1;
3148 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003149 os_memset(&igd, 0, sizeof(igd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003150#endif /* CONFIG_IEEE80211W */
3151 } else {
3152 wpa_printf(MSG_DEBUG, "Unknown element id");
3153 return -1;
3154 }
3155
3156 return 0;
3157}
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003158#endif /* CONFIG_WNM */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003159
3160
3161#ifdef CONFIG_PEERKEY
3162int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
3163 const u8 *buf, size_t len)
3164{
3165 struct wpa_peerkey *peerkey;
3166
3167 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
3168 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
3169 break;
3170 }
3171
3172 if (!peerkey)
3173 return 0;
3174
3175 wpa_sm_rx_eapol(sm, src_addr, buf, len);
3176
3177 return 1;
3178}
3179#endif /* CONFIG_PEERKEY */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08003180
3181
3182#ifdef CONFIG_P2P
3183
3184int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)
3185{
3186 if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0)
3187 return -1;
3188 os_memcpy(buf, sm->p2p_ip_addr, 3 * 4);
3189 return 0;
3190}
3191
3192#endif /* CONFIG_P2P */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003193
3194
3195void wpa_sm_set_rx_replay_ctr(struct wpa_sm *sm, const u8 *rx_replay_counter)
3196{
3197 if (rx_replay_counter == NULL)
3198 return;
3199
3200 os_memcpy(sm->rx_replay_counter, rx_replay_counter,
3201 WPA_REPLAY_COUNTER_LEN);
3202 sm->rx_replay_counter_set = 1;
3203 wpa_printf(MSG_DEBUG, "Updated key replay counter");
3204}
3205
3206
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003207void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
3208 const u8 *ptk_kck, size_t ptk_kck_len,
3209 const u8 *ptk_kek, size_t ptk_kek_len)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003210{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003211 if (ptk_kck && ptk_kck_len <= WPA_KCK_MAX_LEN) {
3212 os_memcpy(sm->ptk.kck, ptk_kck, ptk_kck_len);
3213 sm->ptk.kck_len = ptk_kck_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003214 wpa_printf(MSG_DEBUG, "Updated PTK KCK");
3215 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003216 if (ptk_kek && ptk_kek_len <= WPA_KEK_MAX_LEN) {
3217 os_memcpy(sm->ptk.kek, ptk_kek, ptk_kek_len);
3218 sm->ptk.kek_len = ptk_kek_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003219 wpa_printf(MSG_DEBUG, "Updated PTK KEK");
3220 }
3221 sm->ptk_set = 1;
3222}
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08003223
3224
3225#ifdef CONFIG_TESTING_OPTIONS
3226void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf)
3227{
3228 wpabuf_free(sm->test_assoc_ie);
3229 sm->test_assoc_ie = buf;
3230}
3231#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003232
3233
3234#ifdef CONFIG_FILS
3235
3236struct wpabuf * fils_build_auth(struct wpa_sm *sm)
3237{
3238 struct wpabuf *buf = NULL;
3239 struct wpabuf *erp_msg;
3240
3241 erp_msg = eapol_sm_build_erp_reauth_start(sm->eapol);
3242 if (!erp_msg && !sm->cur_pmksa) {
3243 wpa_printf(MSG_DEBUG,
3244 "FILS: Neither ERP EAP-Initiate/Re-auth nor PMKSA cache entry is available - skip FILS");
3245 goto fail;
3246 }
3247
3248 wpa_printf(MSG_DEBUG, "FILS: Try to use FILS (erp=%d pmksa_cache=%d)",
3249 erp_msg != NULL, sm->cur_pmksa != NULL);
3250
3251 sm->fils_completed = 0;
3252
3253 if (!sm->assoc_wpa_ie) {
3254 wpa_printf(MSG_INFO, "FILS: No own RSN IE set for FILS");
3255 goto fail;
3256 }
3257
3258 if (random_get_bytes(sm->fils_nonce, FILS_NONCE_LEN) < 0 ||
3259 random_get_bytes(sm->fils_session, FILS_SESSION_LEN) < 0)
3260 goto fail;
3261
3262 wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Nonce",
3263 sm->fils_nonce, FILS_NONCE_LEN);
3264 wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Session",
3265 sm->fils_session, FILS_SESSION_LEN);
3266
3267 buf = wpabuf_alloc(1000 + sm->assoc_wpa_ie_len);
3268 if (!buf)
3269 goto fail;
3270
3271 /* Fields following the Authentication algorithm number field */
3272
3273 /* Authentication Transaction seq# */
3274 wpabuf_put_le16(buf, 1);
3275
3276 /* Status Code */
3277 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
3278
3279 /* TODO: Finite Cyclic Group when using PK or PFS */
3280 /* TODO: Element when using PK or PFS */
3281
3282 /* RSNE */
3283 wpa_hexdump(MSG_DEBUG, "FILS: RSNE in FILS Authentication frame",
3284 sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
3285 wpabuf_put_data(buf, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
3286
3287 /* TODO: MDE when using FILS for FT initial association */
3288 /* TODO: FTE when using FILS for FT initial association */
3289
3290 /* FILS Nonce */
3291 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3292 wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN); /* Length */
3293 /* Element ID Extension */
3294 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
3295 wpabuf_put_data(buf, sm->fils_nonce, FILS_NONCE_LEN);
3296
3297 /* FILS Session */
3298 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3299 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
3300 /* Element ID Extension */
3301 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
3302 wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
3303
3304 /* FILS Wrapped Data */
3305 if (erp_msg) {
3306 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3307 wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg)); /* Length */
3308 /* Element ID Extension */
3309 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_WRAPPED_DATA);
3310 wpabuf_put_buf(buf, erp_msg);
3311 }
3312
3313 wpa_hexdump_buf(MSG_DEBUG, "RSN: FILS fields for Authentication frame",
3314 buf);
3315
3316fail:
3317 wpabuf_free(erp_msg);
3318 return buf;
3319}
3320
3321
3322int fils_process_auth(struct wpa_sm *sm, const u8 *data, size_t len)
3323{
3324 const u8 *pos, *end;
3325 struct ieee802_11_elems elems;
3326 struct wpa_ie_data rsn;
3327 int pmkid_match = 0;
3328 u8 ick[FILS_ICK_MAX_LEN];
3329 size_t ick_len;
3330 int res;
3331
3332 wpa_hexdump(MSG_DEBUG, "FILS: Authentication frame fields",
3333 data, len);
3334 pos = data;
3335 end = data + len;
3336
3337 /* TODO: Finite Cyclic Group when using PK or PFS */
3338 /* TODO: Element when using PK or PFS */
3339
3340 wpa_hexdump(MSG_DEBUG, "FILS: Remaining IEs", pos, end - pos);
3341 if (ieee802_11_parse_elems(pos, end - pos, &elems, 1) == ParseFailed) {
3342 wpa_printf(MSG_DEBUG, "FILS: Could not parse elements");
3343 return -1;
3344 }
3345
3346 /* RSNE */
3347 wpa_hexdump(MSG_DEBUG, "FILS: RSN element", elems.rsn_ie,
3348 elems.rsn_ie_len);
3349 if (!elems.rsn_ie ||
3350 wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
3351 &rsn) < 0) {
3352 wpa_printf(MSG_DEBUG, "FILS: No RSN element");
3353 return -1;
3354 }
3355
3356 if (!elems.fils_nonce) {
3357 wpa_printf(MSG_DEBUG, "FILS: No FILS Nonce field");
3358 return -1;
3359 }
3360 os_memcpy(sm->fils_anonce, elems.fils_nonce, FILS_NONCE_LEN);
3361 wpa_hexdump(MSG_DEBUG, "FILS: ANonce", sm->fils_anonce, FILS_NONCE_LEN);
3362
3363 /* TODO: MDE when using FILS+FT */
3364 /* TODO: FTE when using FILS+FT */
3365
3366 /* PMKID List */
3367 if (rsn.pmkid && rsn.num_pmkid > 0) {
3368 wpa_hexdump(MSG_DEBUG, "FILS: PMKID List",
3369 rsn.pmkid, rsn.num_pmkid * PMKID_LEN);
3370
3371 if (rsn.num_pmkid != 1) {
3372 wpa_printf(MSG_DEBUG, "FILS: Invalid PMKID selection");
3373 return -1;
3374 }
3375 wpa_hexdump(MSG_DEBUG, "FILS: PMKID", rsn.pmkid, PMKID_LEN);
3376 if (os_memcmp(sm->cur_pmksa->pmkid, rsn.pmkid, PMKID_LEN) != 0)
3377 {
3378 wpa_printf(MSG_DEBUG, "FILS: PMKID mismatch");
3379 wpa_hexdump(MSG_DEBUG, "FILS: Expected PMKID",
3380 sm->cur_pmksa->pmkid, PMKID_LEN);
3381 return -1;
3382 }
3383 wpa_printf(MSG_DEBUG,
3384 "FILS: Matching PMKID - continue using PMKSA caching");
3385 pmkid_match = 1;
3386 }
3387 if (!pmkid_match && sm->cur_pmksa) {
3388 wpa_printf(MSG_DEBUG,
3389 "FILS: No PMKID match - cannot use cached PMKSA entry");
3390 sm->cur_pmksa = NULL;
3391 }
3392
3393 /* FILS Session */
3394 if (!elems.fils_session) {
3395 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
3396 return -1;
3397 }
3398 wpa_hexdump(MSG_DEBUG, "FILS: FILS Session", elems.fils_session,
3399 FILS_SESSION_LEN);
3400 if (os_memcmp(sm->fils_session, elems.fils_session, FILS_SESSION_LEN)
3401 != 0) {
3402 wpa_printf(MSG_DEBUG, "FILS: Session mismatch");
3403 wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
3404 sm->fils_session, FILS_SESSION_LEN);
3405 return -1;
3406 }
3407
3408 /* FILS Wrapped Data */
3409 if (!sm->cur_pmksa && elems.fils_wrapped_data) {
3410 wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
3411 elems.fils_wrapped_data,
3412 elems.fils_wrapped_data_len);
3413 eapol_sm_process_erp_finish(sm->eapol, elems.fils_wrapped_data,
3414 elems.fils_wrapped_data_len);
3415 if (eapol_sm_failed(sm->eapol))
3416 return -1;
3417
3418 res = eapol_sm_get_key(sm->eapol, sm->pmk, PMK_LEN);
3419 if (res)
3420 return -1;
3421
3422 wpa_printf(MSG_DEBUG, "FILS: ERP processing succeeded - add PMKSA cache entry for the result");
3423 sm->cur_pmksa = pmksa_cache_add(sm->pmksa, sm->pmk, PMK_LEN,
3424 NULL, NULL, 0, sm->bssid,
3425 sm->own_addr,
3426 sm->network_ctx, sm->key_mgmt);
3427 }
3428
3429 if (!sm->cur_pmksa) {
3430 wpa_printf(MSG_DEBUG,
3431 "FILS: No remaining options to continue FILS authentication");
3432 return -1;
3433 }
3434
3435 if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
3436 sm->fils_nonce, sm->fils_anonce, &sm->ptk,
3437 ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher) <
3438 0) {
3439 wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
3440 return -1;
3441 }
3442 sm->ptk_set = 1;
3443 sm->tptk_set = 0;
3444 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
3445
3446 res = fils_key_auth_sk(ick, ick_len, sm->fils_nonce,
3447 sm->fils_anonce, sm->own_addr, sm->bssid,
3448 NULL, 0, NULL, 0, /* TODO: SK+PFS */
3449 sm->key_mgmt, sm->fils_key_auth_sta,
3450 sm->fils_key_auth_ap,
3451 &sm->fils_key_auth_len);
3452 os_memset(ick, 0, sizeof(ick));
3453 return res;
3454}
3455
3456
3457struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek,
3458 size_t *kek_len, const u8 **snonce,
3459 const u8 **anonce)
3460{
3461 struct wpabuf *buf;
3462
3463 buf = wpabuf_alloc(1000);
3464 if (!buf)
3465 return NULL;
3466
3467 /* FILS Session */
3468 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3469 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
3470 /* Element ID Extension */
3471 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
3472 wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
3473
3474 /* Everything after FILS Session element gets encrypted in the driver
3475 * with KEK. The buffer returned from here is the plaintext version. */
3476
3477 /* TODO: FILS Public Key */
3478
3479 /* FILS Key Confirm */
3480 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3481 wpabuf_put_u8(buf, 1 + sm->fils_key_auth_len); /* Length */
3482 /* Element ID Extension */
3483 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_KEY_CONFIRM);
3484 wpabuf_put_data(buf, sm->fils_key_auth_sta, sm->fils_key_auth_len);
3485
3486 /* TODO: FILS HLP Container */
3487
3488 /* TODO: FILS IP Address Assignment */
3489
3490 wpa_hexdump_buf(MSG_DEBUG, "FILS: Association Request plaintext", buf);
3491
3492 *kek = sm->ptk.kek;
3493 *kek_len = sm->ptk.kek_len;
3494 wpa_hexdump_key(MSG_DEBUG, "FILS: KEK for AEAD", *kek, *kek_len);
3495 *snonce = sm->fils_nonce;
3496 wpa_hexdump(MSG_DEBUG, "FILS: SNonce for AEAD AAD",
3497 *snonce, FILS_NONCE_LEN);
3498 *anonce = sm->fils_anonce;
3499 wpa_hexdump(MSG_DEBUG, "FILS: ANonce for AEAD AAD",
3500 *anonce, FILS_NONCE_LEN);
3501
3502 return buf;
3503}
3504
3505
3506int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
3507{
3508 const struct ieee80211_mgmt *mgmt;
3509 const u8 *end, *ie_start;
3510 struct ieee802_11_elems elems;
3511 int keylen, rsclen;
3512 enum wpa_alg alg;
3513 struct wpa_gtk_data gd;
3514 int maxkeylen;
3515 struct wpa_eapol_ie_parse kde;
3516
3517 if (!sm || !sm->ptk_set) {
3518 wpa_printf(MSG_DEBUG, "FILS: No KEK available");
3519 return -1;
3520 }
3521
3522 if (!wpa_key_mgmt_fils(sm->key_mgmt)) {
3523 wpa_printf(MSG_DEBUG, "FILS: Not a FILS AKM");
3524 return -1;
3525 }
3526
3527 wpa_hexdump(MSG_DEBUG, "FILS: (Re)Association Response frame",
3528 resp, len);
3529
3530 mgmt = (const struct ieee80211_mgmt *) resp;
3531 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_resp))
3532 return -1;
3533
3534 end = resp + len;
3535 /* Same offset for Association Response and Reassociation Response */
3536 ie_start = mgmt->u.assoc_resp.variable;
3537
3538 if (ieee802_11_parse_elems(ie_start, end - ie_start, &elems, 1) ==
3539 ParseFailed) {
3540 wpa_printf(MSG_DEBUG,
3541 "FILS: Failed to parse decrypted elements");
3542 goto fail;
3543 }
3544
3545 if (!elems.fils_session) {
3546 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
3547 return -1;
3548 }
3549 if (os_memcmp(elems.fils_session, sm->fils_session,
3550 FILS_SESSION_LEN) != 0) {
3551 wpa_printf(MSG_DEBUG, "FILS: FILS Session mismatch");
3552 wpa_hexdump(MSG_DEBUG, "FILS: Received FILS Session",
3553 elems.fils_session, FILS_SESSION_LEN);
3554 wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
3555 sm->fils_session, FILS_SESSION_LEN);
3556 }
3557
3558 /* TODO: FILS Public Key */
3559
3560 if (!elems.fils_key_confirm) {
3561 wpa_printf(MSG_DEBUG, "FILS: No FILS Key Confirm element");
3562 goto fail;
3563 }
3564 if (elems.fils_key_confirm_len != sm->fils_key_auth_len) {
3565 wpa_printf(MSG_DEBUG,
3566 "FILS: Unexpected Key-Auth length %d (expected %d)",
3567 elems.fils_key_confirm_len,
3568 (int) sm->fils_key_auth_len);
3569 goto fail;
3570 }
3571 if (os_memcmp(elems.fils_key_confirm, sm->fils_key_auth_ap,
3572 sm->fils_key_auth_len) != 0) {
3573 wpa_printf(MSG_DEBUG, "FILS: Key-Auth mismatch");
3574 wpa_hexdump(MSG_DEBUG, "FILS: Received Key-Auth",
3575 elems.fils_key_confirm,
3576 elems.fils_key_confirm_len);
3577 wpa_hexdump(MSG_DEBUG, "FILS: Expected Key-Auth",
3578 sm->fils_key_auth_ap, sm->fils_key_auth_len);
3579 goto fail;
3580 }
3581
3582 /* Key Delivery */
3583 if (!elems.key_delivery) {
3584 wpa_printf(MSG_DEBUG, "FILS: No Key Delivery element");
3585 goto fail;
3586 }
3587
3588 /* Parse GTK and set the key to the driver */
3589 os_memset(&gd, 0, sizeof(gd));
3590 if (wpa_supplicant_parse_ies(elems.key_delivery + WPA_KEY_RSC_LEN,
3591 elems.key_delivery_len - WPA_KEY_RSC_LEN,
3592 &kde) < 0) {
3593 wpa_printf(MSG_DEBUG, "FILS: Failed to parse KDEs");
3594 goto fail;
3595 }
3596 if (!kde.gtk) {
3597 wpa_printf(MSG_DEBUG, "FILS: No GTK KDE");
3598 goto fail;
3599 }
3600 maxkeylen = gd.gtk_len = kde.gtk_len - 2;
3601 if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
3602 gd.gtk_len, maxkeylen,
3603 &gd.key_rsc_len, &gd.alg))
3604 goto fail;
3605
3606 wpa_hexdump_key(MSG_DEBUG, "FILS: Received GTK", kde.gtk, kde.gtk_len);
3607 gd.keyidx = kde.gtk[0] & 0x3;
3608 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
3609 !!(kde.gtk[0] & BIT(2)));
3610 if (kde.gtk_len - 2 > sizeof(gd.gtk)) {
3611 wpa_printf(MSG_DEBUG, "FILS: Too long GTK in GTK KDE (len=%lu)",
3612 (unsigned long) kde.gtk_len - 2);
3613 goto fail;
3614 }
3615 os_memcpy(gd.gtk, kde.gtk + 2, kde.gtk_len - 2);
3616
3617 wpa_printf(MSG_DEBUG, "FILS: Set GTK to driver");
3618 if (wpa_supplicant_install_gtk(sm, &gd, elems.key_delivery) < 0) {
3619 wpa_printf(MSG_DEBUG, "FILS: Failed to set GTK");
3620 goto fail;
3621 }
3622
3623 if (ieee80211w_set_keys(sm, &kde) < 0) {
3624 wpa_printf(MSG_DEBUG, "FILS: Failed to set IGTK");
3625 goto fail;
3626 }
3627
3628 alg = wpa_cipher_to_alg(sm->pairwise_cipher);
3629 keylen = wpa_cipher_key_len(sm->pairwise_cipher);
3630 rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
3631 wpa_hexdump_key(MSG_DEBUG, "FILS: Set TK to driver",
3632 sm->ptk.tk, keylen);
3633 if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, null_rsc, rsclen,
3634 sm->ptk.tk, keylen) < 0) {
3635 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
3636 "FILS: Failed to set PTK to the driver (alg=%d keylen=%d bssid="
3637 MACSTR ")",
3638 alg, keylen, MAC2STR(sm->bssid));
3639 goto fail;
3640 }
3641
3642 /* TODO: TK could be cleared after auth frame exchange now that driver
3643 * takes care of association frame encryption/decryption. */
3644 /* TK is not needed anymore in supplicant */
3645 os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
3646
3647 /* TODO: FILS HLP Container */
3648
3649 /* TODO: FILS IP Address Assignment */
3650
3651 wpa_printf(MSG_DEBUG, "FILS: Auth+Assoc completed successfully");
3652 sm->fils_completed = 1;
3653
3654 return 0;
3655fail:
3656 return -1;
3657}
3658
3659#endif /* CONFIG_FILS */
3660
3661
3662int wpa_fils_is_completed(struct wpa_sm *sm)
3663{
3664#ifdef CONFIG_FILS
3665 return sm && sm->fils_completed;
3666#else /* CONFIG_FILS */
3667 return 0;
3668#endif /* CONFIG_FILS */
3669}