blob: 1fa2783d8c98c6283d374fac880d204a2a72024f [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * WPA Supplicant - WPA state machine and EAPOL-Key processing
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003 * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004 * Copyright(c) 2015 Intel Deutschland GmbH
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08006 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07008 */
9
10#include "includes.h"
11
12#include "common.h"
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080013#include "crypto/aes.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070014#include "crypto/aes_wrap.h"
15#include "crypto/crypto.h"
16#include "crypto/random.h"
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080017#include "crypto/aes_siv.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070018#include "common/ieee802_11_defs.h"
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080019#include "common/ieee802_11_common.h"
Paul Stewart092955c2017-02-06 09:13:09 -080020#include "eap_common/eap_defs.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070021#include "eapol_supp/eapol_supp_sm.h"
22#include "wpa.h"
23#include "eloop.h"
24#include "preauth.h"
25#include "pmksa_cache.h"
26#include "wpa_i.h"
27#include "wpa_ie.h"
28#include "peerkey.h"
29
30
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080031static const u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
32
33
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070034/**
35 * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message
36 * @sm: Pointer to WPA state machine data from wpa_sm_init()
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080037 * @ptk: PTK for Key Confirmation/Encryption Key
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070038 * @ver: Version field from Key Info
39 * @dest: Destination address for the frame
40 * @proto: Ethertype (usually ETH_P_EAPOL)
41 * @msg: EAPOL-Key message
42 * @msg_len: Length of message
43 * @key_mic: Pointer to the buffer to which the EAPOL-Key MIC is written
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080044 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070045 */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080046int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080047 int ver, const u8 *dest, u16 proto,
48 u8 *msg, size_t msg_len, u8 *key_mic)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070049{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080050 int ret = -1;
Dmitry Shmidt807291d2015-01-27 13:40:23 -080051 size_t mic_len = wpa_mic_len(sm->key_mgmt);
52
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070053 if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
54 /*
55 * Association event was not yet received; try to fetch
56 * BSSID from the driver.
57 */
58 if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
59 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
60 "WPA: Failed to read BSSID for "
61 "EAPOL-Key destination address");
62 } else {
63 dest = sm->bssid;
64 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
65 "WPA: Use BSSID (" MACSTR
66 ") as the destination for EAPOL-Key",
67 MAC2STR(dest));
68 }
69 }
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080070
71 if (mic_len) {
72 if (key_mic && (!ptk || !ptk->kck_len))
73 goto out;
74
75 if (key_mic &&
76 wpa_eapol_key_mic(ptk->kck, ptk->kck_len, sm->key_mgmt, ver,
77 msg, msg_len, key_mic)) {
78 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
79 "WPA: Failed to generate EAPOL-Key version %d key_mgmt 0x%x MIC",
80 ver, sm->key_mgmt);
81 goto out;
82 }
Dmitry Shmidt29333592017-01-09 12:27:11 -080083 if (ptk)
84 wpa_hexdump_key(MSG_DEBUG, "WPA: KCK",
85 ptk->kck, ptk->kck_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -080086 wpa_hexdump(MSG_DEBUG, "WPA: Derived Key MIC",
87 key_mic, mic_len);
88 } else {
89#ifdef CONFIG_FILS
90 /* AEAD cipher - Key MIC field not used */
91 struct ieee802_1x_hdr *s_hdr, *hdr;
92 struct wpa_eapol_key *s_key, *key;
93 u8 *buf, *s_key_data, *key_data;
94 size_t buf_len = msg_len + AES_BLOCK_SIZE;
95 size_t key_data_len;
96 u16 eapol_len;
97 const u8 *aad[1];
98 size_t aad_len[1];
99
100 if (!ptk || !ptk->kek_len)
101 goto out;
102
103 key_data_len = msg_len - sizeof(struct ieee802_1x_hdr) -
104 sizeof(struct wpa_eapol_key) - 2;
105
106 buf = os_malloc(buf_len);
107 if (!buf)
108 goto out;
109
110 os_memcpy(buf, msg, msg_len);
111 hdr = (struct ieee802_1x_hdr *) buf;
112 key = (struct wpa_eapol_key *) (hdr + 1);
113 key_data = ((u8 *) (key + 1)) + 2;
114
115 /* Update EAPOL header to include AES-SIV overhead */
116 eapol_len = be_to_host16(hdr->length);
117 eapol_len += AES_BLOCK_SIZE;
118 hdr->length = host_to_be16(eapol_len);
119
120 /* Update Key Data Length field to include AES-SIV overhead */
121 WPA_PUT_BE16((u8 *) (key + 1), AES_BLOCK_SIZE + key_data_len);
122
123 s_hdr = (struct ieee802_1x_hdr *) msg;
124 s_key = (struct wpa_eapol_key *) (s_hdr + 1);
125 s_key_data = ((u8 *) (s_key + 1)) + 2;
126
127 wpa_hexdump_key(MSG_DEBUG, "WPA: Plaintext Key Data",
128 s_key_data, key_data_len);
129
130 wpa_hexdump_key(MSG_DEBUG, "WPA: KEK", ptk->kek, ptk->kek_len);
131 /* AES-SIV AAD from EAPOL protocol version field (inclusive) to
132 * to Key Data (exclusive). */
133 aad[0] = buf;
134 aad_len[0] = key_data - buf;
135 if (aes_siv_encrypt(ptk->kek, ptk->kek_len,
136 s_key_data, key_data_len,
137 1, aad, aad_len, key_data) < 0) {
138 os_free(buf);
139 goto out;
140 }
141
142 wpa_hexdump(MSG_DEBUG, "WPA: Encrypted Key Data from SIV",
143 key_data, AES_BLOCK_SIZE + key_data_len);
144
145 os_free(msg);
146 msg = buf;
147 msg_len = buf_len;
148#else /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700149 goto out;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800150#endif /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700151 }
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800152
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700153 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800154 ret = wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700155 eapol_sm_notify_tx_eapol_key(sm->eapol);
156out:
157 os_free(msg);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800158 return ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700159}
160
161
162/**
163 * wpa_sm_key_request - Send EAPOL-Key Request
164 * @sm: Pointer to WPA state machine data from wpa_sm_init()
165 * @error: Indicate whether this is an Michael MIC error report
166 * @pairwise: 1 = error report for pairwise packet, 0 = for group packet
167 *
168 * Send an EAPOL-Key Request to the current authenticator. This function is
169 * used to request rekeying and it is usually called when a local Michael MIC
170 * failure is detected.
171 */
172void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
173{
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800174 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700175 struct wpa_eapol_key *reply;
176 int key_info, ver;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800177 u8 bssid[ETH_ALEN], *rbuf, *key_mic, *mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700178
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800179 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
180 wpa_key_mgmt_suite_b(sm->key_mgmt))
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800181 ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
182 else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
183 wpa_key_mgmt_sha256(sm->key_mgmt))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700184 ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700185 else if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700186 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
187 else
188 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
189
190 if (wpa_sm_get_bssid(sm, bssid) < 0) {
191 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
192 "Failed to read BSSID for EAPOL-Key request");
193 return;
194 }
195
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800196 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800197 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700198 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800199 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700200 if (rbuf == NULL)
201 return;
202
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800203 reply->type = (sm->proto == WPA_PROTO_RSN ||
204 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700205 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
206 key_info = WPA_KEY_INFO_REQUEST | ver;
207 if (sm->ptk_set)
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800208 key_info |= WPA_KEY_INFO_SECURE;
209 if (sm->ptk_set && mic_len)
210 key_info |= WPA_KEY_INFO_MIC;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700211 if (error)
212 key_info |= WPA_KEY_INFO_ERROR;
213 if (pairwise)
214 key_info |= WPA_KEY_INFO_KEY_TYPE;
215 WPA_PUT_BE16(reply->key_info, key_info);
216 WPA_PUT_BE16(reply->key_length, 0);
217 os_memcpy(reply->replay_counter, sm->request_counter,
218 WPA_REPLAY_COUNTER_LEN);
219 inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
220
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800221 mic = (u8 *) (reply + 1);
222 WPA_PUT_BE16(mic + mic_len, 0);
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800223 if (!(key_info & WPA_KEY_INFO_MIC))
224 key_mic = NULL;
225 else
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800226 key_mic = mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700227
228 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
229 "WPA: Sending EAPOL-Key Request (error=%d "
230 "pairwise=%d ptk_set=%d len=%lu)",
231 error, pairwise, sm->ptk_set, (unsigned long) rlen);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800232 wpa_eapol_key_send(sm, &sm->ptk, ver, bssid, ETH_P_EAPOL, rbuf, rlen,
233 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700234}
235
236
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800237static void wpa_supplicant_key_mgmt_set_pmk(struct wpa_sm *sm)
238{
239#ifdef CONFIG_IEEE80211R
240 if (sm->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
241 if (wpa_sm_key_mgmt_set_pmk(sm, sm->xxkey, sm->xxkey_len))
242 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
243 "RSN: Cannot set low order 256 bits of MSK for key management offload");
244 } else {
245#endif /* CONFIG_IEEE80211R */
246 if (wpa_sm_key_mgmt_set_pmk(sm, sm->pmk, sm->pmk_len))
247 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
248 "RSN: Cannot set PMK for key management offload");
249#ifdef CONFIG_IEEE80211R
250 }
251#endif /* CONFIG_IEEE80211R */
252}
253
254
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700255static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
256 const unsigned char *src_addr,
257 const u8 *pmkid)
258{
259 int abort_cached = 0;
260
261 if (pmkid && !sm->cur_pmksa) {
262 /* When using drivers that generate RSN IE, wpa_supplicant may
263 * not have enough time to get the association information
264 * event before receiving this 1/4 message, so try to find a
265 * matching PMKSA cache entry here. */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800266 sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
267 NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700268 if (sm->cur_pmksa) {
269 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
270 "RSN: found matching PMKID from PMKSA cache");
271 } else {
272 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
273 "RSN: no matching PMKID found");
274 abort_cached = 1;
275 }
276 }
277
278 if (pmkid && sm->cur_pmksa &&
Dmitry Shmidtc2817022014-07-02 10:32:10 -0700279 os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700280 wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
281 wpa_sm_set_pmk_from_pmksa(sm);
282 wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
283 sm->pmk, sm->pmk_len);
284 eapol_sm_notify_cached(sm->eapol);
285#ifdef CONFIG_IEEE80211R
286 sm->xxkey_len = 0;
287#endif /* CONFIG_IEEE80211R */
288 } else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
289 int res, pmk_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800290
Dmitry Shmidtebd93af2017-02-21 13:40:44 -0800291 if (wpa_key_mgmt_sha384(sm->key_mgmt))
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800292 pmk_len = PMK_LEN_SUITE_B_192;
293 else
294 pmk_len = PMK_LEN;
295 res = eapol_sm_get_key(sm->eapol, sm->pmk, pmk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700296 if (res) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800297 if (pmk_len == PMK_LEN) {
298 /*
299 * EAP-LEAP is an exception from other EAP
300 * methods: it uses only 16-byte PMK.
301 */
302 res = eapol_sm_get_key(sm->eapol, sm->pmk, 16);
303 pmk_len = 16;
304 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700305 } else {
306#ifdef CONFIG_IEEE80211R
307 u8 buf[2 * PMK_LEN];
308 if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
309 {
310 os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
311 sm->xxkey_len = PMK_LEN;
312 os_memset(buf, 0, sizeof(buf));
313 }
314#endif /* CONFIG_IEEE80211R */
315 }
316 if (res == 0) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700317 struct rsn_pmksa_cache_entry *sa = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700318 wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
319 "machines", sm->pmk, pmk_len);
320 sm->pmk_len = pmk_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800321 wpa_supplicant_key_mgmt_set_pmk(sm);
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700322 if (sm->proto == WPA_PROTO_RSN &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800323 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700324 !wpa_key_mgmt_ft(sm->key_mgmt)) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700325 sa = pmksa_cache_add(sm->pmksa,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800326 sm->pmk, pmk_len, NULL,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800327 NULL, 0,
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700328 src_addr, sm->own_addr,
329 sm->network_ctx,
330 sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700331 }
332 if (!sm->cur_pmksa && pmkid &&
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800333 pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
334 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700335 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
336 "RSN: the new PMK matches with the "
337 "PMKID");
338 abort_cached = 0;
Jouni Malinen6ec30382015-07-08 20:48:18 +0300339 } else if (sa && !sm->cur_pmksa && pmkid) {
340 /*
341 * It looks like the authentication server
342 * derived mismatching MSK. This should not
343 * really happen, but bugs happen.. There is not
344 * much we can do here without knowing what
345 * exactly caused the server to misbehave.
346 */
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -0800347 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
Jouni Malinen6ec30382015-07-08 20:48:18 +0300348 "RSN: PMKID mismatch - authentication server may have derived different MSK?!");
349 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700350 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700351
352 if (!sm->cur_pmksa)
353 sm->cur_pmksa = sa;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700354 } else {
355 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
356 "WPA: Failed to get master session key from "
357 "EAPOL state machines - key handshake "
358 "aborted");
359 if (sm->cur_pmksa) {
360 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
361 "RSN: Cancelled PMKSA caching "
362 "attempt");
363 sm->cur_pmksa = NULL;
364 abort_cached = 1;
365 } else if (!abort_cached) {
366 return -1;
367 }
368 }
369 }
370
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700371 if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800372 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800373 !wpa_key_mgmt_ft(sm->key_mgmt) && sm->key_mgmt != WPA_KEY_MGMT_OSEN)
374 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700375 /* Send EAPOL-Start to trigger full EAP authentication. */
376 u8 *buf;
377 size_t buflen;
378
379 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
380 "RSN: no PMKSA entry found - trigger "
381 "full EAP authentication");
382 buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
383 NULL, 0, &buflen, NULL);
384 if (buf) {
385 wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
386 buf, buflen);
387 os_free(buf);
388 return -2;
389 }
390
391 return -1;
392 }
393
394 return 0;
395}
396
397
398/**
399 * wpa_supplicant_send_2_of_4 - Send message 2 of WPA/RSN 4-Way Handshake
400 * @sm: Pointer to WPA state machine data from wpa_sm_init()
401 * @dst: Destination address for the frame
402 * @key: Pointer to the EAPOL-Key frame header
403 * @ver: Version bits from EAPOL-Key Key Info
404 * @nonce: Nonce value for the EAPOL-Key frame
405 * @wpa_ie: WPA/RSN IE
406 * @wpa_ie_len: Length of the WPA/RSN IE
407 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800408 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700409 */
410int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
411 const struct wpa_eapol_key *key,
412 int ver, const u8 *nonce,
413 const u8 *wpa_ie, size_t wpa_ie_len,
414 struct wpa_ptk *ptk)
415{
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800416 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700417 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800418 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700419 u8 *rsn_ie_buf = NULL;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800420 u16 key_info;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700421
422 if (wpa_ie == NULL) {
423 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No wpa_ie set - "
424 "cannot generate msg 2/4");
425 return -1;
426 }
427
428#ifdef CONFIG_IEEE80211R
429 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
430 int res;
431
432 /*
433 * Add PMKR1Name into RSN IE (PMKID-List) and add MDIE and
434 * FTIE from (Re)Association Response.
435 */
436 rsn_ie_buf = os_malloc(wpa_ie_len + 2 + 2 + PMKID_LEN +
437 sm->assoc_resp_ies_len);
438 if (rsn_ie_buf == NULL)
439 return -1;
440 os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800441 res = wpa_insert_pmkid(rsn_ie_buf, &wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700442 sm->pmk_r1_name);
443 if (res < 0) {
444 os_free(rsn_ie_buf);
445 return -1;
446 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700447
448 if (sm->assoc_resp_ies) {
449 os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
450 sm->assoc_resp_ies_len);
451 wpa_ie_len += sm->assoc_resp_ies_len;
452 }
453
454 wpa_ie = rsn_ie_buf;
455 }
456#endif /* CONFIG_IEEE80211R */
457
458 wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
459
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800460 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800461 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700462 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800463 NULL, hdrlen + wpa_ie_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700464 &rlen, (void *) &reply);
465 if (rbuf == NULL) {
466 os_free(rsn_ie_buf);
467 return -1;
468 }
469
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800470 reply->type = (sm->proto == WPA_PROTO_RSN ||
471 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700472 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800473 key_info = ver | WPA_KEY_INFO_KEY_TYPE;
474 if (mic_len)
475 key_info |= WPA_KEY_INFO_MIC;
476 else
477 key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
478 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800479 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700480 WPA_PUT_BE16(reply->key_length, 0);
481 else
482 os_memcpy(reply->key_length, key->key_length, 2);
483 os_memcpy(reply->replay_counter, key->replay_counter,
484 WPA_REPLAY_COUNTER_LEN);
485 wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
486 WPA_REPLAY_COUNTER_LEN);
487
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800488 key_mic = (u8 *) (reply + 1);
489 WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len); /* Key Data Length */
490 os_memcpy(key_mic + mic_len + 2, wpa_ie, wpa_ie_len); /* Key Data */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700491 os_free(rsn_ie_buf);
492
493 os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
494
495 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800496 return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen,
497 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700498}
499
500
501static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800502 const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700503{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700504#ifdef CONFIG_IEEE80211R
505 if (wpa_key_mgmt_ft(sm->key_mgmt))
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800506 return wpa_derive_ptk_ft(sm, src_addr, key, ptk);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700507#endif /* CONFIG_IEEE80211R */
508
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800509 return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
510 sm->own_addr, sm->bssid, sm->snonce,
511 key->key_nonce, ptk, sm->key_mgmt,
512 sm->pairwise_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700513}
514
515
516static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
517 const unsigned char *src_addr,
518 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700519 u16 ver, const u8 *key_data,
520 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700521{
522 struct wpa_eapol_ie_parse ie;
523 struct wpa_ptk *ptk;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700524 int res;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800525 u8 *kde, *kde_buf = NULL;
526 size_t kde_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700527
528 if (wpa_sm_get_network_ctx(sm) == NULL) {
529 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
530 "found (msg 1 of 4)");
531 return;
532 }
533
534 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
535 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
536 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
537
538 os_memset(&ie, 0, sizeof(ie));
539
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800540 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700541 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700542 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
543 key_data, key_data_len);
544 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800545 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700546 if (ie.pmkid) {
547 wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
548 "Authenticator", ie.pmkid, PMKID_LEN);
549 }
550 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700551
552 res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
553 if (res == -2) {
554 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
555 "msg 1/4 - requesting full EAP authentication");
556 return;
557 }
558 if (res)
559 goto failed;
560
561 if (sm->renew_snonce) {
562 if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
563 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
564 "WPA: Failed to get random data for SNonce");
565 goto failed;
566 }
567 sm->renew_snonce = 0;
568 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
569 sm->snonce, WPA_NONCE_LEN);
570 }
571
572 /* Calculate PTK which will be stored as a temporary PTK until it has
573 * been verified when processing message 3/4. */
574 ptk = &sm->tptk;
575 wpa_derive_ptk(sm, src_addr, key, ptk);
Dmitry Shmidt98660862014-03-11 17:26:21 -0700576 if (sm->pairwise_cipher == WPA_CIPHER_TKIP) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700577 u8 buf[8];
Dmitry Shmidt98660862014-03-11 17:26:21 -0700578 /* Supplicant: swap tx/rx Mic keys */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800579 os_memcpy(buf, &ptk->tk[16], 8);
580 os_memcpy(&ptk->tk[16], &ptk->tk[24], 8);
581 os_memcpy(&ptk->tk[24], buf, 8);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700582 os_memset(buf, 0, sizeof(buf));
Dmitry Shmidt98660862014-03-11 17:26:21 -0700583 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700584 sm->tptk_set = 1;
585
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800586 kde = sm->assoc_wpa_ie;
587 kde_len = sm->assoc_wpa_ie_len;
588
589#ifdef CONFIG_P2P
590 if (sm->p2p) {
591 kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
592 if (kde_buf) {
593 u8 *pos;
594 wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
595 "into EAPOL-Key 2/4");
596 os_memcpy(kde_buf, kde, kde_len);
597 kde = kde_buf;
598 pos = kde + kde_len;
599 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
600 *pos++ = RSN_SELECTOR_LEN + 1;
601 RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_IP_ADDR_REQ);
602 pos += RSN_SELECTOR_LEN;
603 *pos++ = 0x01;
604 kde_len = pos - kde;
605 }
606 }
607#endif /* CONFIG_P2P */
608
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700609 if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800610 kde, kde_len, ptk) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700611 goto failed;
612
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800613 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700614 os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
615 return;
616
617failed:
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800618 os_free(kde_buf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700619 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
620}
621
622
623static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx)
624{
625 struct wpa_sm *sm = eloop_ctx;
626 rsn_preauth_candidate_process(sm);
627}
628
629
630static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
631 const u8 *addr, int secure)
632{
633 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
634 "WPA: Key negotiation completed with "
635 MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
636 wpa_cipher_txt(sm->pairwise_cipher),
637 wpa_cipher_txt(sm->group_cipher));
638 wpa_sm_cancel_auth_timeout(sm);
639 wpa_sm_set_state(sm, WPA_COMPLETED);
640
641 if (secure) {
642 wpa_sm_mlme_setprotection(
643 sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,
644 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
645 eapol_sm_notify_portValid(sm->eapol, TRUE);
646 if (wpa_key_mgmt_wpa_psk(sm->key_mgmt))
647 eapol_sm_notify_eap_success(sm->eapol, TRUE);
648 /*
649 * Start preauthentication after a short wait to avoid a
650 * possible race condition between the data receive and key
651 * configuration after the 4-Way Handshake. This increases the
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800652 * likelihood of the first preauth EAPOL-Start frame getting to
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700653 * the target AP.
654 */
655 eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);
656 }
657
658 if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {
659 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
660 "RSN: Authenticator accepted "
661 "opportunistic PMKSA entry - marking it valid");
662 sm->cur_pmksa->opportunistic = 0;
663 }
664
665#ifdef CONFIG_IEEE80211R
666 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
667 /* Prepare for the next transition */
668 wpa_ft_prepare_auth_request(sm, NULL);
669 }
670#endif /* CONFIG_IEEE80211R */
671}
672
673
674static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
675{
676 struct wpa_sm *sm = eloop_ctx;
677 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Request PTK rekeying");
678 wpa_sm_key_request(sm, 0, 1);
679}
680
681
682static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
683 const struct wpa_eapol_key *key)
684{
685 int keylen, rsclen;
686 enum wpa_alg alg;
687 const u8 *key_rsc;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800688
Mathy Vanhoefc66556c2017-09-29 04:22:51 +0200689 if (sm->ptk.installed) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800690 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
691 "WPA: Do not re-install same PTK to the driver");
692 return 0;
693 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700694
695 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
696 "WPA: Installing PTK to the driver");
697
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700698 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700699 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Pairwise Cipher "
700 "Suite: NONE - do not use pairwise keys");
701 return 0;
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700702 }
703
704 if (!wpa_cipher_valid_pairwise(sm->pairwise_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700705 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
706 "WPA: Unsupported pairwise cipher %d",
707 sm->pairwise_cipher);
708 return -1;
709 }
710
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700711 alg = wpa_cipher_to_alg(sm->pairwise_cipher);
712 keylen = wpa_cipher_key_len(sm->pairwise_cipher);
713 rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
714
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800715 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700716 key_rsc = null_rsc;
717 } else {
718 key_rsc = key->key_rsc;
719 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
720 }
721
722 if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800723 sm->ptk.tk, keylen) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700724 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
725 "WPA: Failed to set PTK to the "
726 "driver (alg=%d keylen=%d bssid=" MACSTR ")",
727 alg, keylen, MAC2STR(sm->bssid));
728 return -1;
729 }
730
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800731 /* TK is not needed anymore in supplicant */
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800732 os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
Mathy Vanhoefc66556c2017-09-29 04:22:51 +0200733 sm->ptk.installed = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800734
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700735 if (sm->wpa_ptk_rekey) {
736 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
737 eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
738 sm, NULL);
739 }
740
741 return 0;
742}
743
744
745static int wpa_supplicant_check_group_cipher(struct wpa_sm *sm,
746 int group_cipher,
747 int keylen, int maxkeylen,
748 int *key_rsc_len,
749 enum wpa_alg *alg)
750{
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700751 int klen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700752
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700753 *alg = wpa_cipher_to_alg(group_cipher);
754 if (*alg == WPA_ALG_NONE) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700755 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
756 "WPA: Unsupported Group Cipher %d",
757 group_cipher);
758 return -1;
759 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700760 *key_rsc_len = wpa_cipher_rsc_len(group_cipher);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700761
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700762 klen = wpa_cipher_key_len(group_cipher);
763 if (keylen != klen || maxkeylen < klen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700764 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
765 "WPA: Unsupported %s Group Cipher key length %d (%d)",
766 wpa_cipher_txt(group_cipher), keylen, maxkeylen);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700767 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700768 }
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -0700769 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700770}
771
772
773struct wpa_gtk_data {
774 enum wpa_alg alg;
775 int tx, key_rsc_len, keyidx;
776 u8 gtk[32];
777 int gtk_len;
778};
779
780
781static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
782 const struct wpa_gtk_data *gd,
783 const u8 *key_rsc)
784{
785 const u8 *_gtk = gd->gtk;
786 u8 gtk_buf[32];
787
Mathy Vanhoef10bfd642017-07-12 16:03:24 +0200788 /* Detect possible key reinstallation */
789 if (sm->gtk.gtk_len == (size_t) gd->gtk_len &&
790 os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) {
791 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
792 "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
793 gd->keyidx, gd->tx, gd->gtk_len);
794 return 0;
795 }
796
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700797 wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
798 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
799 "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
800 gd->keyidx, gd->tx, gd->gtk_len);
801 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
802 if (sm->group_cipher == WPA_CIPHER_TKIP) {
803 /* Swap Tx/Rx keys for Michael MIC */
804 os_memcpy(gtk_buf, gd->gtk, 16);
805 os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
806 os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
807 _gtk = gtk_buf;
808 }
809 if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
810 if (wpa_sm_set_key(sm, gd->alg, NULL,
811 gd->keyidx, 1, key_rsc, gd->key_rsc_len,
812 _gtk, gd->gtk_len) < 0) {
813 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
814 "WPA: Failed to set GTK to the driver "
815 "(Group only)");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700816 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700817 return -1;
818 }
819 } else if (wpa_sm_set_key(sm, gd->alg, broadcast_ether_addr,
820 gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
821 _gtk, gd->gtk_len) < 0) {
822 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
823 "WPA: Failed to set GTK to "
824 "the driver (alg=%d keylen=%d keyidx=%d)",
825 gd->alg, gd->gtk_len, gd->keyidx);
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700826 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700827 return -1;
828 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700829 os_memset(gtk_buf, 0, sizeof(gtk_buf));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700830
Mathy Vanhoef10bfd642017-07-12 16:03:24 +0200831 sm->gtk.gtk_len = gd->gtk_len;
832 os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
833
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700834 return 0;
835}
836
837
838static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
839 int tx)
840{
841 if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
842 /* Ignore Tx bit for GTK if a pairwise key is used. One AP
843 * seemed to set this bit (incorrectly, since Tx is only when
844 * doing Group Key only APs) and without this workaround, the
845 * data connection does not work because wpa_supplicant
846 * configured non-zero keyidx to be used for unicast. */
847 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
848 "WPA: Tx bit set for GTK, but pairwise "
849 "keys are used - ignore Tx bit");
850 return 0;
851 }
852 return tx;
853}
854
855
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800856static int wpa_supplicant_rsc_relaxation(const struct wpa_sm *sm,
857 const u8 *rsc)
858{
859 int rsclen;
860
861 if (!sm->wpa_rsc_relaxation)
862 return 0;
863
864 rsclen = wpa_cipher_rsc_len(sm->group_cipher);
865
866 /*
867 * Try to detect RSC (endian) corruption issue where the AP sends
868 * the RSC bytes in EAPOL-Key message in the wrong order, both if
869 * it's actually a 6-byte field (as it should be) and if it treats
870 * it as an 8-byte field.
871 * An AP model known to have this bug is the Sapido RB-1632.
872 */
873 if (rsclen == 6 && ((rsc[5] && !rsc[0]) || rsc[6] || rsc[7])) {
874 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
875 "RSC %02x%02x%02x%02x%02x%02x%02x%02x is likely bogus, using 0",
876 rsc[0], rsc[1], rsc[2], rsc[3],
877 rsc[4], rsc[5], rsc[6], rsc[7]);
878
879 return 1;
880 }
881
882 return 0;
883}
884
885
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700886static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
887 const struct wpa_eapol_key *key,
888 const u8 *gtk, size_t gtk_len,
889 int key_info)
890{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700891 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800892 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700893
894 /*
895 * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
896 * GTK KDE format:
897 * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]
898 * Reserved [bits 0-7]
899 * GTK
900 */
901
902 os_memset(&gd, 0, sizeof(gd));
903 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",
904 gtk, gtk_len);
905
906 if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))
907 return -1;
908
909 gd.keyidx = gtk[0] & 0x3;
910 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
911 !!(gtk[0] & BIT(2)));
912 gtk += 2;
913 gtk_len -= 2;
914
915 os_memcpy(gd.gtk, gtk, gtk_len);
916 gd.gtk_len = gtk_len;
917
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800918 key_rsc = key->key_rsc;
919 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
920 key_rsc = null_rsc;
921
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800922 if (sm->group_cipher != WPA_CIPHER_GTK_NOT_USED &&
923 (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
924 gtk_len, gtk_len,
925 &gd.key_rsc_len, &gd.alg) ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800926 wpa_supplicant_install_gtk(sm, &gd, key_rsc))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700927 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
928 "RSN: Failed to install GTK");
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700929 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700930 return -1;
931 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -0700932 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700933
934 wpa_supplicant_key_neg_complete(sm, sm->bssid,
935 key_info & WPA_KEY_INFO_SECURE);
936 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700937}
938
939
Mathy Vanhoef10bfd642017-07-12 16:03:24 +0200940#ifdef CONFIG_IEEE80211W
941static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
942 const struct wpa_igtk_kde *igtk)
943{
944 size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
945 u16 keyidx = WPA_GET_LE16(igtk->keyid);
946
947 /* Detect possible key reinstallation */
948 if (sm->igtk.igtk_len == len &&
949 os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) {
950 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
951 "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)",
952 keyidx);
953 return 0;
954 }
955
956 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
957 "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x",
958 keyidx, MAC2STR(igtk->pn));
959 wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len);
960 if (keyidx > 4095) {
961 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
962 "WPA: Invalid IGTK KeyID %d", keyidx);
963 return -1;
964 }
965 if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
966 broadcast_ether_addr,
967 keyidx, 0, igtk->pn, sizeof(igtk->pn),
968 igtk->igtk, len) < 0) {
969 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
970 "WPA: Failed to configure IGTK to the driver");
971 return -1;
972 }
973
974 sm->igtk.igtk_len = len;
975 os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
976
977 return 0;
978}
979#endif /* CONFIG_IEEE80211W */
980
981
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700982static int ieee80211w_set_keys(struct wpa_sm *sm,
983 struct wpa_eapol_ie_parse *ie)
984{
985#ifdef CONFIG_IEEE80211W
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700986 if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700987 return 0;
988
989 if (ie->igtk) {
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700990 size_t len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700991 const struct wpa_igtk_kde *igtk;
Mathy Vanhoef10bfd642017-07-12 16:03:24 +0200992
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700993 len = wpa_cipher_key_len(sm->mgmt_group_cipher);
994 if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700995 return -1;
Mathy Vanhoef10bfd642017-07-12 16:03:24 +0200996
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700997 igtk = (const struct wpa_igtk_kde *) ie->igtk;
Mathy Vanhoef10bfd642017-07-12 16:03:24 +0200998 if (wpa_supplicant_install_igtk(sm, igtk) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700999 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001000 }
1001
1002 return 0;
1003#else /* CONFIG_IEEE80211W */
1004 return 0;
1005#endif /* CONFIG_IEEE80211W */
1006}
1007
1008
1009static void wpa_report_ie_mismatch(struct wpa_sm *sm,
1010 const char *reason, const u8 *src_addr,
1011 const u8 *wpa_ie, size_t wpa_ie_len,
1012 const u8 *rsn_ie, size_t rsn_ie_len)
1013{
1014 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: %s (src=" MACSTR ")",
1015 reason, MAC2STR(src_addr));
1016
1017 if (sm->ap_wpa_ie) {
1018 wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
1019 sm->ap_wpa_ie, sm->ap_wpa_ie_len);
1020 }
1021 if (wpa_ie) {
1022 if (!sm->ap_wpa_ie) {
1023 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1024 "WPA: No WPA IE in Beacon/ProbeResp");
1025 }
1026 wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
1027 wpa_ie, wpa_ie_len);
1028 }
1029
1030 if (sm->ap_rsn_ie) {
1031 wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
1032 sm->ap_rsn_ie, sm->ap_rsn_ie_len);
1033 }
1034 if (rsn_ie) {
1035 if (!sm->ap_rsn_ie) {
1036 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1037 "WPA: No RSN IE in Beacon/ProbeResp");
1038 }
1039 wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
1040 rsn_ie, rsn_ie_len);
1041 }
1042
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001043 wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001044}
1045
1046
1047#ifdef CONFIG_IEEE80211R
1048
1049static int ft_validate_mdie(struct wpa_sm *sm,
1050 const unsigned char *src_addr,
1051 struct wpa_eapol_ie_parse *ie,
1052 const u8 *assoc_resp_mdie)
1053{
1054 struct rsn_mdie *mdie;
1055
1056 mdie = (struct rsn_mdie *) (ie->mdie + 2);
1057 if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
1058 os_memcmp(mdie->mobility_domain, sm->mobility_domain,
1059 MOBILITY_DOMAIN_ID_LEN) != 0) {
1060 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE in msg 3/4 did "
1061 "not match with the current mobility domain");
1062 return -1;
1063 }
1064
1065 if (assoc_resp_mdie &&
1066 (assoc_resp_mdie[1] != ie->mdie[1] ||
1067 os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
1068 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: MDIE mismatch");
1069 wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
1070 ie->mdie, 2 + ie->mdie[1]);
1071 wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
1072 assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
1073 return -1;
1074 }
1075
1076 return 0;
1077}
1078
1079
1080static int ft_validate_ftie(struct wpa_sm *sm,
1081 const unsigned char *src_addr,
1082 struct wpa_eapol_ie_parse *ie,
1083 const u8 *assoc_resp_ftie)
1084{
1085 if (ie->ftie == NULL) {
1086 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1087 "FT: No FTIE in EAPOL-Key msg 3/4");
1088 return -1;
1089 }
1090
1091 if (assoc_resp_ftie == NULL)
1092 return 0;
1093
1094 if (assoc_resp_ftie[1] != ie->ftie[1] ||
1095 os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
1096 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: FTIE mismatch");
1097 wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
1098 ie->ftie, 2 + ie->ftie[1]);
1099 wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
1100 assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
1101 return -1;
1102 }
1103
1104 return 0;
1105}
1106
1107
1108static int ft_validate_rsnie(struct wpa_sm *sm,
1109 const unsigned char *src_addr,
1110 struct wpa_eapol_ie_parse *ie)
1111{
1112 struct wpa_ie_data rsn;
1113
1114 if (!ie->rsn_ie)
1115 return 0;
1116
1117 /*
1118 * Verify that PMKR1Name from EAPOL-Key message 3/4
1119 * matches with the value we derived.
1120 */
1121 if (wpa_parse_wpa_ie_rsn(ie->rsn_ie, ie->rsn_ie_len, &rsn) < 0 ||
1122 rsn.num_pmkid != 1 || rsn.pmkid == NULL) {
1123 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: No PMKR1Name in "
1124 "FT 4-way handshake message 3/4");
1125 return -1;
1126 }
1127
Dmitry Shmidtc2817022014-07-02 10:32:10 -07001128 if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
1129 {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001130 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1131 "FT: PMKR1Name mismatch in "
1132 "FT 4-way handshake message 3/4");
1133 wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name from Authenticator",
1134 rsn.pmkid, WPA_PMK_NAME_LEN);
1135 wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
1136 sm->pmk_r1_name, WPA_PMK_NAME_LEN);
1137 return -1;
1138 }
1139
1140 return 0;
1141}
1142
1143
1144static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
1145 const unsigned char *src_addr,
1146 struct wpa_eapol_ie_parse *ie)
1147{
1148 const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
1149
1150 if (sm->assoc_resp_ies) {
1151 pos = sm->assoc_resp_ies;
1152 end = pos + sm->assoc_resp_ies_len;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001153 while (end - pos > 2) {
1154 if (2 + pos[1] > end - pos)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001155 break;
1156 switch (*pos) {
1157 case WLAN_EID_MOBILITY_DOMAIN:
1158 mdie = pos;
1159 break;
1160 case WLAN_EID_FAST_BSS_TRANSITION:
1161 ftie = pos;
1162 break;
1163 }
1164 pos += 2 + pos[1];
1165 }
1166 }
1167
1168 if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
1169 ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
1170 ft_validate_rsnie(sm, src_addr, ie) < 0)
1171 return -1;
1172
1173 return 0;
1174}
1175
1176#endif /* CONFIG_IEEE80211R */
1177
1178
1179static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
1180 const unsigned char *src_addr,
1181 struct wpa_eapol_ie_parse *ie)
1182{
1183 if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) {
1184 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1185 "WPA: No WPA/RSN IE for this AP known. "
1186 "Trying to get from scan results");
1187 if (wpa_sm_get_beacon_ie(sm) < 0) {
1188 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1189 "WPA: Could not find AP from "
1190 "the scan results");
1191 } else {
1192 wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG,
1193 "WPA: Found the current AP from "
1194 "updated scan results");
1195 }
1196 }
1197
1198 if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
1199 (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
1200 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1201 "with IE in Beacon/ProbeResp (no IE?)",
1202 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1203 ie->rsn_ie, ie->rsn_ie_len);
1204 return -1;
1205 }
1206
1207 if ((ie->wpa_ie && sm->ap_wpa_ie &&
1208 (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
1209 os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
1210 (ie->rsn_ie && sm->ap_rsn_ie &&
1211 wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
1212 sm->ap_rsn_ie, sm->ap_rsn_ie_len,
1213 ie->rsn_ie, ie->rsn_ie_len))) {
1214 wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
1215 "with IE in Beacon/ProbeResp",
1216 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1217 ie->rsn_ie, ie->rsn_ie_len);
1218 return -1;
1219 }
1220
1221 if (sm->proto == WPA_PROTO_WPA &&
1222 ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
1223 wpa_report_ie_mismatch(sm, "Possible downgrade attack "
1224 "detected - RSN was enabled and RSN IE "
1225 "was in msg 3/4, but not in "
1226 "Beacon/ProbeResp",
1227 src_addr, ie->wpa_ie, ie->wpa_ie_len,
1228 ie->rsn_ie, ie->rsn_ie_len);
1229 return -1;
1230 }
1231
1232#ifdef CONFIG_IEEE80211R
1233 if (wpa_key_mgmt_ft(sm->key_mgmt) &&
1234 wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
1235 return -1;
1236#endif /* CONFIG_IEEE80211R */
1237
1238 return 0;
1239}
1240
1241
1242/**
1243 * wpa_supplicant_send_4_of_4 - Send message 4 of WPA/RSN 4-Way Handshake
1244 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1245 * @dst: Destination address for the frame
1246 * @key: Pointer to the EAPOL-Key frame header
1247 * @ver: Version bits from EAPOL-Key Key Info
1248 * @key_info: Key Info
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001249 * @ptk: PTK to use for keyed hash and encryption
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001250 * Returns: >= 0 on success, < 0 on failure
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001251 */
1252int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
1253 const struct wpa_eapol_key *key,
1254 u16 ver, u16 key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001255 struct wpa_ptk *ptk)
1256{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001257 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001258 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001259 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001260
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001261 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001262 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001263 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001264 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001265 if (rbuf == NULL)
1266 return -1;
1267
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001268 reply->type = (sm->proto == WPA_PROTO_RSN ||
1269 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001270 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1271 key_info &= WPA_KEY_INFO_SECURE;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001272 key_info |= ver | WPA_KEY_INFO_KEY_TYPE;
1273 if (mic_len)
1274 key_info |= WPA_KEY_INFO_MIC;
1275 else
1276 key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001277 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001278 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001279 WPA_PUT_BE16(reply->key_length, 0);
1280 else
1281 os_memcpy(reply->key_length, key->key_length, 2);
1282 os_memcpy(reply->replay_counter, key->replay_counter,
1283 WPA_REPLAY_COUNTER_LEN);
1284
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001285 key_mic = (u8 *) (reply + 1);
1286 WPA_PUT_BE16(key_mic + mic_len, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001287
1288 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001289 return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen,
1290 key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001291}
1292
1293
1294static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
1295 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001296 u16 ver, const u8 *key_data,
1297 size_t key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001298{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001299 u16 key_info, keylen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001300 struct wpa_eapol_ie_parse ie;
1301
1302 wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
1303 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 3 of 4-Way "
1304 "Handshake from " MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);
1305
1306 key_info = WPA_GET_BE16(key->key_info);
1307
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001308 wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", key_data, key_data_len);
1309 if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001310 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001311 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1312 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1313 "WPA: GTK IE in unencrypted key data");
1314 goto failed;
1315 }
1316#ifdef CONFIG_IEEE80211W
1317 if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1318 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1319 "WPA: IGTK KDE in unencrypted key data");
1320 goto failed;
1321 }
1322
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07001323 if (ie.igtk &&
1324 wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) &&
1325 ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN +
1326 (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001327 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1328 "WPA: Invalid IGTK KDE length %lu",
1329 (unsigned long) ie.igtk_len);
1330 goto failed;
1331 }
1332#endif /* CONFIG_IEEE80211W */
1333
1334 if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
1335 goto failed;
1336
1337 if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
1338 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1339 "WPA: ANonce from message 1 of 4-Way Handshake "
1340 "differs from 3 of 4-Way Handshake - drop packet (src="
1341 MACSTR ")", MAC2STR(sm->bssid));
1342 goto failed;
1343 }
1344
1345 keylen = WPA_GET_BE16(key->key_length);
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07001346 if (keylen != wpa_cipher_key_len(sm->pairwise_cipher)) {
1347 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1348 "WPA: Invalid %s key length %d (src=" MACSTR
1349 ")", wpa_cipher_txt(sm->pairwise_cipher), keylen,
1350 MAC2STR(sm->bssid));
1351 goto failed;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001352 }
1353
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08001354#ifdef CONFIG_P2P
1355 if (ie.ip_addr_alloc) {
1356 os_memcpy(sm->p2p_ip_addr, ie.ip_addr_alloc, 3 * 4);
1357 wpa_hexdump(MSG_DEBUG, "P2P: IP address info",
1358 sm->p2p_ip_addr, sizeof(sm->p2p_ip_addr));
1359 }
1360#endif /* CONFIG_P2P */
1361
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001362 if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001363 &sm->ptk) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001364 goto failed;
1365 }
1366
1367 /* SNonce was successfully used in msg 3/4, so mark it to be renewed
1368 * for the next 4-Way Handshake. If msg 3 is received again, the old
1369 * SNonce will still be used to avoid changing PTK. */
1370 sm->renew_snonce = 1;
1371
1372 if (key_info & WPA_KEY_INFO_INSTALL) {
1373 if (wpa_supplicant_install_ptk(sm, key))
1374 goto failed;
1375 }
1376
1377 if (key_info & WPA_KEY_INFO_SECURE) {
1378 wpa_sm_mlme_setprotection(
1379 sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
1380 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
1381 eapol_sm_notify_portValid(sm->eapol, TRUE);
1382 }
1383 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1384
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001385 if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) {
1386 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1387 key_info & WPA_KEY_INFO_SECURE);
1388 } else if (ie.gtk &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001389 wpa_supplicant_pairwise_gtk(sm, key,
1390 ie.gtk, ie.gtk_len, key_info) < 0) {
1391 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1392 "RSN: Failed to configure GTK");
1393 goto failed;
1394 }
1395
1396 if (ieee80211w_set_keys(sm, &ie) < 0) {
1397 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1398 "RSN: Failed to configure IGTK");
1399 goto failed;
1400 }
1401
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001402 if (ie.gtk)
1403 wpa_sm_set_rekey_offload(sm);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001404
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001405 if (sm->proto == WPA_PROTO_RSN && wpa_key_mgmt_suite_b(sm->key_mgmt)) {
1406 struct rsn_pmksa_cache_entry *sa;
1407
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08001408 sa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001409 sm->ptk.kck, sm->ptk.kck_len,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001410 sm->bssid, sm->own_addr,
1411 sm->network_ctx, sm->key_mgmt);
1412 if (!sm->cur_pmksa)
1413 sm->cur_pmksa = sa;
1414 }
1415
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001416 sm->msg_3_of_4_ok = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001417 return;
1418
1419failed:
1420 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1421}
1422
1423
1424static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
1425 const u8 *keydata,
1426 size_t keydatalen,
1427 u16 key_info,
1428 struct wpa_gtk_data *gd)
1429{
1430 int maxkeylen;
1431 struct wpa_eapol_ie_parse ie;
1432
Dmitry Shmidtebd93af2017-02-21 13:40:44 -08001433 wpa_hexdump_key(MSG_DEBUG, "RSN: msg 1/2 key data",
1434 keydata, keydatalen);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001435 if (wpa_supplicant_parse_ies(keydata, keydatalen, &ie) < 0)
1436 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001437 if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
1438 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1439 "WPA: GTK IE in unencrypted key data");
1440 return -1;
1441 }
1442 if (ie.gtk == NULL) {
1443 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1444 "WPA: No GTK IE in Group Key msg 1/2");
1445 return -1;
1446 }
1447 maxkeylen = gd->gtk_len = ie.gtk_len - 2;
1448
1449 if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1450 gd->gtk_len, maxkeylen,
1451 &gd->key_rsc_len, &gd->alg))
1452 return -1;
1453
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001454 wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in group key handshake",
1455 ie.gtk, ie.gtk_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001456 gd->keyidx = ie.gtk[0] & 0x3;
1457 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
1458 !!(ie.gtk[0] & BIT(2)));
1459 if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
1460 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1461 "RSN: Too long GTK in GTK IE (len=%lu)",
1462 (unsigned long) ie.gtk_len - 2);
1463 return -1;
1464 }
1465 os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);
1466
1467 if (ieee80211w_set_keys(sm, &ie) < 0)
1468 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1469 "RSN: Failed to configure IGTK");
1470
1471 return 0;
1472}
1473
1474
1475static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
1476 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001477 const u8 *key_data,
1478 size_t key_data_len, u16 key_info,
1479 u16 ver, struct wpa_gtk_data *gd)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001480{
1481 size_t maxkeylen;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001482 u16 gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001483
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001484 gtk_len = WPA_GET_BE16(key->key_length);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001485 maxkeylen = key_data_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001486 if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
1487 if (maxkeylen < 8) {
1488 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1489 "WPA: Too short maxkeylen (%lu)",
1490 (unsigned long) maxkeylen);
1491 return -1;
1492 }
1493 maxkeylen -= 8;
1494 }
1495
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001496 if (gtk_len > maxkeylen ||
1497 wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
1498 gtk_len, maxkeylen,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001499 &gd->key_rsc_len, &gd->alg))
1500 return -1;
1501
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001502 gd->gtk_len = gtk_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001503 gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1504 WPA_KEY_INFO_KEY_INDEX_SHIFT;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001505 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001506#ifdef CONFIG_NO_RC4
1507 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1508 "WPA: RC4 not supported in the build");
1509 return -1;
1510#else /* CONFIG_NO_RC4 */
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001511 u8 ek[32];
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001512 if (key_data_len > sizeof(gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001513 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1514 "WPA: RC4 key data too long (%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001515 (unsigned long) key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001516 return -1;
1517 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001518 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001519 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001520 os_memcpy(gd->gtk, key_data, key_data_len);
1521 if (rc4_skip(ek, 32, 256, gd->gtk, key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001522 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001523 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1524 "WPA: RC4 failed");
1525 return -1;
1526 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001527 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001528#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001529 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001530 if (maxkeylen % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001531 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1532 "WPA: Unsupported AES-WRAP len %lu",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001533 (unsigned long) maxkeylen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001534 return -1;
1535 }
1536 if (maxkeylen > sizeof(gd->gtk)) {
1537 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1538 "WPA: AES-WRAP key data "
1539 "too long (keydatalen=%lu maxkeylen=%lu)",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001540 (unsigned long) key_data_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001541 (unsigned long) maxkeylen);
1542 return -1;
1543 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001544 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, maxkeylen / 8,
1545 key_data, gd->gtk)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001546 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1547 "WPA: AES unwrap failed - could not decrypt "
1548 "GTK");
1549 return -1;
1550 }
1551 } else {
1552 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1553 "WPA: Unsupported key_info type %d", ver);
1554 return -1;
1555 }
1556 gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
1557 sm, !!(key_info & WPA_KEY_INFO_TXRX));
1558 return 0;
1559}
1560
1561
1562static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
1563 const struct wpa_eapol_key *key,
1564 int ver, u16 key_info)
1565{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001566 size_t mic_len, hdrlen, rlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001567 struct wpa_eapol_key *reply;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001568 u8 *rbuf, *key_mic;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001569
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001570 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001571 hdrlen = sizeof(*reply) + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001572 rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001573 hdrlen, &rlen, (void *) &reply);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001574 if (rbuf == NULL)
1575 return -1;
1576
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001577 reply->type = (sm->proto == WPA_PROTO_RSN ||
1578 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001579 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
1580 key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001581 key_info |= ver | WPA_KEY_INFO_SECURE;
1582 if (mic_len)
1583 key_info |= WPA_KEY_INFO_MIC;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001584 WPA_PUT_BE16(reply->key_info, key_info);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001585 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001586 WPA_PUT_BE16(reply->key_length, 0);
1587 else
1588 os_memcpy(reply->key_length, key->key_length, 2);
1589 os_memcpy(reply->replay_counter, key->replay_counter,
1590 WPA_REPLAY_COUNTER_LEN);
1591
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001592 key_mic = (u8 *) (reply + 1);
1593 WPA_PUT_BE16(key_mic + mic_len, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001594
1595 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001596 return wpa_eapol_key_send(sm, &sm->ptk, ver, sm->bssid, ETH_P_EAPOL,
1597 rbuf, rlen, key_mic);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001598}
1599
1600
1601static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
1602 const unsigned char *src_addr,
1603 const struct wpa_eapol_key *key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001604 const u8 *key_data,
1605 size_t key_data_len, u16 ver)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001606{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001607 u16 key_info;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001608 int rekey, ret;
1609 struct wpa_gtk_data gd;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001610 const u8 *key_rsc;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001611
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07001612 if (!sm->msg_3_of_4_ok) {
1613 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
1614 "WPA: Group Key Handshake started prior to completion of 4-way handshake");
1615 goto failed;
1616 }
1617
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001618 os_memset(&gd, 0, sizeof(gd));
1619
1620 rekey = wpa_sm_get_state(sm) == WPA_COMPLETED;
1621 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of Group Key "
1622 "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
1623
1624 key_info = WPA_GET_BE16(key->key_info);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001625
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001626 if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001627 ret = wpa_supplicant_process_1_of_2_rsn(sm, key_data,
1628 key_data_len, key_info,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001629 &gd);
1630 } else {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001631 ret = wpa_supplicant_process_1_of_2_wpa(sm, key, key_data,
1632 key_data_len,
1633 key_info, ver, &gd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001634 }
1635
1636 wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
1637
1638 if (ret)
1639 goto failed;
1640
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001641 key_rsc = key->key_rsc;
1642 if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
1643 key_rsc = null_rsc;
1644
1645 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc) ||
1646 wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001647 goto failed;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001648 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001649
1650 if (rekey) {
1651 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Group rekeying "
1652 "completed with " MACSTR " [GTK=%s]",
1653 MAC2STR(sm->bssid), wpa_cipher_txt(sm->group_cipher));
1654 wpa_sm_cancel_auth_timeout(sm);
1655 wpa_sm_set_state(sm, WPA_COMPLETED);
1656 } else {
1657 wpa_supplicant_key_neg_complete(sm, sm->bssid,
1658 key_info &
1659 WPA_KEY_INFO_SECURE);
1660 }
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001661
1662 wpa_sm_set_rekey_offload(sm);
1663
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001664 return;
1665
1666failed:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001667 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001668 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
1669}
1670
1671
1672static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001673 struct wpa_eapol_key *key,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001674 u16 ver,
1675 const u8 *buf, size_t len)
1676{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001677 u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001678 int ok = 0;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001679 size_t mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001680
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001681 os_memcpy(mic, key + 1, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001682 if (sm->tptk_set) {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001683 os_memset(key + 1, 0, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001684 wpa_eapol_key_mic(sm->tptk.kck, sm->tptk.kck_len, sm->key_mgmt,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001685 ver, buf, len, (u8 *) (key + 1));
1686 if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001687 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1688 "WPA: Invalid EAPOL-Key MIC "
1689 "when using TPTK - ignoring TPTK");
1690 } else {
1691 ok = 1;
1692 sm->tptk_set = 0;
1693 sm->ptk_set = 1;
1694 os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001695 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001696 }
1697 }
1698
1699 if (!ok && sm->ptk_set) {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001700 os_memset(key + 1, 0, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001701 wpa_eapol_key_mic(sm->ptk.kck, sm->ptk.kck_len, sm->key_mgmt,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001702 ver, buf, len, (u8 *) (key + 1));
1703 if (os_memcmp_const(mic, key + 1, mic_len) != 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001704 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1705 "WPA: Invalid EAPOL-Key MIC - "
1706 "dropping packet");
1707 return -1;
1708 }
1709 ok = 1;
1710 }
1711
1712 if (!ok) {
1713 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1714 "WPA: Could not verify EAPOL-Key MIC - "
1715 "dropping packet");
1716 return -1;
1717 }
1718
1719 os_memcpy(sm->rx_replay_counter, key->replay_counter,
1720 WPA_REPLAY_COUNTER_LEN);
1721 sm->rx_replay_counter_set = 1;
1722 return 0;
1723}
1724
1725
1726/* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
1727static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001728 struct wpa_eapol_key *key,
1729 size_t mic_len, u16 ver,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001730 u8 *key_data, size_t *key_data_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001731{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001732 wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001733 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001734 if (!sm->ptk_set) {
1735 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1736 "WPA: PTK not available, cannot decrypt EAPOL-Key Key "
1737 "Data");
1738 return -1;
1739 }
1740
1741 /* Decrypt key data here so that this operation does not need
1742 * to be implemented separately for each message type. */
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001743 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001744#ifdef CONFIG_NO_RC4
1745 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1746 "WPA: RC4 not supported in the build");
1747 return -1;
1748#else /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001749 u8 ek[32];
1750 os_memcpy(ek, key->key_iv, 16);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001751 os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001752 if (rc4_skip(ek, 32, 256, key_data, *key_data_len)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001753 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001754 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
1755 "WPA: RC4 failed");
1756 return -1;
1757 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07001758 os_memset(ek, 0, sizeof(ek));
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001759#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001760 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001761 ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001762 sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
1763 wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001764 u8 *buf;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001765 if (*key_data_len < 8 || *key_data_len % 8) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001766 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001767 "WPA: Unsupported AES-WRAP len %u",
1768 (unsigned int) *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001769 return -1;
1770 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001771 *key_data_len -= 8; /* AES-WRAP adds 8 bytes */
1772 buf = os_malloc(*key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001773 if (buf == NULL) {
1774 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1775 "WPA: No memory for AES-UNWRAP buffer");
1776 return -1;
1777 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001778 if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, *key_data_len / 8,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001779 key_data, buf)) {
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001780 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001781 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1782 "WPA: AES unwrap failed - "
1783 "could not decrypt EAPOL-Key key data");
1784 return -1;
1785 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001786 os_memcpy(key_data, buf, *key_data_len);
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001787 bin_clear_free(buf, *key_data_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001788 WPA_PUT_BE16(((u8 *) (key + 1)) + mic_len, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001789 } else {
1790 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
1791 "WPA: Unsupported key_info type %d", ver);
1792 return -1;
1793 }
1794 wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001795 key_data, *key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001796 return 0;
1797}
1798
1799
1800/**
1801 * wpa_sm_aborted_cached - Notify WPA that PMKSA caching was aborted
1802 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1803 */
1804void wpa_sm_aborted_cached(struct wpa_sm *sm)
1805{
1806 if (sm && sm->cur_pmksa) {
1807 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1808 "RSN: Cancelling PMKSA caching attempt");
1809 sm->cur_pmksa = NULL;
1810 }
1811}
1812
1813
1814static void wpa_eapol_key_dump(struct wpa_sm *sm,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001815 const struct wpa_eapol_key *key,
1816 unsigned int key_data_len,
1817 const u8 *mic, unsigned int mic_len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001818{
1819#ifndef CONFIG_NO_STDOUT_DEBUG
1820 u16 key_info = WPA_GET_BE16(key->key_info);
1821
1822 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, " EAPOL-Key type=%d", key->type);
1823 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1824 " key_info 0x%x (ver=%d keyidx=%d rsvd=%d %s%s%s%s%s%s%s%s)",
1825 key_info, key_info & WPA_KEY_INFO_TYPE_MASK,
1826 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
1827 WPA_KEY_INFO_KEY_INDEX_SHIFT,
1828 (key_info & (BIT(13) | BIT(14) | BIT(15))) >> 13,
1829 key_info & WPA_KEY_INFO_KEY_TYPE ? "Pairwise" : "Group",
1830 key_info & WPA_KEY_INFO_INSTALL ? " Install" : "",
1831 key_info & WPA_KEY_INFO_ACK ? " Ack" : "",
1832 key_info & WPA_KEY_INFO_MIC ? " MIC" : "",
1833 key_info & WPA_KEY_INFO_SECURE ? " Secure" : "",
1834 key_info & WPA_KEY_INFO_ERROR ? " Error" : "",
1835 key_info & WPA_KEY_INFO_REQUEST ? " Request" : "",
1836 key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
1837 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1838 " key_length=%u key_data_length=%u",
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001839 WPA_GET_BE16(key->key_length), key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001840 wpa_hexdump(MSG_DEBUG, " replay_counter",
1841 key->replay_counter, WPA_REPLAY_COUNTER_LEN);
1842 wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN);
1843 wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16);
1844 wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8);
1845 wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001846 wpa_hexdump(MSG_DEBUG, " key_mic", mic, mic_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001847#endif /* CONFIG_NO_STDOUT_DEBUG */
1848}
1849
1850
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001851#ifdef CONFIG_FILS
1852static int wpa_supp_aead_decrypt(struct wpa_sm *sm, u8 *buf, size_t buf_len,
1853 size_t *key_data_len)
1854{
1855 struct wpa_ptk *ptk;
1856 struct ieee802_1x_hdr *hdr;
1857 struct wpa_eapol_key *key;
1858 u8 *pos, *tmp;
1859 const u8 *aad[1];
1860 size_t aad_len[1];
1861
1862 if (*key_data_len < AES_BLOCK_SIZE) {
1863 wpa_printf(MSG_INFO, "No room for AES-SIV data in the frame");
1864 return -1;
1865 }
1866
1867 if (sm->tptk_set)
1868 ptk = &sm->tptk;
1869 else if (sm->ptk_set)
1870 ptk = &sm->ptk;
1871 else
1872 return -1;
1873
1874 hdr = (struct ieee802_1x_hdr *) buf;
1875 key = (struct wpa_eapol_key *) (hdr + 1);
1876 pos = (u8 *) (key + 1);
1877 pos += 2; /* Pointing at the Encrypted Key Data field */
1878
1879 tmp = os_malloc(*key_data_len);
1880 if (!tmp)
1881 return -1;
1882
1883 /* AES-SIV AAD from EAPOL protocol version field (inclusive) to
1884 * to Key Data (exclusive). */
1885 aad[0] = buf;
1886 aad_len[0] = pos - buf;
1887 if (aes_siv_decrypt(ptk->kek, ptk->kek_len, pos, *key_data_len,
1888 1, aad, aad_len, tmp) < 0) {
1889 wpa_printf(MSG_INFO, "Invalid AES-SIV data in the frame");
1890 bin_clear_free(tmp, *key_data_len);
1891 return -1;
1892 }
1893
1894 /* AEAD decryption and validation completed successfully */
1895 (*key_data_len) -= AES_BLOCK_SIZE;
1896 wpa_hexdump_key(MSG_DEBUG, "WPA: Decrypted Key Data",
1897 tmp, *key_data_len);
1898
1899 /* Replace Key Data field with the decrypted version */
1900 os_memcpy(pos, tmp, *key_data_len);
1901 pos -= 2; /* Key Data Length field */
1902 WPA_PUT_BE16(pos, *key_data_len);
1903 bin_clear_free(tmp, *key_data_len);
1904
1905 if (sm->tptk_set) {
1906 sm->tptk_set = 0;
1907 sm->ptk_set = 1;
1908 os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
1909 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
1910 }
1911
1912 os_memcpy(sm->rx_replay_counter, key->replay_counter,
1913 WPA_REPLAY_COUNTER_LEN);
1914 sm->rx_replay_counter_set = 1;
1915
1916 return 0;
1917}
1918#endif /* CONFIG_FILS */
1919
1920
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001921/**
1922 * wpa_sm_rx_eapol - Process received WPA EAPOL frames
1923 * @sm: Pointer to WPA state machine data from wpa_sm_init()
1924 * @src_addr: Source MAC address of the EAPOL packet
1925 * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
1926 * @len: Length of the EAPOL frame
1927 * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
1928 *
1929 * This function is called for each received EAPOL frame. Other than EAPOL-Key
1930 * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
1931 * only processing WPA and WPA2 EAPOL-Key frames.
1932 *
1933 * The received EAPOL-Key packets are validated and valid packets are replied
1934 * to. In addition, key material (PTK, GTK) is configured at the end of a
1935 * successful key handshake.
1936 */
1937int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
1938 const u8 *buf, size_t len)
1939{
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001940 size_t plen, data_len, key_data_len;
1941 const struct ieee802_1x_hdr *hdr;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001942 struct wpa_eapol_key *key;
1943 u16 key_info, ver;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001944 u8 *tmp = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001945 int ret = -1;
1946 struct wpa_peerkey *peerkey = NULL;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001947 u8 *mic, *key_data;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001948 size_t mic_len, keyhdrlen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001949
1950#ifdef CONFIG_IEEE80211R
1951 sm->ft_completed = 0;
1952#endif /* CONFIG_IEEE80211R */
1953
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001954 mic_len = wpa_mic_len(sm->key_mgmt);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08001955 keyhdrlen = sizeof(*key) + mic_len + 2;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001956
1957 if (len < sizeof(*hdr) + keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001958 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1959 "WPA: EAPOL frame too short to be a WPA "
1960 "EAPOL-Key (len %lu, expecting at least %lu)",
1961 (unsigned long) len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001962 (unsigned long) sizeof(*hdr) + keyhdrlen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001963 return 0;
1964 }
1965
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001966 hdr = (const struct ieee802_1x_hdr *) buf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001967 plen = be_to_host16(hdr->length);
1968 data_len = plen + sizeof(*hdr);
1969 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1970 "IEEE 802.1X RX: version=%d type=%d length=%lu",
1971 hdr->version, hdr->type, (unsigned long) plen);
1972
1973 if (hdr->version < EAPOL_VERSION) {
1974 /* TODO: backwards compatibility */
1975 }
1976 if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
1977 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1978 "WPA: EAPOL frame (type %u) discarded, "
1979 "not a Key frame", hdr->type);
1980 ret = 0;
1981 goto out;
1982 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001983 wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001984 if (plen > len - sizeof(*hdr) || plen < keyhdrlen) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001985 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1986 "WPA: EAPOL frame payload size %lu "
1987 "invalid (frame size %lu)",
1988 (unsigned long) plen, (unsigned long) len);
1989 ret = 0;
1990 goto out;
1991 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07001992 if (data_len < len) {
1993 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
1994 "WPA: ignoring %lu bytes after the IEEE 802.1X data",
1995 (unsigned long) len - data_len);
1996 }
1997
1998 /*
1999 * Make a copy of the frame since we need to modify the buffer during
2000 * MAC validation and Key Data decryption.
2001 */
2002 tmp = os_malloc(data_len);
2003 if (tmp == NULL)
2004 goto out;
2005 os_memcpy(tmp, buf, data_len);
2006 key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr));
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002007 mic = (u8 *) (key + 1);
2008 key_data = mic + mic_len + 2;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002009
2010 if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
2011 {
2012 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2013 "WPA: EAPOL-Key type (%d) unknown, discarded",
2014 key->type);
2015 ret = 0;
2016 goto out;
2017 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002018
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002019 key_data_len = WPA_GET_BE16(mic + mic_len);
2020 wpa_eapol_key_dump(sm, key, key_data_len, mic, mic_len);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002021
2022 if (key_data_len > plen - keyhdrlen) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002023 wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
2024 "frame - key_data overflow (%u > %u)",
2025 (unsigned int) key_data_len,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002026 (unsigned int) (plen - keyhdrlen));
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002027 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002028 }
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002029
2030 eapol_sm_notify_lower_layer_success(sm->eapol, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002031 key_info = WPA_GET_BE16(key->key_info);
2032 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
2033 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
2034#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
2035 ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
2036#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002037 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002038 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002039 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002040 sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002041 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2042 "WPA: Unsupported EAPOL-Key descriptor version %d",
2043 ver);
2044 goto out;
2045 }
2046
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002047 if (sm->key_mgmt == WPA_KEY_MGMT_OSEN &&
2048 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
2049 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2050 "OSEN: Unsupported EAPOL-Key descriptor version %d",
2051 ver);
2052 goto out;
2053 }
2054
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002055 if ((wpa_key_mgmt_suite_b(sm->key_mgmt) ||
2056 wpa_key_mgmt_fils(sm->key_mgmt)) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002057 ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
2058 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2059 "RSN: Unsupported EAPOL-Key descriptor version %d (expected AKM defined = 0)",
2060 ver);
2061 goto out;
2062 }
2063
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002064#ifdef CONFIG_IEEE80211R
2065 if (wpa_key_mgmt_ft(sm->key_mgmt)) {
2066 /* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
2067 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
2068 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2069 "FT: AP did not use AES-128-CMAC");
2070 goto out;
2071 }
2072 } else
2073#endif /* CONFIG_IEEE80211R */
2074#ifdef CONFIG_IEEE80211W
2075 if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002076 if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002077 sm->key_mgmt != WPA_KEY_MGMT_OSEN &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002078 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002079 !wpa_key_mgmt_suite_b(sm->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002080 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2081 "WPA: AP did not use the "
2082 "negotiated AES-128-CMAC");
2083 goto out;
2084 }
2085 } else
2086#endif /* CONFIG_IEEE80211W */
2087 if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002088 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002089 !wpa_key_mgmt_fils(sm->key_mgmt) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002090 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
2091 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2092 "WPA: CCMP is used, but EAPOL-Key "
2093 "descriptor version (%d) is not 2", ver);
2094 if (sm->group_cipher != WPA_CIPHER_CCMP &&
2095 !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
2096 /* Earlier versions of IEEE 802.11i did not explicitly
2097 * require version 2 descriptor for all EAPOL-Key
2098 * packets, so allow group keys to use version 1 if
2099 * CCMP is not used for them. */
2100 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2101 "WPA: Backwards compatibility: allow invalid "
2102 "version for non-CCMP group keys");
Jouni Malinen658fb4a2014-11-14 20:57:05 +02002103 } else if (ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
2104 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2105 "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 -07002106 } else
2107 goto out;
Dmitry Shmidt71757432014-06-02 13:50:35 -07002108 } else if (sm->pairwise_cipher == WPA_CIPHER_GCMP &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002109 !wpa_key_mgmt_suite_b(sm->key_mgmt) &&
Dmitry Shmidt71757432014-06-02 13:50:35 -07002110 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002111 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2112 "WPA: GCMP is used, but EAPOL-Key "
2113 "descriptor version (%d) is not 2", ver);
2114 goto out;
2115 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002116
2117#ifdef CONFIG_PEERKEY
2118 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
2119 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
2120 break;
2121 }
2122
2123 if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
2124 if (!peerkey->initiator && peerkey->replay_counter_set &&
2125 os_memcmp(key->replay_counter, peerkey->replay_counter,
2126 WPA_REPLAY_COUNTER_LEN) <= 0) {
2127 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2128 "RSN: EAPOL-Key Replay Counter did not "
2129 "increase (STK) - dropping packet");
2130 goto out;
2131 } else if (peerkey->initiator) {
2132 u8 _tmp[WPA_REPLAY_COUNTER_LEN];
2133 os_memcpy(_tmp, key->replay_counter,
2134 WPA_REPLAY_COUNTER_LEN);
2135 inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
2136 if (os_memcmp(_tmp, peerkey->replay_counter,
2137 WPA_REPLAY_COUNTER_LEN) != 0) {
2138 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2139 "RSN: EAPOL-Key Replay "
2140 "Counter did not match (STK) - "
2141 "dropping packet");
2142 goto out;
2143 }
2144 }
2145 }
2146
2147 if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
2148 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2149 "RSN: Ack bit in key_info from STK peer");
2150 goto out;
2151 }
2152#endif /* CONFIG_PEERKEY */
2153
2154 if (!peerkey && sm->rx_replay_counter_set &&
2155 os_memcmp(key->replay_counter, sm->rx_replay_counter,
2156 WPA_REPLAY_COUNTER_LEN) <= 0) {
2157 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2158 "WPA: EAPOL-Key Replay Counter did not increase - "
2159 "dropping packet");
2160 goto out;
2161 }
2162
2163 if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
2164#ifdef CONFIG_PEERKEY
2165 && (peerkey == NULL || !peerkey->initiator)
2166#endif /* CONFIG_PEERKEY */
2167 ) {
2168 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2169 "WPA: No Ack bit in key_info");
2170 goto out;
2171 }
2172
2173 if (key_info & WPA_KEY_INFO_REQUEST) {
2174 wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
2175 "WPA: EAPOL-Key with Request bit - dropped");
2176 goto out;
2177 }
2178
2179 if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002180 wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002181 goto out;
2182
2183#ifdef CONFIG_PEERKEY
2184 if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002185 peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002186 data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002187 goto out;
2188#endif /* CONFIG_PEERKEY */
2189
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002190#ifdef CONFIG_FILS
2191 if (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
2192 if (wpa_supp_aead_decrypt(sm, tmp, data_len, &key_data_len))
2193 goto out;
2194 }
2195#endif /* CONFIG_FILS */
2196
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002197 if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002198 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) && mic_len) {
2199 if (wpa_supplicant_decrypt_key_data(sm, key, mic_len,
2200 ver, key_data,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002201 &key_data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002202 goto out;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002203 }
2204
2205 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
2206 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
2207 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
2208 "WPA: Ignored EAPOL-Key (Pairwise) with "
2209 "non-zero key index");
2210 goto out;
2211 }
2212 if (peerkey) {
2213 /* PeerKey 4-Way Handshake */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07002214 peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
2215 key_data, key_data_len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002216 } else if (key_info & (WPA_KEY_INFO_MIC |
2217 WPA_KEY_INFO_ENCR_KEY_DATA)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002218 /* 3/4 4-Way Handshake */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002219 wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
2220 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002221 } else {
2222 /* 1/4 4-Way Handshake */
2223 wpa_supplicant_process_1_of_4(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002224 ver, key_data,
2225 key_data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002226 }
2227 } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
2228 /* PeerKey SMK Handshake */
Dmitry Shmidt29333592017-01-09 12:27:11 -08002229 peerkey_rx_eapol_smk(sm, src_addr, key, key_data, key_data_len,
2230 key_info, ver);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002231 } else {
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002232 if ((mic_len && (key_info & WPA_KEY_INFO_MIC)) ||
2233 (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002234 /* 1/2 Group Key Handshake */
2235 wpa_supplicant_process_1_of_2(sm, src_addr, key,
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07002236 key_data, key_data_len,
2237 ver);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002238 } else {
2239 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002240 "WPA: EAPOL-Key (Group) without Mic/Encr bit - "
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002241 "dropped");
2242 }
2243 }
2244
2245 ret = 1;
2246
2247out:
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002248 bin_clear_free(tmp, data_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002249 return ret;
2250}
2251
2252
2253#ifdef CONFIG_CTRL_IFACE
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002254static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
2255{
2256 switch (sm->key_mgmt) {
2257 case WPA_KEY_MGMT_IEEE8021X:
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002258 return ((sm->proto == WPA_PROTO_RSN ||
2259 sm->proto == WPA_PROTO_OSEN) ?
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002260 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
2261 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
2262 case WPA_KEY_MGMT_PSK:
2263 return (sm->proto == WPA_PROTO_RSN ?
2264 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
2265 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
2266#ifdef CONFIG_IEEE80211R
2267 case WPA_KEY_MGMT_FT_IEEE8021X:
2268 return RSN_AUTH_KEY_MGMT_FT_802_1X;
2269 case WPA_KEY_MGMT_FT_PSK:
2270 return RSN_AUTH_KEY_MGMT_FT_PSK;
2271#endif /* CONFIG_IEEE80211R */
2272#ifdef CONFIG_IEEE80211W
2273 case WPA_KEY_MGMT_IEEE8021X_SHA256:
2274 return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
2275 case WPA_KEY_MGMT_PSK_SHA256:
2276 return RSN_AUTH_KEY_MGMT_PSK_SHA256;
2277#endif /* CONFIG_IEEE80211W */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002278 case WPA_KEY_MGMT_CCKM:
2279 return (sm->proto == WPA_PROTO_RSN ?
2280 RSN_AUTH_KEY_MGMT_CCKM:
2281 WPA_AUTH_KEY_MGMT_CCKM);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002282 case WPA_KEY_MGMT_WPA_NONE:
2283 return WPA_AUTH_KEY_MGMT_NONE;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002284 case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
2285 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002286 case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
2287 return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002288 default:
2289 return 0;
2290 }
2291}
2292
2293
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002294#define RSN_SUITE "%02x-%02x-%02x-%d"
2295#define RSN_SUITE_ARG(s) \
2296((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
2297
2298/**
2299 * wpa_sm_get_mib - Dump text list of MIB entries
2300 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2301 * @buf: Buffer for the list
2302 * @buflen: Length of the buffer
2303 * Returns: Number of bytes written to buffer
2304 *
2305 * This function is used fetch dot11 MIB variables.
2306 */
2307int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
2308{
2309 char pmkid_txt[PMKID_LEN * 2 + 1];
2310 int rsna, ret;
2311 size_t len;
2312
2313 if (sm->cur_pmksa) {
2314 wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
2315 sm->cur_pmksa->pmkid, PMKID_LEN);
2316 } else
2317 pmkid_txt[0] = '\0';
2318
2319 if ((wpa_key_mgmt_wpa_psk(sm->key_mgmt) ||
2320 wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) &&
2321 sm->proto == WPA_PROTO_RSN)
2322 rsna = 1;
2323 else
2324 rsna = 0;
2325
2326 ret = os_snprintf(buf, buflen,
2327 "dot11RSNAOptionImplemented=TRUE\n"
2328 "dot11RSNAPreauthenticationImplemented=TRUE\n"
2329 "dot11RSNAEnabled=%s\n"
2330 "dot11RSNAPreauthenticationEnabled=%s\n"
2331 "dot11RSNAConfigVersion=%d\n"
2332 "dot11RSNAConfigPairwiseKeysSupported=5\n"
2333 "dot11RSNAConfigGroupCipherSize=%d\n"
2334 "dot11RSNAConfigPMKLifetime=%d\n"
2335 "dot11RSNAConfigPMKReauthThreshold=%d\n"
2336 "dot11RSNAConfigNumberOfPTKSAReplayCounters=1\n"
2337 "dot11RSNAConfigSATimeout=%d\n",
2338 rsna ? "TRUE" : "FALSE",
2339 rsna ? "TRUE" : "FALSE",
2340 RSN_VERSION,
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002341 wpa_cipher_key_len(sm->group_cipher) * 8,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002342 sm->dot11RSNAConfigPMKLifetime,
2343 sm->dot11RSNAConfigPMKReauthThreshold,
2344 sm->dot11RSNAConfigSATimeout);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002345 if (os_snprintf_error(buflen, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002346 return 0;
2347 len = ret;
2348
2349 ret = os_snprintf(
2350 buf + len, buflen - len,
2351 "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
2352 "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
2353 "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
2354 "dot11RSNAPMKIDUsed=%s\n"
2355 "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
2356 "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
2357 "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
2358 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n"
2359 "dot11RSNA4WayHandshakeFailures=%u\n",
2360 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002361 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2362 sm->pairwise_cipher)),
2363 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2364 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002365 pmkid_txt,
2366 RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
Dmitry Shmidt4530cfd2012-09-09 15:20:40 -07002367 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2368 sm->pairwise_cipher)),
2369 RSN_SUITE_ARG(wpa_cipher_to_suite(sm->proto,
2370 sm->group_cipher)),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002371 sm->dot11RSNA4WayHandshakeFailures);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002372 if (!os_snprintf_error(buflen - len, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002373 len += ret;
2374
2375 return (int) len;
2376}
2377#endif /* CONFIG_CTRL_IFACE */
2378
2379
2380static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002381 void *ctx, enum pmksa_free_reason reason)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002382{
2383 struct wpa_sm *sm = ctx;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002384 int deauth = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002385
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002386 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA cache entry free_cb: "
2387 MACSTR " reason=%d", MAC2STR(entry->aa), reason);
2388
2389 if (sm->cur_pmksa == entry) {
2390 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2391 "RSN: %s current PMKSA entry",
2392 reason == PMKSA_REPLACE ? "replaced" : "removed");
2393 pmksa_cache_clear_current(sm);
2394
2395 /*
2396 * If an entry is simply being replaced, there's no need to
2397 * deauthenticate because it will be immediately re-added.
2398 * This happens when EAP authentication is completed again
2399 * (reauth or failed PMKSA caching attempt).
2400 */
2401 if (reason != PMKSA_REPLACE)
2402 deauth = 1;
2403 }
2404
2405 if (reason == PMKSA_EXPIRE &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002406 (sm->pmk_len == entry->pmk_len &&
2407 os_memcmp(sm->pmk, entry->pmk, sm->pmk_len) == 0)) {
2408 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002409 "RSN: deauthenticating due to expired PMK");
2410 pmksa_cache_clear_current(sm);
2411 deauth = 1;
2412 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002413
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002414 if (deauth) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002415 os_memset(sm->pmk, 0, sizeof(sm->pmk));
2416 wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
2417 }
2418}
2419
2420
2421/**
2422 * wpa_sm_init - Initialize WPA state machine
2423 * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
2424 * Returns: Pointer to the allocated WPA state machine data
2425 *
2426 * This function is used to allocate a new WPA state machine and the returned
2427 * value is passed to all WPA state machine calls.
2428 */
2429struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
2430{
2431 struct wpa_sm *sm;
2432
2433 sm = os_zalloc(sizeof(*sm));
2434 if (sm == NULL)
2435 return NULL;
2436 dl_list_init(&sm->pmksa_candidates);
2437 sm->renew_snonce = 1;
2438 sm->ctx = ctx;
2439
2440 sm->dot11RSNAConfigPMKLifetime = 43200;
2441 sm->dot11RSNAConfigPMKReauthThreshold = 70;
2442 sm->dot11RSNAConfigSATimeout = 60;
2443
2444 sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
2445 if (sm->pmksa == NULL) {
2446 wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
2447 "RSN: PMKSA cache initialization failed");
2448 os_free(sm);
2449 return NULL;
2450 }
2451
2452 return sm;
2453}
2454
2455
2456/**
2457 * wpa_sm_deinit - Deinitialize WPA state machine
2458 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2459 */
2460void wpa_sm_deinit(struct wpa_sm *sm)
2461{
2462 if (sm == NULL)
2463 return;
2464 pmksa_cache_deinit(sm->pmksa);
2465 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2466 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
2467 os_free(sm->assoc_wpa_ie);
2468 os_free(sm->ap_wpa_ie);
2469 os_free(sm->ap_rsn_ie);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002470 wpa_sm_drop_sa(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002471 os_free(sm->ctx);
2472 peerkey_deinit(sm);
2473#ifdef CONFIG_IEEE80211R
2474 os_free(sm->assoc_resp_ies);
2475#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002476#ifdef CONFIG_TESTING_OPTIONS
2477 wpabuf_free(sm->test_assoc_ie);
2478#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002479 os_free(sm);
2480}
2481
2482
2483/**
2484 * wpa_sm_notify_assoc - Notify WPA state machine about association
2485 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2486 * @bssid: The BSSID of the new association
2487 *
2488 * This function is called to let WPA state machine know that the connection
2489 * was established.
2490 */
2491void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
2492{
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02002493 int clear_keys = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002494
2495 if (sm == NULL)
2496 return;
2497
2498 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2499 "WPA: Association event - clear replay counter");
2500 os_memcpy(sm->bssid, bssid, ETH_ALEN);
2501 os_memset(sm->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
2502 sm->rx_replay_counter_set = 0;
2503 sm->renew_snonce = 1;
2504 if (os_memcmp(sm->preauth_bssid, bssid, ETH_ALEN) == 0)
2505 rsn_preauth_deinit(sm);
2506
2507#ifdef CONFIG_IEEE80211R
2508 if (wpa_ft_is_completed(sm)) {
2509 /*
2510 * Clear portValid to kick EAPOL state machine to re-enter
2511 * AUTHENTICATED state to get the EAPOL port Authorized.
2512 */
2513 eapol_sm_notify_portValid(sm->eapol, FALSE);
2514 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
2515
2516 /* Prepare for the next transition */
2517 wpa_ft_prepare_auth_request(sm, NULL);
2518
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02002519 clear_keys = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002520 }
2521#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002522#ifdef CONFIG_FILS
2523 if (sm->fils_completed) {
2524 /*
2525 * Clear portValid to kick EAPOL state machine to re-enter
2526 * AUTHENTICATED state to get the EAPOL port Authorized.
2527 */
2528 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02002529 clear_keys = 0;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002530 }
2531#endif /* CONFIG_FILS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002532
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02002533 if (clear_keys) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002534 /*
2535 * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
2536 * this is not part of a Fast BSS Transition.
2537 */
2538 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
2539 sm->ptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002540 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002541 sm->tptk_set = 0;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07002542 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02002543 os_memset(&sm->gtk, 0, sizeof(sm->gtk));
2544#ifdef CONFIG_IEEE80211W
2545 os_memset(&sm->igtk, 0, sizeof(sm->igtk));
2546#endif /* CONFIG_IEEE80211W */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002547 }
2548
2549#ifdef CONFIG_TDLS
2550 wpa_tdls_assoc(sm);
2551#endif /* CONFIG_TDLS */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002552
2553#ifdef CONFIG_P2P
2554 os_memset(sm->p2p_ip_addr, 0, sizeof(sm->p2p_ip_addr));
2555#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002556}
2557
2558
2559/**
2560 * wpa_sm_notify_disassoc - Notify WPA state machine about disassociation
2561 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2562 *
2563 * This function is called to let WPA state machine know that the connection
2564 * was lost. This will abort any existing pre-authentication session.
2565 */
2566void wpa_sm_notify_disassoc(struct wpa_sm *sm)
2567{
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002568 eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
2569 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002570 peerkey_deinit(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002571 rsn_preauth_deinit(sm);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002572 pmksa_cache_clear_current(sm);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002573 if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
2574 sm->dot11RSNA4WayHandshakeFailures++;
2575#ifdef CONFIG_TDLS
2576 wpa_tdls_disassoc(sm);
2577#endif /* CONFIG_TDLS */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002578#ifdef CONFIG_FILS
2579 sm->fils_completed = 0;
2580#endif /* CONFIG_FILS */
Jouni Malinen4283f9e2017-09-22 12:06:37 +03002581#ifdef CONFIG_IEEE80211R
2582 sm->ft_reassoc_completed = 0;
2583#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002584
2585 /* Keys are not needed in the WPA state machine anymore */
2586 wpa_sm_drop_sa(sm);
Dmitry Shmidt4dd28dc2015-03-10 11:21:43 -07002587
2588 sm->msg_3_of_4_ok = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002589}
2590
2591
2592/**
2593 * wpa_sm_set_pmk - Set PMK
2594 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2595 * @pmk: The new PMK
2596 * @pmk_len: The length of the new PMK in bytes
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002597 * @pmkid: Calculated PMKID
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002598 * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002599 *
2600 * Configure the PMK for WPA state machine.
2601 */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002602void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002603 const u8 *pmkid, const u8 *bssid)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002604{
2605 if (sm == NULL)
2606 return;
2607
2608 sm->pmk_len = pmk_len;
2609 os_memcpy(sm->pmk, pmk, pmk_len);
2610
2611#ifdef CONFIG_IEEE80211R
2612 /* Set XXKey to be PSK for FT key derivation */
2613 sm->xxkey_len = pmk_len;
2614 os_memcpy(sm->xxkey, pmk, pmk_len);
2615#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002616
2617 if (bssid) {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -08002618 pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002619 bssid, sm->own_addr,
2620 sm->network_ctx, sm->key_mgmt);
2621 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002622}
2623
2624
2625/**
2626 * wpa_sm_set_pmk_from_pmksa - Set PMK based on the current PMKSA
2627 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2628 *
2629 * Take the PMK from the current PMKSA into use. If no PMKSA is active, the PMK
2630 * will be cleared.
2631 */
2632void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm)
2633{
2634 if (sm == NULL)
2635 return;
2636
2637 if (sm->cur_pmksa) {
2638 sm->pmk_len = sm->cur_pmksa->pmk_len;
2639 os_memcpy(sm->pmk, sm->cur_pmksa->pmk, sm->pmk_len);
2640 } else {
2641 sm->pmk_len = PMK_LEN;
2642 os_memset(sm->pmk, 0, PMK_LEN);
2643 }
2644}
2645
2646
2647/**
2648 * wpa_sm_set_fast_reauth - Set fast reauthentication (EAP) enabled/disabled
2649 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2650 * @fast_reauth: Whether fast reauthentication (EAP) is allowed
2651 */
2652void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth)
2653{
2654 if (sm)
2655 sm->fast_reauth = fast_reauth;
2656}
2657
2658
2659/**
2660 * wpa_sm_set_scard_ctx - Set context pointer for smartcard callbacks
2661 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2662 * @scard_ctx: Context pointer for smartcard related callback functions
2663 */
2664void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx)
2665{
2666 if (sm == NULL)
2667 return;
2668 sm->scard_ctx = scard_ctx;
2669 if (sm->preauth_eapol)
2670 eapol_sm_register_scard_ctx(sm->preauth_eapol, scard_ctx);
2671}
2672
2673
2674/**
2675 * wpa_sm_set_config - Notification of current configration change
2676 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2677 * @config: Pointer to current network configuration
2678 *
2679 * Notify WPA state machine that configuration has changed. config will be
2680 * stored as a backpointer to network configuration. This can be %NULL to clear
2681 * the stored pointed.
2682 */
2683void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
2684{
2685 if (!sm)
2686 return;
2687
2688 if (config) {
2689 sm->network_ctx = config->network_ctx;
2690 sm->peerkey_enabled = config->peerkey_enabled;
2691 sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
2692 sm->proactive_key_caching = config->proactive_key_caching;
2693 sm->eap_workaround = config->eap_workaround;
2694 sm->eap_conf_ctx = config->eap_conf_ctx;
2695 if (config->ssid) {
2696 os_memcpy(sm->ssid, config->ssid, config->ssid_len);
2697 sm->ssid_len = config->ssid_len;
2698 } else
2699 sm->ssid_len = 0;
2700 sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002701 sm->p2p = config->p2p;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002702 sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002703 } else {
2704 sm->network_ctx = NULL;
2705 sm->peerkey_enabled = 0;
2706 sm->allowed_pairwise_cipher = 0;
2707 sm->proactive_key_caching = 0;
2708 sm->eap_workaround = 0;
2709 sm->eap_conf_ctx = NULL;
2710 sm->ssid_len = 0;
2711 sm->wpa_ptk_rekey = 0;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002712 sm->p2p = 0;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002713 sm->wpa_rsc_relaxation = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002714 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002715}
2716
2717
2718/**
2719 * wpa_sm_set_own_addr - Set own MAC address
2720 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2721 * @addr: Own MAC address
2722 */
2723void wpa_sm_set_own_addr(struct wpa_sm *sm, const u8 *addr)
2724{
2725 if (sm)
2726 os_memcpy(sm->own_addr, addr, ETH_ALEN);
2727}
2728
2729
2730/**
2731 * wpa_sm_set_ifname - Set network interface name
2732 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2733 * @ifname: Interface name
2734 * @bridge_ifname: Optional bridge interface name (for pre-auth)
2735 */
2736void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname,
2737 const char *bridge_ifname)
2738{
2739 if (sm) {
2740 sm->ifname = ifname;
2741 sm->bridge_ifname = bridge_ifname;
2742 }
2743}
2744
2745
2746/**
2747 * wpa_sm_set_eapol - Set EAPOL state machine pointer
2748 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2749 * @eapol: Pointer to EAPOL state machine allocated with eapol_sm_init()
2750 */
2751void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol)
2752{
2753 if (sm)
2754 sm->eapol = eapol;
2755}
2756
2757
2758/**
2759 * wpa_sm_set_param - Set WPA state machine parameters
2760 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2761 * @param: Parameter field
2762 * @value: Parameter value
2763 * Returns: 0 on success, -1 on failure
2764 */
2765int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
2766 unsigned int value)
2767{
2768 int ret = 0;
2769
2770 if (sm == NULL)
2771 return -1;
2772
2773 switch (param) {
2774 case RSNA_PMK_LIFETIME:
2775 if (value > 0)
2776 sm->dot11RSNAConfigPMKLifetime = value;
2777 else
2778 ret = -1;
2779 break;
2780 case RSNA_PMK_REAUTH_THRESHOLD:
2781 if (value > 0 && value <= 100)
2782 sm->dot11RSNAConfigPMKReauthThreshold = value;
2783 else
2784 ret = -1;
2785 break;
2786 case RSNA_SA_TIMEOUT:
2787 if (value > 0)
2788 sm->dot11RSNAConfigSATimeout = value;
2789 else
2790 ret = -1;
2791 break;
2792 case WPA_PARAM_PROTO:
2793 sm->proto = value;
2794 break;
2795 case WPA_PARAM_PAIRWISE:
2796 sm->pairwise_cipher = value;
2797 break;
2798 case WPA_PARAM_GROUP:
2799 sm->group_cipher = value;
2800 break;
2801 case WPA_PARAM_KEY_MGMT:
2802 sm->key_mgmt = value;
2803 break;
2804#ifdef CONFIG_IEEE80211W
2805 case WPA_PARAM_MGMT_GROUP:
2806 sm->mgmt_group_cipher = value;
2807 break;
2808#endif /* CONFIG_IEEE80211W */
2809 case WPA_PARAM_RSN_ENABLED:
2810 sm->rsn_enabled = value;
2811 break;
2812 case WPA_PARAM_MFP:
2813 sm->mfp = value;
2814 break;
2815 default:
2816 break;
2817 }
2818
2819 return ret;
2820}
2821
2822
2823/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002824 * wpa_sm_get_status - Get WPA state machine
2825 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2826 * @buf: Buffer for status information
2827 * @buflen: Maximum buffer length
2828 * @verbose: Whether to include verbose status information
2829 * Returns: Number of bytes written to buf.
2830 *
2831 * Query WPA state machine for status information. This function fills in
2832 * a text area with current status information. If the buffer (buf) is not
2833 * large enough, status information will be truncated to fit the buffer.
2834 */
2835int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
2836 int verbose)
2837{
2838 char *pos = buf, *end = buf + buflen;
2839 int ret;
2840
2841 ret = os_snprintf(pos, end - pos,
2842 "pairwise_cipher=%s\n"
2843 "group_cipher=%s\n"
2844 "key_mgmt=%s\n",
2845 wpa_cipher_txt(sm->pairwise_cipher),
2846 wpa_cipher_txt(sm->group_cipher),
2847 wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002848 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002849 return pos - buf;
2850 pos += ret;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002851
2852 if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
2853 struct wpa_ie_data rsn;
2854 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
2855 >= 0 &&
2856 rsn.capabilities & (WPA_CAPABILITY_MFPR |
2857 WPA_CAPABILITY_MFPC)) {
2858 ret = os_snprintf(pos, end - pos, "pmf=%d\n",
2859 (rsn.capabilities &
2860 WPA_CAPABILITY_MFPR) ? 2 : 1);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002861 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002862 return pos - buf;
2863 pos += ret;
2864 }
2865 }
2866
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002867 return pos - buf;
2868}
2869
2870
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07002871int wpa_sm_pmf_enabled(struct wpa_sm *sm)
2872{
2873 struct wpa_ie_data rsn;
2874
2875 if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
2876 return 0;
2877
2878 if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
2879 rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
2880 return 1;
2881
2882 return 0;
2883}
2884
2885
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002886/**
2887 * wpa_sm_set_assoc_wpa_ie_default - Generate own WPA/RSN IE from configuration
2888 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2889 * @wpa_ie: Pointer to buffer for WPA/RSN IE
2890 * @wpa_ie_len: Pointer to the length of the wpa_ie buffer
2891 * Returns: 0 on success, -1 on failure
2892 */
2893int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
2894 size_t *wpa_ie_len)
2895{
2896 int res;
2897
2898 if (sm == NULL)
2899 return -1;
2900
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08002901#ifdef CONFIG_TESTING_OPTIONS
2902 if (sm->test_assoc_ie) {
2903 wpa_printf(MSG_DEBUG,
2904 "TESTING: Replace association WPA/RSN IE");
2905 if (*wpa_ie_len < wpabuf_len(sm->test_assoc_ie))
2906 return -1;
2907 os_memcpy(wpa_ie, wpabuf_head(sm->test_assoc_ie),
2908 wpabuf_len(sm->test_assoc_ie));
2909 res = wpabuf_len(sm->test_assoc_ie);
2910 } else
2911#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002912 res = wpa_gen_wpa_ie(sm, wpa_ie, *wpa_ie_len);
2913 if (res < 0)
2914 return -1;
2915 *wpa_ie_len = res;
2916
2917 wpa_hexdump(MSG_DEBUG, "WPA: Set own WPA IE default",
2918 wpa_ie, *wpa_ie_len);
2919
2920 if (sm->assoc_wpa_ie == NULL) {
2921 /*
2922 * Make a copy of the WPA/RSN IE so that 4-Way Handshake gets
2923 * the correct version of the IE even if PMKSA caching is
2924 * aborted (which would remove PMKID from IE generation).
2925 */
2926 sm->assoc_wpa_ie = os_malloc(*wpa_ie_len);
2927 if (sm->assoc_wpa_ie == NULL)
2928 return -1;
2929
2930 os_memcpy(sm->assoc_wpa_ie, wpa_ie, *wpa_ie_len);
2931 sm->assoc_wpa_ie_len = *wpa_ie_len;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08002932 } else {
2933 wpa_hexdump(MSG_DEBUG,
2934 "WPA: Leave previously set WPA IE default",
2935 sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002936 }
2937
2938 return 0;
2939}
2940
2941
2942/**
2943 * wpa_sm_set_assoc_wpa_ie - Set own WPA/RSN IE from (Re)AssocReq
2944 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2945 * @ie: Pointer to IE data (starting from id)
2946 * @len: IE length
2947 * Returns: 0 on success, -1 on failure
2948 *
2949 * Inform WPA state machine about the WPA/RSN IE used in (Re)Association
2950 * Request frame. The IE will be used to override the default value generated
2951 * with wpa_sm_set_assoc_wpa_ie_default().
2952 */
2953int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2954{
2955 if (sm == NULL)
2956 return -1;
2957
2958 os_free(sm->assoc_wpa_ie);
2959 if (ie == NULL || len == 0) {
2960 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2961 "WPA: clearing own WPA/RSN IE");
2962 sm->assoc_wpa_ie = NULL;
2963 sm->assoc_wpa_ie_len = 0;
2964 } else {
2965 wpa_hexdump(MSG_DEBUG, "WPA: set own WPA/RSN IE", ie, len);
2966 sm->assoc_wpa_ie = os_malloc(len);
2967 if (sm->assoc_wpa_ie == NULL)
2968 return -1;
2969
2970 os_memcpy(sm->assoc_wpa_ie, ie, len);
2971 sm->assoc_wpa_ie_len = len;
2972 }
2973
2974 return 0;
2975}
2976
2977
2978/**
2979 * wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
2980 * @sm: Pointer to WPA state machine data from wpa_sm_init()
2981 * @ie: Pointer to IE data (starting from id)
2982 * @len: IE length
2983 * Returns: 0 on success, -1 on failure
2984 *
2985 * Inform WPA state machine about the WPA IE used in Beacon / Probe Response
2986 * frame.
2987 */
2988int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
2989{
2990 if (sm == NULL)
2991 return -1;
2992
2993 os_free(sm->ap_wpa_ie);
2994 if (ie == NULL || len == 0) {
2995 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
2996 "WPA: clearing AP WPA IE");
2997 sm->ap_wpa_ie = NULL;
2998 sm->ap_wpa_ie_len = 0;
2999 } else {
3000 wpa_hexdump(MSG_DEBUG, "WPA: set AP WPA IE", ie, len);
3001 sm->ap_wpa_ie = os_malloc(len);
3002 if (sm->ap_wpa_ie == NULL)
3003 return -1;
3004
3005 os_memcpy(sm->ap_wpa_ie, ie, len);
3006 sm->ap_wpa_ie_len = len;
3007 }
3008
3009 return 0;
3010}
3011
3012
3013/**
3014 * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
3015 * @sm: Pointer to WPA state machine data from wpa_sm_init()
3016 * @ie: Pointer to IE data (starting from id)
3017 * @len: IE length
3018 * Returns: 0 on success, -1 on failure
3019 *
3020 * Inform WPA state machine about the RSN IE used in Beacon / Probe Response
3021 * frame.
3022 */
3023int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
3024{
3025 if (sm == NULL)
3026 return -1;
3027
3028 os_free(sm->ap_rsn_ie);
3029 if (ie == NULL || len == 0) {
3030 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
3031 "WPA: clearing AP RSN IE");
3032 sm->ap_rsn_ie = NULL;
3033 sm->ap_rsn_ie_len = 0;
3034 } else {
3035 wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
3036 sm->ap_rsn_ie = os_malloc(len);
3037 if (sm->ap_rsn_ie == NULL)
3038 return -1;
3039
3040 os_memcpy(sm->ap_rsn_ie, ie, len);
3041 sm->ap_rsn_ie_len = len;
3042 }
3043
3044 return 0;
3045}
3046
3047
3048/**
3049 * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
3050 * @sm: Pointer to WPA state machine data from wpa_sm_init()
3051 * @data: Pointer to data area for parsing results
3052 * Returns: 0 on success, -1 if IE is not known, or -2 on parsing failure
3053 *
3054 * Parse the contents of the own WPA or RSN IE from (Re)AssocReq and write the
3055 * parsed data into data.
3056 */
3057int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data)
3058{
3059 if (sm == NULL)
3060 return -1;
3061
3062 if (sm->assoc_wpa_ie == NULL) {
3063 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
3064 "WPA: No WPA/RSN IE available from association info");
3065 return -1;
3066 }
3067 if (wpa_parse_wpa_ie(sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, data))
3068 return -2;
3069 return 0;
3070}
3071
3072
3073int wpa_sm_pmksa_cache_list(struct wpa_sm *sm, char *buf, size_t len)
3074{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003075 return pmksa_cache_list(sm->pmksa, buf, len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003076}
3077
3078
Dmitry Shmidt29333592017-01-09 12:27:11 -08003079struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_head(struct wpa_sm *sm)
3080{
3081 return pmksa_cache_head(sm->pmksa);
3082}
3083
3084
3085struct rsn_pmksa_cache_entry *
3086wpa_sm_pmksa_cache_add_entry(struct wpa_sm *sm,
3087 struct rsn_pmksa_cache_entry * entry)
3088{
3089 return pmksa_cache_add_entry(sm->pmksa, entry);
3090}
3091
3092
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003093void wpa_sm_drop_sa(struct wpa_sm *sm)
3094{
3095 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
3096 sm->ptk_set = 0;
3097 sm->tptk_set = 0;
3098 os_memset(sm->pmk, 0, sizeof(sm->pmk));
3099 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
3100 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02003101 os_memset(&sm->gtk, 0, sizeof(sm->gtk));
3102#ifdef CONFIG_IEEE80211W
3103 os_memset(&sm->igtk, 0, sizeof(sm->igtk));
3104#endif /* CONFIG_IEEE80211W */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003105#ifdef CONFIG_IEEE80211R
3106 os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
3107 os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
3108 os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1));
3109#endif /* CONFIG_IEEE80211R */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003110}
3111
3112
3113int wpa_sm_has_ptk(struct wpa_sm *sm)
3114{
3115 if (sm == NULL)
3116 return 0;
3117 return sm->ptk_set;
3118}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003119
3120
3121void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
3122{
3123 os_memcpy(sm->rx_replay_counter, replay_ctr, WPA_REPLAY_COUNTER_LEN);
3124}
3125
3126
3127void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
3128{
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07003129 pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003130}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003131
3132
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003133#ifdef CONFIG_WNM
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003134int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
3135{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003136 u16 keyinfo;
3137 u8 keylen; /* plaintext key len */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003138 u8 *key_rsc;
3139
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003140 if (subelem_id == WNM_SLEEP_SUBELEM_GTK) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003141 struct wpa_gtk_data gd;
3142
3143 os_memset(&gd, 0, sizeof(gd));
3144 keylen = wpa_cipher_key_len(sm->group_cipher);
3145 gd.key_rsc_len = wpa_cipher_rsc_len(sm->group_cipher);
3146 gd.alg = wpa_cipher_to_alg(sm->group_cipher);
3147 if (gd.alg == WPA_ALG_NONE) {
3148 wpa_printf(MSG_DEBUG, "Unsupported group cipher suite");
3149 return -1;
3150 }
3151
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003152 key_rsc = buf + 5;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003153 keyinfo = WPA_GET_LE16(buf + 2);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003154 gd.gtk_len = keylen;
3155 if (gd.gtk_len != buf[4]) {
3156 wpa_printf(MSG_DEBUG, "GTK len mismatch len %d vs %d",
3157 gd.gtk_len, buf[4]);
3158 return -1;
3159 }
3160 gd.keyidx = keyinfo & 0x03; /* B0 - B1 */
3161 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(
3162 sm, !!(keyinfo & WPA_KEY_INFO_TXRX));
3163
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003164 os_memcpy(gd.gtk, buf + 13, gd.gtk_len);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003165
3166 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
3167 gd.gtk, gd.gtk_len);
3168 if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003169 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003170 wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
3171 "WNM mode");
3172 return -1;
3173 }
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003174 os_memset(&gd, 0, sizeof(gd));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003175#ifdef CONFIG_IEEE80211W
3176 } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02003177 const struct wpa_igtk_kde *igtk;
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003178
Mathy Vanhoef10bfd642017-07-12 16:03:24 +02003179 igtk = (const struct wpa_igtk_kde *) (buf + 2);
3180 if (wpa_supplicant_install_igtk(sm, igtk) < 0)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003181 return -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003182#endif /* CONFIG_IEEE80211W */
3183 } else {
3184 wpa_printf(MSG_DEBUG, "Unknown element id");
3185 return -1;
3186 }
3187
3188 return 0;
3189}
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003190#endif /* CONFIG_WNM */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003191
3192
3193#ifdef CONFIG_PEERKEY
3194int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
3195 const u8 *buf, size_t len)
3196{
3197 struct wpa_peerkey *peerkey;
3198
3199 for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
3200 if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
3201 break;
3202 }
3203
3204 if (!peerkey)
3205 return 0;
3206
3207 wpa_sm_rx_eapol(sm, src_addr, buf, len);
3208
3209 return 1;
3210}
3211#endif /* CONFIG_PEERKEY */
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08003212
3213
3214#ifdef CONFIG_P2P
3215
3216int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)
3217{
3218 if (sm == NULL || WPA_GET_BE32(sm->p2p_ip_addr) == 0)
3219 return -1;
3220 os_memcpy(buf, sm->p2p_ip_addr, 3 * 4);
3221 return 0;
3222}
3223
3224#endif /* CONFIG_P2P */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003225
3226
3227void wpa_sm_set_rx_replay_ctr(struct wpa_sm *sm, const u8 *rx_replay_counter)
3228{
3229 if (rx_replay_counter == NULL)
3230 return;
3231
3232 os_memcpy(sm->rx_replay_counter, rx_replay_counter,
3233 WPA_REPLAY_COUNTER_LEN);
3234 sm->rx_replay_counter_set = 1;
3235 wpa_printf(MSG_DEBUG, "Updated key replay counter");
3236}
3237
3238
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003239void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
3240 const u8 *ptk_kck, size_t ptk_kck_len,
3241 const u8 *ptk_kek, size_t ptk_kek_len)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003242{
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003243 if (ptk_kck && ptk_kck_len <= WPA_KCK_MAX_LEN) {
3244 os_memcpy(sm->ptk.kck, ptk_kck, ptk_kck_len);
3245 sm->ptk.kck_len = ptk_kck_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003246 wpa_printf(MSG_DEBUG, "Updated PTK KCK");
3247 }
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003248 if (ptk_kek && ptk_kek_len <= WPA_KEK_MAX_LEN) {
3249 os_memcpy(sm->ptk.kek, ptk_kek, ptk_kek_len);
3250 sm->ptk.kek_len = ptk_kek_len;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003251 wpa_printf(MSG_DEBUG, "Updated PTK KEK");
3252 }
3253 sm->ptk_set = 1;
3254}
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08003255
3256
3257#ifdef CONFIG_TESTING_OPTIONS
3258void wpa_sm_set_test_assoc_ie(struct wpa_sm *sm, struct wpabuf *buf)
3259{
3260 wpabuf_free(sm->test_assoc_ie);
3261 sm->test_assoc_ie = buf;
3262}
3263#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003264
3265
3266#ifdef CONFIG_FILS
3267
3268struct wpabuf * fils_build_auth(struct wpa_sm *sm)
3269{
3270 struct wpabuf *buf = NULL;
3271 struct wpabuf *erp_msg;
3272
3273 erp_msg = eapol_sm_build_erp_reauth_start(sm->eapol);
3274 if (!erp_msg && !sm->cur_pmksa) {
3275 wpa_printf(MSG_DEBUG,
3276 "FILS: Neither ERP EAP-Initiate/Re-auth nor PMKSA cache entry is available - skip FILS");
3277 goto fail;
3278 }
3279
3280 wpa_printf(MSG_DEBUG, "FILS: Try to use FILS (erp=%d pmksa_cache=%d)",
3281 erp_msg != NULL, sm->cur_pmksa != NULL);
3282
3283 sm->fils_completed = 0;
3284
3285 if (!sm->assoc_wpa_ie) {
3286 wpa_printf(MSG_INFO, "FILS: No own RSN IE set for FILS");
3287 goto fail;
3288 }
3289
3290 if (random_get_bytes(sm->fils_nonce, FILS_NONCE_LEN) < 0 ||
3291 random_get_bytes(sm->fils_session, FILS_SESSION_LEN) < 0)
3292 goto fail;
3293
3294 wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Nonce",
3295 sm->fils_nonce, FILS_NONCE_LEN);
3296 wpa_hexdump(MSG_DEBUG, "FILS: Generated FILS Session",
3297 sm->fils_session, FILS_SESSION_LEN);
3298
3299 buf = wpabuf_alloc(1000 + sm->assoc_wpa_ie_len);
3300 if (!buf)
3301 goto fail;
3302
3303 /* Fields following the Authentication algorithm number field */
3304
3305 /* Authentication Transaction seq# */
3306 wpabuf_put_le16(buf, 1);
3307
3308 /* Status Code */
3309 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
3310
3311 /* TODO: Finite Cyclic Group when using PK or PFS */
3312 /* TODO: Element when using PK or PFS */
3313
3314 /* RSNE */
3315 wpa_hexdump(MSG_DEBUG, "FILS: RSNE in FILS Authentication frame",
3316 sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
3317 wpabuf_put_data(buf, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len);
3318
3319 /* TODO: MDE when using FILS for FT initial association */
3320 /* TODO: FTE when using FILS for FT initial association */
3321
3322 /* FILS Nonce */
3323 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3324 wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN); /* Length */
3325 /* Element ID Extension */
3326 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
3327 wpabuf_put_data(buf, sm->fils_nonce, FILS_NONCE_LEN);
3328
3329 /* FILS Session */
3330 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3331 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
3332 /* Element ID Extension */
3333 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
3334 wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
3335
3336 /* FILS Wrapped Data */
Paul Stewart092955c2017-02-06 09:13:09 -08003337 sm->fils_erp_pmkid_set = 0;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003338 if (erp_msg) {
3339 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3340 wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg)); /* Length */
3341 /* Element ID Extension */
3342 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_WRAPPED_DATA);
3343 wpabuf_put_buf(buf, erp_msg);
Paul Stewart092955c2017-02-06 09:13:09 -08003344 /* Calculate pending PMKID here so that we do not need to
3345 * maintain a copy of the EAP-Initiate/Reauth message. */
3346 if (fils_pmkid_erp(sm->key_mgmt, wpabuf_head(erp_msg),
3347 wpabuf_len(erp_msg),
3348 sm->fils_erp_pmkid) == 0)
3349 sm->fils_erp_pmkid_set = 1;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003350 }
3351
3352 wpa_hexdump_buf(MSG_DEBUG, "RSN: FILS fields for Authentication frame",
3353 buf);
3354
3355fail:
3356 wpabuf_free(erp_msg);
3357 return buf;
3358}
3359
3360
3361int fils_process_auth(struct wpa_sm *sm, const u8 *data, size_t len)
3362{
3363 const u8 *pos, *end;
3364 struct ieee802_11_elems elems;
3365 struct wpa_ie_data rsn;
3366 int pmkid_match = 0;
3367 u8 ick[FILS_ICK_MAX_LEN];
3368 size_t ick_len;
3369 int res;
3370
3371 wpa_hexdump(MSG_DEBUG, "FILS: Authentication frame fields",
3372 data, len);
3373 pos = data;
3374 end = data + len;
3375
3376 /* TODO: Finite Cyclic Group when using PK or PFS */
3377 /* TODO: Element when using PK or PFS */
3378
3379 wpa_hexdump(MSG_DEBUG, "FILS: Remaining IEs", pos, end - pos);
3380 if (ieee802_11_parse_elems(pos, end - pos, &elems, 1) == ParseFailed) {
3381 wpa_printf(MSG_DEBUG, "FILS: Could not parse elements");
3382 return -1;
3383 }
3384
3385 /* RSNE */
3386 wpa_hexdump(MSG_DEBUG, "FILS: RSN element", elems.rsn_ie,
3387 elems.rsn_ie_len);
3388 if (!elems.rsn_ie ||
3389 wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
3390 &rsn) < 0) {
3391 wpa_printf(MSG_DEBUG, "FILS: No RSN element");
3392 return -1;
3393 }
3394
3395 if (!elems.fils_nonce) {
3396 wpa_printf(MSG_DEBUG, "FILS: No FILS Nonce field");
3397 return -1;
3398 }
3399 os_memcpy(sm->fils_anonce, elems.fils_nonce, FILS_NONCE_LEN);
3400 wpa_hexdump(MSG_DEBUG, "FILS: ANonce", sm->fils_anonce, FILS_NONCE_LEN);
3401
3402 /* TODO: MDE when using FILS+FT */
3403 /* TODO: FTE when using FILS+FT */
3404
3405 /* PMKID List */
3406 if (rsn.pmkid && rsn.num_pmkid > 0) {
3407 wpa_hexdump(MSG_DEBUG, "FILS: PMKID List",
3408 rsn.pmkid, rsn.num_pmkid * PMKID_LEN);
3409
3410 if (rsn.num_pmkid != 1) {
3411 wpa_printf(MSG_DEBUG, "FILS: Invalid PMKID selection");
3412 return -1;
3413 }
3414 wpa_hexdump(MSG_DEBUG, "FILS: PMKID", rsn.pmkid, PMKID_LEN);
3415 if (os_memcmp(sm->cur_pmksa->pmkid, rsn.pmkid, PMKID_LEN) != 0)
3416 {
3417 wpa_printf(MSG_DEBUG, "FILS: PMKID mismatch");
3418 wpa_hexdump(MSG_DEBUG, "FILS: Expected PMKID",
3419 sm->cur_pmksa->pmkid, PMKID_LEN);
3420 return -1;
3421 }
3422 wpa_printf(MSG_DEBUG,
3423 "FILS: Matching PMKID - continue using PMKSA caching");
3424 pmkid_match = 1;
3425 }
3426 if (!pmkid_match && sm->cur_pmksa) {
3427 wpa_printf(MSG_DEBUG,
3428 "FILS: No PMKID match - cannot use cached PMKSA entry");
3429 sm->cur_pmksa = NULL;
3430 }
3431
3432 /* FILS Session */
3433 if (!elems.fils_session) {
3434 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
3435 return -1;
3436 }
3437 wpa_hexdump(MSG_DEBUG, "FILS: FILS Session", elems.fils_session,
3438 FILS_SESSION_LEN);
3439 if (os_memcmp(sm->fils_session, elems.fils_session, FILS_SESSION_LEN)
3440 != 0) {
3441 wpa_printf(MSG_DEBUG, "FILS: Session mismatch");
3442 wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
3443 sm->fils_session, FILS_SESSION_LEN);
3444 return -1;
3445 }
3446
3447 /* FILS Wrapped Data */
3448 if (!sm->cur_pmksa && elems.fils_wrapped_data) {
Paul Stewart092955c2017-02-06 09:13:09 -08003449 u8 rmsk[ERP_MAX_KEY_LEN];
3450 size_t rmsk_len;
3451
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003452 wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
3453 elems.fils_wrapped_data,
3454 elems.fils_wrapped_data_len);
3455 eapol_sm_process_erp_finish(sm->eapol, elems.fils_wrapped_data,
3456 elems.fils_wrapped_data_len);
3457 if (eapol_sm_failed(sm->eapol))
3458 return -1;
3459
Paul Stewart092955c2017-02-06 09:13:09 -08003460 rmsk_len = ERP_MAX_KEY_LEN;
3461 res = eapol_sm_get_key(sm->eapol, rmsk, rmsk_len);
3462 if (res == PMK_LEN) {
3463 rmsk_len = PMK_LEN;
3464 res = eapol_sm_get_key(sm->eapol, rmsk, rmsk_len);
3465 }
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003466 if (res)
3467 return -1;
3468
Paul Stewart092955c2017-02-06 09:13:09 -08003469 res = fils_rmsk_to_pmk(sm->key_mgmt, rmsk, rmsk_len,
3470 sm->fils_nonce, sm->fils_anonce, NULL, 0,
3471 sm->pmk, &sm->pmk_len);
3472 os_memset(rmsk, 0, sizeof(rmsk));
Dmitry Shmidtebd93af2017-02-21 13:40:44 -08003473 if (res)
3474 return -1;
Paul Stewart092955c2017-02-06 09:13:09 -08003475
3476 if (!sm->fils_erp_pmkid_set) {
3477 wpa_printf(MSG_DEBUG, "FILS: PMKID not available");
3478 return -1;
3479 }
3480 wpa_hexdump(MSG_DEBUG, "FILS: PMKID", sm->fils_erp_pmkid,
3481 PMKID_LEN);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003482 wpa_printf(MSG_DEBUG, "FILS: ERP processing succeeded - add PMKSA cache entry for the result");
Paul Stewart092955c2017-02-06 09:13:09 -08003483 sm->cur_pmksa = pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len,
3484 sm->fils_erp_pmkid, NULL, 0,
3485 sm->bssid, sm->own_addr,
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003486 sm->network_ctx, sm->key_mgmt);
3487 }
3488
3489 if (!sm->cur_pmksa) {
3490 wpa_printf(MSG_DEBUG,
3491 "FILS: No remaining options to continue FILS authentication");
3492 return -1;
3493 }
3494
3495 if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
3496 sm->fils_nonce, sm->fils_anonce, &sm->ptk,
3497 ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher) <
3498 0) {
3499 wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
3500 return -1;
3501 }
3502 sm->ptk_set = 1;
3503 sm->tptk_set = 0;
3504 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
3505
3506 res = fils_key_auth_sk(ick, ick_len, sm->fils_nonce,
3507 sm->fils_anonce, sm->own_addr, sm->bssid,
3508 NULL, 0, NULL, 0, /* TODO: SK+PFS */
3509 sm->key_mgmt, sm->fils_key_auth_sta,
3510 sm->fils_key_auth_ap,
3511 &sm->fils_key_auth_len);
3512 os_memset(ick, 0, sizeof(ick));
3513 return res;
3514}
3515
3516
3517struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek,
3518 size_t *kek_len, const u8 **snonce,
Paul Stewart092955c2017-02-06 09:13:09 -08003519 const u8 **anonce,
3520 const struct wpabuf **hlp,
3521 unsigned int num_hlp)
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003522{
3523 struct wpabuf *buf;
Paul Stewart092955c2017-02-06 09:13:09 -08003524 size_t len;
3525 unsigned int i;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003526
Paul Stewart092955c2017-02-06 09:13:09 -08003527 len = 1000;
3528 for (i = 0; hlp && i < num_hlp; i++)
3529 len += 10 + wpabuf_len(hlp[i]);
3530 buf = wpabuf_alloc(len);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003531 if (!buf)
3532 return NULL;
3533
3534 /* FILS Session */
3535 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3536 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN); /* Length */
3537 /* Element ID Extension */
3538 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
3539 wpabuf_put_data(buf, sm->fils_session, FILS_SESSION_LEN);
3540
3541 /* Everything after FILS Session element gets encrypted in the driver
3542 * with KEK. The buffer returned from here is the plaintext version. */
3543
3544 /* TODO: FILS Public Key */
3545
3546 /* FILS Key Confirm */
3547 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3548 wpabuf_put_u8(buf, 1 + sm->fils_key_auth_len); /* Length */
3549 /* Element ID Extension */
3550 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_KEY_CONFIRM);
3551 wpabuf_put_data(buf, sm->fils_key_auth_sta, sm->fils_key_auth_len);
3552
Paul Stewart092955c2017-02-06 09:13:09 -08003553 /* FILS HLP Container */
3554 for (i = 0; hlp && i < num_hlp; i++) {
3555 const u8 *pos = wpabuf_head(hlp[i]);
3556 size_t left = wpabuf_len(hlp[i]);
3557
3558 wpabuf_put_u8(buf, WLAN_EID_EXTENSION); /* Element ID */
3559 if (left <= 254)
3560 len = 1 + left;
3561 else
3562 len = 255;
3563 wpabuf_put_u8(buf, len); /* Length */
3564 /* Element ID Extension */
3565 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_HLP_CONTAINER);
3566 /* Destination MAC Address, Source MAC Address, HLP Packet.
3567 * HLP Packet is in MSDU format (i.e., included the LLC/SNAP
3568 * header when LPD is used). */
3569 wpabuf_put_data(buf, pos, len - 1);
3570 pos += len - 1;
3571 left -= len - 1;
3572 while (left) {
3573 wpabuf_put_u8(buf, WLAN_EID_FRAGMENT);
3574 len = left > 255 ? 255 : left;
3575 wpabuf_put_u8(buf, len);
3576 wpabuf_put_data(buf, pos, len);
3577 pos += len;
3578 left -= len;
3579 }
3580 }
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003581
3582 /* TODO: FILS IP Address Assignment */
3583
3584 wpa_hexdump_buf(MSG_DEBUG, "FILS: Association Request plaintext", buf);
3585
3586 *kek = sm->ptk.kek;
3587 *kek_len = sm->ptk.kek_len;
3588 wpa_hexdump_key(MSG_DEBUG, "FILS: KEK for AEAD", *kek, *kek_len);
3589 *snonce = sm->fils_nonce;
3590 wpa_hexdump(MSG_DEBUG, "FILS: SNonce for AEAD AAD",
3591 *snonce, FILS_NONCE_LEN);
3592 *anonce = sm->fils_anonce;
3593 wpa_hexdump(MSG_DEBUG, "FILS: ANonce for AEAD AAD",
3594 *anonce, FILS_NONCE_LEN);
3595
3596 return buf;
3597}
3598
3599
Dmitry Shmidtebd93af2017-02-21 13:40:44 -08003600static void fils_process_hlp_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
3601{
3602 const u8 *pos, *end;
3603
3604 wpa_hexdump(MSG_MSGDUMP, "FILS: HLP response", resp, len);
3605 if (len < 2 * ETH_ALEN)
3606 return;
3607 pos = resp + 2 * ETH_ALEN;
3608 end = resp + len;
3609 if (end - pos >= 6 &&
3610 os_memcmp(pos, "\xaa\xaa\x03\x00\x00\x00", 6) == 0)
3611 pos += 6; /* Remove SNAP/LLC header */
3612 wpa_sm_fils_hlp_rx(sm, resp, resp + ETH_ALEN, pos, end - pos);
3613}
3614
3615
3616static void fils_process_hlp_container(struct wpa_sm *sm, const u8 *pos,
3617 size_t len)
3618{
3619 const u8 *end = pos + len;
3620 u8 *tmp, *tmp_pos;
3621
3622 /* Check if there are any FILS HLP Container elements */
3623 while (end - pos >= 2) {
3624 if (2 + pos[1] > end - pos)
3625 return;
3626 if (pos[0] == WLAN_EID_EXTENSION &&
3627 pos[1] >= 1 + 2 * ETH_ALEN &&
3628 pos[2] == WLAN_EID_EXT_FILS_HLP_CONTAINER)
3629 break;
3630 pos += 2 + pos[1];
3631 }
3632 if (end - pos < 2)
3633 return; /* No FILS HLP Container elements */
3634
3635 tmp = os_malloc(end - pos);
3636 if (!tmp)
3637 return;
3638
3639 while (end - pos >= 2) {
3640 if (2 + pos[1] > end - pos ||
3641 pos[0] != WLAN_EID_EXTENSION ||
3642 pos[1] < 1 + 2 * ETH_ALEN ||
3643 pos[2] != WLAN_EID_EXT_FILS_HLP_CONTAINER)
3644 break;
3645 tmp_pos = tmp;
3646 os_memcpy(tmp_pos, pos + 3, pos[1] - 1);
3647 tmp_pos += pos[1] - 1;
3648 pos += 2 + pos[1];
3649
3650 /* Add possible fragments */
3651 while (end - pos >= 2 && pos[0] == WLAN_EID_FRAGMENT &&
3652 2 + pos[1] <= end - pos) {
3653 os_memcpy(tmp_pos, pos + 2, pos[1]);
3654 tmp_pos += pos[1];
3655 pos += 2 + pos[1];
3656 }
3657
3658 fils_process_hlp_resp(sm, tmp, tmp_pos - tmp);
3659 }
3660
3661 os_free(tmp);
3662}
3663
3664
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003665int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
3666{
3667 const struct ieee80211_mgmt *mgmt;
3668 const u8 *end, *ie_start;
3669 struct ieee802_11_elems elems;
3670 int keylen, rsclen;
3671 enum wpa_alg alg;
3672 struct wpa_gtk_data gd;
3673 int maxkeylen;
3674 struct wpa_eapol_ie_parse kde;
3675
3676 if (!sm || !sm->ptk_set) {
3677 wpa_printf(MSG_DEBUG, "FILS: No KEK available");
3678 return -1;
3679 }
3680
3681 if (!wpa_key_mgmt_fils(sm->key_mgmt)) {
3682 wpa_printf(MSG_DEBUG, "FILS: Not a FILS AKM");
3683 return -1;
3684 }
3685
3686 wpa_hexdump(MSG_DEBUG, "FILS: (Re)Association Response frame",
3687 resp, len);
3688
3689 mgmt = (const struct ieee80211_mgmt *) resp;
3690 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_resp))
3691 return -1;
3692
3693 end = resp + len;
3694 /* Same offset for Association Response and Reassociation Response */
3695 ie_start = mgmt->u.assoc_resp.variable;
3696
3697 if (ieee802_11_parse_elems(ie_start, end - ie_start, &elems, 1) ==
3698 ParseFailed) {
3699 wpa_printf(MSG_DEBUG,
3700 "FILS: Failed to parse decrypted elements");
3701 goto fail;
3702 }
3703
3704 if (!elems.fils_session) {
3705 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
3706 return -1;
3707 }
3708 if (os_memcmp(elems.fils_session, sm->fils_session,
3709 FILS_SESSION_LEN) != 0) {
3710 wpa_printf(MSG_DEBUG, "FILS: FILS Session mismatch");
3711 wpa_hexdump(MSG_DEBUG, "FILS: Received FILS Session",
3712 elems.fils_session, FILS_SESSION_LEN);
3713 wpa_hexdump(MSG_DEBUG, "FILS: Expected FILS Session",
3714 sm->fils_session, FILS_SESSION_LEN);
3715 }
3716
3717 /* TODO: FILS Public Key */
3718
3719 if (!elems.fils_key_confirm) {
3720 wpa_printf(MSG_DEBUG, "FILS: No FILS Key Confirm element");
3721 goto fail;
3722 }
3723 if (elems.fils_key_confirm_len != sm->fils_key_auth_len) {
3724 wpa_printf(MSG_DEBUG,
3725 "FILS: Unexpected Key-Auth length %d (expected %d)",
3726 elems.fils_key_confirm_len,
3727 (int) sm->fils_key_auth_len);
3728 goto fail;
3729 }
3730 if (os_memcmp(elems.fils_key_confirm, sm->fils_key_auth_ap,
3731 sm->fils_key_auth_len) != 0) {
3732 wpa_printf(MSG_DEBUG, "FILS: Key-Auth mismatch");
3733 wpa_hexdump(MSG_DEBUG, "FILS: Received Key-Auth",
3734 elems.fils_key_confirm,
3735 elems.fils_key_confirm_len);
3736 wpa_hexdump(MSG_DEBUG, "FILS: Expected Key-Auth",
3737 sm->fils_key_auth_ap, sm->fils_key_auth_len);
3738 goto fail;
3739 }
3740
3741 /* Key Delivery */
3742 if (!elems.key_delivery) {
3743 wpa_printf(MSG_DEBUG, "FILS: No Key Delivery element");
3744 goto fail;
3745 }
3746
3747 /* Parse GTK and set the key to the driver */
3748 os_memset(&gd, 0, sizeof(gd));
3749 if (wpa_supplicant_parse_ies(elems.key_delivery + WPA_KEY_RSC_LEN,
3750 elems.key_delivery_len - WPA_KEY_RSC_LEN,
3751 &kde) < 0) {
3752 wpa_printf(MSG_DEBUG, "FILS: Failed to parse KDEs");
3753 goto fail;
3754 }
3755 if (!kde.gtk) {
3756 wpa_printf(MSG_DEBUG, "FILS: No GTK KDE");
3757 goto fail;
3758 }
3759 maxkeylen = gd.gtk_len = kde.gtk_len - 2;
3760 if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
3761 gd.gtk_len, maxkeylen,
3762 &gd.key_rsc_len, &gd.alg))
3763 goto fail;
3764
3765 wpa_hexdump_key(MSG_DEBUG, "FILS: Received GTK", kde.gtk, kde.gtk_len);
3766 gd.keyidx = kde.gtk[0] & 0x3;
3767 gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
3768 !!(kde.gtk[0] & BIT(2)));
3769 if (kde.gtk_len - 2 > sizeof(gd.gtk)) {
3770 wpa_printf(MSG_DEBUG, "FILS: Too long GTK in GTK KDE (len=%lu)",
3771 (unsigned long) kde.gtk_len - 2);
3772 goto fail;
3773 }
3774 os_memcpy(gd.gtk, kde.gtk + 2, kde.gtk_len - 2);
3775
3776 wpa_printf(MSG_DEBUG, "FILS: Set GTK to driver");
3777 if (wpa_supplicant_install_gtk(sm, &gd, elems.key_delivery) < 0) {
3778 wpa_printf(MSG_DEBUG, "FILS: Failed to set GTK");
3779 goto fail;
3780 }
3781
3782 if (ieee80211w_set_keys(sm, &kde) < 0) {
3783 wpa_printf(MSG_DEBUG, "FILS: Failed to set IGTK");
3784 goto fail;
3785 }
3786
3787 alg = wpa_cipher_to_alg(sm->pairwise_cipher);
3788 keylen = wpa_cipher_key_len(sm->pairwise_cipher);
3789 rsclen = wpa_cipher_rsc_len(sm->pairwise_cipher);
3790 wpa_hexdump_key(MSG_DEBUG, "FILS: Set TK to driver",
3791 sm->ptk.tk, keylen);
3792 if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, null_rsc, rsclen,
3793 sm->ptk.tk, keylen) < 0) {
3794 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
3795 "FILS: Failed to set PTK to the driver (alg=%d keylen=%d bssid="
3796 MACSTR ")",
3797 alg, keylen, MAC2STR(sm->bssid));
3798 goto fail;
3799 }
3800
3801 /* TODO: TK could be cleared after auth frame exchange now that driver
3802 * takes care of association frame encryption/decryption. */
3803 /* TK is not needed anymore in supplicant */
3804 os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
Mathy Vanhoefc66556c2017-09-29 04:22:51 +02003805 sm->ptk.installed = 1;
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003806
Dmitry Shmidtebd93af2017-02-21 13:40:44 -08003807 /* FILS HLP Container */
3808 fils_process_hlp_container(sm, ie_start, end - ie_start);
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -08003809
3810 /* TODO: FILS IP Address Assignment */
3811
3812 wpa_printf(MSG_DEBUG, "FILS: Auth+Assoc completed successfully");
3813 sm->fils_completed = 1;
3814
3815 return 0;
3816fail:
3817 return -1;
3818}
3819
3820#endif /* CONFIG_FILS */
3821
3822
3823int wpa_fils_is_completed(struct wpa_sm *sm)
3824{
3825#ifdef CONFIG_FILS
3826 return sm && sm->fils_completed;
3827#else /* CONFIG_FILS */
3828 return 0;
3829#endif /* CONFIG_FILS */
3830}