14126Szf162725 /*
25895Syz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
34126Szf162725 * Use is subject to license terms.
44126Szf162725 */
54126Szf162725
64126Szf162725 /*
74126Szf162725 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
84126Szf162725 * Sun elects to license this software under the BSD license.
94126Szf162725 * See README for more details.
104126Szf162725 */
114126Szf162725
124126Szf162725 #include <stdio.h>
134126Szf162725 #include <stdlib.h>
144126Szf162725 #include <string.h>
154126Szf162725 #include <time.h>
164126Szf162725 #include <netinet/in.h>
174126Szf162725 #include <sys/ethernet.h>
184126Szf162725 #include <fcntl.h>
194126Szf162725 #include <unistd.h>
204126Szf162725
214126Szf162725 #include "wpa_impl.h"
224126Szf162725 #include "wpa_enc.h"
234126Szf162725 #include "driver.h"
244126Szf162725 #include "eloop.h"
254126Szf162725 #include "l2_packet.h"
264126Szf162725
274126Szf162725 static void pmksa_cache_set_expiration(struct wpa_supplicant *);
284126Szf162725
294126Szf162725 /*
304126Szf162725 * IEEE 802.11i/D3.0
314126Szf162725 */
324126Szf162725 static const int WPA_SELECTOR_LEN = 4;
336411Szf162725 static const uint8_t WPA_OUI_AND_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
344126Szf162725 static const uint8_t
354126Szf162725 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 };
364126Szf162725 static const uint8_t
374126Szf162725 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 };
384126Szf162725 static const uint8_t WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 };
394126Szf162725 static const uint8_t WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 };
404126Szf162725 static const uint8_t WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 };
414126Szf162725 static const uint8_t WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 };
424126Szf162725 static const uint8_t WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
434126Szf162725
444126Szf162725 /*
454126Szf162725 * WPA IE version 1
464126Szf162725 * 00-50-f2:1 (OUI:OUI type)
474126Szf162725 * 0x01 0x00 (version; little endian)
484126Szf162725 * (all following fields are optional:)
494126Szf162725 * Group Suite Selector (4 octets) (default: TKIP)
504126Szf162725 * Pairwise Suite Count (2 octets, little endian) (default: 1)
514126Szf162725 * Pairwise Suite List (4 * n octets) (default: TKIP)
524126Szf162725 * Authenticated Key Management Suite Count (2 octets, little endian)
534126Szf162725 * (default: 1)
544126Szf162725 * Authenticated Key Management Suite List (4 * n octets)
554126Szf162725 * (default: unspec 802.1x)
564126Szf162725 * WPA Capabilities (2 octets, little endian) (default: 0)
574126Szf162725 */
584126Szf162725 #pragma pack(1)
594126Szf162725 struct wpa_ie_hdr {
604126Szf162725 uint8_t elem_id;
614126Szf162725 uint8_t len;
624126Szf162725 uint8_t oui[3];
634126Szf162725 uint8_t oui_type;
644126Szf162725 uint16_t version;
654126Szf162725 };
664126Szf162725 #pragma pack()
674126Szf162725
684126Szf162725 /*
694126Szf162725 * IEEE 802.11i/D9.0
704126Szf162725 */
714126Szf162725 static const int RSN_SELECTOR_LEN = 4;
724126Szf162725 static const uint16_t RSN_VERSION = 1;
734126Szf162725 static const uint8_t
744126Szf162725 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 };
754126Szf162725 static const uint8_t
764126Szf162725 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 };
774126Szf162725 static const uint8_t RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 };
784126Szf162725 static const uint8_t RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 };
794126Szf162725 static const uint8_t RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 };
804126Szf162725 static const uint8_t RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 };
814126Szf162725 static const uint8_t RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 };
824126Szf162725
834126Szf162725 /*
844126Szf162725 * EAPOL-Key Key Data Encapsulation
854126Szf162725 * GroupKey and STAKey require encryption, otherwise, encryption is optional.
864126Szf162725 */
874126Szf162725 static const uint8_t RSN_KEY_DATA_GROUPKEY[] = { 0x00, 0x0f, 0xac, 1 };
884126Szf162725 static const uint8_t RSN_KEY_DATA_PMKID[] = { 0x00, 0x0f, 0xac, 4 };
894126Szf162725
904126Szf162725 /*
914126Szf162725 * 1/4: PMKID
924126Szf162725 * 2/4: RSN IE
934126Szf162725 * 3/4: one or two RSN IEs + GTK IE (encrypted)
944126Szf162725 * 4/4: empty
954126Szf162725 * 1/2: GTK IE (encrypted)
964126Szf162725 * 2/2: empty
974126Szf162725 */
984126Szf162725
994126Szf162725 /*
1004126Szf162725 * RSN IE version 1
1014126Szf162725 * 0x01 0x00 (version; little endian)
1024126Szf162725 * (all following fields are optional:)
1034126Szf162725 * Group Suite Selector (4 octets) (default: CCMP)
1044126Szf162725 * Pairwise Suite Count (2 octets, little endian) (default: 1)
1054126Szf162725 * Pairwise Suite List (4 * n octets) (default: CCMP)
1064126Szf162725 * Authenticated Key Management Suite Count (2 octets, little endian)
1074126Szf162725 * (default: 1)
1084126Szf162725 * Authenticated Key Management Suite List (4 * n octets)
1094126Szf162725 * (default: unspec 802.1x)
1104126Szf162725 * RSN Capabilities (2 octets, little endian) (default: 0)
1114126Szf162725 * PMKID Count (2 octets) (default: 0)
1124126Szf162725 * PMKID List (16 * n octets)
1134126Szf162725 */
1144126Szf162725 #pragma pack(1)
1154126Szf162725 struct rsn_ie_hdr {
1164126Szf162725 uint8_t elem_id; /* WLAN_EID_RSN */
1174126Szf162725 uint8_t len;
1184126Szf162725 uint16_t version;
1194126Szf162725 };
1204126Szf162725 #pragma pack()
1214126Szf162725
1224126Szf162725 static int
random_get_pseudo_bytes(uint8_t * ptr,size_t len)1234126Szf162725 random_get_pseudo_bytes(uint8_t *ptr, size_t len)
1244126Szf162725 {
1254126Szf162725 int fd;
1264126Szf162725 size_t resid = len;
1274126Szf162725 size_t bytes;
1284126Szf162725
1294126Szf162725 fd = open("/dev/urandom", O_RDONLY);
1304126Szf162725 if (fd == -1) {
1314126Szf162725 wpa_printf(MSG_ERROR, "Could not open /dev/urandom.\n");
1324126Szf162725 return (-1);
1334126Szf162725 }
1344126Szf162725
1354126Szf162725 while (resid != 0) {
1364126Szf162725 bytes = read(fd, ptr, resid);
1374126Szf162725 ptr += bytes;
1384126Szf162725 resid -= bytes;
1394126Szf162725 }
1404126Szf162725
1414126Szf162725 (void) close(fd);
1424126Szf162725
1434126Szf162725 return (0);
1444126Szf162725 }
1454126Szf162725
1464126Szf162725 static void
inc_byte_array(uint8_t * counter,size_t len)1474126Szf162725 inc_byte_array(uint8_t *counter, size_t len)
1484126Szf162725 {
1494126Szf162725 int pos = len - 1;
1504126Szf162725 while (pos >= 0) {
1514126Szf162725 counter[pos]++;
1524126Szf162725 if (counter[pos] != 0)
1534126Szf162725 break;
1544126Szf162725 pos--;
1554126Szf162725 }
1564126Szf162725 }
1574126Szf162725
1584126Szf162725 static int
wpa_selector_to_bitfield(uint8_t * s)1594126Szf162725 wpa_selector_to_bitfield(uint8_t *s)
1604126Szf162725 {
1614126Szf162725 if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)
1624126Szf162725 return (WPA_CIPHER_NONE);
1634126Szf162725 if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0)
1644126Szf162725 return (WPA_CIPHER_WEP40);
1654126Szf162725 if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0)
1664126Szf162725 return (WPA_CIPHER_TKIP);
1674126Szf162725 if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0)
1684126Szf162725 return (WPA_CIPHER_CCMP);
1694126Szf162725 if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0)
1704126Szf162725 return (WPA_CIPHER_WEP104);
1714126Szf162725 return (0);
1724126Szf162725 }
1734126Szf162725
1744126Szf162725 static int
wpa_key_mgmt_to_bitfield(uint8_t * s)1754126Szf162725 wpa_key_mgmt_to_bitfield(uint8_t *s)
1764126Szf162725 {
1774126Szf162725 if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0)
1784126Szf162725 return (WPA_KEY_MGMT_IEEE8021X);
1794126Szf162725 if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) ==
1804126Szf162725 0)
1814126Szf162725 return (WPA_KEY_MGMT_PSK);
1824126Szf162725 return (0);
1834126Szf162725 }
1844126Szf162725
1854126Szf162725 static int
rsn_selector_to_bitfield(uint8_t * s)1864126Szf162725 rsn_selector_to_bitfield(uint8_t *s)
1874126Szf162725 {
1884126Szf162725 if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0)
1894126Szf162725 return (WPA_CIPHER_NONE);
1904126Szf162725 if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0)
1914126Szf162725 return (WPA_CIPHER_WEP40);
1924126Szf162725 if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0)
1934126Szf162725 return (WPA_CIPHER_TKIP);
1944126Szf162725 if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0)
1954126Szf162725 return (WPA_CIPHER_CCMP);
1964126Szf162725 if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0)
1974126Szf162725 return (WPA_CIPHER_WEP104);
1984126Szf162725 return (0);
1994126Szf162725 }
2004126Szf162725
2014126Szf162725 static int
rsn_key_mgmt_to_bitfield(uint8_t * s)2024126Szf162725 rsn_key_mgmt_to_bitfield(uint8_t *s)
2034126Szf162725 {
2044126Szf162725 if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0)
2054126Szf162725 return (WPA_KEY_MGMT_IEEE8021X);
2064126Szf162725 if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) ==
2074126Szf162725 0)
2084126Szf162725 return (WPA_KEY_MGMT_PSK);
2094126Szf162725 return (0);
2104126Szf162725 }
2114126Szf162725
2124126Szf162725 static void
pmksa_cache_free_entry(struct wpa_supplicant * wpa_s,struct rsn_pmksa_cache * entry)2134126Szf162725 pmksa_cache_free_entry(struct wpa_supplicant *wpa_s,
2144126Szf162725 struct rsn_pmksa_cache *entry)
2154126Szf162725 {
2164126Szf162725 wpa_s->pmksa_count--;
2174126Szf162725 if (wpa_s->cur_pmksa == entry) {
2184126Szf162725 wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA entry");
2194126Szf162725 wpa_s->cur_pmksa = NULL;
2204126Szf162725 }
2214126Szf162725 free(entry);
2224126Szf162725 }
2234126Szf162725
2244126Szf162725 /* ARGSUSED */
2254126Szf162725 static void
pmksa_cache_expire(void * eloop_ctx,void * timeout_ctx)2264126Szf162725 pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
2274126Szf162725 {
2284126Szf162725 struct wpa_supplicant *wpa_s = eloop_ctx;
2294126Szf162725 time_t now;
2304126Szf162725
2314126Szf162725 (void) time(&now);
2324126Szf162725 while (wpa_s->pmksa && wpa_s->pmksa->expiration <= now) {
2334126Szf162725 struct rsn_pmksa_cache *entry = wpa_s->pmksa;
2344126Szf162725 wpa_s->pmksa = entry->next;
2354126Szf162725 wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
2364126Szf162725 MACSTR, MAC2STR(entry->aa));
2374126Szf162725 pmksa_cache_free_entry(wpa_s, entry);
2384126Szf162725 }
2394126Szf162725
2404126Szf162725 pmksa_cache_set_expiration(wpa_s);
2414126Szf162725 }
2424126Szf162725
2434126Szf162725 static void
pmksa_cache_set_expiration(struct wpa_supplicant * wpa_s)2444126Szf162725 pmksa_cache_set_expiration(struct wpa_supplicant *wpa_s)
2454126Szf162725 {
2464126Szf162725 int sec;
2474126Szf162725 eloop_cancel_timeout(pmksa_cache_expire, wpa_s, NULL);
2484126Szf162725 if (wpa_s->pmksa == NULL)
2494126Szf162725 return;
2504126Szf162725 sec = wpa_s->pmksa->expiration - time(NULL);
2514126Szf162725 if (sec < 0)
2524126Szf162725 sec = 0;
2534126Szf162725 (void) eloop_register_timeout(sec + 1, 0, pmksa_cache_expire,
2544126Szf162725 wpa_s, NULL);
2554126Szf162725 }
2564126Szf162725
2574126Szf162725 void
pmksa_cache_free(struct wpa_supplicant * wpa_s)2584126Szf162725 pmksa_cache_free(struct wpa_supplicant *wpa_s)
2594126Szf162725 {
2604126Szf162725 struct rsn_pmksa_cache *entry, *prev;
2614126Szf162725
2624126Szf162725 entry = wpa_s->pmksa;
2634126Szf162725 wpa_s->pmksa = NULL;
2644126Szf162725 while (entry) {
2654126Szf162725 prev = entry;
2664126Szf162725 entry = entry->next;
2674126Szf162725 free(prev);
2684126Szf162725 }
2694126Szf162725 pmksa_cache_set_expiration(wpa_s);
2704126Szf162725 wpa_s->cur_pmksa = NULL;
2714126Szf162725 }
2724126Szf162725
2734126Szf162725 struct rsn_pmksa_cache *
pmksa_cache_get(struct wpa_supplicant * wpa_s,uint8_t * aa,uint8_t * pmkid)2744126Szf162725 pmksa_cache_get(struct wpa_supplicant *wpa_s,
2754126Szf162725 uint8_t *aa, uint8_t *pmkid)
2764126Szf162725 {
2774126Szf162725 struct rsn_pmksa_cache *entry = wpa_s->pmksa;
2784126Szf162725 while (entry) {
2794126Szf162725 if ((aa == NULL ||
2804126Szf162725 memcmp(entry->aa, aa, IEEE80211_ADDR_LEN) == 0) &&
2814126Szf162725 (pmkid == NULL ||
2824126Szf162725 memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
2834126Szf162725 return (entry);
2844126Szf162725 entry = entry->next;
2854126Szf162725 }
2864126Szf162725 return (NULL);
2874126Szf162725 }
2884126Szf162725
2894126Szf162725 int
pmksa_cache_list(struct wpa_supplicant * wpa_s,char * buf,size_t len)2904126Szf162725 pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf, size_t len)
2914126Szf162725 {
2924126Szf162725 int i, j;
2934126Szf162725 char *pos = buf;
2944126Szf162725 struct rsn_pmksa_cache *entry;
2954126Szf162725 time_t now;
2964126Szf162725
2974126Szf162725 (void) time(&now);
2984126Szf162725 pos += snprintf(pos, buf + len - pos,
2994126Szf162725 "Index / AA / PMKID / expiration (in seconds)\n");
3004126Szf162725 i = 0;
3014126Szf162725 entry = wpa_s->pmksa;
3024126Szf162725 while (entry) {
3034126Szf162725 i++;
3044126Szf162725 pos += snprintf(pos, buf + len - pos, "%d " MACSTR " ",
3054126Szf162725 i, MAC2STR(entry->aa));
3064126Szf162725 for (j = 0; j < PMKID_LEN; j++)
3074126Szf162725 pos += snprintf(pos, buf + len - pos, "%02x",
3084126Szf162725 entry->pmkid[j]);
3094126Szf162725 pos += snprintf(pos, buf + len - pos, " %d\n",
3104126Szf162725 (int)(entry->expiration - now));
3114126Szf162725 entry = entry->next;
3124126Szf162725 }
3134126Szf162725 return (pos - buf);
3144126Szf162725 }
3154126Szf162725
3164126Szf162725 void
pmksa_candidate_free(struct wpa_supplicant * wpa_s)3174126Szf162725 pmksa_candidate_free(struct wpa_supplicant *wpa_s)
3184126Szf162725 {
3194126Szf162725 struct rsn_pmksa_candidate *entry, *prev;
3204126Szf162725
3214126Szf162725 entry = wpa_s->pmksa_candidates;
3224126Szf162725 wpa_s->pmksa_candidates = NULL;
3234126Szf162725 while (entry) {
3244126Szf162725 prev = entry;
3254126Szf162725 entry = entry->next;
3264126Szf162725 free(prev);
3274126Szf162725 }
3284126Szf162725 }
3294126Szf162725
3304126Szf162725 /* ARGSUSED */
3314126Szf162725 static int
wpa_parse_wpa_ie_wpa(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie,size_t wpa_ie_len,struct wpa_ie_data * data)3324126Szf162725 wpa_parse_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
3334126Szf162725 size_t wpa_ie_len, struct wpa_ie_data *data)
3344126Szf162725 {
3354126Szf162725 struct wpa_ie_hdr *hdr;
3364126Szf162725 uint8_t *pos;
3374126Szf162725 int left;
3384126Szf162725 int i, count;
3394126Szf162725
3404126Szf162725 data->proto = WPA_PROTO_WPA;
3414126Szf162725 data->pairwise_cipher = WPA_CIPHER_TKIP;
3424126Szf162725 data->group_cipher = WPA_CIPHER_TKIP;
3434126Szf162725 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
3444126Szf162725 data->capabilities = 0;
3454126Szf162725
3464126Szf162725 if (wpa_ie_len == 0) {
3474126Szf162725 /* No WPA IE - fail silently */
3484126Szf162725 return (-1);
3494126Szf162725 }
3504126Szf162725
3514126Szf162725 if (wpa_ie_len < sizeof (struct wpa_ie_hdr)) {
3524126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
3534126Szf162725 "wpa_parse_wpa_ie_wpa", wpa_ie_len);
3544126Szf162725 return (-1);
3554126Szf162725 }
3564126Szf162725
3574126Szf162725 hdr = (struct wpa_ie_hdr *)wpa_ie;
3584126Szf162725
3594126Szf162725 if (hdr->elem_id != GENERIC_INFO_ELEM ||
3604126Szf162725 hdr->len != wpa_ie_len - 2 ||
3616411Szf162725 memcmp(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN) != 0 ||
3624126Szf162725 LE_16(hdr->version) != WPA_VERSION) {
3634126Szf162725 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
3644126Szf162725 "wpa_parse_wpa_ie_wpa");
3654126Szf162725 return (-1);
3664126Szf162725 }
3674126Szf162725
3684126Szf162725 pos = (uint8_t *)(hdr + 1);
3694126Szf162725 left = wpa_ie_len - sizeof (*hdr);
3704126Szf162725
3714126Szf162725 if (left >= WPA_SELECTOR_LEN) {
3724126Szf162725 data->group_cipher = wpa_selector_to_bitfield(pos);
3734126Szf162725 pos += WPA_SELECTOR_LEN;
3744126Szf162725 left -= WPA_SELECTOR_LEN;
3754126Szf162725 } else if (left > 0) {
3764126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
3774126Szf162725 "wpa_parse_wpa_ie_wpa", left);
3784126Szf162725 return (-1);
3794126Szf162725 }
3804126Szf162725
3814126Szf162725 if (left >= 2) {
3824126Szf162725 data->pairwise_cipher = 0;
3834126Szf162725 count = pos[0] | (pos[1] << 8);
3844126Szf162725 pos += 2;
3854126Szf162725 left -= 2;
3864126Szf162725 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
3874126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
3884126Szf162725 "count %u left %u",
3894126Szf162725 "wpa_parse_wpa_ie_wpa", count, left);
3904126Szf162725 return (-1);
3914126Szf162725 }
3924126Szf162725 for (i = 0; i < count; i++) {
3934126Szf162725 data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
3944126Szf162725 pos += WPA_SELECTOR_LEN;
3954126Szf162725 left -= WPA_SELECTOR_LEN;
3964126Szf162725 }
3974126Szf162725 } else if (left == 1) {
3984126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
3994126Szf162725 "wpa_parse_wpa_ie_wpa");
4004126Szf162725 return (-1);
4014126Szf162725 }
4024126Szf162725
4034126Szf162725 if (left >= 2) {
4044126Szf162725 data->key_mgmt = 0;
4054126Szf162725 count = pos[0] | (pos[1] << 8);
4064126Szf162725 pos += 2;
4074126Szf162725 left -= 2;
4084126Szf162725 if (count == 0 || left < count * WPA_SELECTOR_LEN) {
4094126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
4104126Szf162725 "count %u left %u",
4114126Szf162725 "wpa_parse_wpa_ie_wpa", count, left);
4124126Szf162725 return (-1);
4134126Szf162725 }
4144126Szf162725 for (i = 0; i < count; i++) {
4154126Szf162725 data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
4164126Szf162725 pos += WPA_SELECTOR_LEN;
4174126Szf162725 left -= WPA_SELECTOR_LEN;
4184126Szf162725 }
4194126Szf162725 } else if (left == 1) {
4204126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
4214126Szf162725 "wpa_parse_wpa_ie_wpa");
4224126Szf162725 return (-1);
4234126Szf162725 }
4244126Szf162725
4254126Szf162725 if (left >= 2) {
4264126Szf162725 data->capabilities = pos[0] | (pos[1] << 8);
4274126Szf162725 pos += 2;
4284126Szf162725 left -= 2;
4294126Szf162725 }
4304126Szf162725
4314126Szf162725 if (left > 0) {
4324126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes",
4334126Szf162725 "wpa_parse_wpa_ie_wpa", left);
4344126Szf162725 return (-1);
4354126Szf162725 }
4364126Szf162725
4374126Szf162725 return (0);
4384126Szf162725 }
4394126Szf162725
4404126Szf162725 /* ARGSUSED */
4414126Szf162725 static int
wpa_parse_wpa_ie_rsn(struct wpa_supplicant * wpa_s,uint8_t * rsn_ie,size_t rsn_ie_len,struct wpa_ie_data * data)4424126Szf162725 wpa_parse_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie,
4434126Szf162725 size_t rsn_ie_len, struct wpa_ie_data *data)
4444126Szf162725 {
4454126Szf162725 struct rsn_ie_hdr *hdr;
4464126Szf162725 uint8_t *pos;
4474126Szf162725 int left;
4484126Szf162725 int i, count;
4494126Szf162725
4504126Szf162725 data->proto = WPA_PROTO_RSN;
4514126Szf162725 data->pairwise_cipher = WPA_CIPHER_CCMP;
4524126Szf162725 data->group_cipher = WPA_CIPHER_CCMP;
4534126Szf162725 data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
4544126Szf162725 data->capabilities = 0;
4554126Szf162725
4564126Szf162725 if (rsn_ie_len == 0) {
4574126Szf162725 /* No RSN IE - fail silently */
4584126Szf162725 return (-1);
4594126Szf162725 }
4604126Szf162725
4614126Szf162725 if (rsn_ie_len < sizeof (struct rsn_ie_hdr)) {
4624126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie len too short %u",
4634126Szf162725 "wpa_parse_wpa_ie_rsn", rsn_ie_len);
4644126Szf162725 return (-1);
4654126Szf162725 }
4664126Szf162725
4674126Szf162725 hdr = (struct rsn_ie_hdr *)rsn_ie;
4684126Szf162725
4694126Szf162725 if (hdr->elem_id != RSN_INFO_ELEM ||
4704126Szf162725 hdr->len != rsn_ie_len - 2 ||
4714126Szf162725 LE_16(hdr->version) != RSN_VERSION) {
4724126Szf162725 wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
4734126Szf162725 "wpa_parse_wpa_ie_rsn");
4744126Szf162725 return (-1);
4754126Szf162725 }
4764126Szf162725
4774126Szf162725 pos = (uint8_t *)(hdr + 1);
4784126Szf162725 left = rsn_ie_len - sizeof (*hdr);
4794126Szf162725
4804126Szf162725 if (left >= RSN_SELECTOR_LEN) {
4814126Szf162725 data->group_cipher = rsn_selector_to_bitfield(pos);
4824126Szf162725 pos += RSN_SELECTOR_LEN;
4834126Szf162725 left -= RSN_SELECTOR_LEN;
4844126Szf162725 } else if (left > 0) {
4854126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",
4864126Szf162725 "wpa_parse_wpa_ie_rsn", left);
4874126Szf162725 return (-1);
4884126Szf162725 }
4894126Szf162725
4904126Szf162725 if (left >= 2) {
4914126Szf162725 data->pairwise_cipher = 0;
4924126Szf162725 count = pos[0] | (pos[1] << 8);
4934126Szf162725 pos += 2;
4944126Szf162725 left -= 2;
4954126Szf162725 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
4964126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "
4974126Szf162725 "count %u left %u",
4984126Szf162725 "wpa_parse_wpa_ie_rsn", count, left);
4994126Szf162725 return (-1);
5004126Szf162725 }
5014126Szf162725 for (i = 0; i < count; i++) {
5024126Szf162725 data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
5034126Szf162725 pos += RSN_SELECTOR_LEN;
5044126Szf162725 left -= RSN_SELECTOR_LEN;
5054126Szf162725 }
5064126Szf162725 } else if (left == 1) {
5074126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",
5084126Szf162725 "wpa_parse_wpa_ie_rsn");
5094126Szf162725 return (-1);
5104126Szf162725 }
5114126Szf162725
5124126Szf162725 if (left >= 2) {
5134126Szf162725 data->key_mgmt = 0;
5144126Szf162725 count = pos[0] | (pos[1] << 8);
5154126Szf162725 pos += 2;
5164126Szf162725 left -= 2;
5174126Szf162725 if (count == 0 || left < count * RSN_SELECTOR_LEN) {
5184126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "
5194126Szf162725 "count %u left %u",
5204126Szf162725 "wpa_parse_wpa_ie_rsn", count, left);
5214126Szf162725 return (-1);
5224126Szf162725 }
5234126Szf162725 for (i = 0; i < count; i++) {
5244126Szf162725 data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
5254126Szf162725 pos += RSN_SELECTOR_LEN;
5264126Szf162725 left -= RSN_SELECTOR_LEN;
5274126Szf162725 }
5284126Szf162725 } else if (left == 1) {
5294126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",
5304126Szf162725 "wpa_parse_wpa_ie_rsn");
5314126Szf162725 return (-1);
5324126Szf162725 }
5334126Szf162725
5344126Szf162725 if (left >= 2) {
5354126Szf162725 data->capabilities = pos[0] | (pos[1] << 8);
5364126Szf162725 pos += 2;
5374126Szf162725 left -= 2;
5384126Szf162725 }
5394126Szf162725
5404126Szf162725 if (left > 0) {
5414126Szf162725 /*
5424126Szf162725 * RSN IE could include PMKID data, but Authenticator should
5434126Szf162725 * never include it, so no need to parse it in the Supplicant.
5444126Szf162725 */
5454126Szf162725 wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",
5464126Szf162725 "wpa_parse_wpa_ie_rsn", left);
5474126Szf162725 }
5484126Szf162725
5494126Szf162725 return (0);
5504126Szf162725 }
5514126Szf162725
5524126Szf162725 int
wpa_parse_wpa_ie(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie,size_t wpa_ie_len,struct wpa_ie_data * data)5534126Szf162725 wpa_parse_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie,
5544126Szf162725 size_t wpa_ie_len, struct wpa_ie_data *data)
5554126Szf162725 {
5564126Szf162725 if (wpa_ie_len >= 1 && wpa_ie[0] == RSN_INFO_ELEM)
5574126Szf162725 return (wpa_parse_wpa_ie_rsn(wpa_s, wpa_ie, wpa_ie_len, data));
5584126Szf162725 else
5594126Szf162725 return (wpa_parse_wpa_ie_wpa(wpa_s, wpa_ie, wpa_ie_len, data));
5604126Szf162725 }
5614126Szf162725
5624126Szf162725 static int
wpa_gen_wpa_ie_wpa(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie)5634126Szf162725 wpa_gen_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
5644126Szf162725 {
5654126Szf162725 uint8_t *pos;
5664126Szf162725 struct wpa_ie_hdr *hdr;
5674126Szf162725
5684126Szf162725 hdr = (struct wpa_ie_hdr *)wpa_ie;
5694126Szf162725 hdr->elem_id = GENERIC_INFO_ELEM;
5706411Szf162725 (void) memcpy(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN);
5714126Szf162725 hdr->version = LE_16(WPA_VERSION);
5724126Szf162725 pos = (uint8_t *)(hdr + 1);
5734126Szf162725
5744126Szf162725 if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
5754126Szf162725 (void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
5764126Szf162725 } else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
5774126Szf162725 (void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
5784126Szf162725 } else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
5794126Szf162725 (void) memcpy(pos, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN);
5804126Szf162725 } else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
5814126Szf162725 (void) memcpy(pos, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN);
5824126Szf162725 } else {
5834126Szf162725 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
5844126Szf162725 wpa_s->group_cipher);
5854126Szf162725 return (-1);
5864126Szf162725 }
5874126Szf162725 pos += WPA_SELECTOR_LEN;
5884126Szf162725
5894126Szf162725 *pos++ = 1;
5904126Szf162725 *pos++ = 0;
5914126Szf162725 if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
5924126Szf162725 (void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
5934126Szf162725 } else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
5944126Szf162725 (void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
5954126Szf162725 } else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
5964126Szf162725 (void) memcpy(pos, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN);
5974126Szf162725 } else {
5984126Szf162725 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
5994126Szf162725 wpa_s->pairwise_cipher);
6004126Szf162725 return (-1);
6014126Szf162725 }
6024126Szf162725 pos += WPA_SELECTOR_LEN;
6034126Szf162725
6044126Szf162725 *pos++ = 1;
6054126Szf162725 *pos++ = 0;
6064126Szf162725 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
6074126Szf162725 (void) memcpy(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X,
6084126Szf162725 WPA_SELECTOR_LEN);
6094126Szf162725 } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
6104126Szf162725 (void) memcpy(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X,
6114126Szf162725 WPA_SELECTOR_LEN);
6124126Szf162725 } else {
6134126Szf162725 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
6144126Szf162725 wpa_s->key_mgmt);
6154126Szf162725 return (-1);
6164126Szf162725 }
6174126Szf162725 pos += WPA_SELECTOR_LEN;
6184126Szf162725
6194126Szf162725 /*
6204126Szf162725 * WPA Capabilities; use defaults, so no need to include it
6214126Szf162725 */
6224126Szf162725 hdr->len = (pos - wpa_ie) - 2;
6234126Szf162725
6244126Szf162725 return (pos - wpa_ie);
6254126Szf162725 }
6264126Szf162725
6274126Szf162725 static int
wpa_gen_wpa_ie_rsn(struct wpa_supplicant * wpa_s,uint8_t * rsn_ie)6284126Szf162725 wpa_gen_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie)
6294126Szf162725 {
6304126Szf162725 uint8_t *pos;
6314126Szf162725 struct rsn_ie_hdr *hdr;
6324126Szf162725
6334126Szf162725 hdr = (struct rsn_ie_hdr *)rsn_ie;
6344126Szf162725 hdr->elem_id = RSN_INFO_ELEM;
6354126Szf162725 hdr->version = LE_16(RSN_VERSION);
6364126Szf162725 pos = (uint8_t *)(hdr + 1);
6374126Szf162725
6384126Szf162725 if (wpa_s->group_cipher == WPA_CIPHER_CCMP) {
6394126Szf162725 (void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
6404126Szf162725 } else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
6414126Szf162725 (void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
6424126Szf162725 } else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) {
6434126Szf162725 (void) memcpy(pos, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN);
6444126Szf162725 } else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) {
6454126Szf162725 (void) memcpy(pos, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN);
6464126Szf162725 } else {
6474126Szf162725 wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
6484126Szf162725 wpa_s->group_cipher);
6494126Szf162725 return (-1);
6504126Szf162725 }
6514126Szf162725 pos += RSN_SELECTOR_LEN;
6524126Szf162725
6534126Szf162725 *pos++ = 1;
6544126Szf162725 *pos++ = 0;
6554126Szf162725 if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) {
6564126Szf162725 (void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
6574126Szf162725 } else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
6584126Szf162725 (void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
6594126Szf162725 } else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
6604126Szf162725 (void) memcpy(pos, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN);
6614126Szf162725 } else {
6624126Szf162725 wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
6634126Szf162725 wpa_s->pairwise_cipher);
6644126Szf162725 return (-1);
6654126Szf162725 }
6664126Szf162725 pos += RSN_SELECTOR_LEN;
6674126Szf162725
6684126Szf162725 *pos++ = 1;
6694126Szf162725 *pos++ = 0;
6704126Szf162725 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
6714126Szf162725 (void) memcpy(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X,
6724126Szf162725 RSN_SELECTOR_LEN);
6734126Szf162725 } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
6744126Szf162725 (void) memcpy(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X,
6754126Szf162725 RSN_SELECTOR_LEN);
6764126Szf162725 } else {
6774126Szf162725 wpa_printf(MSG_WARNING, "Invalid key management type (%d).",
6784126Szf162725 wpa_s->key_mgmt);
6794126Szf162725 return (-1);
6804126Szf162725 }
6814126Szf162725 pos += RSN_SELECTOR_LEN;
6824126Szf162725
6834126Szf162725 /* RSN Capabilities */
6844126Szf162725 *pos++ = 0;
6854126Szf162725 *pos++ = 0;
6864126Szf162725
6874126Szf162725 if (wpa_s->cur_pmksa) {
6884126Szf162725 /* PMKID Count (2 octets, little endian) */
6894126Szf162725 *pos++ = 1;
6904126Szf162725 *pos++ = 0;
6914126Szf162725 /* PMKID */
6924126Szf162725 (void) memcpy(pos, wpa_s->cur_pmksa->pmkid, PMKID_LEN);
6934126Szf162725 pos += PMKID_LEN;
6944126Szf162725 }
6954126Szf162725
6964126Szf162725 hdr->len = (pos - rsn_ie) - 2;
6974126Szf162725
6984126Szf162725 return (pos - rsn_ie);
6994126Szf162725 }
7004126Szf162725
7014126Szf162725 int
wpa_gen_wpa_ie(struct wpa_supplicant * wpa_s,uint8_t * wpa_ie)7024126Szf162725 wpa_gen_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie)
7034126Szf162725 {
7044126Szf162725 if (wpa_s->proto == WPA_PROTO_RSN)
7054126Szf162725 return (wpa_gen_wpa_ie_rsn(wpa_s, wpa_ie));
7064126Szf162725 else
7074126Szf162725 return (wpa_gen_wpa_ie_wpa(wpa_s, wpa_ie));
7084126Szf162725 }
7094126Szf162725
7104126Szf162725 static void
wpa_pmk_to_ptk(uint8_t * pmk,uint8_t * addr1,uint8_t * addr2,uint8_t * nonce1,uint8_t * nonce2,uint8_t * ptk,size_t ptk_len)7114126Szf162725 wpa_pmk_to_ptk(uint8_t *pmk, uint8_t *addr1, uint8_t *addr2,
7124126Szf162725 uint8_t *nonce1, uint8_t *nonce2, uint8_t *ptk, size_t ptk_len)
7134126Szf162725 {
7144126Szf162725 uint8_t data[2 * IEEE80211_ADDR_LEN + 2 * WPA_PMK_LEN];
7154126Szf162725
7164126Szf162725 /*
7174126Szf162725 * PTK = PRF-X(PMK, "Pairwise key expansion",
7184126Szf162725 * Min(AA, SA) || Max(AA, SA) ||
7194126Szf162725 * Min(ANonce, SNonce) || Max(ANonce, SNonce))
7204126Szf162725 */
7214126Szf162725
7224126Szf162725 if (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) < 0) {
7234126Szf162725 (void) memcpy(data, addr1, IEEE80211_ADDR_LEN);
7244126Szf162725 (void) memcpy(data + IEEE80211_ADDR_LEN, addr2,
7254126Szf162725 IEEE80211_ADDR_LEN);
7264126Szf162725 } else {
7274126Szf162725 (void) memcpy(data, addr2, IEEE80211_ADDR_LEN);
7284126Szf162725 (void) memcpy(data + IEEE80211_ADDR_LEN, addr1,
7294126Szf162725 IEEE80211_ADDR_LEN);
7304126Szf162725 }
7314126Szf162725
7324126Szf162725 if (memcmp(nonce1, nonce2, WPA_PMK_LEN) < 0) {
7334126Szf162725 (void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce1,
7344126Szf162725 WPA_PMK_LEN);
7354126Szf162725 (void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
7364126Szf162725 nonce2, WPA_PMK_LEN);
7374126Szf162725 } else {
7384126Szf162725 (void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce2,
7394126Szf162725 WPA_PMK_LEN);
7404126Szf162725 (void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN,
7414126Szf162725 nonce1, WPA_PMK_LEN);
7424126Szf162725 }
7434126Szf162725
7444126Szf162725 sha1_prf(pmk, WPA_PMK_LEN, "Pairwise key expansion", data,
7454126Szf162725 sizeof (data), ptk, ptk_len);
7464126Szf162725
7474126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: PMK", pmk, WPA_PMK_LEN);
7484126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: PTK", ptk, ptk_len);
7494126Szf162725 }
7504126Szf162725
7514126Szf162725 struct wpa_ssid *
wpa_supplicant_get_ssid(struct wpa_supplicant * wpa_s)7524126Szf162725 wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
7534126Szf162725 {
7544126Szf162725 struct wpa_ssid *entry;
7554126Szf162725 uint8_t ssid[MAX_ESSID_LENGTH];
7564126Szf162725 int ssid_len;
7574126Szf162725 uint8_t bssid[IEEE80211_ADDR_LEN];
7584126Szf162725
7594126Szf162725 (void) memset(ssid, 0, MAX_ESSID_LENGTH);
760*8453SAnurag.Maskey@Sun.COM ssid_len = wpa_s->driver->get_ssid(wpa_s->handle, wpa_s->linkid,
761*8453SAnurag.Maskey@Sun.COM (char *)ssid);
7624126Szf162725 if (ssid_len < 0) {
7634126Szf162725 wpa_printf(MSG_WARNING, "Could not read SSID from driver.");
7644126Szf162725 return (NULL);
7654126Szf162725 }
7664126Szf162725
767*8453SAnurag.Maskey@Sun.COM if (wpa_s->driver->get_bssid(wpa_s->handle, wpa_s->linkid,
768*8453SAnurag.Maskey@Sun.COM (char *)bssid) < 0) {
7694126Szf162725 wpa_printf(MSG_WARNING, "Could not read BSSID from driver.");
7704126Szf162725 return (NULL);
7714126Szf162725 }
7724126Szf162725
7734126Szf162725 entry = wpa_s->conf->ssid;
7744126Szf162725 wpa_printf(MSG_DEBUG, "entry len=%d ssid=%s,"
7754126Szf162725 " driver len=%d ssid=%s",
7764126Szf162725 entry->ssid_len, entry->ssid, ssid_len, ssid);
7774126Szf162725
7784126Szf162725 if (ssid_len == entry->ssid_len &&
7794126Szf162725 memcmp(ssid, entry->ssid, ssid_len) == 0 &&
7804126Szf162725 (!entry->bssid_set ||
7814126Szf162725 memcmp(bssid, entry->bssid, IEEE80211_ADDR_LEN) == 0))
7824126Szf162725 return (entry);
7834126Szf162725
7844126Szf162725 return (NULL);
7854126Szf162725 }
7864126Szf162725
7874126Szf162725 static void
wpa_eapol_key_mic(uint8_t * key,int ver,uint8_t * buf,size_t len,uint8_t * mic)7884126Szf162725 wpa_eapol_key_mic(uint8_t *key, int ver, uint8_t *buf, size_t len, uint8_t *mic)
7894126Szf162725 {
7904126Szf162725 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
7914126Szf162725 hmac_md5(key, 16, buf, len, mic);
7924126Szf162725 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
7934126Szf162725 uint8_t hash[SHA1_MAC_LEN];
7944126Szf162725 hmac_sha1(key, 16, buf, len, hash);
7954126Szf162725 (void) memcpy(mic, hash, MD5_MAC_LEN);
7964126Szf162725 }
7974126Szf162725 }
7984126Szf162725
7994126Szf162725 void
wpa_supplicant_key_request(struct wpa_supplicant * wpa_s,int error,int pairwise)8004126Szf162725 wpa_supplicant_key_request(struct wpa_supplicant *wpa_s,
8014126Szf162725 int error, int pairwise)
8024126Szf162725 {
8034126Szf162725 int rlen;
8044126Szf162725 struct ieee802_1x_hdr *hdr;
8054126Szf162725 struct wpa_eapol_key *reply;
8064126Szf162725 unsigned char *rbuf;
8074126Szf162725 struct l2_ethhdr *ethhdr;
8084126Szf162725 int key_info, ver;
8094126Szf162725 uint8_t bssid[IEEE80211_ADDR_LEN];
8104126Szf162725
8114126Szf162725 if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP)
8124126Szf162725 ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
8134126Szf162725 else
8144126Szf162725 ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
8154126Szf162725
816*8453SAnurag.Maskey@Sun.COM if (wpa_s->driver->get_bssid(wpa_s->handle, wpa_s->linkid,
817*8453SAnurag.Maskey@Sun.COM (char *)bssid) < 0) {
8184126Szf162725 wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
8194126Szf162725 "request");
8204126Szf162725 return;
8214126Szf162725 }
8224126Szf162725
8234126Szf162725 rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
8244126Szf162725 rbuf = malloc(rlen);
8254126Szf162725 if (rbuf == NULL)
8264126Szf162725 return;
8274126Szf162725
8284126Szf162725 (void) memset(rbuf, 0, rlen);
8294126Szf162725 ethhdr = (struct l2_ethhdr *)rbuf;
8304126Szf162725 (void) memcpy(ethhdr->h_dest, bssid, IEEE80211_ADDR_LEN);
8314126Szf162725 (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
8324126Szf162725 ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
8334126Szf162725
8344126Szf162725 hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
8354126Szf162725 hdr->version = wpa_s->conf->eapol_version;
8364126Szf162725 hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
8374126Szf162725 hdr->length = htons(sizeof (*reply));
8384126Szf162725
8394126Szf162725 reply = (struct wpa_eapol_key *)(hdr + 1);
8404126Szf162725 reply->type = wpa_s->proto == WPA_PROTO_RSN ?
8415895Syz147064 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
8424126Szf162725 key_info = WPA_KEY_INFO_REQUEST | ver;
8434126Szf162725 if (wpa_s->ptk_set)
8444126Szf162725 key_info |= WPA_KEY_INFO_MIC;
8454126Szf162725 if (error)
8464126Szf162725 key_info |= WPA_KEY_INFO_ERROR;
8474126Szf162725 if (pairwise)
8484126Szf162725 key_info |= WPA_KEY_INFO_KEY_TYPE;
8494126Szf162725 reply->key_info = BE_16(key_info);
8504126Szf162725 reply->key_length = 0;
8514126Szf162725 (void) memcpy(reply->replay_counter, wpa_s->request_counter,
8525895Syz147064 WPA_REPLAY_COUNTER_LEN);
8534126Szf162725 inc_byte_array(wpa_s->request_counter, WPA_REPLAY_COUNTER_LEN);
8544126Szf162725
8554126Szf162725 reply->key_data_length = BE_16(0);
8564126Szf162725
8574126Szf162725 if (key_info & WPA_KEY_INFO_MIC) {
8584126Szf162725 wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
8594126Szf162725 rlen - sizeof (*ethhdr), reply->key_mic);
8604126Szf162725 }
8614126Szf162725
8624126Szf162725 wpa_printf(MSG_INFO, "WPA: Sending EAPOL-Key Request (error=%d "
8634126Szf162725 "pairwise=%d ptk_set=%d len=%d)",
8644126Szf162725 error, pairwise, wpa_s->ptk_set, rlen);
8654126Szf162725 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key Request", rbuf, rlen);
8664126Szf162725 (void) l2_packet_send(wpa_s->l2, rbuf, rlen);
8674126Szf162725 free(rbuf);
8684126Szf162725 }
8694126Szf162725
8704126Szf162725 static void
wpa_supplicant_process_1_of_4(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,int ver)8714126Szf162725 wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
8724126Szf162725 unsigned char *src_addr, struct wpa_eapol_key *key, int ver)
8734126Szf162725 {
8744126Szf162725 int rlen;
8754126Szf162725 struct ieee802_1x_hdr *hdr;
8764126Szf162725 struct wpa_eapol_key *reply;
8774126Szf162725 unsigned char *rbuf;
8784126Szf162725 struct l2_ethhdr *ethhdr;
8794126Szf162725 struct wpa_ssid *ssid;
8804126Szf162725 struct wpa_ptk *ptk;
8814126Szf162725 uint8_t buf[8], wpa_ie_buf[80], *wpa_ie, *pmkid = NULL;
8824126Szf162725 int wpa_ie_len;
8834126Szf162725
8844126Szf162725 wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
8854126Szf162725 wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from "
8864126Szf162725 MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
8874126Szf162725
8884126Szf162725 ssid = wpa_supplicant_get_ssid(wpa_s);
8894126Szf162725 if (ssid == NULL) {
8904126Szf162725 wpa_printf(MSG_WARNING,
8914126Szf162725 "WPA: No SSID info found (msg 1 of 4).");
8924126Szf162725 return;
8934126Szf162725 }
8944126Szf162725
8954126Szf162725 if (wpa_s->proto == WPA_PROTO_RSN) {
8964126Szf162725 /* RSN: msg 1/4 should contain PMKID for the selected PMK */
8974126Szf162725 uint8_t *pos = (uint8_t *)(key + 1);
8984126Szf162725 uint8_t *end = pos + BE_16(key->key_data_length);
8994126Szf162725
9004126Szf162725 wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
9014126Szf162725 pos, BE_16(key->key_data_length));
9024126Szf162725
9034126Szf162725 while (pos + 1 < end) {
9044126Szf162725 if (pos + 2 + pos[1] > end) {
9054126Szf162725 wpa_printf(MSG_DEBUG, "RSN: key data "
9064126Szf162725 "underflow (ie=%d len=%d)",
9074126Szf162725 pos[0], pos[1]);
9084126Szf162725 break;
9094126Szf162725 }
9104126Szf162725 if (pos[0] == GENERIC_INFO_ELEM &&
9115895Syz147064 pos + 1 + RSN_SELECTOR_LEN < end &&
9125895Syz147064 pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
9135895Syz147064 memcmp(pos + 2, RSN_KEY_DATA_PMKID,
9145895Syz147064 RSN_SELECTOR_LEN) == 0) {
9154126Szf162725 pmkid = pos + 2 + RSN_SELECTOR_LEN;
9164126Szf162725 wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
9174126Szf162725 "Authenticator", pmkid, PMKID_LEN);
9184126Szf162725 break;
9194126Szf162725 } else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0)
9204126Szf162725 break;
9214126Szf162725 pos += 2 + pos[1];
9224126Szf162725 }
9234126Szf162725 }
9244126Szf162725
9254126Szf162725 wpa_ie = wpa_ie_buf;
9264126Szf162725 wpa_ie_len = wpa_gen_wpa_ie(wpa_s, wpa_ie);
9274126Szf162725 if (wpa_ie_len < 0) {
9284126Szf162725 wpa_printf(MSG_WARNING, "WPA: Failed to generate "
9294126Szf162725 "WPA IE (for msg 2 of 4).");
9304126Szf162725 return;
9314126Szf162725 }
9324126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
9334126Szf162725
9344126Szf162725 rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply) + wpa_ie_len;
9354126Szf162725 rbuf = malloc(rlen);
9364126Szf162725 if (rbuf == NULL)
9374126Szf162725 return;
9384126Szf162725
9394126Szf162725 (void) memset(rbuf, 0, rlen);
9404126Szf162725 ethhdr = (struct l2_ethhdr *)rbuf;
9414126Szf162725 (void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
9424126Szf162725 (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
9434126Szf162725 ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
9444126Szf162725
9454126Szf162725 hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
9464126Szf162725 hdr->version = wpa_s->conf->eapol_version;
9474126Szf162725 hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
9484126Szf162725 hdr->length = htons(sizeof (*reply) + wpa_ie_len);
9494126Szf162725
9504126Szf162725 reply = (struct wpa_eapol_key *)(hdr + 1);
9514126Szf162725 reply->type = wpa_s->proto == WPA_PROTO_RSN ?
9525895Syz147064 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
9535895Syz147064 reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
9544126Szf162725 reply->key_length = key->key_length;
9554126Szf162725 (void) memcpy(reply->replay_counter, key->replay_counter,
9565895Syz147064 WPA_REPLAY_COUNTER_LEN);
9574126Szf162725
9584126Szf162725 reply->key_data_length = BE_16(wpa_ie_len);
9594126Szf162725 (void) memcpy(reply + 1, wpa_ie, wpa_ie_len);
9604126Szf162725
9614126Szf162725 if (wpa_s->renew_snonce) {
9624126Szf162725 if (random_get_pseudo_bytes(wpa_s->snonce, WPA_NONCE_LEN)) {
9634126Szf162725 wpa_printf(MSG_WARNING, "WPA: Failed to get "
9644126Szf162725 "random data for SNonce");
9654126Szf162725 free(rbuf);
9664126Szf162725 return;
9674126Szf162725 }
9684126Szf162725
9694126Szf162725 wpa_s->renew_snonce = 0;
9704126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
9714126Szf162725 wpa_s->snonce, WPA_NONCE_LEN);
9724126Szf162725 }
9734126Szf162725 (void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN);
9744126Szf162725 ptk = &wpa_s->tptk;
9754126Szf162725 (void) memcpy(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN);
9764126Szf162725
9774126Szf162725 wpa_pmk_to_ptk(wpa_s->pmk, wpa_s->own_addr, src_addr,
9784126Szf162725 wpa_s->snonce, key->key_nonce, (uint8_t *)ptk, sizeof (*ptk));
9794126Szf162725
9804126Szf162725 /*
9814126Szf162725 * Supplicant: swap tx/rx Mic keys
9824126Szf162725 */
9834126Szf162725 (void) memcpy(buf, ptk->u.auth.tx_mic_key, 8);
9844126Szf162725 (void) memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
9854126Szf162725 (void) memcpy(ptk->u.auth.rx_mic_key, buf, 8);
9864126Szf162725 wpa_s->tptk_set = 1;
9874126Szf162725 wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, (uint8_t *)hdr,
9885895Syz147064 rlen - sizeof (*ethhdr), reply->key_mic);
9894126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: EAPOL-Key MIC", reply->key_mic, 16);
9904126Szf162725
9914126Szf162725 wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
9924126Szf162725 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/4", rbuf, rlen);
9934126Szf162725 (void) l2_packet_send(wpa_s->l2, rbuf, rlen);
9944126Szf162725
9954126Szf162725 free(rbuf);
9964126Szf162725 }
9974126Szf162725
9984126Szf162725 static void
wpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,uint8_t * gtk,int gtk_len)9994126Szf162725 wpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant *wpa_s,
10004126Szf162725 unsigned char *src_addr, struct wpa_eapol_key *key,
10014126Szf162725 uint8_t *gtk, int gtk_len)
10024126Szf162725 {
10034126Szf162725 int keyidx, tx, key_rsc_len = 0, alg;
10044126Szf162725
10054126Szf162725 wpa_hexdump(MSG_DEBUG,
10064126Szf162725 "WPA: received GTK in pairwise handshake", gtk, gtk_len);
10074126Szf162725
10084126Szf162725 keyidx = gtk[0] & 0x3;
10094126Szf162725 tx = !!(gtk[0] & BIT(2));
10104126Szf162725 if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
10114126Szf162725 /*
10124126Szf162725 * Ignore Tx bit in GTK IE if a pairwise key is used.
10134126Szf162725 * One AP seemed to set this bit (incorrectly, since Tx
10144126Szf162725 * is only when doing Group Key only APs) and without
10154126Szf162725 * this workaround, the data connection does not work
10164126Szf162725 * because wpa_supplicant configured non-zero keyidx to
10174126Szf162725 * be used for unicast.
10184126Szf162725 */
10194126Szf162725 wpa_printf(MSG_INFO, "RSN: Tx bit set for GTK IE, but "
10204126Szf162725 "pairwise keys are used - ignore Tx bit");
10214126Szf162725 tx = 0;
10224126Szf162725 }
10234126Szf162725
10244126Szf162725 gtk += 2;
10254126Szf162725 gtk_len -= 2;
10264126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, gtk_len);
10274126Szf162725
10284126Szf162725 switch (wpa_s->group_cipher) {
10294126Szf162725 case WPA_CIPHER_CCMP:
10304126Szf162725 if (gtk_len != 16) {
10314126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP"
10324126Szf162725 " Group Cipher key length %d.", gtk_len);
10334126Szf162725 return;
10344126Szf162725 }
10354126Szf162725 key_rsc_len = 6;
10364126Szf162725 alg = WPA_ALG_CCMP;
10374126Szf162725 break;
10384126Szf162725 case WPA_CIPHER_TKIP:
10394126Szf162725 if (gtk_len != 32) {
10404126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP"
10414126Szf162725 " Group Cipher key length %d.", gtk_len);
10424126Szf162725 return;
10434126Szf162725 }
10444126Szf162725 key_rsc_len = 6;
10454126Szf162725 alg = WPA_ALG_TKIP;
10464126Szf162725 break;
10474126Szf162725 case WPA_CIPHER_WEP104:
10484126Szf162725 if (gtk_len != 13) {
10494126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported "
10504126Szf162725 "WEP104 Group Cipher key length " "%d.", gtk_len);
10514126Szf162725 return;
10524126Szf162725 }
10534126Szf162725 alg = WPA_ALG_WEP;
10544126Szf162725 break;
10554126Szf162725 case WPA_CIPHER_WEP40:
10564126Szf162725 if (gtk_len != 5) {
10574126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported "
10584126Szf162725 "WEP40 Group Cipher key length %d.", gtk_len);
10594126Szf162725 return;
10604126Szf162725 }
10614126Szf162725 alg = WPA_ALG_WEP;
10624126Szf162725 break;
10634126Szf162725 default:
10644126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher "
10654126Szf162725 "%d", wpa_s->group_cipher);
10664126Szf162725 return;
10674126Szf162725 }
10684126Szf162725
10694126Szf162725 wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "
10704126Szf162725 "(keyidx=%d tx=%d).", keyidx, tx);
10714126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len);
10724126Szf162725 if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
10734126Szf162725 uint8_t tmpbuf[8];
10744126Szf162725 /*
10754126Szf162725 * Swap Tx/Rx keys for Michael MIC
10764126Szf162725 */
10774126Szf162725 (void) memcpy(tmpbuf, gtk + 16, 8);
10784126Szf162725 (void) memcpy(gtk + 16, gtk + 24, 8);
10794126Szf162725 (void) memcpy(gtk + 24, tmpbuf, 8);
10804126Szf162725 }
10814126Szf162725 if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
1082*8453SAnurag.Maskey@Sun.COM if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
10834126Szf162725 (uint8_t *)"\xff\xff\xff\xff\xff\xff",
10844126Szf162725 keyidx, 1, key->key_rsc,
10854126Szf162725 key_rsc_len, gtk, gtk_len) < 0)
10864126Szf162725 wpa_printf(MSG_WARNING, "WPA: Failed to set "
10874126Szf162725 "GTK to the driver (Group only).");
1088*8453SAnurag.Maskey@Sun.COM } else if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
10895895Syz147064 (uint8_t *)"\xff\xff\xff\xff\xff\xff", keyidx, tx,
10905895Syz147064 key->key_rsc, key_rsc_len, gtk, gtk_len) < 0) {
10914126Szf162725 wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "
10924126Szf162725 "the driver.");
10934126Szf162725 }
10944126Szf162725
10954126Szf162725 wpa_printf(MSG_INFO, "WPA: Key negotiation completed with "
10965895Syz147064 MACSTR, MAC2STR(src_addr));
10974126Szf162725 eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
10984126Szf162725 wpa_supplicant_cancel_auth_timeout(wpa_s);
10994126Szf162725 wpa_s->wpa_state = WPA_COMPLETED;
11004126Szf162725 }
11014126Szf162725
11024126Szf162725 static void
wpa_supplicant_process_3_of_4(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,int extra_len,int ver)11034126Szf162725 wpa_supplicant_process_3_of_4(struct wpa_supplicant *wpa_s,
11044126Szf162725 unsigned char *src_addr, struct wpa_eapol_key *key,
11054126Szf162725 int extra_len, int ver)
11064126Szf162725 {
11074126Szf162725 int rlen;
11084126Szf162725 struct ieee802_1x_hdr *hdr;
11094126Szf162725 struct wpa_eapol_key *reply;
11104126Szf162725 unsigned char *rbuf;
11114126Szf162725 struct l2_ethhdr *ethhdr;
11124126Szf162725 int key_info, ie_len = 0, keylen, gtk_len = 0;
11134126Szf162725 uint8_t *ie = NULL, *gtk = NULL, *key_rsc;
11144126Szf162725 uint8_t null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
11154126Szf162725
11164126Szf162725 wpa_s->wpa_state = WPA_4WAY_HANDSHAKE;
11174126Szf162725 wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from "
11184126Szf162725 MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
11194126Szf162725
11204126Szf162725 key_info = BE_16(key->key_info);
11214126Szf162725
11224126Szf162725 if (wpa_s->proto == WPA_PROTO_RSN) {
11234126Szf162725 uint8_t *pos = (uint8_t *)(key + 1);
11244126Szf162725 uint8_t *end = pos + BE_16(key->key_data_length);
11254126Szf162725 while (pos + 1 < end) {
11264126Szf162725 if (pos + 2 + pos[1] > end) {
11274126Szf162725 wpa_printf(MSG_DEBUG, "RSN: key data "
11284126Szf162725 "underflow (ie=%d len=%d)",
11294126Szf162725 pos[0], pos[1]);
11304126Szf162725 break;
11314126Szf162725 }
11324126Szf162725 if (*pos == RSN_INFO_ELEM) {
11334126Szf162725 ie = pos;
11344126Szf162725 ie_len = pos[1] + 2;
11354126Szf162725 } else if (pos[0] == GENERIC_INFO_ELEM &&
11365895Syz147064 pos + 1 + RSN_SELECTOR_LEN < end &&
11375895Syz147064 pos[1] > RSN_SELECTOR_LEN + 2 &&
11385895Syz147064 memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY,
11395895Syz147064 RSN_SELECTOR_LEN) == 0) {
11404126Szf162725 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
11414126Szf162725 wpa_printf(MSG_WARNING, "WPA: GTK IE "
11424126Szf162725 "in unencrypted key data");
11434126Szf162725 return;
11444126Szf162725 }
11454126Szf162725 gtk = pos + 2 + RSN_SELECTOR_LEN;
11464126Szf162725 gtk_len = pos[1] - RSN_SELECTOR_LEN;
11474126Szf162725 } else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0)
11484126Szf162725 break;
11494126Szf162725
11504126Szf162725 pos += 2 + pos[1];
11514126Szf162725 }
11524126Szf162725 } else {
11534126Szf162725 ie = (uint8_t *)(key + 1);
11544126Szf162725 ie_len = BE_16(key->key_data_length);
11554126Szf162725 if (ie_len > extra_len) {
11564126Szf162725 wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"
11574126Szf162725 " ie_len=%d > extra_len=%d",
11584126Szf162725 ie_len, extra_len);
11594126Szf162725 return;
11604126Szf162725 }
11614126Szf162725 }
11624126Szf162725
11634126Szf162725 if (wpa_s->ap_wpa_ie &&
11644126Szf162725 (wpa_s->ap_wpa_ie_len != ie_len ||
11655895Syz147064 memcmp(wpa_s->ap_wpa_ie, ie, ie_len) != 0)) {
11664126Szf162725 wpa_printf(MSG_WARNING, "WPA: WPA IE in 3/4 msg does not match"
11674126Szf162725 " with WPA IE in Beacon/ProbeResp (src=" MACSTR ")",
11684126Szf162725 MAC2STR(src_addr));
11694126Szf162725 wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
11704126Szf162725 wpa_s->ap_wpa_ie, wpa_s->ap_wpa_ie_len);
11714126Szf162725 wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg", ie, ie_len);
11724126Szf162725 wpa_supplicant_disassociate(wpa_s, REASON_IE_IN_4WAY_DIFFERS);
11734126Szf162725 wpa_supplicant_req_scan(wpa_s, 0, 0);
11744126Szf162725 return;
11754126Szf162725 }
11764126Szf162725
11774126Szf162725 if (memcmp(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
11784126Szf162725 wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way "
11794126Szf162725 "Handshake differs from 3 of 4-Way Handshake - drop"
11804126Szf162725 " packet (src=" MACSTR ")", MAC2STR(src_addr));
11814126Szf162725 return;
11824126Szf162725 }
11834126Szf162725
11844126Szf162725 keylen = BE_16(key->key_length);
11854126Szf162725 switch (wpa_s->pairwise_cipher) {
11864126Szf162725 case WPA_CIPHER_CCMP:
11874126Szf162725 if (keylen != 16) {
11884126Szf162725 wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "
11894126Szf162725 "%d (src=" MACSTR ")",
11904126Szf162725 keylen, MAC2STR(src_addr));
11914126Szf162725 return;
11924126Szf162725 }
11934126Szf162725 break;
11944126Szf162725 case WPA_CIPHER_TKIP:
11954126Szf162725 if (keylen != 32) {
11964126Szf162725 wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length "
11974126Szf162725 "%d (src=" MACSTR ")",
11984126Szf162725 keylen, MAC2STR(src_addr));
11994126Szf162725 return;
12004126Szf162725 }
12014126Szf162725 break;
12024126Szf162725 }
12034126Szf162725
12044126Szf162725 rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
12054126Szf162725 rbuf = malloc(rlen);
12064126Szf162725 if (rbuf == NULL)
12074126Szf162725 return;
12084126Szf162725
12094126Szf162725 (void) memset(rbuf, 0, rlen);
12104126Szf162725 ethhdr = (struct l2_ethhdr *)rbuf;
12114126Szf162725 (void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
12124126Szf162725 (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
12134126Szf162725 ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
12144126Szf162725
12154126Szf162725 hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
12164126Szf162725 hdr->version = wpa_s->conf->eapol_version;
12174126Szf162725 hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
12184126Szf162725 hdr->length = htons(sizeof (*reply));
12194126Szf162725
12204126Szf162725 reply = (struct wpa_eapol_key *)(hdr + 1);
12214126Szf162725 reply->type = wpa_s->proto == WPA_PROTO_RSN ?
12225895Syz147064 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
12234126Szf162725 reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE |
12245895Syz147064 WPA_KEY_INFO_MIC | (key_info & WPA_KEY_INFO_SECURE));
12254126Szf162725 reply->key_length = key->key_length;
12264126Szf162725 (void) memcpy(reply->replay_counter, key->replay_counter,
12275895Syz147064 WPA_REPLAY_COUNTER_LEN);
12284126Szf162725
12294126Szf162725 reply->key_data_length = BE_16(0);
12304126Szf162725
12314126Szf162725 (void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN);
12324126Szf162725 wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
12334126Szf162725 rlen - sizeof (*ethhdr), reply->key_mic);
12344126Szf162725
12354126Szf162725 wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
12364126Szf162725 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 4/4", rbuf, rlen);
12374126Szf162725 (void) l2_packet_send(wpa_s->l2, rbuf, rlen);
12384126Szf162725
12394126Szf162725 free(rbuf);
12404126Szf162725
12414126Szf162725 /*
12424126Szf162725 * SNonce was successfully used in msg 3/4, so mark it to be renewed
12434126Szf162725 * for the next 4-Way Handshake. If msg 3 is received again, the old
12444126Szf162725 * SNonce will still be used to avoid changing PTK.
12454126Szf162725 */
12464126Szf162725 wpa_s->renew_snonce = 1;
12474126Szf162725
12484126Szf162725 if (key_info & WPA_KEY_INFO_INSTALL) {
12494126Szf162725 int alg, keylen, rsclen;
12504126Szf162725 wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.");
12514126Szf162725 switch (wpa_s->pairwise_cipher) {
12524126Szf162725 case WPA_CIPHER_CCMP:
12534126Szf162725 alg = WPA_ALG_CCMP;
12544126Szf162725 keylen = 16;
12554126Szf162725 rsclen = 6;
12564126Szf162725 break;
12574126Szf162725 case WPA_CIPHER_TKIP:
12584126Szf162725 alg = WPA_ALG_TKIP;
12594126Szf162725 keylen = 32;
12604126Szf162725 rsclen = 6;
12614126Szf162725 break;
12624126Szf162725 case WPA_CIPHER_NONE:
12634126Szf162725 wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: "
12644126Szf162725 "NONE - do not use pairwise keys");
12654126Szf162725 return;
12664126Szf162725 default:
12674126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise "
12684126Szf162725 "cipher %d", wpa_s->pairwise_cipher);
12694126Szf162725 return;
12704126Szf162725 }
12714126Szf162725 if (wpa_s->proto == WPA_PROTO_RSN) {
12724126Szf162725 key_rsc = null_rsc;
12734126Szf162725 } else {
12744126Szf162725 key_rsc = key->key_rsc;
12754126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);
12764126Szf162725 }
12774126Szf162725
1278*8453SAnurag.Maskey@Sun.COM if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
1279*8453SAnurag.Maskey@Sun.COM src_addr, 0, 1, key_rsc, rsclen,
12804126Szf162725 (uint8_t *)&wpa_s->ptk.tk1, keylen) < 0) {
12814126Szf162725 wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the"
12824126Szf162725 " driver.");
12834126Szf162725 }
12844126Szf162725 }
12854126Szf162725
12864126Szf162725 wpa_printf(MSG_DEBUG, "%s: key_info=%x gtk=%p\n",
12874126Szf162725 "wpa_supplicant_process_3_of_4", key_info, gtk);
12884126Szf162725 wpa_s->wpa_state = WPA_GROUP_HANDSHAKE;
12894126Szf162725
12904126Szf162725 if (gtk)
12914126Szf162725 wpa_supplicant_process_3_of_4_gtk(wpa_s,
12924126Szf162725 src_addr, key, gtk, gtk_len);
12934126Szf162725 }
12944126Szf162725
12954126Szf162725 static void
wpa_supplicant_process_1_of_2(struct wpa_supplicant * wpa_s,unsigned char * src_addr,struct wpa_eapol_key * key,int extra_len,int ver)12964126Szf162725 wpa_supplicant_process_1_of_2(struct wpa_supplicant *wpa_s,
12974126Szf162725 unsigned char *src_addr, struct wpa_eapol_key *key,
12984126Szf162725 int extra_len, int ver)
12994126Szf162725 {
13004126Szf162725 int rlen;
13014126Szf162725 struct ieee802_1x_hdr *hdr;
13024126Szf162725 struct wpa_eapol_key *reply;
13034126Szf162725 unsigned char *rbuf;
13044126Szf162725 struct l2_ethhdr *ethhdr;
13054126Szf162725 int key_info, keylen, keydatalen, maxkeylen, keyidx, key_rsc_len = 0;
13064126Szf162725 int alg, tx;
13074126Szf162725 uint8_t ek[32], tmpbuf[8], gtk[32];
13084126Szf162725 uint8_t *gtk_ie = NULL;
13094126Szf162725 size_t gtk_ie_len = 0;
13104126Szf162725
13114126Szf162725 wpa_s->wpa_state = WPA_GROUP_HANDSHAKE;
13124126Szf162725 wpa_printf(MSG_DEBUG, "WPA: RX message 1 of Group Key Handshake from "
13134126Szf162725 MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
13144126Szf162725
13154126Szf162725 key_info = BE_16(key->key_info);
13164126Szf162725 keydatalen = BE_16(key->key_data_length);
13174126Szf162725
13184126Szf162725 if (wpa_s->proto == WPA_PROTO_RSN) {
13194126Szf162725 uint8_t *pos = (uint8_t *)(key + 1);
13204126Szf162725 uint8_t *end = pos + keydatalen;
13214126Szf162725 while (pos + 1 < end) {
13224126Szf162725 if (pos + 2 + pos[1] > end) {
13234126Szf162725 wpa_printf(MSG_DEBUG, "RSN: key data "
13244126Szf162725 "underflow (ie=%d len=%d)",
13254126Szf162725 pos[0], pos[1]);
13264126Szf162725 break;
13274126Szf162725 }
13284126Szf162725 if (pos[0] == GENERIC_INFO_ELEM &&
13294126Szf162725 pos + 1 + RSN_SELECTOR_LEN < end &&
13304126Szf162725 pos[1] > RSN_SELECTOR_LEN + 2 &&
13314126Szf162725 memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY,
13324126Szf162725 RSN_SELECTOR_LEN) == 0) {
13334126Szf162725 if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
13344126Szf162725 wpa_printf(MSG_WARNING, "WPA: GTK IE "
13354126Szf162725 "in unencrypted key data");
13364126Szf162725 return;
13374126Szf162725 }
13384126Szf162725 gtk_ie = pos + 2 + RSN_SELECTOR_LEN;
13394126Szf162725 gtk_ie_len = pos[1] - RSN_SELECTOR_LEN;
13404126Szf162725 break;
13415895Syz147064 } else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0) {
13424126Szf162725 break;
13435895Syz147064 }
13444126Szf162725
13454126Szf162725 pos += 2 + pos[1];
13464126Szf162725 }
13474126Szf162725
13484126Szf162725 if (gtk_ie == NULL) {
13494126Szf162725 wpa_printf(MSG_INFO, "WPA: No GTK IE in Group Key "
13504126Szf162725 "message 1/2");
13514126Szf162725 return;
13524126Szf162725 }
13534126Szf162725 maxkeylen = keylen = gtk_ie_len - 2;
13544126Szf162725 } else {
13554126Szf162725 keylen = BE_16(key->key_length);
13564126Szf162725 maxkeylen = keydatalen;
13574126Szf162725 if (keydatalen > extra_len) {
13584126Szf162725 wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:"
13594126Szf162725 " key_data_length=%d > extra_len=%d",
13604126Szf162725 keydatalen, extra_len);
13614126Szf162725 return;
13624126Szf162725 }
13634126Szf162725 if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES)
13644126Szf162725 maxkeylen -= 8;
13654126Szf162725 }
13664126Szf162725
13674126Szf162725 switch (wpa_s->group_cipher) {
13684126Szf162725 case WPA_CIPHER_CCMP:
13694126Szf162725 if (keylen != 16 || maxkeylen < 16) {
13704126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP Group "
13714126Szf162725 "Cipher key length %d (%d).", keylen, maxkeylen);
13724126Szf162725 return;
13734126Szf162725 }
13744126Szf162725 key_rsc_len = 6;
13754126Szf162725 alg = WPA_ALG_CCMP;
13764126Szf162725 break;
13774126Szf162725 case WPA_CIPHER_TKIP:
13784126Szf162725 if (keylen != 32 || maxkeylen < 32) {
13794126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP Group "
13804126Szf162725 "Cipher key length %d (%d).", keylen, maxkeylen);
13814126Szf162725 return;
13824126Szf162725 }
13834126Szf162725 key_rsc_len = 6; /* key->key_data; */
13844126Szf162725 alg = WPA_ALG_TKIP;
13854126Szf162725 break;
13864126Szf162725 case WPA_CIPHER_WEP104:
13874126Szf162725 if (keylen != 13 || maxkeylen < 13) {
13884126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported WEP104 Group"
13894126Szf162725 " Cipher key length %d (%d).", keylen, maxkeylen);
13904126Szf162725 return;
13914126Szf162725 }
13924126Szf162725 alg = WPA_ALG_WEP;
13934126Szf162725 break;
13944126Szf162725 case WPA_CIPHER_WEP40:
13954126Szf162725 if (keylen != 5 || maxkeylen < 5) {
13964126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported WEP40 Group "
13974126Szf162725 "Cipher key length %d (%d).", keylen, maxkeylen);
13984126Szf162725 return;
13994126Szf162725 }
14004126Szf162725 alg = WPA_ALG_WEP;
14014126Szf162725 break;
14024126Szf162725 default:
14034126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher %d",
14044126Szf162725 wpa_s->group_cipher);
14054126Szf162725 return;
14064126Szf162725 }
14074126Szf162725
14084126Szf162725 if (wpa_s->proto == WPA_PROTO_RSN) {
14094126Szf162725 wpa_hexdump(MSG_DEBUG,
14104126Szf162725 "WPA: received GTK in group key handshake",
14114126Szf162725 gtk_ie, gtk_ie_len);
14124126Szf162725 keyidx = gtk_ie[0] & 0x3;
14134126Szf162725 tx = !!(gtk_ie[0] & BIT(2));
14144126Szf162725 if (gtk_ie_len - 2 > sizeof (gtk)) {
14154126Szf162725 wpa_printf(MSG_INFO, "WPA: Too long GTK in GTK IE "
14164126Szf162725 "(len=%d)", gtk_ie_len - 2);
14174126Szf162725 return;
14184126Szf162725 }
14194126Szf162725 (void) memcpy(gtk, gtk_ie + 2, gtk_ie_len - 2);
14204126Szf162725 } else {
14214126Szf162725 keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
14225895Syz147064 WPA_KEY_INFO_KEY_INDEX_SHIFT;
14234126Szf162725 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
14244126Szf162725 (void) memcpy(ek, key->key_iv, 16);
14254126Szf162725 (void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16);
14264126Szf162725 rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen);
14274126Szf162725 (void) memcpy(gtk, key + 1, keylen);
14284126Szf162725 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
14294126Szf162725 if (keydatalen % 8) {
14304126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported "
14314126Szf162725 "AES-WRAP len %d", keydatalen);
14324126Szf162725 return;
14334126Szf162725 }
14344126Szf162725 if (aes_unwrap(wpa_s->ptk.encr_key, maxkeylen / 8,
14355895Syz147064 (uint8_t *)(key + 1), gtk)) {
14364126Szf162725 wpa_printf(MSG_WARNING, "WPA: AES unwrap "
14374126Szf162725 "failed - could not decrypt GTK");
14384126Szf162725 return;
14394126Szf162725 }
14404126Szf162725 }
14414126Szf162725 tx = !!(key_info & WPA_KEY_INFO_TXRX);
14424126Szf162725 if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
14434126Szf162725 /*
14444126Szf162725 * Ignore Tx bit in Group Key message if a pairwise key
14454126Szf162725 * is used. Some APs seem to setting this bit
14464126Szf162725 * (incorrectly, since Tx is only when doing Group Key
14474126Szf162725 * only APs) and without this workaround, the data
14484126Szf162725 * connection does not work because wpa_supplicant
14494126Szf162725 * configured non-zero keyidx to be used for unicast.
14504126Szf162725 */
14514126Szf162725 wpa_printf(MSG_INFO, "WPA: Tx bit set for GTK, but "
14524126Szf162725 "pairwise keys are used - ignore Tx bit");
14534126Szf162725 tx = 0;
14544126Szf162725 }
14554126Szf162725 }
14564126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, keylen);
14574126Szf162725 wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver (keyidx=%d "
14584126Szf162725 "tx=%d).", keyidx, tx);
14594126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len);
14604126Szf162725 if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
14614126Szf162725 /*
14624126Szf162725 * Swap Tx/Rx keys for Michael MIC
14634126Szf162725 */
14644126Szf162725 (void) memcpy(tmpbuf, gtk + 16, 8);
14654126Szf162725 (void) memcpy(gtk + 16, gtk + 24, 8);
14664126Szf162725 (void) memcpy(gtk + 24, tmpbuf, 8);
14674126Szf162725 }
14684126Szf162725 if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
1469*8453SAnurag.Maskey@Sun.COM if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
14704126Szf162725 (uint8_t *)"\xff\xff\xff\xff\xff\xff",
14714126Szf162725 keyidx, 1, key->key_rsc,
14724126Szf162725 key_rsc_len, gtk, keylen) < 0)
14734126Szf162725 wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the"
14744126Szf162725 " driver (Group only).");
1475*8453SAnurag.Maskey@Sun.COM } else if (wpa_s->driver->set_key(wpa_s->handle, wpa_s->linkid, alg,
14764126Szf162725 (uint8_t *)"\xff\xff\xff\xff\xff\xff",
14774126Szf162725 keyidx, tx,
14784126Szf162725 key->key_rsc, key_rsc_len,
14794126Szf162725 gtk, keylen) < 0) {
14804126Szf162725 wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the "
14814126Szf162725 "driver.");
14824126Szf162725 }
14834126Szf162725
14844126Szf162725 rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply);
14854126Szf162725 rbuf = malloc(rlen);
14864126Szf162725 if (rbuf == NULL)
14874126Szf162725 return;
14884126Szf162725
14894126Szf162725 (void) memset(rbuf, 0, rlen);
14904126Szf162725 ethhdr = (struct l2_ethhdr *)rbuf;
14914126Szf162725 (void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN);
14924126Szf162725 (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN);
14934126Szf162725 ethhdr->h_proto = htons(ETHERTYPE_EAPOL);
14944126Szf162725
14954126Szf162725 hdr = (struct ieee802_1x_hdr *)(ethhdr + 1);
14964126Szf162725 hdr->version = wpa_s->conf->eapol_version;
14974126Szf162725 hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
14984126Szf162725 hdr->length = htons(sizeof (*reply));
14994126Szf162725
15004126Szf162725 reply = (struct wpa_eapol_key *)(hdr + 1);
15014126Szf162725 reply->type = wpa_s->proto == WPA_PROTO_RSN ?
15024126Szf162725 EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
15034126Szf162725 reply->key_info =
15044126Szf162725 BE_16(ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE |
15054126Szf162725 (key_info & WPA_KEY_INFO_KEY_INDEX_MASK));
15064126Szf162725 reply->key_length = key->key_length;
15074126Szf162725 (void) memcpy(reply->replay_counter, key->replay_counter,
15084126Szf162725 WPA_REPLAY_COUNTER_LEN);
15094126Szf162725
15104126Szf162725 reply->key_data_length = BE_16(0);
15114126Szf162725
15124126Szf162725 wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr,
15134126Szf162725 rlen - sizeof (*ethhdr), reply->key_mic);
15144126Szf162725
15154126Szf162725 wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
15164126Szf162725 wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/2", rbuf, rlen);
15174126Szf162725 (void) l2_packet_send(wpa_s->l2, rbuf, rlen);
15184126Szf162725 free(rbuf);
15194126Szf162725
15204126Szf162725 wpa_printf(MSG_INFO, "WPA: Key negotiation completed with " MACSTR,
15214126Szf162725 MAC2STR(src_addr));
15224126Szf162725 eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
15234126Szf162725 wpa_supplicant_cancel_auth_timeout(wpa_s);
15244126Szf162725 wpa_s->wpa_state = WPA_COMPLETED;
15254126Szf162725 wpa_printf(MSG_INFO, "-----------------------------------\n");
15264126Szf162725 }
15274126Szf162725
15284126Szf162725 static int
wpa_supplicant_verify_eapol_key_mic(struct wpa_supplicant * wpa_s,struct wpa_eapol_key * key,int ver,uint8_t * buf,size_t len)15294126Szf162725 wpa_supplicant_verify_eapol_key_mic(struct wpa_supplicant *wpa_s,
15304126Szf162725 struct wpa_eapol_key *key, int ver, uint8_t *buf, size_t len)
15314126Szf162725 {
15324126Szf162725 uint8_t mic[16];
15334126Szf162725 int ok = 0;
15344126Szf162725
15354126Szf162725 (void) memcpy(mic, key->key_mic, 16);
15364126Szf162725 if (wpa_s->tptk_set) {
15374126Szf162725 (void) memset(key->key_mic, 0, 16);
15384126Szf162725 wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, buf, len,
15394126Szf162725 key->key_mic);
15404126Szf162725 if (memcmp(mic, key->key_mic, 16) != 0) {
15414126Szf162725 wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
15424126Szf162725 "when using TPTK - ignoring TPTK");
15434126Szf162725 } else {
15444126Szf162725 ok = 1;
15454126Szf162725 wpa_s->tptk_set = 0;
15464126Szf162725 wpa_s->ptk_set = 1;
15474126Szf162725 (void) memcpy(&wpa_s->ptk, &wpa_s->tptk,
15484126Szf162725 sizeof (wpa_s->ptk));
15494126Szf162725 }
15504126Szf162725 }
15514126Szf162725
15524126Szf162725 if (!ok && wpa_s->ptk_set) {
15534126Szf162725 (void) memset(key->key_mic, 0, 16);
15544126Szf162725 wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, buf, len,
15554126Szf162725 key->key_mic);
15564126Szf162725 if (memcmp(mic, key->key_mic, 16) != 0) {
15574126Szf162725 wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC "
15584126Szf162725 "- dropping packet");
15594126Szf162725 return (-1);
15604126Szf162725 }
15614126Szf162725 ok = 1;
15624126Szf162725 }
15634126Szf162725
15644126Szf162725 if (!ok) {
15654126Szf162725 wpa_printf(MSG_WARNING, "WPA: Could not verify EAPOL-Key MIC "
15664126Szf162725 "- dropping packet");
15674126Szf162725 return (-1);
15684126Szf162725 }
15694126Szf162725
15704126Szf162725 (void) memcpy(wpa_s->rx_replay_counter, key->replay_counter,
15714126Szf162725 WPA_REPLAY_COUNTER_LEN);
15724126Szf162725 wpa_s->rx_replay_counter_set = 1;
15734126Szf162725
15744126Szf162725 return (0);
15754126Szf162725 }
15764126Szf162725
15774126Szf162725 /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
15784126Szf162725 static int
wpa_supplicant_decrypt_key_data(struct wpa_supplicant * wpa_s,struct wpa_eapol_key * key,int ver)15794126Szf162725 wpa_supplicant_decrypt_key_data(struct wpa_supplicant *wpa_s,
15804126Szf162725 struct wpa_eapol_key *key, int ver)
15814126Szf162725 {
15824126Szf162725 int keydatalen = BE_16(key->key_data_length);
15834126Szf162725
15844126Szf162725 wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",
15854126Szf162725 (uint8_t *)(key + 1), keydatalen);
15864126Szf162725 if (!wpa_s->ptk_set) {
15874126Szf162725 wpa_printf(MSG_WARNING, "WPA: PTK not available, "
15884126Szf162725 "cannot decrypt EAPOL-Key key data.");
15894126Szf162725 return (-1);
15904126Szf162725 }
15914126Szf162725
15924126Szf162725 /*
15934126Szf162725 * Decrypt key data here so that this operation does not need
15944126Szf162725 * to be implemented separately for each message type.
15954126Szf162725 */
15964126Szf162725 if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) {
15974126Szf162725 uint8_t ek[32];
15984126Szf162725 (void) memcpy(ek, key->key_iv, 16);
15994126Szf162725 (void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16);
16004126Szf162725 rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen);
16014126Szf162725 } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
16024126Szf162725 uint8_t *buf;
16034126Szf162725 if (keydatalen % 8) {
16044126Szf162725 wpa_printf(MSG_WARNING, "WPA: Unsupported "
16054126Szf162725 "AES-WRAP len %d", keydatalen);
16064126Szf162725 return (-1);
16074126Szf162725 }
16084126Szf162725 keydatalen -= 8; /* AES-WRAP adds 8 bytes */
16094126Szf162725 buf = malloc(keydatalen);
16104126Szf162725 if (buf == NULL) {
16114126Szf162725 wpa_printf(MSG_WARNING, "WPA: No memory for "
16124126Szf162725 "AES-UNWRAP buffer");
16134126Szf162725 return (-1);
16144126Szf162725 }
16154126Szf162725 if (aes_unwrap(wpa_s->ptk.encr_key, keydatalen / 8,
16164126Szf162725 (uint8_t *)(key + 1), buf)) {
16174126Szf162725 free(buf);
16184126Szf162725 wpa_printf(MSG_WARNING, "WPA: AES unwrap failed - "
16194126Szf162725 "could not decrypt EAPOL-Key key data");
16204126Szf162725 return (-1);
16214126Szf162725 }
16224126Szf162725 (void) memcpy(key + 1, buf, keydatalen);
16234126Szf162725 free(buf);
16244126Szf162725 key->key_data_length = BE_16(keydatalen);
16254126Szf162725 }
16264126Szf162725 wpa_hexdump(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data",
16274126Szf162725 (uint8_t *)(key + 1), keydatalen);
16284126Szf162725
16294126Szf162725 return (0);
16304126Szf162725 }
16314126Szf162725
16324126Szf162725 static void
wpa_sm_rx_eapol(struct wpa_supplicant * wpa_s,unsigned char * src_addr,unsigned char * buf,size_t len)16334126Szf162725 wpa_sm_rx_eapol(struct wpa_supplicant *wpa_s,
16344126Szf162725 unsigned char *src_addr, unsigned char *buf, size_t len)
16354126Szf162725 {
16364126Szf162725 size_t plen, data_len, extra_len;
16374126Szf162725 struct ieee802_1x_hdr *hdr;
16384126Szf162725 struct wpa_eapol_key *key;
16394126Szf162725 int key_info, ver;
16404126Szf162725
16414126Szf162725 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame len %u\n ", len);
16424126Szf162725
16434126Szf162725 hdr = (struct ieee802_1x_hdr *)buf;
16444126Szf162725 key = (struct wpa_eapol_key *)(hdr + 1);
16454126Szf162725 wpa_printf(MSG_DEBUG, "hdr_len=%u, key_len=%u",
16464126Szf162725 sizeof (*hdr), sizeof (*key));
16474126Szf162725 if (len < sizeof (*hdr) + sizeof (*key)) {
16484126Szf162725 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short, len %u, "
16494126Szf162725 "expecting at least %u",
16504126Szf162725 len, sizeof (*hdr) + sizeof (*key));
16514126Szf162725 return;
16524126Szf162725 }
16534126Szf162725 plen = ntohs(hdr->length);
16544126Szf162725 data_len = plen + sizeof (*hdr);
16554126Szf162725 wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d",
16564126Szf162725 hdr->version, hdr->type, plen);
16574126Szf162725
16584126Szf162725 if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) {
16594126Szf162725 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame (type %u) discarded, "
16604126Szf162725 "not a Key frame", hdr->type);
16614126Szf162725 return;
16624126Szf162725 }
16634126Szf162725 if (plen > len - sizeof (*hdr) || plen < sizeof (*key)) {
16644126Szf162725 wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %u "
16654126Szf162725 "invalid (frame size %u)", plen, len);
16664126Szf162725 return;
16674126Szf162725 }
16684126Szf162725
16694126Szf162725 wpa_printf(MSG_DEBUG, " EAPOL-Key type=%d", key->type);
16704126Szf162725 if (key->type != EAPOL_KEY_TYPE_WPA && key->type !=
16714126Szf162725 EAPOL_KEY_TYPE_RSN) {
16724126Szf162725 wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key type (%d) unknown, "
16734126Szf162725 "discarded", key->type);
16744126Szf162725 return;
16754126Szf162725 }
16764126Szf162725
16774126Szf162725 wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
16784126Szf162725 if (data_len < len) {
16794126Szf162725 wpa_printf(MSG_DEBUG, "WPA: ignoring %d bytes after the IEEE "
16804126Szf162725 "802.1X data", len - data_len);
16814126Szf162725 }
16824126Szf162725 key_info = BE_16(key->key_info);
16834126Szf162725 ver = key_info & WPA_KEY_INFO_TYPE_MASK;
16844126Szf162725 if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
16854126Szf162725 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
16864126Szf162725 wpa_printf(MSG_INFO, "WPA: Unsupported EAPOL-Key descriptor "
16874126Szf162725 "version %d.", ver);
16884126Szf162725 return;
16894126Szf162725 }
16904126Szf162725
16914126Szf162725 if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP &&
16924126Szf162725 ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
16934126Szf162725 wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key "
16944126Szf162725 "descriptor version (%d) is not 2.", ver);
16954126Szf162725 if (wpa_s->group_cipher != WPA_CIPHER_CCMP &&
16964126Szf162725 !(key_info & WPA_KEY_INFO_KEY_TYPE)) {
16974126Szf162725 /*
16984126Szf162725 * Earlier versions of IEEE 802.11i did not explicitly
16994126Szf162725 * require version 2 descriptor for all EAPOL-Key
17004126Szf162725 * packets, so allow group keys to use version 1 if
17014126Szf162725 * CCMP is not used for them.
17024126Szf162725 */
17034126Szf162725 wpa_printf(MSG_INFO, "WPA: Backwards compatibility: "
17044126Szf162725 "allow invalid version for non-CCMP group keys");
17054126Szf162725 } else
17064126Szf162725 return;
17074126Szf162725 }
17084126Szf162725
17094126Szf162725 if (wpa_s->rx_replay_counter_set &&
17104126Szf162725 memcmp(key->replay_counter, wpa_s->rx_replay_counter,
17114126Szf162725 WPA_REPLAY_COUNTER_LEN) <= 0) {
17124126Szf162725 wpa_printf(MSG_WARNING, "WPA: EAPOL-Key Replay Counter did not"
17134126Szf162725 " increase - dropping packet");
17144126Szf162725 return;
17154126Szf162725 }
17164126Szf162725
17174126Szf162725 if (!(key_info & WPA_KEY_INFO_ACK)) {
17184126Szf162725 wpa_printf(MSG_INFO, "WPA: No Ack bit in key_info");
17194126Szf162725 return;
17204126Szf162725 }
17214126Szf162725
17224126Szf162725 if (key_info & WPA_KEY_INFO_REQUEST) {
17234126Szf162725 wpa_printf(MSG_INFO, "WPA: EAPOL-Key with Request bit - "
17244126Szf162725 "dropped");
17254126Szf162725 return;
17264126Szf162725 }
17274126Szf162725
17284126Szf162725 if ((key_info & WPA_KEY_INFO_MIC) &&
17295895Syz147064 wpa_supplicant_verify_eapol_key_mic(wpa_s, key, ver, buf,
17305895Syz147064 data_len)) {
17314126Szf162725 return;
17325895Syz147064 }
17334126Szf162725
17344126Szf162725 extra_len = data_len - sizeof (*hdr) - sizeof (*key);
17354126Szf162725
17364126Szf162725 if (wpa_s->proto == WPA_PROTO_RSN &&
17374126Szf162725 (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) &&
17384126Szf162725 wpa_supplicant_decrypt_key_data(wpa_s, key, ver))
17394126Szf162725 return;
17404126Szf162725
17414126Szf162725 if (key_info & WPA_KEY_INFO_KEY_TYPE) {
17424126Szf162725 if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
17434126Szf162725 wpa_printf(MSG_WARNING, "WPA: Ignored EAPOL-Key "
17444126Szf162725 "(Pairwise) with non-zero key index");
17454126Szf162725 return;
17464126Szf162725 }
17474126Szf162725 if (key_info & WPA_KEY_INFO_MIC) {
17484126Szf162725 /* 3/4 4-Way Handshake */
17494126Szf162725 wpa_supplicant_process_3_of_4(wpa_s, src_addr, key,
17504126Szf162725 extra_len, ver);
17514126Szf162725 } else {
17524126Szf162725 /* 1/4 4-Way Handshake */
17534126Szf162725 wpa_supplicant_process_1_of_4(wpa_s, src_addr, key,
17544126Szf162725 ver);
17554126Szf162725 }
17564126Szf162725 } else {
17574126Szf162725 if (key_info & WPA_KEY_INFO_MIC) {
17584126Szf162725 /* 1/2 Group Key Handshake */
17594126Szf162725 wpa_supplicant_process_1_of_2(wpa_s, src_addr, key,
17604126Szf162725 extra_len, ver);
17614126Szf162725 } else {
17624126Szf162725 wpa_printf(MSG_WARNING, "WPA: EAPOL-Key (Group) "
17634126Szf162725 "without Mic bit - dropped");
17644126Szf162725 }
17654126Szf162725 }
17664126Szf162725 }
17674126Szf162725
17684126Szf162725 void
wpa_supplicant_rx_eapol(void * ctx,unsigned char * src_addr,unsigned char * buf,size_t len)17694126Szf162725 wpa_supplicant_rx_eapol(void *ctx, unsigned char *src_addr,
17704126Szf162725 unsigned char *buf, size_t len)
17714126Szf162725 {
17724126Szf162725 struct wpa_supplicant *wpa_s = ctx;
17734126Szf162725
17744126Szf162725 wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
17754126Szf162725 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
17764126Szf162725
17774126Szf162725 if (wpa_s->eapol_received == 0) {
17784126Szf162725 /* Timeout for completing IEEE 802.1X and WPA authentication */
17794126Szf162725 wpa_supplicant_req_auth_timeout(
17804126Szf162725 wpa_s, wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ?
17814126Szf162725 70 : 10, 0);
17824126Szf162725 }
17834126Szf162725 wpa_s->eapol_received++;
17844126Szf162725
17854126Szf162725 /*
17864126Szf162725 * Source address of the incoming EAPOL frame could be compared to the
17874126Szf162725 * current BSSID. However, it is possible that a centralized
17884126Szf162725 * Authenticator could be using another MAC address than the BSSID of
17894126Szf162725 * an AP, so just allow any address to be used for now. The replies are
17904126Szf162725 * still sent to the current BSSID (if available), though.
17914126Szf162725 */
17924126Szf162725 wpa_sm_rx_eapol(wpa_s, src_addr, buf, len);
17934126Szf162725 }
1794