~ubuntu-branches/ubuntu/precise/wpasupplicant/precise-proposed

« back to all changes in this revision

Viewing changes to .pc/0012-pmkokc-PMKSA-make-deauthentication-due-to-cache-entry-remov.patch/src/rsn_supp/wpa.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2013-06-12 15:57:50 UTC
  • Revision ID: package-import@ubuntu.com-20130612155750-go9lgylcef8n3f2f
Tags: 0.7.3-6ubuntu2.2
* Multiple patches to reduce the number of disconnections for WPA Enterprise
  roaming and Opportunistic Key Caching. (LP: #1187524)
* In debian/patches:
  0001-sme-fix-retry-after-auth-assoc-timeout-failure.patch,
  0002-sme-optimize-recovery-from-common-load-balancing-mechanisms.patch,
  0003-sme-blacklist-bss-on-first-failure-if-only-a-*.patch,
  0004-sme-extend-load-balancing-optimization-in-bss-blacklisting.patch,
  0005-sme-optimize-recovery-from-association-command-failures.patch,
  0006-sme-add-timers-for-authentication-and-association.patch,
  0007-sme-nl80211-set-cipher-suites.patch:
  Cherry-pick patches fixing SME (Session Management Entity) for the nl80211
  driver, which works as a basis for the OKC patches.
* In debian/patches:
  0001-pmkokc-Set-portValid-TRUE-on-association-for-driver-based-4.patch,
  0002-pmkokc-Clear-WPA-and-EAPOL-state-machine-config-pointer-on-.patch,
  0003-pmkokc-Clear-driver-PMKSA-cache-entry-on-PMKSA-cache-expira.patch,
  0004-pmkokc-Flush-PMKSA-cache-entries-and-invalidate-EAP-state-o.patch,
  0005-pmkokc-Fix-proactive_key_caching-configuration-to-WPA-code.patch,
  0006-pmkokc-RSN-Add-a-debug-message-when-considing-addition-of-O.patch,
  0007-pmkokc-Clear-OKC-based-PMKSA-caching-entries-if-PMK-is-chan.patch,
  0008-pmkokc-Move-wpa_sm_remove_pmkid-call-to-PMKSA-cache-entry-f.patch,
  0009-pmkokc-Use-PMKSA-cache-entries-with-only-a-single-network-c.patch,
  0010-pmkokc-PMKSA-Do-not-evict-active-cache-entry-when-adding-ne.patch,
  0011-pmkokc-PMKSA-Set-cur_pmksa-pointer-during-initial-associati.patch,
  0012-pmkokc-PMKSA-make-deauthentication-due-to-cache-entry-remov.patch,
  0013-pmkokc-PMKSA-update-current-cache-entry-due-to-association-.patch:
  Cherry-pick patches to properly do OKC (Opportunistic Key Caching) which
  helps maintaining connectivity on networks secured with WPA Enterprise,
  especially on nl80211-based drivers -- these patches require SME, and add
  or fix key caching and handling of the cache entries.
* debian/patches/force-enable-okc.patch: force Opportunistic Key Caching to
  be enabled.
* debian/patches/less-aggressive-roaming.patch: use less aggressive roaming
  settings to avoid switching to another AP unnecessarily, when the actual
  signal level difference is small.
* debian/patches/wpa_supplicant-dbus-null-error.patch: Don't send NULL to
  dbus_message_new_error().
* debian/patches/0001-nl80211-Fix-UNSPEC-signal-quality-reporting.patch: fix
  marking qual as invalid rather than signal level.
* debian/patches/wpa_supplicant-squelch-driver-disconnect-spam.patch: recover
  cleanly from streams of disconnect messages (like on iwl3945).
* debian/patches/wpa_supplicant-assoc-timeout.patch: increase association
  timeouts.

Show diffs side-by-side

added added

removed removed

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