blob: 441c8562f0a18d53920f013cf54dcb977b435066 [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"
13#include "crypto/aes_wrap.h"
14#include "crypto/crypto.h"
15#include "crypto/random.h"
16#include "common/ieee802_11_defs.h"
17#include "eapol_supp/eapol_supp_sm.h"
18#include "wpa.h"
19#include "eloop.h"
20#include "preauth.h"
21#include "pmksa_cache.h"
22#include "wpa_i.h"
23#include "wpa_ie.h"
24#include "peerkey.h"
25
26
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080027static const u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
28
29
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070030/**
31 * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message
32 * @sm: Pointer to WPA state machine data from wpa_sm_init()
33 * @kck: Key Confirmation Key (KCK, part of PTK)
Dmitry Shmidt807291d2015-01-27 13:40:23 -080034 * @kck_len: KCK length in octets
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070035 * @ver: Version field from Key Info
36 * @dest: Destination address for the frame
37 * @proto: Ethertype (usually ETH_P_EAPOL)
38 * @msg: EAPOL-Key message
39 * @msg_len: Length of message
40 * @key_mic: Pointer to the buffer to which the EAPOL-Key MIC is written
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080041 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070042 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080043int wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck, size_t kck_len,
44 int ver, const u8 *dest, u16 proto,
45 u8 *msg, size_t msg_len, u8 *key_mic)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070046{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080047 int ret = -1;
Dmitry Shmidt807291d2015-01-27 13:40:23 -080048 size_t mic_len = wpa_mic_len(sm->key_mgmt);
49
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070050 if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
51 /*
52 * Association event was not yet received; try to fetch
53 * BSSID from the driver.
54 */
55 if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
56 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
57 "WPA: Failed to read BSSID for "
58 "EAPOL-Key destination address");
59 } else {
60 dest = sm->bssid;
61 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
62 "WPA: Use BSSID (" MACSTR
63 ") as the destination for EAPOL-Key",
64 MAC2STR(dest));
65 }
66 }
67 if (key_mic &&
Dmitry Shmidt807291d2015-01-27 13:40:23 -080068 wpa_eapol_key_mic(kck, kck_len, sm->key_mgmt, ver, msg, msg_len,
69 key_mic)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070070 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -080071 "WPA: Failed to generate EAPOL-Key version %d key_mgmt 0x%x MIC",
72 ver, sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070073 goto out;
74 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -080075 wpa_hexdump_key(MSG_DEBUG, "WPA: KCK", kck, kck_len);
76 wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC", key_mic, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070077 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080078 ret = wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070079 eapol_sm_notify_tx_eapol_key(sm->eapol);
80out:
81 os_free(msg);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080082 return ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070083}
84
85
86/**
87 * wpa_sm_key_request - Send EAPOL-Key Request
88 * @sm: Pointer to WPA state machine data from wpa_sm_init()
89 * @error: Indicate whether this is an Michael MIC error report
90 * @pairwise: 1 = error report for pairwise packet, 0 = for group packet
91 *
92 * Send an EAPOL-Key Request to the current authenticator. This function is
93 * used to request rekeying and it is usually called when a local Michael MIC
94 * failure is detected.
95 */
96void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
97{
Dmitry Shmidt807291d2015-01-27 13:40:23 -080098 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070099 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800100 struct wpa_eapol_key_192 *reply192;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700101 int key_info, ver;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800102 u8 bssid[ETH_ALEN], *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700103
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800104 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
105 wpa_key_mgmt_suite_b(sm->key_mgmt))
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800106 ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
107 else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
108 wpa_key_mgmt_sha256(sm->key_mgmt))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700109 ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700110 else if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700111 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
112 else
113 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
114
115 if (wpa_sm_get_bssid(sm, bssid) < 0) {
116 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
117 "Failed to read BSSID for EAPOL-Key request");
118 return;
119 }
120
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800121 mic_len = wpa_mic_len(sm->key_mgmt);
122 hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700123 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800124 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700125 if (rbuf == NULL)
126 return;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800127 reply192 = (struct wpa_eapol_key_192 *) reply;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700128
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800129 reply->type = (sm->proto == WPA_PROTO_RSN ||
130 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700131 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
132 key_info = WPA_KEY_INFO_REQUEST | ver;
133 if (sm->ptk_set)
Dmitry Shmidt17022322016-04-06 13:28:42 -0700134 key_info |= WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700135 if (error)
136 key_info |= WPA_KEY_INFO_ERROR;
137 if (pairwise)
138 key_info |= WPA_KEY_INFO_KEY_TYPE;
139 WPA_PUT_BE16(reply->key_info, key_info);
140 WPA_PUT_BE16(reply->key_length, 0);
141 os_memcpy(reply->replay_counter, sm->request_counter,
142 WPA_REPLAY_COUNTER_LEN);
143 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
144
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800145 if (mic_len == 24)
146 WPA_PUT_BE16(reply192->key_data_length, 0);
147 else
148 WPA_PUT_BE16(reply->key_data_length, 0);
149 if (!(key_info & WPA_KEY_INFO_MIC))
150 key_mic = NULL;
151 else
152 key_mic = reply192->key_mic; /* same offset in reply */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700153
154 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
155 "WPA: Sending EAPOL-Key Request (error=%d "
156 "pairwise=%d ptk_set=%d len=%lu)",
157 error, pairwise, sm->ptk_set, (unsigned long) rlen);
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800158 wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, bssid,
159 ETH_P_EAPOL, rbuf, rlen, key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700160}
161
162
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800163static void wpa_supplicant_key_mgmt_set_pmk(struct wpa_sm *sm)
164{
165#ifdef CONFIG_IEEE80211R
166 if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
167 if (wpa_sm_key_mgmt_set_pmk(sm, sm->xxkey, sm->xxkey_len))
168 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
169 "RSN: Cannot set low order 256 bits of MSK for key management offload");
170 } else {
171#endif /* CONFIG_IEEE80211R */
172 if (wpa_sm_key_mgmt_set_pmk(sm, sm->pmk, sm->pmk_len))
173 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
174 "RSN: Cannot set PMK for key management offload");
175#ifdef CONFIG_IEEE80211R
176 }
177#endif /* CONFIG_IEEE80211R */
178}
179
180
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700181static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
182 const unsigned char *src_addr,
183 const u8 *pmkid)
184{
185 int abort_cached = 0;
186
187 if (pmkid && !sm->cur_pmksa) {
188 /* When using drivers that generate RSN IE, wpa_supplicant may
189 * not have enough time to get the association information
190 * event before receiving this 1/4 message, so try to find a
191 * matching PMKSA cache entry here. */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800192 sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
193 NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700194 if (sm->cur_pmksa) {
195 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
196 "RSN: found matching PMKID from PMKSA cache");
197 } else {
198 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
199 "RSN: no matching PMKID found");
200 abort_cached = 1;
201 }
202 }
203
204 if (pmkid && sm->cur_pmksa &&
Dmitry Shmidtc2817022014-07-02 10:32:10 -0700205 os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700206 wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
207 wpa_sm_set_pmk_from_pmksa(sm);
208 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
209 sm->pmk, sm->pmk_len);
210 eapol_sm_notify_cached(sm->eapol);
211#ifdef CONFIG_IEEE80211R
212 sm->xxkey_len = 0;
213#endif /* CONFIG_IEEE80211R */
214 } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
215 int res, pmk_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800216
217 if (sm->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
218 pmk_len = PMK_LEN_SUITE_B_192;
219 else
220 pmk_len = PMK_LEN;
221 res = eapol_sm_get_key(sm->eapol, sm->pmk, pmk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700222 if (res) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800223 if (pmk_len == PMK_LEN) {
224 /*
225 * EAP-LEAP is an exception from other EAP
226 * methods: it uses only 16-byte PMK.
227 */
228 res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
229 pmk_len = 16;
230 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700231 } else {
232#ifdef CONFIG_IEEE80211R
233 u8 buf[2 * PMK_LEN];
234 if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
235 {
236 os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
237 sm->xxkey_len = PMK_LEN;
238 os_memset(buf, 0, sizeof(buf));
239 }
240#endif /* CONFIG_IEEE80211R */
241 }
242 if (res == 0) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700243 struct rsn_pmksa_cache_entry *sa = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700244 wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
245 "machines", sm->pmk, pmk_len);
246 sm->pmk_len = pmk_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800247 wpa_supplicant_key_mgmt_set_pmk(sm);
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700248 if (sm->proto == WPA_PROTO_RSN &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800249 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700250 !wpa_key_mgmt_ft(sm->key_mgmt)) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700251 sa = pmksa_cache_add(sm->pmksa,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800252 sm->pmk, pmk_len, NULL,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800253 NULL, 0,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700254 src_addr, sm->own_addr,
255 sm->network_ctx,
256 sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700257 }
258 if (!sm->cur_pmksa && pmkid &&
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800259 pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
260 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700261 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
262 "RSN: the new PMK matches with the "
263 "PMKID");
264 abort_cached = 0;
Jouni Malinen6ec30382015-07-08 20:48:18 +0300265 } else if (sa && !sm->cur_pmksa && pmkid) {
266 /*
267 * It looks like the authentication server
268 * derived mismatching MSK. This should not
269 * really happen, but bugs happen.. There is not
270 * much we can do here without knowing what
271 * exactly caused the server to misbehave.
272 */
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -0800273 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
Jouni Malinen6ec30382015-07-08 20:48:18 +0300274 "RSN: PMKID mismatch - authentication server may have derived different MSK?!");
275 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700276 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700277
278 if (!sm->cur_pmksa)
279 sm->cur_pmksa = sa;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700280 } else {
281 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
282 "WPA: Failed to get master session key from "
283 "EAPOL state machines - key handshake "
284 "aborted");
285 if (sm->cur_pmksa) {
286 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
287 "RSN: Cancelled PMKSA caching "
288 "attempt");
289 sm->cur_pmksa = NULL;
290 abort_cached = 1;
291 } else if (!abort_cached) {
292 return -1;
293 }
294 }
295 }
296
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700297 if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800298 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800299 !wpa_key_mgmt_ft(sm->key_mgmt) && sm->key_mgmt != WPA_KEY_MGMT_OSEN)
300 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700301 /* Send EAPOL-Start to trigger full EAP authentication. */
302 u8 *buf;
303 size_t buflen;
304
305 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
306 "RSN: no PMKSA entry found - trigger "
307 "full EAP authentication");
308 buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
309 NULL, 0, &buflen, NULL);
310 if (buf) {
311 wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
312 buf, buflen);
313 os_free(buf);
314 return -2;
315 }
316
317 return -1;
318 }
319
320 return 0;
321}
322
323
324/**
325 * wpa_supplicant_send_2_of_4 - Send message 2 of WPA/RSN 4-Way Handshake
326 * @sm: Pointer to WPA state machine data from wpa_sm_init()
327 * @dst: Destination address for the frame
328 * @key: Pointer to the EAPOL-Key frame header
329 * @ver: Version bits from EAPOL-Key Key Info
330 * @nonce: Nonce value for the EAPOL-Key frame
331 * @wpa_ie: WPA/RSN IE
332 * @wpa_ie_len: Length of the WPA/RSN IE
333 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800334 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700335 */
336int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
337 const struct wpa_eapol_key *key,
338 int ver, const u8 *nonce,
339 const u8 *wpa_ie, size_t wpa_ie_len,
340 struct wpa_ptk *ptk)
341{
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800342 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700343 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800344 struct wpa_eapol_key_192 *reply192;
345 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700346 u8 *rsn_ie_buf = NULL;
347
348 if (wpa_ie == NULL) {
349 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No wpa_ie set - "
350 "cannot generate msg 2/4");
351 return -1;
352 }
353
354#ifdef CONFIG_IEEE80211R
355 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
356 int res;
357
358 /*
359 * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
360 * FTIE from (Re)Association Response.
361 */
362 rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
363 sm->assoc_resp_ies_len);
364 if (rsn_ie_buf == NULL)
365 return -1;
366 os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800367 res = wpa_insert_pmkid(rsn_ie_buf, &wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700368 sm->pmk_r1_name);
369 if (res < 0) {
370 os_free(rsn_ie_buf);
371 return -1;
372 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700373
374 if (sm->assoc_resp_ies) {
375 os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
376 sm->assoc_resp_ies_len);
377 wpa_ie_len += sm->assoc_resp_ies_len;
378 }
379
380 wpa_ie = rsn_ie_buf;
381 }
382#endif /* CONFIG_IEEE80211R */
383
384 wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
385
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800386 mic_len = wpa_mic_len(sm->key_mgmt);
387 hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700388 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800389 NULL, hdrlen + wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700390 &rlen, (void *) &reply);
391 if (rbuf == NULL) {
392 os_free(rsn_ie_buf);
393 return -1;
394 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800395 reply192 = (struct wpa_eapol_key_192 *) reply;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700396
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800397 reply->type = (sm->proto == WPA_PROTO_RSN ||
398 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700399 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
400 WPA_PUT_BE16(reply->key_info,
401 ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800402 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700403 WPA_PUT_BE16(reply->key_length, 0);
404 else
405 os_memcpy(reply->key_length, key->key_length, 2);
406 os_memcpy(reply->replay_counter, key->replay_counter,
407 WPA_REPLAY_COUNTER_LEN);
408 wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
409 WPA_REPLAY_COUNTER_LEN);
410
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800411 key_mic = reply192->key_mic; /* same offset for reply and reply192 */
412 if (mic_len == 24) {
413 WPA_PUT_BE16(reply192->key_data_length, wpa_ie_len);
414 os_memcpy(reply192 + 1, wpa_ie, wpa_ie_len);
415 } else {
416 WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
417 os_memcpy(reply + 1, wpa_ie, wpa_ie_len);
418 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700419 os_free(rsn_ie_buf);
420
421 os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
422
423 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800424 return wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst,
425 ETH_P_EAPOL, rbuf, rlen, key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700426}
427
428
429static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800430 const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700431{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700432#ifdef CONFIG_IEEE80211R
433 if (wpa_key_mgmt_ft(sm->key_mgmt))
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800434 return wpa_derive_ptk_ft(sm, src_addr, key, ptk);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700435#endif /* CONFIG_IEEE80211R */
436
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800437 return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
438 sm->own_addr, sm->bssid, sm->snonce,
439 key->key_nonce, ptk, sm->key_mgmt,
440 sm->pairwise_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700441}
442
443
444static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
445 const unsigned char *src_addr,
446 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700447 u16 ver, const u8 *key_data,
448 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700449{
450 struct wpa_eapol_ie_parse ie;
451 struct wpa_ptk *ptk;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700452 int res;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800453 u8 *kde, *kde_buf = NULL;
454 size_t kde_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700455
456 if (wpa_sm_get_network_ctx(sm) == NULL) {
457 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
458 "found (msg 1 of 4)");
459 return;
460 }
461
462 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
463 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
464 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
465
466 os_memset(&ie, 0, sizeof(ie));
467
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800468 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700469 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700470 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
471 key_data, key_data_len);
472 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800473 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700474 if (ie.pmkid) {
475 wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
476 "Authenticator", ie.pmkid, PMKID_LEN);
477 }
478 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700479
480 res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
481 if (res == -2) {
482 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
483 "msg 1/4 - requesting full EAP authentication");
484 return;
485 }
486 if (res)
487 goto failed;
488
489 if (sm->renew_snonce) {
490 if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
491 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
492 "WPA: Failed to get random data for SNonce");
493 goto failed;
494 }
495 sm->renew_snonce = 0;
496 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
497 sm->snonce, WPA_NONCE_LEN);
498 }
499
500 /* Calculate PTK which will be stored as a temporary PTK until it has
501 * been verified when processing message 3/4. */
502 ptk = &sm->tptk;
503 wpa_derive_ptk(sm, src_addr, key, ptk);
Dmitry Shmidt98660862014-03-11 17:26:21 -0700504 if (sm->pairwise_cipher == WPA_CIPHER_TKIP) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700505 u8 buf[8];
Dmitry Shmidt98660862014-03-11 17:26:21 -0700506 /* Supplicant: swap tx/rx Mic keys */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800507 os_memcpy(buf, &ptk->tk[16], 8);
508 os_memcpy(&ptk->tk[16], &ptk->tk[24], 8);
509 os_memcpy(&ptk->tk[24], buf, 8);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700510 os_memset(buf, 0, sizeof(buf));
Dmitry Shmidt98660862014-03-11 17:26:21 -0700511 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700512 sm->tptk_set = 1;
513
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800514 kde = sm->assoc_wpa_ie;
515 kde_len = sm->assoc_wpa_ie_len;
516
517#ifdef CONFIG_P2P
518 if (sm->p2p) {
519 kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
520 if (kde_buf) {
521 u8 *pos;
522 wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
523 "into EAPOL-Key 2/4");
524 os_memcpy(kde_buf, kde, kde_len);
525 kde = kde_buf;
526 pos = kde + kde_len;
527 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
528 *pos++ = RSN_SELECTOR_LEN + 1;
529 RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ);
530 pos += RSN_SELECTOR_LEN;
531 *pos++ = 0x01;
532 kde_len = pos - kde;
533 }
534 }
535#endif /* CONFIG_P2P */
536
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700537 if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800538 kde, kde_len, ptk) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700539 goto failed;
540
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800541 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700542 os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
543 return;
544
545failed:
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800546 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700547 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
548}
549
550
551static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
552{
553 struct wpa_sm *sm = eloop_ctx;
554 rsn_preauth_candidate_process(sm);
555}
556
557
558static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
559 const u8 *addr, int secure)
560{
561 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
562 "WPA: Key negotiation completed with "
563 MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
564 wpa_cipher_txt(sm->pairwise_cipher),
565 wpa_cipher_txt(sm->group_cipher));
566 wpa_sm_cancel_auth_timeout(sm);
567 wpa_sm_set_state(sm, WPA_COMPLETED);
568
569 if (secure) {
570 wpa_sm_mlme_setprotection(
571 sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
572 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
573 eapol_sm_notify_portValid(sm->eapol, TRUE);
574 if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
575 eapol_sm_notify_eap_success(sm->eapol, TRUE);
576 /*
577 * Start preauthentication after a short wait to avoid a
578 * possible race condition between the data receive and key
579 * configuration after the 4-Way Handshake. This increases the
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800580 * likelihood of the first preauth EAPOL-Start frame getting to
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700581 * the target AP.
582 */
583 eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
584 }
585
586 if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {
587 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
588 "RSN: Authenticator accepted "
589 "opportunistic PMKSA entry - marking it valid");
590 sm->cur_pmksa->opportunistic = 0;
591 }
592
593#ifdef CONFIG_IEEE80211R
594 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
595 /* Prepare for the next transition */
596 wpa_ft_prepare_auth_request(sm, NULL);
597 }
598#endif /* CONFIG_IEEE80211R */
599}
600
601
602static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
603{
604 struct wpa_sm *sm = eloop_ctx;
605 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Request PTK rekeying");
606 wpa_sm_key_request(sm, 0, 1);
607}
608
609
610static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
611 const struct wpa_eapol_key *key)
612{
613 int keylen, rsclen;
614 enum wpa_alg alg;
615 const u8 *key_rsc;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800616
Mathy Vanhoef5ad4a6a2017-09-29 04:22:51 +0200617 if (sm->ptk.installed) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800618 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
619 "WPA: Do not re-install same PTK to the driver");
620 return 0;
621 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700622
623 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
624 "WPA: Installing PTK to the driver");
625
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700626 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700627 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Pairwise Cipher "
628 "Suite: NONE - do not use pairwise keys");
629 return 0;
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700630 }
631
632 if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700633 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
634 "WPA: Unsupported pairwise cipher %d",
635 sm->pairwise_cipher);
636 return -1;
637 }
638
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700639 alg = wpa_cipher_to_alg(sm->pairwise_cipher);
640 keylen = wpa_cipher_key_len(sm->pairwise_cipher);
641 rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
642
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800643 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700644 key_rsc = null_rsc;
645 } else {
646 key_rsc = key->key_rsc;
647 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
648 }
649
650 if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800651 sm->ptk.tk, keylen) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700652 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
653 "WPA: Failed to set PTK to the "
654 "driver (alg=%d keylen=%d bssid=" MACSTR ")",
655 alg, keylen, MAC2STR(sm->bssid));
656 return -1;
657 }
658
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800659 /* TK is not needed anymore in supplicant */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800660 os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
Mathy Vanhoef5ad4a6a2017-09-29 04:22:51 +0200661 sm->ptk.installed = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800662
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700663 if (sm->wpa_ptk_rekey) {
664 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
665 eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
666 sm, NULL);
667 }
668
669 return 0;
670}
671
672
673static int wpa_supplicant_check_group_cipher(struct wpa_sm *sm,
674 int group_cipher,
675 int keylen, int maxkeylen,
676 int *key_rsc_len,
677 enum wpa_alg *alg)
678{
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700679 int klen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700680
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700681 *alg = wpa_cipher_to_alg(group_cipher);
682 if (*alg == WPA_ALG_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700683 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
684 "WPA: Unsupported Group Cipher %d",
685 group_cipher);
686 return -1;
687 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700688 *key_rsc_len = wpa_cipher_rsc_len(group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700689
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700690 klen = wpa_cipher_key_len(group_cipher);
691 if (keylen != klen || maxkeylen < klen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700692 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
693 "WPA: Unsupported %s Group Cipher key length %d (%d)",
694 wpa_cipher_txt(group_cipher), keylen, maxkeylen);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700695 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700696 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700697 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700698}
699
700
701struct wpa_gtk_data {
702 enum wpa_alg alg;
703 int tx, key_rsc_len, keyidx;
704 u8 gtk[32];
705 int gtk_len;
706};
707
708
709static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
710 const struct wpa_gtk_data *gd,
Jouni Malineneac6bde2017-10-01 12:12:24 +0300711 const u8 *key_rsc, int wnm_sleep)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700712{
713 const u8 *_gtk = gd->gtk;
714 u8 gtk_buf[32];
715
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200716 /* Detect possible key reinstallation */
Jouni Malineneac6bde2017-10-01 12:12:24 +0300717 if ((sm->gtk.gtk_len == (size_t) gd->gtk_len &&
718 os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) ||
719 (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len &&
720 os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk,
721 sm->gtk_wnm_sleep.gtk_len) == 0)) {
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200722 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
723 "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
724 gd->keyidx, gd->tx, gd->gtk_len);
725 return 0;
726 }
727
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700728 wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
729 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
730 "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
731 gd->keyidx, gd->tx, gd->gtk_len);
732 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
733 if (sm->group_cipher == WPA_CIPHER_TKIP) {
734 /* Swap Tx/Rx keys for Michael MIC */
735 os_memcpy(gtk_buf, gd->gtk, 16);
736 os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
737 os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
738 _gtk = gtk_buf;
739 }
740 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
741 if (wpa_sm_set_key(sm, gd->alg, NULL,
742 gd->keyidx, 1, key_rsc, gd->key_rsc_len,
743 _gtk, gd->gtk_len) < 0) {
744 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
745 "WPA: Failed to set GTK to the driver "
746 "(Group only)");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700747 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700748 return -1;
749 }
750 } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
751 gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
752 _gtk, gd->gtk_len) < 0) {
753 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
754 "WPA: Failed to set GTK to "
755 "the driver (alg=%d keylen=%d keyidx=%d)",
756 gd->alg, gd->gtk_len, gd->keyidx);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700757 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700758 return -1;
759 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700760 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700761
Jouni Malineneac6bde2017-10-01 12:12:24 +0300762 if (wnm_sleep) {
763 sm->gtk_wnm_sleep.gtk_len = gd->gtk_len;
764 os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk,
765 sm->gtk_wnm_sleep.gtk_len);
766 } else {
767 sm->gtk.gtk_len = gd->gtk_len;
768 os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
769 }
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200770
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700771 return 0;
772}
773
774
775static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
776 int tx)
777{
778 if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
779 /* Ignore Tx bit for GTK if a pairwise key is used. One AP
780 * seemed to set this bit (incorrectly, since Tx is only when
781 * doing Group Key only APs) and without this workaround, the
782 * data connection does not work because wpa_supplicant
783 * configured non-zero keyidx to be used for unicast. */
784 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
785 "WPA: Tx bit set for GTK, but pairwise "
786 "keys are used - ignore Tx bit");
787 return 0;
788 }
789 return tx;
790}
791
792
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800793static int wpa_supplicant_rsc_relaxation(const struct wpa_sm *sm,
794 const u8 *rsc)
795{
796 int rsclen;
797
798 if (!sm->wpa_rsc_relaxation)
799 return 0;
800
801 rsclen = wpa_cipher_rsc_len(sm->group_cipher);
802
803 /*
804 * Try to detect RSC (endian) corruption issue where the AP sends
805 * the RSC bytes in EAPOL-Key message in the wrong order, both if
806 * it's actually a 6-byte field (as it should be) and if it treats
807 * it as an 8-byte field.
808 * An AP model known to have this bug is the Sapido RB-1632.
809 */
810 if (rsclen == 6 && ((rsc[5] && !rsc[0]) || rsc[6] || rsc[7])) {
811 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
812 "RSC %02x%02x%02x%02x%02x%02x%02x%02x is likely bogus, using 0",
813 rsc[0], rsc[1], rsc[2], rsc[3],
814 rsc[4], rsc[5], rsc[6], rsc[7]);
815
816 return 1;
817 }
818
819 return 0;
820}
821
822
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700823static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
824 const struct wpa_eapol_key *key,
825 const u8 *gtk, size_t gtk_len,
826 int key_info)
827{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700828 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800829 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700830
831 /*
832 * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
833 * GTK KDE format:
834 * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]
835 * Reserved [bits 0-7]
836 * GTK
837 */
838
839 os_memset(&gd, 0, sizeof(gd));
840 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
841 gtk, gtk_len);
842
843 if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
844 return -1;
845
846 gd.keyidx = gtk[0] & 0x3;
847 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
848 !!(gtk[0] & BIT(2)));
849 gtk += 2;
850 gtk_len -= 2;
851
852 os_memcpy(gd.gtk, gtk, gtk_len);
853 gd.gtk_len = gtk_len;
854
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800855 key_rsc = key->key_rsc;
856 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
857 key_rsc = null_rsc;
858
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800859 if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED &&
860 (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
861 gtk_len, gtk_len,
862 &gd.key_rsc_len, &gd.alg) ||
Jouni Malineneac6bde2017-10-01 12:12:24 +0300863 wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700864 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
865 "RSN: Failed to install GTK");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700866 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700867 return -1;
868 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700869 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700870
871 wpa_supplicant_key_neg_complete(sm, sm->bssid,
872 key_info & WPA_KEY_INFO_SECURE);
873 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700874}
875
876
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200877#ifdef CONFIG_IEEE80211W
878static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
Jouni Malineneac6bde2017-10-01 12:12:24 +0300879 const struct wpa_igtk_kde *igtk,
880 int wnm_sleep)
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200881{
882 size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
883 u16 keyidx = WPA_GET_LE16(igtk->keyid);
884
885 /* Detect possible key reinstallation */
Jouni Malineneac6bde2017-10-01 12:12:24 +0300886 if ((sm->igtk.igtk_len == len &&
887 os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) ||
888 (sm->igtk_wnm_sleep.igtk_len == len &&
889 os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk,
890 sm->igtk_wnm_sleep.igtk_len) == 0)) {
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200891 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
892 "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)",
893 keyidx);
894 return 0;
895 }
896
897 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
898 "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x",
899 keyidx, MAC2STR(igtk->pn));
900 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len);
901 if (keyidx > 4095) {
902 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
903 "WPA: Invalid IGTK KeyID %d", keyidx);
904 return -1;
905 }
906 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
907 broadcast_ether_addr,
908 keyidx, 0, igtk->pn, sizeof(igtk->pn),
909 igtk->igtk, len) < 0) {
910 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
911 "WPA: Failed to configure IGTK to the driver");
912 return -1;
913 }
914
Jouni Malineneac6bde2017-10-01 12:12:24 +0300915 if (wnm_sleep) {
916 sm->igtk_wnm_sleep.igtk_len = len;
917 os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk,
918 sm->igtk_wnm_sleep.igtk_len);
919 } else {
920 sm->igtk.igtk_len = len;
921 os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
922 }
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200923
924 return 0;
925}
926#endif /* CONFIG_IEEE80211W */
927
928
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700929static int ieee80211w_set_keys(struct wpa_sm *sm,
930 struct wpa_eapol_ie_parse *ie)
931{
932#ifdef CONFIG_IEEE80211W
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700933 if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700934 return 0;
935
936 if (ie->igtk) {
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700937 size_t len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700938 const struct wpa_igtk_kde *igtk;
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200939
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700940 len = wpa_cipher_key_len(sm->mgmt_group_cipher);
941 if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700942 return -1;
Mathy Vanhoef480c21c2017-07-12 16:03:24 +0200943
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700944 igtk = (const struct wpa_igtk_kde *) ie->igtk;
Jouni Malineneac6bde2017-10-01 12:12:24 +0300945 if (wpa_supplicant_install_igtk(sm, igtk, 0) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700946 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700947 }
948
949 return 0;
950#else /* CONFIG_IEEE80211W */
951 return 0;
952#endif /* CONFIG_IEEE80211W */
953}
954
955
956static void wpa_report_ie_mismatch(struct wpa_sm *sm,
957 const char *reason, const u8 *src_addr,
958 const u8 *wpa_ie, size_t wpa_ie_len,
959 const u8 *rsn_ie, size_t rsn_ie_len)
960{
961 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",
962 reason, MAC2STR(src_addr));
963
964 if (sm->ap_wpa_ie) {
965 wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
966 sm->ap_wpa_ie, sm->ap_wpa_ie_len);
967 }
968 if (wpa_ie) {
969 if (!sm->ap_wpa_ie) {
970 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
971 "WPA: No WPA IE in Beacon/ProbeResp");
972 }
973 wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
974 wpa_ie, wpa_ie_len);
975 }
976
977 if (sm->ap_rsn_ie) {
978 wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
979 sm->ap_rsn_ie, sm->ap_rsn_ie_len);
980 }
981 if (rsn_ie) {
982 if (!sm->ap_rsn_ie) {
983 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
984 "WPA: No RSN IE in Beacon/ProbeResp");
985 }
986 wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
987 rsn_ie, rsn_ie_len);
988 }
989
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800990 wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700991}
992
993
994#ifdef CONFIG_IEEE80211R
995
996static int ft_validate_mdie(struct wpa_sm *sm,
997 const unsigned char *src_addr,
998 struct wpa_eapol_ie_parse *ie,
999 const u8 *assoc_resp_mdie)
1000{
1001 struct rsn_mdie *mdie;
1002
1003 mdie = (struct rsn_mdie *) (ie->mdie + 2);
1004 if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
1005 os_memcmp(mdie->mobility_domain, sm->mobility_domain,
1006 MOBILITY_DOMAIN_ID_LEN) != 0) {
1007 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did "
1008 "not match with the current mobility domain");
1009 return -1;
1010 }
1011
1012 if (assoc_resp_mdie &&
1013 (assoc_resp_mdie[1] != ie->mdie[1] ||
1014 os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
1015 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch");
1016 wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
1017 ie->mdie, 2 + ie->mdie[1]);
1018 wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
1019 assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
1020 return -1;
1021 }
1022
1023 return 0;
1024}
1025
1026
1027static int ft_validate_ftie(struct wpa_sm *sm,
1028 const unsigned char *src_addr,
1029 struct wpa_eapol_ie_parse *ie,
1030 const u8 *assoc_resp_ftie)
1031{
1032 if (ie->ftie == NULL) {
1033 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1034 "FT: No FTIE in EAPOL-Key msg 3/4");
1035 return -1;
1036 }
1037
1038 if (assoc_resp_ftie == NULL)
1039 return 0;
1040
1041 if (assoc_resp_ftie[1] != ie->ftie[1] ||
1042 os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
1043 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch");
1044 wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
1045 ie->ftie, 2 + ie->ftie[1]);
1046 wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
1047 assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
1048 return -1;
1049 }
1050
1051 return 0;
1052}
1053
1054
1055static int ft_validate_rsnie(struct wpa_sm *sm,
1056 const unsigned char *src_addr,
1057 struct wpa_eapol_ie_parse *ie)
1058{
1059 struct wpa_ie_data rsn;
1060
1061 if (!ie->rsn_ie)
1062 return 0;
1063
1064 /*
1065 * Verify that PMKR1Name from EAPOL-Key message 3/4
1066 * matches with the value we derived.
1067 */
1068 if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
1069 rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
1070 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in "
1071 "FT 4-way handshake message 3/4");
1072 return -1;
1073 }
1074
Dmitry Shmidtc2817022014-07-02 10:32:10 -07001075 if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
1076 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001077 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1078 "FT: PMKR1Name mismatch in "
1079 "FT 4-way handshake message 3/4");
1080 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
1081 rsn.pmkid, WPA_PMK_NAME_LEN);
1082 wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
1083 sm->pmk_r1_name, WPA_PMK_NAME_LEN);
1084 return -1;
1085 }
1086
1087 return 0;
1088}
1089
1090
1091static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
1092 const unsigned char *src_addr,
1093 struct wpa_eapol_ie_parse *ie)
1094{
1095 const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
1096
1097 if (sm->assoc_resp_ies) {
1098 pos = sm->assoc_resp_ies;
1099 end = pos + sm->assoc_resp_ies_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001100 while (end - pos > 2) {
1101 if (2 + pos[1] > end - pos)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001102 break;
1103 switch (*pos) {
1104 case WLAN_EID_MOBILITY_DOMAIN:
1105 mdie = pos;
1106 break;
1107 case WLAN_EID_FAST_BSS_TRANSITION:
1108 ftie = pos;
1109 break;
1110 }
1111 pos += 2 + pos[1];
1112 }
1113 }
1114
1115 if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
1116 ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
1117 ft_validate_rsnie(sm, src_addr, ie) < 0)
1118 return -1;
1119
1120 return 0;
1121}
1122
1123#endif /* CONFIG_IEEE80211R */
1124
1125
1126static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
1127 const unsigned char *src_addr,
1128 struct wpa_eapol_ie_parse *ie)
1129{
1130 if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {
1131 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1132 "WPA: No WPA/RSN IE for this AP known. "
1133 "Trying to get from scan results");
1134 if (wpa_sm_get_beacon_ie(sm) < 0) {
1135 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1136 "WPA: Could not find AP from "
1137 "the scan results");
1138 } else {
1139 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
1140 "WPA: Found the current AP from "
1141 "updated scan results");
1142 }
1143 }
1144
1145 if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
1146 (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
1147 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1148 "with IE in Beacon/ProbeResp (no IE?)",
1149 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1150 ie->rsn_ie, ie->rsn_ie_len);
1151 return -1;
1152 }
1153
1154 if ((ie->wpa_ie && sm->ap_wpa_ie &&
1155 (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
1156 os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
1157 (ie->rsn_ie && sm->ap_rsn_ie &&
1158 wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
1159 sm->ap_rsn_ie, sm->ap_rsn_ie_len,
1160 ie->rsn_ie, ie->rsn_ie_len))) {
1161 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1162 "with IE in Beacon/ProbeResp",
1163 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1164 ie->rsn_ie, ie->rsn_ie_len);
1165 return -1;
1166 }
1167
1168 if (sm->proto == WPA_PROTO_WPA &&
1169 ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
1170 wpa_report_ie_mismatch(sm, "Possible downgrade attack "
1171 "detected - RSN was enabled and RSN IE "
1172 "was in msg 3/4, but not in "
1173 "Beacon/ProbeResp",
1174 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1175 ie->rsn_ie, ie->rsn_ie_len);
1176 return -1;
1177 }
1178
1179#ifdef CONFIG_IEEE80211R
1180 if (wpa_key_mgmt_ft(sm->key_mgmt) &&
1181 wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
1182 return -1;
1183#endif /* CONFIG_IEEE80211R */
1184
1185 return 0;
1186}
1187
1188
1189/**
1190 * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake
1191 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1192 * @dst: Destination address for the frame
1193 * @key: Pointer to the EAPOL-Key frame header
1194 * @ver: Version bits from EAPOL-Key Key Info
1195 * @key_info: Key Info
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001196 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001197 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001198 */
1199int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
1200 const struct wpa_eapol_key *key,
1201 u16 ver, u16 key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001202 struct wpa_ptk *ptk)
1203{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001204 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001205 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001206 struct wpa_eapol_key_192 *reply192;
1207 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001208
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001209 mic_len = wpa_mic_len(sm->key_mgmt);
1210 hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001211 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001212 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001213 if (rbuf == NULL)
1214 return -1;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001215 reply192 = (struct wpa_eapol_key_192 *) reply;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001216
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001217 reply->type = (sm->proto == WPA_PROTO_RSN ||
1218 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001219 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1220 key_info &= WPA_KEY_INFO_SECURE;
1221 key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC;
1222 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001223 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001224 WPA_PUT_BE16(reply->key_length, 0);
1225 else
1226 os_memcpy(reply->key_length, key->key_length, 2);
1227 os_memcpy(reply->replay_counter, key->replay_counter,
1228 WPA_REPLAY_COUNTER_LEN);
1229
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001230 key_mic = reply192->key_mic; /* same offset for reply and reply192 */
1231 if (mic_len == 24)
1232 WPA_PUT_BE16(reply192->key_data_length, 0);
1233 else
1234 WPA_PUT_BE16(reply->key_data_length, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001235
1236 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001237 return wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst,
1238 ETH_P_EAPOL, rbuf, rlen, key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001239}
1240
1241
1242static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
1243 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001244 u16 ver, const u8 *key_data,
1245 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001246{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001247 u16 key_info, keylen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001248 struct wpa_eapol_ie_parse ie;
1249
1250 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
1251 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 3 of 4-Way "
1252 "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
1253
1254 key_info = WPA_GET_BE16(key->key_info);
1255
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001256 wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", key_data, key_data_len);
1257 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001258 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001259 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1260 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1261 "WPA: GTK IE in unencrypted key data");
1262 goto failed;
1263 }
1264#ifdef CONFIG_IEEE80211W
1265 if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1266 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1267 "WPA: IGTK KDE in unencrypted key data");
1268 goto failed;
1269 }
1270
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07001271 if (ie.igtk &&
1272 wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) &&
1273 ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN +
1274 (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001275 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1276 "WPA: Invalid IGTK KDE length %lu",
1277 (unsigned long) ie.igtk_len);
1278 goto failed;
1279 }
1280#endif /* CONFIG_IEEE80211W */
1281
1282 if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
1283 goto failed;
1284
1285 if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
1286 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1287 "WPA: ANonce from message 1 of 4-Way Handshake "
1288 "differs from 3 of 4-Way Handshake - drop packet (src="
1289 MACSTR ")", MAC2STR(sm->bssid));
1290 goto failed;
1291 }
1292
1293 keylen = WPA_GET_BE16(key->key_length);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07001294 if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) {
1295 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1296 "WPA: Invalid %s key length %d (src=" MACSTR
1297 ")", wpa_cipher_txt(sm->pairwise_cipher), keylen,
1298 MAC2STR(sm->bssid));
1299 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001300 }
1301
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08001302#ifdef CONFIG_P2P
1303 if (ie.ip_addr_alloc) {
1304 os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4);
1305 wpa_hexdump(MSG_DEBUG, "P2P: IP address info",
1306 sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr));
1307 }
1308#endif /* CONFIG_P2P */
1309
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001310 if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001311 &sm->ptk) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001312 goto failed;
1313 }
1314
1315 /* SNonce was successfully used in msg 3/4, so mark it to be renewed
1316 * for the next 4-Way Handshake. If msg 3 is received again, the old
1317 * SNonce will still be used to avoid changing PTK. */
1318 sm->renew_snonce = 1;
1319
1320 if (key_info & WPA_KEY_INFO_INSTALL) {
1321 if (wpa_supplicant_install_ptk(sm, key))
1322 goto failed;
1323 }
1324
1325 if (key_info & WPA_KEY_INFO_SECURE) {
1326 wpa_sm_mlme_setprotection(
1327 sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
1328 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1329 eapol_sm_notify_portValid(sm->eapol, TRUE);
1330 }
1331 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1332
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001333 if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) {
1334 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1335 key_info & WPA_KEY_INFO_SECURE);
1336 } else if (ie.gtk &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001337 wpa_supplicant_pairwise_gtk(sm, key,
1338 ie.gtk, ie.gtk_len, key_info) < 0) {
1339 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1340 "RSN: Failed to configure GTK");
1341 goto failed;
1342 }
1343
1344 if (ieee80211w_set_keys(sm, &ie) < 0) {
1345 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1346 "RSN: Failed to configure IGTK");
1347 goto failed;
1348 }
1349
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001350 if (ie.gtk)
1351 wpa_sm_set_rekey_offload(sm);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001352
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001353 if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) {
1354 struct rsn_pmksa_cache_entry *sa;
1355
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001356 sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001357 sm->ptk.kck, sm->ptk.kck_len,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001358 sm->bssid, sm->own_addr,
1359 sm->network_ctx, sm->key_mgmt);
1360 if (!sm->cur_pmksa)
1361 sm->cur_pmksa = sa;
1362 }
1363
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001364 sm->msg_3_of_4_ok = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001365 return;
1366
1367failed:
1368 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1369}
1370
1371
1372static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
1373 const u8 *keydata,
1374 size_t keydatalen,
1375 u16 key_info,
1376 struct wpa_gtk_data *gd)
1377{
1378 int maxkeylen;
1379 struct wpa_eapol_ie_parse ie;
1380
1381 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/2 key data", keydata, keydatalen);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001382 if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0)
1383 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001384 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1385 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1386 "WPA: GTK IE in unencrypted key data");
1387 return -1;
1388 }
1389 if (ie.gtk == NULL) {
1390 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1391 "WPA: No GTK IE in Group Key msg 1/2");
1392 return -1;
1393 }
1394 maxkeylen = gd->gtk_len = ie.gtk_len - 2;
1395
1396 if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1397 gd->gtk_len, maxkeylen,
1398 &gd->key_rsc_len, &gd->alg))
1399 return -1;
1400
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001401 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in group key handshake",
1402 ie.gtk, ie.gtk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001403 gd->keyidx = ie.gtk[0] & 0x3;
1404 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
1405 !!(ie.gtk[0] & BIT(2)));
1406 if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
1407 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1408 "RSN: Too long GTK in GTK IE (len=%lu)",
1409 (unsigned long) ie.gtk_len - 2);
1410 return -1;
1411 }
1412 os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
1413
1414 if (ieee80211w_set_keys(sm, &ie) < 0)
1415 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1416 "RSN: Failed to configure IGTK");
1417
1418 return 0;
1419}
1420
1421
1422static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
1423 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001424 const u8 *key_data,
1425 size_t key_data_len, u16 key_info,
1426 u16 ver, struct wpa_gtk_data *gd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001427{
1428 size_t maxkeylen;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001429 u16 gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001430
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001431 gtk_len = WPA_GET_BE16(key->key_length);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001432 maxkeylen = key_data_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001433 if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1434 if (maxkeylen < 8) {
1435 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1436 "WPA: Too short maxkeylen (%lu)",
1437 (unsigned long) maxkeylen);
1438 return -1;
1439 }
1440 maxkeylen -= 8;
1441 }
1442
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001443 if (gtk_len > maxkeylen ||
1444 wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1445 gtk_len, maxkeylen,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001446 &gd->key_rsc_len, &gd->alg))
1447 return -1;
1448
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001449 gd->gtk_len = gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001450 gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1451 WPA_KEY_INFO_KEY_INDEX_SHIFT;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001452 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001453#ifdef CONFIG_NO_RC4
1454 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1455 "WPA: RC4 not supported in the build");
1456 return -1;
1457#else /* CONFIG_NO_RC4 */
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001458 u8 ek[32];
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001459 if (key_data_len > sizeof(gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001460 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1461 "WPA: RC4 key data too long (%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001462 (unsigned long) key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001463 return -1;
1464 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001465 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001466 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001467 os_memcpy(gd->gtk, key_data, key_data_len);
1468 if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001469 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001470 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1471 "WPA: RC4 failed");
1472 return -1;
1473 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001474 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001475#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001476 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001477 if (maxkeylen % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001478 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1479 "WPA: Unsupported AES-WRAP len %lu",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001480 (unsigned long) maxkeylen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001481 return -1;
1482 }
1483 if (maxkeylen > sizeof(gd->gtk)) {
1484 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1485 "WPA: AES-WRAP key data "
1486 "too long (keydatalen=%lu maxkeylen=%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001487 (unsigned long) key_data_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001488 (unsigned long) maxkeylen);
1489 return -1;
1490 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001491 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, maxkeylen / 8,
1492 key_data, gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001493 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1494 "WPA: AES unwrap failed - could not decrypt "
1495 "GTK");
1496 return -1;
1497 }
1498 } else {
1499 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1500 "WPA: Unsupported key_info type %d", ver);
1501 return -1;
1502 }
1503 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
1504 sm, !!(key_info & WPA_KEY_INFO_TXRX));
1505 return 0;
1506}
1507
1508
1509static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
1510 const struct wpa_eapol_key *key,
1511 int ver, u16 key_info)
1512{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001513 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001514 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001515 struct wpa_eapol_key_192 *reply192;
1516 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001517
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001518 mic_len = wpa_mic_len(sm->key_mgmt);
1519 hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001520 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001521 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001522 if (rbuf == NULL)
1523 return -1;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001524 reply192 = (struct wpa_eapol_key_192 *) reply;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001525
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001526 reply->type = (sm->proto == WPA_PROTO_RSN ||
1527 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001528 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1529 key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
1530 key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
1531 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001532 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001533 WPA_PUT_BE16(reply->key_length, 0);
1534 else
1535 os_memcpy(reply->key_length, key->key_length, 2);
1536 os_memcpy(reply->replay_counter, key->replay_counter,
1537 WPA_REPLAY_COUNTER_LEN);
1538
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001539 key_mic = reply192->key_mic; /* same offset for reply and reply192 */
1540 if (mic_len == 24)
1541 WPA_PUT_BE16(reply192->key_data_length, 0);
1542 else
1543 WPA_PUT_BE16(reply->key_data_length, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001544
1545 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001546 return wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver,
1547 sm->bssid, ETH_P_EAPOL, rbuf, rlen, key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001548}
1549
1550
1551static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
1552 const unsigned char *src_addr,
1553 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001554 const u8 *key_data,
1555 size_t key_data_len, u16 ver)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001556{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001557 u16 key_info;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001558 int rekey, ret;
1559 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001560 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001561
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001562 if (!sm->msg_3_of_4_ok) {
1563 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1564 "WPA: Group Key Handshake started prior to completion of 4-way handshake");
1565 goto failed;
1566 }
1567
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001568 os_memset(&gd, 0, sizeof(gd));
1569
1570 rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
1571 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of Group Key "
1572 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1573
1574 key_info = WPA_GET_BE16(key->key_info);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001575
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001576 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001577 ret = wpa_supplicant_process_1_of_2_rsn(sm, key_data,
1578 key_data_len, key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001579 &gd);
1580 } else {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001581 ret = wpa_supplicant_process_1_of_2_wpa(sm, key, key_data,
1582 key_data_len,
1583 key_info, ver, &gd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001584 }
1585
1586 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1587
1588 if (ret)
1589 goto failed;
1590
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001591 key_rsc = key->key_rsc;
1592 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
1593 key_rsc = null_rsc;
1594
Jouni Malineneac6bde2017-10-01 12:12:24 +03001595 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0) ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001596 wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001597 goto failed;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001598 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001599
1600 if (rekey) {
1601 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
1602 "completed with " MACSTR " [GTK=%s]",
1603 MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
1604 wpa_sm_cancel_auth_timeout(sm);
1605 wpa_sm_set_state(sm, WPA_COMPLETED);
1606 } else {
1607 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1608 key_info &
1609 WPA_KEY_INFO_SECURE);
1610 }
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001611
1612 wpa_sm_set_rekey_offload(sm);
1613
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001614 return;
1615
1616failed:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001617 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001618 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1619}
1620
1621
1622static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001623 struct wpa_eapol_key_192 *key,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001624 u16 ver,
1625 const u8 *buf, size_t len)
1626{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001627 u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001628 int ok = 0;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001629 size_t mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001630
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001631 os_memcpy(mic, key->key_mic, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001632 if (sm->tptk_set) {
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001633 os_memset(key->key_mic, 0, mic_len);
1634 wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len, sm->key_mgmt,
1635 ver, buf, len, key->key_mic);
1636 if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001637 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1638 "WPA: Invalid EAPOL-Key MIC "
1639 "when using TPTK - ignoring TPTK");
1640 } else {
1641 ok = 1;
1642 sm->tptk_set = 0;
1643 sm->ptk_set = 1;
1644 os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001645 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001646 }
1647 }
1648
1649 if (!ok && sm->ptk_set) {
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001650 os_memset(key->key_mic, 0, mic_len);
1651 wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len, sm->key_mgmt,
1652 ver, buf, len, key->key_mic);
1653 if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001654 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1655 "WPA: Invalid EAPOL-Key MIC - "
1656 "dropping packet");
1657 return -1;
1658 }
1659 ok = 1;
1660 }
1661
1662 if (!ok) {
1663 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1664 "WPA: Could not verify EAPOL-Key MIC - "
1665 "dropping packet");
1666 return -1;
1667 }
1668
1669 os_memcpy(sm->rx_replay_counter, key->replay_counter,
1670 WPA_REPLAY_COUNTER_LEN);
1671 sm->rx_replay_counter_set = 1;
1672 return 0;
1673}
1674
1675
1676/* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
1677static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001678 struct wpa_eapol_key *key, u16 ver,
1679 u8 *key_data, size_t *key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001680{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001681 wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001682 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001683 if (!sm->ptk_set) {
1684 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1685 "WPA: PTK not available, cannot decrypt EAPOL-Key Key "
1686 "Data");
1687 return -1;
1688 }
1689
1690 /* Decrypt key data here so that this operation does not need
1691 * to be implemented separately for each message type. */
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001692 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001693#ifdef CONFIG_NO_RC4
1694 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1695 "WPA: RC4 not supported in the build");
1696 return -1;
1697#else /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001698 u8 ek[32];
1699 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001700 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001701 if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001702 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001703 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1704 "WPA: RC4 failed");
1705 return -1;
1706 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001707 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001708#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001709 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001710 ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001711 sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
1712 wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001713 u8 *buf;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001714 if (*key_data_len < 8 || *key_data_len % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001715 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001716 "WPA: Unsupported AES-WRAP len %u",
1717 (unsigned int) *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001718 return -1;
1719 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001720 *key_data_len -= 8; /* AES-WRAP adds 8 bytes */
1721 buf = os_malloc(*key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001722 if (buf == NULL) {
1723 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1724 "WPA: No memory for AES-UNWRAP buffer");
1725 return -1;
1726 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001727 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, *key_data_len / 8,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001728 key_data, buf)) {
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001729 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001730 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1731 "WPA: AES unwrap failed - "
1732 "could not decrypt EAPOL-Key key data");
1733 return -1;
1734 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001735 os_memcpy(key_data, buf, *key_data_len);
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001736 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001737 WPA_PUT_BE16(key->key_data_length, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001738 } else {
1739 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1740 "WPA: Unsupported key_info type %d", ver);
1741 return -1;
1742 }
1743 wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001744 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001745 return 0;
1746}
1747
1748
1749/**
1750 * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted
1751 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1752 */
1753void wpa_sm_aborted_cached(struct wpa_sm *sm)
1754{
1755 if (sm && sm->cur_pmksa) {
1756 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1757 "RSN: Cancelling PMKSA caching attempt");
1758 sm->cur_pmksa = NULL;
1759 }
1760}
1761
1762
1763static void wpa_eapol_key_dump(struct wpa_sm *sm,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001764 const struct wpa_eapol_key *key,
1765 unsigned int key_data_len,
1766 const u8 *mic, unsigned int mic_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001767{
1768#ifndef CONFIG_NO_STDOUT_DEBUG
1769 u16 key_info = WPA_GET_BE16(key->key_info);
1770
1771 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, " EAPOL-Key type=%d", key->type);
1772 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1773 " key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s%s%s%s%s%s%s%s)",
1774 key_info, key_info & WPA_KEY_INFO_TYPE_MASK,
1775 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1776 WPA_KEY_INFO_KEY_INDEX_SHIFT,
1777 (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,
1778 key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",
1779 key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",
1780 key_info & WPA_KEY_INFO_ACK ? " Ack" : "",
1781 key_info & WPA_KEY_INFO_MIC ? " MIC" : "",
1782 key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",
1783 key_info & WPA_KEY_INFO_ERROR ? " Error" : "",
1784 key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",
1785 key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
1786 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1787 " key_length=%u key_data_length=%u",
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001788 WPA_GET_BE16(key->key_length), key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001789 wpa_hexdump(MSG_DEBUG, " replay_counter",
1790 key->replay_counter, WPA_REPLAY_COUNTER_LEN);
1791 wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN);
1792 wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16);
1793 wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8);
1794 wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001795 wpa_hexdump(MSG_DEBUG, " key_mic", mic, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001796#endif /* CONFIG_NO_STDOUT_DEBUG */
1797}
1798
1799
1800/**
1801 * wpa_sm_rx_eapol - Process received WPA EAPOL frames
1802 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1803 * @src_addr: Source MAC address of the EAPOL packet
1804 * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
1805 * @len: Length of the EAPOL frame
1806 * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
1807 *
1808 * This function is called for each received EAPOL frame. Other than EAPOL-Key
1809 * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
1810 * only processing WPA and WPA2 EAPOL-Key frames.
1811 *
1812 * The received EAPOL-Key packets are validated and valid packets are replied
1813 * to. In addition, key material (PTK, GTK) is configured at the end of a
1814 * successful key handshake.
1815 */
1816int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
1817 const u8 *buf, size_t len)
1818{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001819 size_t plen, data_len, key_data_len;
1820 const struct ieee802_1x_hdr *hdr;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001821 struct wpa_eapol_key *key;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001822 struct wpa_eapol_key_192 *key192;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001823 u16 key_info, ver;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001824 u8 *tmp = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001825 int ret = -1;
1826 struct wpa_peerkey *peerkey = NULL;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001827 u8 *key_data;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001828 size_t mic_len, keyhdrlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001829
1830#ifdef CONFIG_IEEE80211R
1831 sm->ft_completed = 0;
1832#endif /* CONFIG_IEEE80211R */
1833
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001834 mic_len = wpa_mic_len(sm->key_mgmt);
1835 keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key);
1836
1837 if (len < sizeof(*hdr) + keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001838 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1839 "WPA: EAPOL frame too short to be a WPA "
1840 "EAPOL-Key (len %lu, expecting at least %lu)",
1841 (unsigned long) len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001842 (unsigned long) sizeof(*hdr) + keyhdrlen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001843 return 0;
1844 }
1845
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001846 hdr = (const struct ieee802_1x_hdr *) buf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001847 plen = be_to_host16(hdr->length);
1848 data_len = plen + sizeof(*hdr);
1849 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1850 "IEEE 802.1X RX: version=%d type=%d length=%lu",
1851 hdr->version, hdr->type, (unsigned long) plen);
1852
1853 if (hdr->version < EAPOL_VERSION) {
1854 /* TODO: backwards compatibility */
1855 }
1856 if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
1857 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1858 "WPA: EAPOL frame (type %u) discarded, "
1859 "not a Key frame", hdr->type);
1860 ret = 0;
1861 goto out;
1862 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001863 wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001864 if (plen > len - sizeof(*hdr) || plen < keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001865 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1866 "WPA: EAPOL frame payload size %lu "
1867 "invalid (frame size %lu)",
1868 (unsigned long) plen, (unsigned long) len);
1869 ret = 0;
1870 goto out;
1871 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001872 if (data_len < len) {
1873 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1874 "WPA: ignoring %lu bytes after the IEEE 802.1X data",
1875 (unsigned long) len - data_len);
1876 }
1877
1878 /*
1879 * Make a copy of the frame since we need to modify the buffer during
1880 * MAC validation and Key Data decryption.
1881 */
1882 tmp = os_malloc(data_len);
1883 if (tmp == NULL)
1884 goto out;
1885 os_memcpy(tmp, buf, data_len);
1886 key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr));
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001887 key192 = (struct wpa_eapol_key_192 *)
1888 (tmp + sizeof(struct ieee802_1x_hdr));
1889 if (mic_len == 24)
1890 key_data = (u8 *) (key192 + 1);
1891 else
1892 key_data = (u8 *) (key + 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001893
1894 if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
1895 {
1896 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1897 "WPA: EAPOL-Key type (%d) unknown, discarded",
1898 key->type);
1899 ret = 0;
1900 goto out;
1901 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001902
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001903 if (mic_len == 24)
1904 key_data_len = WPA_GET_BE16(key192->key_data_length);
1905 else
1906 key_data_len = WPA_GET_BE16(key->key_data_length);
1907 wpa_eapol_key_dump(sm, key, key_data_len, key192->key_mic, mic_len);
1908
1909 if (key_data_len > plen - keyhdrlen) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001910 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
1911 "frame - key_data overflow (%u > %u)",
1912 (unsigned int) key_data_len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001913 (unsigned int) (plen - keyhdrlen));
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001914 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001915 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001916
1917 eapol_sm_notify_lower_layer_success(sm->eapol, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001918 key_info = WPA_GET_BE16(key->key_info);
1919 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
1920 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
1921#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
1922 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
1923#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001924 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001925 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001926 sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001927 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1928 "WPA: Unsupported EAPOL-Key descriptor version %d",
1929 ver);
1930 goto out;
1931 }
1932
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001933 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN &&
1934 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
1935 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1936 "OSEN: Unsupported EAPOL-Key descriptor version %d",
1937 ver);
1938 goto out;
1939 }
1940
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001941 if (wpa_key_mgmt_suite_b(sm->key_mgmt) &&
1942 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
1943 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1944 "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)",
1945 ver);
1946 goto out;
1947 }
1948
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001949#ifdef CONFIG_IEEE80211R
1950 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
1951 /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
1952 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
1953 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1954 "FT: AP did not use AES-128-CMAC");
1955 goto out;
1956 }
1957 } else
1958#endif /* CONFIG_IEEE80211R */
1959#ifdef CONFIG_IEEE80211W
1960 if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001961 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001962 sm->key_mgmt != WPA_KEY_MGMT_OSEN &&
1963 !wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001964 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1965 "WPA: AP did not use the "
1966 "negotiated AES-128-CMAC");
1967 goto out;
1968 }
1969 } else
1970#endif /* CONFIG_IEEE80211W */
1971 if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001972 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001973 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1974 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1975 "WPA: CCMP is used, but EAPOL-Key "
1976 "descriptor version (%d) is not 2", ver);
1977 if (sm->group_cipher != WPA_CIPHER_CCMP &&
1978 !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
1979 /* Earlier versions of IEEE 802.11i did not explicitly
1980 * require version 2 descriptor for all EAPOL-Key
1981 * packets, so allow group keys to use version 1 if
1982 * CCMP is not used for them. */
1983 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1984 "WPA: Backwards compatibility: allow invalid "
1985 "version for non-CCMP group keys");
Jouni Malinen658fb4a2014-11-14 20:57:05 +02001986 } else if (ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
1987 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1988 "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 -07001989 } else
1990 goto out;
Dmitry Shmidt71757432014-06-02 13:50:35 -07001991 } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001992 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt71757432014-06-02 13:50:35 -07001993 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001994 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1995 "WPA: GCMP is used, but EAPOL-Key "
1996 "descriptor version (%d) is not 2", ver);
1997 goto out;
1998 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001999
2000#ifdef CONFIG_PEERKEY
2001 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
2002 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
2003 break;
2004 }
2005
2006 if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
2007 if (!peerkey->initiator && peerkey->replay_counter_set &&
2008 os_memcmp(key->replay_counter, peerkey->replay_counter,
2009 WPA_REPLAY_COUNTER_LEN) <= 0) {
2010 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2011 "RSN: EAPOL-Key Replay Counter did not "
2012 "increase (STK) - dropping packet");
2013 goto out;
2014 } else if (peerkey->initiator) {
2015 u8 _tmp[WPA_REPLAY_COUNTER_LEN];
2016 os_memcpy(_tmp, key->replay_counter,
2017 WPA_REPLAY_COUNTER_LEN);
2018 inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
2019 if (os_memcmp(_tmp, peerkey->replay_counter,
2020 WPA_REPLAY_COUNTER_LEN) != 0) {
2021 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2022 "RSN: EAPOL-Key Replay "
2023 "Counter did not match (STK) - "
2024 "dropping packet");
2025 goto out;
2026 }
2027 }
2028 }
2029
2030 if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
2031 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2032 "RSN: Ack bit in key_info from STK peer");
2033 goto out;
2034 }
2035#endif /* CONFIG_PEERKEY */
2036
2037 if (!peerkey && sm->rx_replay_counter_set &&
2038 os_memcmp(key->replay_counter, sm->rx_replay_counter,
2039 WPA_REPLAY_COUNTER_LEN) <= 0) {
2040 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2041 "WPA: EAPOL-Key Replay Counter did not increase - "
2042 "dropping packet");
2043 goto out;
2044 }
2045
2046 if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
2047#ifdef CONFIG_PEERKEY
2048 && (peerkey == NULL || !peerkey->initiator)
2049#endif /* CONFIG_PEERKEY */
2050 ) {
2051 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2052 "WPA: No Ack bit in key_info");
2053 goto out;
2054 }
2055
2056 if (key_info & WPA_KEY_INFO_REQUEST) {
2057 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2058 "WPA: EAPOL-Key with Request bit - dropped");
2059 goto out;
2060 }
2061
2062 if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002063 wpa_supplicant_verify_eapol_key_mic(sm, key192, ver, tmp, data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002064 goto out;
2065
2066#ifdef CONFIG_PEERKEY
2067 if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002068 peerkey_verify_eapol_key_mic(sm, peerkey, key192, ver, tmp,
2069 data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002070 goto out;
2071#endif /* CONFIG_PEERKEY */
2072
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002073 if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002074 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002075 if (wpa_supplicant_decrypt_key_data(sm, key, ver, key_data,
2076 &key_data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002077 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002078 }
2079
2080 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
2081 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
2082 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2083 "WPA: Ignored EAPOL-Key (Pairwise) with "
2084 "non-zero key index");
2085 goto out;
2086 }
2087 if (peerkey) {
2088 /* PeerKey 4-Way Handshake */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07002089 peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
2090 key_data, key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002091 } else if (key_info & WPA_KEY_INFO_MIC) {
2092 /* 3/4 4-Way Handshake */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002093 wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
2094 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002095 } else {
2096 /* 1/4 4-Way Handshake */
2097 wpa_supplicant_process_1_of_4(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002098 ver, key_data,
2099 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002100 }
2101 } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
2102 /* PeerKey SMK Handshake */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002103 peerkey_rx_eapol_smk(sm, src_addr, key, key_data_len, key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002104 ver);
2105 } else {
2106 if (key_info & WPA_KEY_INFO_MIC) {
2107 /* 1/2 Group Key Handshake */
2108 wpa_supplicant_process_1_of_2(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002109 key_data, key_data_len,
2110 ver);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002111 } else {
2112 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2113 "WPA: EAPOL-Key (Group) without Mic bit - "
2114 "dropped");
2115 }
2116 }
2117
2118 ret = 1;
2119
2120out:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002121 bin_clear_free(tmp, data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002122 return ret;
2123}
2124
2125
2126#ifdef CONFIG_CTRL_IFACE
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002127static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
2128{
2129 switch (sm->key_mgmt) {
2130 case WPA_KEY_MGMT_IEEE8021X:
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002131 return ((sm->proto == WPA_PROTO_RSN ||
2132 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002133 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
2134 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
2135 case WPA_KEY_MGMT_PSK:
2136 return (sm->proto == WPA_PROTO_RSN ?
2137 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
2138 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
2139#ifdef CONFIG_IEEE80211R
2140 case WPA_KEY_MGMT_FT_IEEE8021X:
2141 return RSN_AUTH_KEY_MGMT_FT_802_1X;
2142 case WPA_KEY_MGMT_FT_PSK:
2143 return RSN_AUTH_KEY_MGMT_FT_PSK;
2144#endif /* CONFIG_IEEE80211R */
2145#ifdef CONFIG_IEEE80211W
2146 case WPA_KEY_MGMT_IEEE8021X_SHA256:
2147 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
2148 case WPA_KEY_MGMT_PSK_SHA256:
2149 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
2150#endif /* CONFIG_IEEE80211W */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002151 case WPA_KEY_MGMT_CCKM:
2152 return (sm->proto == WPA_PROTO_RSN ?
2153 RSN_AUTH_KEY_MGMT_CCKM:
2154 WPA_AUTH_KEY_MGMT_CCKM);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002155 case WPA_KEY_MGMT_WPA_NONE:
2156 return WPA_AUTH_KEY_MGMT_NONE;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002157 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
2158 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002159 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
2160 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002161 default:
2162 return 0;
2163 }
2164}
2165
2166
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002167#define RSN_SUITE "%02x-%02x-%02x-%d"
2168#define RSN_SUITE_ARG(s) \
2169((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
2170
2171/**
2172 * wpa_sm_get_mib - Dump text list of MIB entries
2173 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2174 * @buf: Buffer for the list
2175 * @buflen: Length of the buffer
2176 * Returns: Number of bytes written to buffer
2177 *
2178 * This function is used fetch dot11 MIB variables.
2179 */
2180int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
2181{
2182 char pmkid_txt[PMKID_LEN * 2 + 1];
2183 int rsna, ret;
2184 size_t len;
2185
2186 if (sm->cur_pmksa) {
2187 wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
2188 sm->cur_pmksa->pmkid, PMKID_LEN);
2189 } else
2190 pmkid_txt[0] = '\0';
2191
2192 if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
2193 wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
2194 sm->proto == WPA_PROTO_RSN)
2195 rsna = 1;
2196 else
2197 rsna = 0;
2198
2199 ret = os_snprintf(buf, buflen,
2200 "dot11RSNAOptionImplemented=TRUE\n"
2201 "dot11RSNAPreauthenticationImplemented=TRUE\n"
2202 "dot11RSNAEnabled=%s\n"
2203 "dot11RSNAPreauthenticationEnabled=%s\n"
2204 "dot11RSNAConfigVersion=%d\n"
2205 "dot11RSNAConfigPairwiseKeysSupported=5\n"
2206 "dot11RSNAConfigGroupCipherSize=%d\n"
2207 "dot11RSNAConfigPMKLifetime=%d\n"
2208 "dot11RSNAConfigPMKReauthThreshold=%d\n"
2209 "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
2210 "dot11RSNAConfigSATimeout=%d\n",
2211 rsna ? "TRUE" : "FALSE",
2212 rsna ? "TRUE" : "FALSE",
2213 RSN_VERSION,
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002214 wpa_cipher_key_len(sm->group_cipher) * 8,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002215 sm->dot11RSNAConfigPMKLifetime,
2216 sm->dot11RSNAConfigPMKReauthThreshold,
2217 sm->dot11RSNAConfigSATimeout);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002218 if (os_snprintf_error(buflen, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002219 return 0;
2220 len = ret;
2221
2222 ret = os_snprintf(
2223 buf + len, buflen - len,
2224 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
2225 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
2226 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
2227 "dot11RSNAPMKIDUsed=%s\n"
2228 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
2229 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
2230 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
2231 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
2232 "dot11RSNA4WayHandshakeFailures=%u\n",
2233 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002234 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2235 sm->pairwise_cipher)),
2236 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2237 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002238 pmkid_txt,
2239 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002240 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2241 sm->pairwise_cipher)),
2242 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2243 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002244 sm->dot11RSNA4WayHandshakeFailures);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002245 if (!os_snprintf_error(buflen - len, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002246 len += ret;
2247
2248 return (int) len;
2249}
2250#endif /* CONFIG_CTRL_IFACE */
2251
2252
2253static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002254 void *ctx, enum pmksa_free_reason reason)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002255{
2256 struct wpa_sm *sm = ctx;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002257 int deauth = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002258
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002259 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: "
2260 MACSTR " reason=%d", MAC2STR(entry->aa), reason);
2261
2262 if (sm->cur_pmksa == entry) {
2263 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2264 "RSN: %s current PMKSA entry",
2265 reason == PMKSA_REPLACE ? "replaced" : "removed");
2266 pmksa_cache_clear_current(sm);
2267
2268 /*
2269 * If an entry is simply being replaced, there's no need to
2270 * deauthenticate because it will be immediately re-added.
2271 * This happens when EAP authentication is completed again
2272 * (reauth or failed PMKSA caching attempt).
2273 */
2274 if (reason != PMKSA_REPLACE)
2275 deauth = 1;
2276 }
2277
2278 if (reason == PMKSA_EXPIRE &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002279 (sm->pmk_len == entry->pmk_len &&
2280 os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
2281 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002282 "RSN: deauthenticating due to expired PMK");
2283 pmksa_cache_clear_current(sm);
2284 deauth = 1;
2285 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002286
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002287 if (deauth) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002288 os_memset(sm->pmk, 0, sizeof(sm->pmk));
2289 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
2290 }
2291}
2292
2293
2294/**
2295 * wpa_sm_init - Initialize WPA state machine
2296 * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
2297 * Returns: Pointer to the allocated WPA state machine data
2298 *
2299 * This function is used to allocate a new WPA state machine and the returned
2300 * value is passed to all WPA state machine calls.
2301 */
2302struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
2303{
2304 struct wpa_sm *sm;
2305
2306 sm = os_zalloc(sizeof(*sm));
2307 if (sm == NULL)
2308 return NULL;
2309 dl_list_init(&sm->pmksa_candidates);
2310 sm->renew_snonce = 1;
2311 sm->ctx = ctx;
2312
2313 sm->dot11RSNAConfigPMKLifetime = 43200;
2314 sm->dot11RSNAConfigPMKReauthThreshold = 70;
2315 sm->dot11RSNAConfigSATimeout = 60;
2316
2317 sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
2318 if (sm->pmksa == NULL) {
2319 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
2320 "RSN: PMKSA cache initialization failed");
2321 os_free(sm);
2322 return NULL;
2323 }
2324
2325 return sm;
2326}
2327
2328
2329/**
2330 * wpa_sm_deinit - Deinitialize WPA state machine
2331 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2332 */
2333void wpa_sm_deinit(struct wpa_sm *sm)
2334{
2335 if (sm == NULL)
2336 return;
2337 pmksa_cache_deinit(sm->pmksa);
2338 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2339 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
2340 os_free(sm->assoc_wpa_ie);
2341 os_free(sm->ap_wpa_ie);
2342 os_free(sm->ap_rsn_ie);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002343 wpa_sm_drop_sa(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002344 os_free(sm->ctx);
2345 peerkey_deinit(sm);
2346#ifdef CONFIG_IEEE80211R
2347 os_free(sm->assoc_resp_ies);
2348#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002349#ifdef CONFIG_TESTING_OPTIONS
2350 wpabuf_free(sm->test_assoc_ie);
2351#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002352 os_free(sm);
2353}
2354
2355
2356/**
2357 * wpa_sm_notify_assoc - Notify WPA state machine about association
2358 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2359 * @bssid: The BSSID of the new association
2360 *
2361 * This function is called to let WPA state machine know that the connection
2362 * was established.
2363 */
2364void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
2365{
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002366 int clear_keys = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002367
2368 if (sm == NULL)
2369 return;
2370
2371 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2372 "WPA: Association event - clear replay counter");
2373 os_memcpy(sm->bssid, bssid, ETH_ALEN);
2374 os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
2375 sm->rx_replay_counter_set = 0;
2376 sm->renew_snonce = 1;
2377 if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
2378 rsn_preauth_deinit(sm);
2379
2380#ifdef CONFIG_IEEE80211R
2381 if (wpa_ft_is_completed(sm)) {
2382 /*
2383 * Clear portValid to kick EAPOL state machine to re-enter
2384 * AUTHENTICATED state to get the EAPOL port Authorized.
2385 */
2386 eapol_sm_notify_portValid(sm->eapol, FALSE);
2387 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
2388
2389 /* Prepare for the next transition */
2390 wpa_ft_prepare_auth_request(sm, NULL);
2391
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002392 clear_keys = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002393 }
2394#endif /* CONFIG_IEEE80211R */
2395
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002396 if (clear_keys) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002397 /*
2398 * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
2399 * this is not part of a Fast BSS Transition.
2400 */
2401 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
2402 sm->ptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002403 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002404 sm->tptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002405 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002406 os_memset(&sm->gtk, 0, sizeof(sm->gtk));
Jouni Malineneac6bde2017-10-01 12:12:24 +03002407 os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002408#ifdef CONFIG_IEEE80211W
2409 os_memset(&sm->igtk, 0, sizeof(sm->igtk));
Jouni Malineneac6bde2017-10-01 12:12:24 +03002410 os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002411#endif /* CONFIG_IEEE80211W */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002412 }
2413
2414#ifdef CONFIG_TDLS
2415 wpa_tdls_assoc(sm);
2416#endif /* CONFIG_TDLS */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002417
2418#ifdef CONFIG_P2P
2419 os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
2420#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002421}
2422
2423
2424/**
2425 * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation
2426 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2427 *
2428 * This function is called to let WPA state machine know that the connection
2429 * was lost. This will abort any existing pre-authentication session.
2430 */
2431void wpa_sm_notify_disassoc(struct wpa_sm *sm)
2432{
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002433 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2434 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002435 peerkey_deinit(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002436 rsn_preauth_deinit(sm);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002437 pmksa_cache_clear_current(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002438 if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
2439 sm->dot11RSNA4WayHandshakeFailures++;
2440#ifdef CONFIG_TDLS
2441 wpa_tdls_disassoc(sm);
2442#endif /* CONFIG_TDLS */
Jouni Malinene01e4802017-09-22 12:06:37 +03002443#ifdef CONFIG_IEEE80211R
2444 sm->ft_reassoc_completed = 0;
2445#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002446 /* Keys are not needed in the WPA state machine anymore */
2447 wpa_sm_drop_sa(sm);
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002448
2449 sm->msg_3_of_4_ok = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002450}
2451
2452
2453/**
2454 * wpa_sm_set_pmk - Set PMK
2455 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2456 * @pmk: The new PMK
2457 * @pmk_len: The length of the new PMK in bytes
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002458 * @pmkid: Calculated PMKID
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002459 * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002460 *
2461 * Configure the PMK for WPA state machine.
2462 */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002463void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002464 const u8 *pmkid, const u8 *bssid)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002465{
2466 if (sm == NULL)
2467 return;
2468
2469 sm->pmk_len = pmk_len;
2470 os_memcpy(sm->pmk, pmk, pmk_len);
2471
2472#ifdef CONFIG_IEEE80211R
2473 /* Set XXKey to be PSK for FT key derivation */
2474 sm->xxkey_len = pmk_len;
2475 os_memcpy(sm->xxkey, pmk, pmk_len);
2476#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002477
2478 if (bssid) {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002479 pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002480 bssid, sm->own_addr,
2481 sm->network_ctx, sm->key_mgmt);
2482 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002483}
2484
2485
2486/**
2487 * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA
2488 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2489 *
2490 * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK
2491 * will be cleared.
2492 */
2493void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
2494{
2495 if (sm == NULL)
2496 return;
2497
2498 if (sm->cur_pmksa) {
2499 sm->pmk_len = sm->cur_pmksa->pmk_len;
2500 os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
2501 } else {
2502 sm->pmk_len = PMK_LEN;
2503 os_memset(sm->pmk, 0, PMK_LEN);
2504 }
2505}
2506
2507
2508/**
2509 * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled
2510 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2511 * @fast_reauth: Whether fast reauthentication (EAP) is allowed
2512 */
2513void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
2514{
2515 if (sm)
2516 sm->fast_reauth = fast_reauth;
2517}
2518
2519
2520/**
2521 * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks
2522 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2523 * @scard_ctx: Context pointer for smartcard related callback functions
2524 */
2525void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
2526{
2527 if (sm == NULL)
2528 return;
2529 sm->scard_ctx = scard_ctx;
2530 if (sm->preauth_eapol)
2531 eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
2532}
2533
2534
2535/**
2536 * wpa_sm_set_config - Notification of current configration change
2537 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2538 * @config: Pointer to current network configuration
2539 *
2540 * Notify WPA state machine that configuration has changed. config will be
2541 * stored as a backpointer to network configuration. This can be %NULL to clear
2542 * the stored pointed.
2543 */
2544void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
2545{
2546 if (!sm)
2547 return;
2548
2549 if (config) {
2550 sm->network_ctx = config->network_ctx;
2551 sm->peerkey_enabled = config->peerkey_enabled;
2552 sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
2553 sm->proactive_key_caching = config->proactive_key_caching;
2554 sm->eap_workaround = config->eap_workaround;
2555 sm->eap_conf_ctx = config->eap_conf_ctx;
2556 if (config->ssid) {
2557 os_memcpy(sm->ssid, config->ssid, config->ssid_len);
2558 sm->ssid_len = config->ssid_len;
2559 } else
2560 sm->ssid_len = 0;
2561 sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002562 sm->p2p = config->p2p;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002563 sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002564 } else {
2565 sm->network_ctx = NULL;
2566 sm->peerkey_enabled = 0;
2567 sm->allowed_pairwise_cipher = 0;
2568 sm->proactive_key_caching = 0;
2569 sm->eap_workaround = 0;
2570 sm->eap_conf_ctx = NULL;
2571 sm->ssid_len = 0;
2572 sm->wpa_ptk_rekey = 0;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002573 sm->p2p = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002574 sm->wpa_rsc_relaxation = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002575 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002576}
2577
2578
2579/**
2580 * wpa_sm_set_own_addr - Set own MAC address
2581 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2582 * @addr: Own MAC address
2583 */
2584void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
2585{
2586 if (sm)
2587 os_memcpy(sm->own_addr, addr, ETH_ALEN);
2588}
2589
2590
2591/**
2592 * wpa_sm_set_ifname - Set network interface name
2593 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2594 * @ifname: Interface name
2595 * @bridge_ifname: Optional bridge interface name (for pre-auth)
2596 */
2597void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
2598 const char *bridge_ifname)
2599{
2600 if (sm) {
2601 sm->ifname = ifname;
2602 sm->bridge_ifname = bridge_ifname;
2603 }
2604}
2605
2606
2607/**
2608 * wpa_sm_set_eapol - Set EAPOL state machine pointer
2609 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2610 * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init()
2611 */
2612void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
2613{
2614 if (sm)
2615 sm->eapol = eapol;
2616}
2617
2618
2619/**
2620 * wpa_sm_set_param - Set WPA state machine parameters
2621 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2622 * @param: Parameter field
2623 * @value: Parameter value
2624 * Returns: 0 on success, -1 on failure
2625 */
2626int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
2627 unsigned int value)
2628{
2629 int ret = 0;
2630
2631 if (sm == NULL)
2632 return -1;
2633
2634 switch (param) {
2635 case RSNA_PMK_LIFETIME:
2636 if (value > 0)
2637 sm->dot11RSNAConfigPMKLifetime = value;
2638 else
2639 ret = -1;
2640 break;
2641 case RSNA_PMK_REAUTH_THRESHOLD:
2642 if (value > 0 && value <= 100)
2643 sm->dot11RSNAConfigPMKReauthThreshold = value;
2644 else
2645 ret = -1;
2646 break;
2647 case RSNA_SA_TIMEOUT:
2648 if (value > 0)
2649 sm->dot11RSNAConfigSATimeout = value;
2650 else
2651 ret = -1;
2652 break;
2653 case WPA_PARAM_PROTO:
2654 sm->proto = value;
2655 break;
2656 case WPA_PARAM_PAIRWISE:
2657 sm->pairwise_cipher = value;
2658 break;
2659 case WPA_PARAM_GROUP:
2660 sm->group_cipher = value;
2661 break;
2662 case WPA_PARAM_KEY_MGMT:
2663 sm->key_mgmt = value;
2664 break;
2665#ifdef CONFIG_IEEE80211W
2666 case WPA_PARAM_MGMT_GROUP:
2667 sm->mgmt_group_cipher = value;
2668 break;
2669#endif /* CONFIG_IEEE80211W */
2670 case WPA_PARAM_RSN_ENABLED:
2671 sm->rsn_enabled = value;
2672 break;
2673 case WPA_PARAM_MFP:
2674 sm->mfp = value;
2675 break;
2676 default:
2677 break;
2678 }
2679
2680 return ret;
2681}
2682
2683
2684/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002685 * wpa_sm_get_status - Get WPA state machine
2686 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2687 * @buf: Buffer for status information
2688 * @buflen: Maximum buffer length
2689 * @verbose: Whether to include verbose status information
2690 * Returns: Number of bytes written to buf.
2691 *
2692 * Query WPA state machine for status information. This function fills in
2693 * a text area with current status information. If the buffer (buf) is not
2694 * large enough, status information will be truncated to fit the buffer.
2695 */
2696int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
2697 int verbose)
2698{
2699 char *pos = buf, *end = buf + buflen;
2700 int ret;
2701
2702 ret = os_snprintf(pos, end - pos,
2703 "pairwise_cipher=%s\n"
2704 "group_cipher=%s\n"
2705 "key_mgmt=%s\n",
2706 wpa_cipher_txt(sm->pairwise_cipher),
2707 wpa_cipher_txt(sm->group_cipher),
2708 wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002709 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002710 return pos - buf;
2711 pos += ret;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002712
2713 if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
2714 struct wpa_ie_data rsn;
2715 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
2716 >= 0 &&
2717 rsn.capabilities & (WPA_CAPABILITY_MFPR |
2718 WPA_CAPABILITY_MFPC)) {
2719 ret = os_snprintf(pos, end - pos, "pmf=%d\n",
2720 (rsn.capabilities &
2721 WPA_CAPABILITY_MFPR) ? 2 : 1);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002722 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002723 return pos - buf;
2724 pos += ret;
2725 }
2726 }
2727
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002728 return pos - buf;
2729}
2730
2731
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07002732int wpa_sm_pmf_enabled(struct wpa_sm *sm)
2733{
2734 struct wpa_ie_data rsn;
2735
2736 if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
2737 return 0;
2738
2739 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
2740 rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
2741 return 1;
2742
2743 return 0;
2744}
2745
2746
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002747/**
2748 * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration
2749 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2750 * @wpa_ie: Pointer to buffer for WPA/RSN IE
2751 * @wpa_ie_len: Pointer to the length of the wpa_ie buffer
2752 * Returns: 0 on success, -1 on failure
2753 */
2754int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
2755 size_t *wpa_ie_len)
2756{
2757 int res;
2758
2759 if (sm == NULL)
2760 return -1;
2761
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002762#ifdef CONFIG_TESTING_OPTIONS
2763 if (sm->test_assoc_ie) {
2764 wpa_printf(MSG_DEBUG,
2765 "TESTING: Replace association WPA/RSN IE");
2766 if (*wpa_ie_len < wpabuf_len(sm->test_assoc_ie))
2767 return -1;
2768 os_memcpy(wpa_ie, wpabuf_head(sm->test_assoc_ie),
2769 wpabuf_len(sm->test_assoc_ie));
2770 res = wpabuf_len(sm->test_assoc_ie);
2771 } else
2772#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002773 res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
2774 if (res < 0)
2775 return -1;
2776 *wpa_ie_len = res;
2777
2778 wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
2779 wpa_ie, *wpa_ie_len);
2780
2781 if (sm->assoc_wpa_ie == NULL) {
2782 /*
2783 * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
2784 * the correct version of the IE even if PMKSA caching is
2785 * aborted (which would remove PMKID from IE generation).
2786 */
2787 sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
2788 if (sm->assoc_wpa_ie == NULL)
2789 return -1;
2790
2791 os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
2792 sm->assoc_wpa_ie_len = *wpa_ie_len;
2793 }
2794
2795 return 0;
2796}
2797
2798
2799/**
2800 * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq
2801 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2802 * @ie: Pointer to IE data (starting from id)
2803 * @len: IE length
2804 * Returns: 0 on success, -1 on failure
2805 *
2806 * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
2807 * Request frame. The IE will be used to override the default value generated
2808 * with wpa_sm_set_assoc_wpa_ie_default().
2809 */
2810int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2811{
2812 if (sm == NULL)
2813 return -1;
2814
2815 os_free(sm->assoc_wpa_ie);
2816 if (ie == NULL || len == 0) {
2817 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2818 "WPA: clearing own WPA/RSN IE");
2819 sm->assoc_wpa_ie = NULL;
2820 sm->assoc_wpa_ie_len = 0;
2821 } else {
2822 wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
2823 sm->assoc_wpa_ie = os_malloc(len);
2824 if (sm->assoc_wpa_ie == NULL)
2825 return -1;
2826
2827 os_memcpy(sm->assoc_wpa_ie, ie, len);
2828 sm->assoc_wpa_ie_len = len;
2829 }
2830
2831 return 0;
2832}
2833
2834
2835/**
2836 * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
2837 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2838 * @ie: Pointer to IE data (starting from id)
2839 * @len: IE length
2840 * Returns: 0 on success, -1 on failure
2841 *
2842 * Inform WPA state machine about the WPA IE used in Beacon / Probe Response
2843 * frame.
2844 */
2845int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2846{
2847 if (sm == NULL)
2848 return -1;
2849
2850 os_free(sm->ap_wpa_ie);
2851 if (ie == NULL || len == 0) {
2852 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2853 "WPA: clearing AP WPA IE");
2854 sm->ap_wpa_ie = NULL;
2855 sm->ap_wpa_ie_len = 0;
2856 } else {
2857 wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
2858 sm->ap_wpa_ie = os_malloc(len);
2859 if (sm->ap_wpa_ie == NULL)
2860 return -1;
2861
2862 os_memcpy(sm->ap_wpa_ie, ie, len);
2863 sm->ap_wpa_ie_len = len;
2864 }
2865
2866 return 0;
2867}
2868
2869
2870/**
2871 * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
2872 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2873 * @ie: Pointer to IE data (starting from id)
2874 * @len: IE length
2875 * Returns: 0 on success, -1 on failure
2876 *
2877 * Inform WPA state machine about the RSN IE used in Beacon / Probe Response
2878 * frame.
2879 */
2880int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2881{
2882 if (sm == NULL)
2883 return -1;
2884
2885 os_free(sm->ap_rsn_ie);
2886 if (ie == NULL || len == 0) {
2887 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2888 "WPA: clearing AP RSN IE");
2889 sm->ap_rsn_ie = NULL;
2890 sm->ap_rsn_ie_len = 0;
2891 } else {
2892 wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
2893 sm->ap_rsn_ie = os_malloc(len);
2894 if (sm->ap_rsn_ie == NULL)
2895 return -1;
2896
2897 os_memcpy(sm->ap_rsn_ie, ie, len);
2898 sm->ap_rsn_ie_len = len;
2899 }
2900
2901 return 0;
2902}
2903
2904
2905/**
2906 * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
2907 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2908 * @data: Pointer to data area for parsing results
2909 * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure
2910 *
2911 * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the
2912 * parsed data into data.
2913 */
2914int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
2915{
2916 if (sm == NULL)
2917 return -1;
2918
2919 if (sm->assoc_wpa_ie == NULL) {
2920 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2921 "WPA: No WPA/RSN IE available from association info");
2922 return -1;
2923 }
2924 if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
2925 return -2;
2926 return 0;
2927}
2928
2929
2930int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
2931{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002932 return pmksa_cache_list(sm->pmksa, buf, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002933}
2934
2935
2936void wpa_sm_drop_sa(struct wpa_sm *sm)
2937{
2938 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
2939 sm->ptk_set = 0;
2940 sm->tptk_set = 0;
2941 os_memset(sm->pmk, 0, sizeof(sm->pmk));
2942 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
2943 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002944 os_memset(&sm->gtk, 0, sizeof(sm->gtk));
Jouni Malineneac6bde2017-10-01 12:12:24 +03002945 os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002946#ifdef CONFIG_IEEE80211W
2947 os_memset(&sm->igtk, 0, sizeof(sm->igtk));
Jouni Malineneac6bde2017-10-01 12:12:24 +03002948 os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02002949#endif /* CONFIG_IEEE80211W */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002950#ifdef CONFIG_IEEE80211R
2951 os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
2952 os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
2953 os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1));
2954#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002955}
2956
2957
2958int wpa_sm_has_ptk(struct wpa_sm *sm)
2959{
2960 if (sm == NULL)
2961 return 0;
2962 return sm->ptk_set;
2963}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002964
2965
2966void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
2967{
2968 os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
2969}
2970
2971
2972void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
2973{
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07002974 pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002975}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002976
2977
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002978#ifdef CONFIG_WNM
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002979int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
2980{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002981 u16 keyinfo;
2982 u8 keylen; /* plaintext key len */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002983 u8 *key_rsc;
2984
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002985 if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002986 struct wpa_gtk_data gd;
2987
2988 os_memset(&gd, 0, sizeof(gd));
2989 keylen = wpa_cipher_key_len(sm->group_cipher);
2990 gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
2991 gd.alg = wpa_cipher_to_alg(sm->group_cipher);
2992 if (gd.alg == WPA_ALG_NONE) {
2993 wpa_printf(MSG_DEBUG, "Unsupported group cipher suite");
2994 return -1;
2995 }
2996
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002997 key_rsc = buf + 5;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002998 keyinfo = WPA_GET_LE16(buf + 2);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002999 gd.gtk_len = keylen;
3000 if (gd.gtk_len != buf[4]) {
3001 wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
3002 gd.gtk_len, buf[4]);
3003 return -1;
3004 }
3005 gd.keyidx = keyinfo & 0x03; /* B0 - B1 */
3006 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
3007 sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
3008
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003009 os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003010
3011 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
3012 gd.gtk, gd.gtk_len);
Jouni Malineneac6bde2017-10-01 12:12:24 +03003013 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003014 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003015 wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
3016 "WNM mode");
3017 return -1;
3018 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003019 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003020#ifdef CONFIG_IEEE80211W
3021 } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02003022 const struct wpa_igtk_kde *igtk;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003023
Mathy Vanhoef480c21c2017-07-12 16:03:24 +02003024 igtk = (const struct wpa_igtk_kde *) (buf + 2);
Jouni Malineneac6bde2017-10-01 12:12:24 +03003025 if (wpa_supplicant_install_igtk(sm, igtk, 1) < 0)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003026 return -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003027#endif /* CONFIG_IEEE80211W */
3028 } else {
3029 wpa_printf(MSG_DEBUG, "Unknown element id");
3030 return -1;
3031 }
3032
3033 return 0;
3034}
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003035#endif /* CONFIG_WNM */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003036
3037
3038#ifdef CONFIG_PEERKEY
3039int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
3040 const u8 *buf, size_t len)
3041{
3042 struct wpa_peerkey *peerkey;
3043
3044 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
3045 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
3046 break;
3047 }
3048
3049 if (!peerkey)
3050 return 0;
3051
3052 wpa_sm_rx_eapol(sm, src_addr, buf, len);
3053
3054 return 1;
3055}
3056#endif /* CONFIG_PEERKEY */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08003057
3058
3059#ifdef CONFIG_P2P
3060
3061int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)
3062{
3063 if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0)
3064 return -1;
3065 os_memcpy(buf, sm->p2p_ip_addr, 3 * 4);
3066 return 0;
3067}
3068
3069#endif /* CONFIG_P2P */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003070
3071
3072void wpa_sm_set_rx_replay_ctr(struct wpa_sm *sm, const u8 *rx_replay_counter)
3073{
3074 if (rx_replay_counter == NULL)
3075 return;
3076
3077 os_memcpy(sm->rx_replay_counter, rx_replay_counter,
3078 WPA_REPLAY_COUNTER_LEN);
3079 sm->rx_replay_counter_set = 1;
3080 wpa_printf(MSG_DEBUG, "Updated key replay counter");
3081}
3082
3083
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003084void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
3085 const u8 *ptk_kck, size_t ptk_kck_len,
3086 const u8 *ptk_kek, size_t ptk_kek_len)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003087{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003088 if (ptk_kck && ptk_kck_len <= WPA_KCK_MAX_LEN) {
3089 os_memcpy(sm->ptk.kck, ptk_kck, ptk_kck_len);
3090 sm->ptk.kck_len = ptk_kck_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003091 wpa_printf(MSG_DEBUG, "Updated PTK KCK");
3092 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003093 if (ptk_kek && ptk_kek_len <= WPA_KEK_MAX_LEN) {
3094 os_memcpy(sm->ptk.kek, ptk_kek, ptk_kek_len);
3095 sm->ptk.kek_len = ptk_kek_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003096 wpa_printf(MSG_DEBUG, "Updated PTK KEK");
3097 }
3098 sm->ptk_set = 1;
3099}
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08003100
3101
3102#ifdef CONFIG_TESTING_OPTIONS
3103void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf)
3104{
3105 wpabuf_free(sm->test_assoc_ie);
3106 sm->test_assoc_ie = buf;
3107}
3108#endif /* CONFIG_TESTING_OPTIONS */