1a399b765Szf /* 2d62bc4baSyz * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3a399b765Szf * Use is subject to license terms. 4a399b765Szf */ 5a399b765Szf 6a399b765Szf /* 7a399b765Szf * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> 8a399b765Szf * Sun elects to license this software under the BSD license. 9a399b765Szf * See README for more details. 10a399b765Szf */ 11a399b765Szf 12a399b765Szf #pragma ident "%Z%%M% %I% %E% SMI" 13a399b765Szf 14a399b765Szf #include <stdio.h> 15a399b765Szf #include <stdlib.h> 16a399b765Szf #include <string.h> 17a399b765Szf #include <time.h> 18a399b765Szf #include <netinet/in.h> 19a399b765Szf #include <sys/ethernet.h> 20a399b765Szf #include <fcntl.h> 21a399b765Szf #include <unistd.h> 22a399b765Szf 23a399b765Szf #include "wpa_impl.h" 24a399b765Szf #include "wpa_enc.h" 25a399b765Szf #include "driver.h" 26a399b765Szf #include "eloop.h" 27a399b765Szf #include "l2_packet.h" 28a399b765Szf 29a399b765Szf static void pmksa_cache_set_expiration(struct wpa_supplicant *); 30a399b765Szf 31a399b765Szf /* 32a399b765Szf * IEEE 802.11i/D3.0 33a399b765Szf */ 34a399b765Szf static const int WPA_SELECTOR_LEN = 4; 35*fb91fd8aSzf static const uint8_t WPA_OUI_AND_TYPE[] = { 0x00, 0x50, 0xf2, 1 }; 36a399b765Szf static const uint8_t 37a399b765Szf WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 }; 38a399b765Szf static const uint8_t 39a399b765Szf WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 }; 40a399b765Szf static const uint8_t WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 }; 41a399b765Szf static const uint8_t WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 }; 42a399b765Szf static const uint8_t WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 }; 43a399b765Szf static const uint8_t WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 }; 44a399b765Szf static const uint8_t WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 }; 45a399b765Szf 46a399b765Szf /* 47a399b765Szf * WPA IE version 1 48a399b765Szf * 00-50-f2:1 (OUI:OUI type) 49a399b765Szf * 0x01 0x00 (version; little endian) 50a399b765Szf * (all following fields are optional:) 51a399b765Szf * Group Suite Selector (4 octets) (default: TKIP) 52a399b765Szf * Pairwise Suite Count (2 octets, little endian) (default: 1) 53a399b765Szf * Pairwise Suite List (4 * n octets) (default: TKIP) 54a399b765Szf * Authenticated Key Management Suite Count (2 octets, little endian) 55a399b765Szf * (default: 1) 56a399b765Szf * Authenticated Key Management Suite List (4 * n octets) 57a399b765Szf * (default: unspec 802.1x) 58a399b765Szf * WPA Capabilities (2 octets, little endian) (default: 0) 59a399b765Szf */ 60a399b765Szf #pragma pack(1) 61a399b765Szf struct wpa_ie_hdr { 62a399b765Szf uint8_t elem_id; 63a399b765Szf uint8_t len; 64a399b765Szf uint8_t oui[3]; 65a399b765Szf uint8_t oui_type; 66a399b765Szf uint16_t version; 67a399b765Szf }; 68a399b765Szf #pragma pack() 69a399b765Szf 70a399b765Szf /* 71a399b765Szf * IEEE 802.11i/D9.0 72a399b765Szf */ 73a399b765Szf static const int RSN_SELECTOR_LEN = 4; 74a399b765Szf static const uint16_t RSN_VERSION = 1; 75a399b765Szf static const uint8_t 76a399b765Szf RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 }; 77a399b765Szf static const uint8_t 78a399b765Szf RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 }; 79a399b765Szf static const uint8_t RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 }; 80a399b765Szf static const uint8_t RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 }; 81a399b765Szf static const uint8_t RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 }; 82a399b765Szf static const uint8_t RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 }; 83a399b765Szf static const uint8_t RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 }; 84a399b765Szf 85a399b765Szf /* 86a399b765Szf * EAPOL-Key Key Data Encapsulation 87a399b765Szf * GroupKey and STAKey require encryption, otherwise, encryption is optional. 88a399b765Szf */ 89a399b765Szf static const uint8_t RSN_KEY_DATA_GROUPKEY[] = { 0x00, 0x0f, 0xac, 1 }; 90a399b765Szf static const uint8_t RSN_KEY_DATA_PMKID[] = { 0x00, 0x0f, 0xac, 4 }; 91a399b765Szf 92a399b765Szf /* 93a399b765Szf * 1/4: PMKID 94a399b765Szf * 2/4: RSN IE 95a399b765Szf * 3/4: one or two RSN IEs + GTK IE (encrypted) 96a399b765Szf * 4/4: empty 97a399b765Szf * 1/2: GTK IE (encrypted) 98a399b765Szf * 2/2: empty 99a399b765Szf */ 100a399b765Szf 101a399b765Szf /* 102a399b765Szf * RSN IE version 1 103a399b765Szf * 0x01 0x00 (version; little endian) 104a399b765Szf * (all following fields are optional:) 105a399b765Szf * Group Suite Selector (4 octets) (default: CCMP) 106a399b765Szf * Pairwise Suite Count (2 octets, little endian) (default: 1) 107a399b765Szf * Pairwise Suite List (4 * n octets) (default: CCMP) 108a399b765Szf * Authenticated Key Management Suite Count (2 octets, little endian) 109a399b765Szf * (default: 1) 110a399b765Szf * Authenticated Key Management Suite List (4 * n octets) 111a399b765Szf * (default: unspec 802.1x) 112a399b765Szf * RSN Capabilities (2 octets, little endian) (default: 0) 113a399b765Szf * PMKID Count (2 octets) (default: 0) 114a399b765Szf * PMKID List (16 * n octets) 115a399b765Szf */ 116a399b765Szf #pragma pack(1) 117a399b765Szf struct rsn_ie_hdr { 118a399b765Szf uint8_t elem_id; /* WLAN_EID_RSN */ 119a399b765Szf uint8_t len; 120a399b765Szf uint16_t version; 121a399b765Szf }; 122a399b765Szf #pragma pack() 123a399b765Szf 124a399b765Szf static int 125a399b765Szf random_get_pseudo_bytes(uint8_t *ptr, size_t len) 126a399b765Szf { 127a399b765Szf int fd; 128a399b765Szf size_t resid = len; 129a399b765Szf size_t bytes; 130a399b765Szf 131a399b765Szf fd = open("/dev/urandom", O_RDONLY); 132a399b765Szf if (fd == -1) { 133a399b765Szf wpa_printf(MSG_ERROR, "Could not open /dev/urandom.\n"); 134a399b765Szf return (-1); 135a399b765Szf } 136a399b765Szf 137a399b765Szf while (resid != 0) { 138a399b765Szf bytes = read(fd, ptr, resid); 139a399b765Szf ptr += bytes; 140a399b765Szf resid -= bytes; 141a399b765Szf } 142a399b765Szf 143a399b765Szf (void) close(fd); 144a399b765Szf 145a399b765Szf return (0); 146a399b765Szf } 147a399b765Szf 148a399b765Szf static void 149a399b765Szf inc_byte_array(uint8_t *counter, size_t len) 150a399b765Szf { 151a399b765Szf int pos = len - 1; 152a399b765Szf while (pos >= 0) { 153a399b765Szf counter[pos]++; 154a399b765Szf if (counter[pos] != 0) 155a399b765Szf break; 156a399b765Szf pos--; 157a399b765Szf } 158a399b765Szf } 159a399b765Szf 160a399b765Szf static int 161a399b765Szf wpa_selector_to_bitfield(uint8_t *s) 162a399b765Szf { 163a399b765Szf if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0) 164a399b765Szf return (WPA_CIPHER_NONE); 165a399b765Szf if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0) 166a399b765Szf return (WPA_CIPHER_WEP40); 167a399b765Szf if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0) 168a399b765Szf return (WPA_CIPHER_TKIP); 169a399b765Szf if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0) 170a399b765Szf return (WPA_CIPHER_CCMP); 171a399b765Szf if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0) 172a399b765Szf return (WPA_CIPHER_WEP104); 173a399b765Szf return (0); 174a399b765Szf } 175a399b765Szf 176a399b765Szf static int 177a399b765Szf wpa_key_mgmt_to_bitfield(uint8_t *s) 178a399b765Szf { 179a399b765Szf if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0) 180a399b765Szf return (WPA_KEY_MGMT_IEEE8021X); 181a399b765Szf if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) == 182a399b765Szf 0) 183a399b765Szf return (WPA_KEY_MGMT_PSK); 184a399b765Szf return (0); 185a399b765Szf } 186a399b765Szf 187a399b765Szf static int 188a399b765Szf rsn_selector_to_bitfield(uint8_t *s) 189a399b765Szf { 190a399b765Szf if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0) 191a399b765Szf return (WPA_CIPHER_NONE); 192a399b765Szf if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0) 193a399b765Szf return (WPA_CIPHER_WEP40); 194a399b765Szf if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0) 195a399b765Szf return (WPA_CIPHER_TKIP); 196a399b765Szf if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0) 197a399b765Szf return (WPA_CIPHER_CCMP); 198a399b765Szf if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0) 199a399b765Szf return (WPA_CIPHER_WEP104); 200a399b765Szf return (0); 201a399b765Szf } 202a399b765Szf 203a399b765Szf static int 204a399b765Szf rsn_key_mgmt_to_bitfield(uint8_t *s) 205a399b765Szf { 206a399b765Szf if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0) 207a399b765Szf return (WPA_KEY_MGMT_IEEE8021X); 208a399b765Szf if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) == 209a399b765Szf 0) 210a399b765Szf return (WPA_KEY_MGMT_PSK); 211a399b765Szf return (0); 212a399b765Szf } 213a399b765Szf 214a399b765Szf static void 215a399b765Szf pmksa_cache_free_entry(struct wpa_supplicant *wpa_s, 216a399b765Szf struct rsn_pmksa_cache *entry) 217a399b765Szf { 218a399b765Szf wpa_s->pmksa_count--; 219a399b765Szf if (wpa_s->cur_pmksa == entry) { 220a399b765Szf wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA entry"); 221a399b765Szf wpa_s->cur_pmksa = NULL; 222a399b765Szf } 223a399b765Szf free(entry); 224a399b765Szf } 225a399b765Szf 226a399b765Szf /* ARGSUSED */ 227a399b765Szf static void 228a399b765Szf pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx) 229a399b765Szf { 230a399b765Szf struct wpa_supplicant *wpa_s = eloop_ctx; 231a399b765Szf time_t now; 232a399b765Szf 233a399b765Szf (void) time(&now); 234a399b765Szf while (wpa_s->pmksa && wpa_s->pmksa->expiration <= now) { 235a399b765Szf struct rsn_pmksa_cache *entry = wpa_s->pmksa; 236a399b765Szf wpa_s->pmksa = entry->next; 237a399b765Szf wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for " 238a399b765Szf MACSTR, MAC2STR(entry->aa)); 239a399b765Szf pmksa_cache_free_entry(wpa_s, entry); 240a399b765Szf } 241a399b765Szf 242a399b765Szf pmksa_cache_set_expiration(wpa_s); 243a399b765Szf } 244a399b765Szf 245a399b765Szf static void 246a399b765Szf pmksa_cache_set_expiration(struct wpa_supplicant *wpa_s) 247a399b765Szf { 248a399b765Szf int sec; 249a399b765Szf eloop_cancel_timeout(pmksa_cache_expire, wpa_s, NULL); 250a399b765Szf if (wpa_s->pmksa == NULL) 251a399b765Szf return; 252a399b765Szf sec = wpa_s->pmksa->expiration - time(NULL); 253a399b765Szf if (sec < 0) 254a399b765Szf sec = 0; 255a399b765Szf (void) eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, 256a399b765Szf wpa_s, NULL); 257a399b765Szf } 258a399b765Szf 259a399b765Szf void 260a399b765Szf pmksa_cache_free(struct wpa_supplicant *wpa_s) 261a399b765Szf { 262a399b765Szf struct rsn_pmksa_cache *entry, *prev; 263a399b765Szf 264a399b765Szf entry = wpa_s->pmksa; 265a399b765Szf wpa_s->pmksa = NULL; 266a399b765Szf while (entry) { 267a399b765Szf prev = entry; 268a399b765Szf entry = entry->next; 269a399b765Szf free(prev); 270a399b765Szf } 271a399b765Szf pmksa_cache_set_expiration(wpa_s); 272a399b765Szf wpa_s->cur_pmksa = NULL; 273a399b765Szf } 274a399b765Szf 275a399b765Szf struct rsn_pmksa_cache * 276a399b765Szf pmksa_cache_get(struct wpa_supplicant *wpa_s, 277a399b765Szf uint8_t *aa, uint8_t *pmkid) 278a399b765Szf { 279a399b765Szf struct rsn_pmksa_cache *entry = wpa_s->pmksa; 280a399b765Szf while (entry) { 281a399b765Szf if ((aa == NULL || 282a399b765Szf memcmp(entry->aa, aa, IEEE80211_ADDR_LEN) == 0) && 283a399b765Szf (pmkid == NULL || 284a399b765Szf memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0)) 285a399b765Szf return (entry); 286a399b765Szf entry = entry->next; 287a399b765Szf } 288a399b765Szf return (NULL); 289a399b765Szf } 290a399b765Szf 291a399b765Szf int 292a399b765Szf pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf, size_t len) 293a399b765Szf { 294a399b765Szf int i, j; 295a399b765Szf char *pos = buf; 296a399b765Szf struct rsn_pmksa_cache *entry; 297a399b765Szf time_t now; 298a399b765Szf 299a399b765Szf (void) time(&now); 300a399b765Szf pos += snprintf(pos, buf + len - pos, 301a399b765Szf "Index / AA / PMKID / expiration (in seconds)\n"); 302a399b765Szf i = 0; 303a399b765Szf entry = wpa_s->pmksa; 304a399b765Szf while (entry) { 305a399b765Szf i++; 306a399b765Szf pos += snprintf(pos, buf + len - pos, "%d " MACSTR " ", 307a399b765Szf i, MAC2STR(entry->aa)); 308a399b765Szf for (j = 0; j < PMKID_LEN; j++) 309a399b765Szf pos += snprintf(pos, buf + len - pos, "%02x", 310a399b765Szf entry->pmkid[j]); 311a399b765Szf pos += snprintf(pos, buf + len - pos, " %d\n", 312a399b765Szf (int)(entry->expiration - now)); 313a399b765Szf entry = entry->next; 314a399b765Szf } 315a399b765Szf return (pos - buf); 316a399b765Szf } 317a399b765Szf 318a399b765Szf void 319a399b765Szf pmksa_candidate_free(struct wpa_supplicant *wpa_s) 320a399b765Szf { 321a399b765Szf struct rsn_pmksa_candidate *entry, *prev; 322a399b765Szf 323a399b765Szf entry = wpa_s->pmksa_candidates; 324a399b765Szf wpa_s->pmksa_candidates = NULL; 325a399b765Szf while (entry) { 326a399b765Szf prev = entry; 327a399b765Szf entry = entry->next; 328a399b765Szf free(prev); 329a399b765Szf } 330a399b765Szf } 331a399b765Szf 332a399b765Szf /* ARGSUSED */ 333a399b765Szf static int 334a399b765Szf wpa_parse_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie, 335a399b765Szf size_t wpa_ie_len, struct wpa_ie_data *data) 336a399b765Szf { 337a399b765Szf struct wpa_ie_hdr *hdr; 338a399b765Szf uint8_t *pos; 339a399b765Szf int left; 340a399b765Szf int i, count; 341a399b765Szf 342a399b765Szf data->proto = WPA_PROTO_WPA; 343a399b765Szf data->pairwise_cipher = WPA_CIPHER_TKIP; 344a399b765Szf data->group_cipher = WPA_CIPHER_TKIP; 345a399b765Szf data->key_mgmt = WPA_KEY_MGMT_IEEE8021X; 346a399b765Szf data->capabilities = 0; 347a399b765Szf 348a399b765Szf if (wpa_ie_len == 0) { 349a399b765Szf /* No WPA IE - fail silently */ 350a399b765Szf return (-1); 351a399b765Szf } 352a399b765Szf 353a399b765Szf if (wpa_ie_len < sizeof (struct wpa_ie_hdr)) { 354a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie len too short %u", 355a399b765Szf "wpa_parse_wpa_ie_wpa", wpa_ie_len); 356a399b765Szf return (-1); 357a399b765Szf } 358a399b765Szf 359a399b765Szf hdr = (struct wpa_ie_hdr *)wpa_ie; 360a399b765Szf 361a399b765Szf if (hdr->elem_id != GENERIC_INFO_ELEM || 362a399b765Szf hdr->len != wpa_ie_len - 2 || 363*fb91fd8aSzf memcmp(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN) != 0 || 364a399b765Szf LE_16(hdr->version) != WPA_VERSION) { 365a399b765Szf wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", 366a399b765Szf "wpa_parse_wpa_ie_wpa"); 367a399b765Szf return (-1); 368a399b765Szf } 369a399b765Szf 370a399b765Szf pos = (uint8_t *)(hdr + 1); 371a399b765Szf left = wpa_ie_len - sizeof (*hdr); 372a399b765Szf 373a399b765Szf if (left >= WPA_SELECTOR_LEN) { 374a399b765Szf data->group_cipher = wpa_selector_to_bitfield(pos); 375a399b765Szf pos += WPA_SELECTOR_LEN; 376a399b765Szf left -= WPA_SELECTOR_LEN; 377a399b765Szf } else if (left > 0) { 378a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much", 379a399b765Szf "wpa_parse_wpa_ie_wpa", left); 380a399b765Szf return (-1); 381a399b765Szf } 382a399b765Szf 383a399b765Szf if (left >= 2) { 384a399b765Szf data->pairwise_cipher = 0; 385a399b765Szf count = pos[0] | (pos[1] << 8); 386a399b765Szf pos += 2; 387a399b765Szf left -= 2; 388a399b765Szf if (count == 0 || left < count * WPA_SELECTOR_LEN) { 389a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), " 390a399b765Szf "count %u left %u", 391a399b765Szf "wpa_parse_wpa_ie_wpa", count, left); 392a399b765Szf return (-1); 393a399b765Szf } 394a399b765Szf for (i = 0; i < count; i++) { 395a399b765Szf data->pairwise_cipher |= wpa_selector_to_bitfield(pos); 396a399b765Szf pos += WPA_SELECTOR_LEN; 397a399b765Szf left -= WPA_SELECTOR_LEN; 398a399b765Szf } 399a399b765Szf } else if (left == 1) { 400a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)", 401a399b765Szf "wpa_parse_wpa_ie_wpa"); 402a399b765Szf return (-1); 403a399b765Szf } 404a399b765Szf 405a399b765Szf if (left >= 2) { 406a399b765Szf data->key_mgmt = 0; 407a399b765Szf count = pos[0] | (pos[1] << 8); 408a399b765Szf pos += 2; 409a399b765Szf left -= 2; 410a399b765Szf if (count == 0 || left < count * WPA_SELECTOR_LEN) { 411a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), " 412a399b765Szf "count %u left %u", 413a399b765Szf "wpa_parse_wpa_ie_wpa", count, left); 414a399b765Szf return (-1); 415a399b765Szf } 416a399b765Szf for (i = 0; i < count; i++) { 417a399b765Szf data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos); 418a399b765Szf pos += WPA_SELECTOR_LEN; 419a399b765Szf left -= WPA_SELECTOR_LEN; 420a399b765Szf } 421a399b765Szf } else if (left == 1) { 422a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)", 423a399b765Szf "wpa_parse_wpa_ie_wpa"); 424a399b765Szf return (-1); 425a399b765Szf } 426a399b765Szf 427a399b765Szf if (left >= 2) { 428a399b765Szf data->capabilities = pos[0] | (pos[1] << 8); 429a399b765Szf pos += 2; 430a399b765Szf left -= 2; 431a399b765Szf } 432a399b765Szf 433a399b765Szf if (left > 0) { 434a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes", 435a399b765Szf "wpa_parse_wpa_ie_wpa", left); 436a399b765Szf return (-1); 437a399b765Szf } 438a399b765Szf 439a399b765Szf return (0); 440a399b765Szf } 441a399b765Szf 442a399b765Szf /* ARGSUSED */ 443a399b765Szf static int 444a399b765Szf wpa_parse_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie, 445a399b765Szf size_t rsn_ie_len, struct wpa_ie_data *data) 446a399b765Szf { 447a399b765Szf struct rsn_ie_hdr *hdr; 448a399b765Szf uint8_t *pos; 449a399b765Szf int left; 450a399b765Szf int i, count; 451a399b765Szf 452a399b765Szf data->proto = WPA_PROTO_RSN; 453a399b765Szf data->pairwise_cipher = WPA_CIPHER_CCMP; 454a399b765Szf data->group_cipher = WPA_CIPHER_CCMP; 455a399b765Szf data->key_mgmt = WPA_KEY_MGMT_IEEE8021X; 456a399b765Szf data->capabilities = 0; 457a399b765Szf 458a399b765Szf if (rsn_ie_len == 0) { 459a399b765Szf /* No RSN IE - fail silently */ 460a399b765Szf return (-1); 461a399b765Szf } 462a399b765Szf 463a399b765Szf if (rsn_ie_len < sizeof (struct rsn_ie_hdr)) { 464a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie len too short %u", 465a399b765Szf "wpa_parse_wpa_ie_rsn", rsn_ie_len); 466a399b765Szf return (-1); 467a399b765Szf } 468a399b765Szf 469a399b765Szf hdr = (struct rsn_ie_hdr *)rsn_ie; 470a399b765Szf 471a399b765Szf if (hdr->elem_id != RSN_INFO_ELEM || 472a399b765Szf hdr->len != rsn_ie_len - 2 || 473a399b765Szf LE_16(hdr->version) != RSN_VERSION) { 474a399b765Szf wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version", 475a399b765Szf "wpa_parse_wpa_ie_rsn"); 476a399b765Szf return (-1); 477a399b765Szf } 478a399b765Szf 479a399b765Szf pos = (uint8_t *)(hdr + 1); 480a399b765Szf left = rsn_ie_len - sizeof (*hdr); 481a399b765Szf 482a399b765Szf if (left >= RSN_SELECTOR_LEN) { 483a399b765Szf data->group_cipher = rsn_selector_to_bitfield(pos); 484a399b765Szf pos += RSN_SELECTOR_LEN; 485a399b765Szf left -= RSN_SELECTOR_LEN; 486a399b765Szf } else if (left > 0) { 487a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much", 488a399b765Szf "wpa_parse_wpa_ie_rsn", left); 489a399b765Szf return (-1); 490a399b765Szf } 491a399b765Szf 492a399b765Szf if (left >= 2) { 493a399b765Szf data->pairwise_cipher = 0; 494a399b765Szf count = pos[0] | (pos[1] << 8); 495a399b765Szf pos += 2; 496a399b765Szf left -= 2; 497a399b765Szf if (count == 0 || left < count * RSN_SELECTOR_LEN) { 498a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), " 499a399b765Szf "count %u left %u", 500a399b765Szf "wpa_parse_wpa_ie_rsn", count, left); 501a399b765Szf return (-1); 502a399b765Szf } 503a399b765Szf for (i = 0; i < count; i++) { 504a399b765Szf data->pairwise_cipher |= rsn_selector_to_bitfield(pos); 505a399b765Szf pos += RSN_SELECTOR_LEN; 506a399b765Szf left -= RSN_SELECTOR_LEN; 507a399b765Szf } 508a399b765Szf } else if (left == 1) { 509a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)", 510a399b765Szf "wpa_parse_wpa_ie_rsn"); 511a399b765Szf return (-1); 512a399b765Szf } 513a399b765Szf 514a399b765Szf if (left >= 2) { 515a399b765Szf data->key_mgmt = 0; 516a399b765Szf count = pos[0] | (pos[1] << 8); 517a399b765Szf pos += 2; 518a399b765Szf left -= 2; 519a399b765Szf if (count == 0 || left < count * RSN_SELECTOR_LEN) { 520a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), " 521a399b765Szf "count %u left %u", 522a399b765Szf "wpa_parse_wpa_ie_rsn", count, left); 523a399b765Szf return (-1); 524a399b765Szf } 525a399b765Szf for (i = 0; i < count; i++) { 526a399b765Szf data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos); 527a399b765Szf pos += RSN_SELECTOR_LEN; 528a399b765Szf left -= RSN_SELECTOR_LEN; 529a399b765Szf } 530a399b765Szf } else if (left == 1) { 531a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)", 532a399b765Szf "wpa_parse_wpa_ie_rsn"); 533a399b765Szf return (-1); 534a399b765Szf } 535a399b765Szf 536a399b765Szf if (left >= 2) { 537a399b765Szf data->capabilities = pos[0] | (pos[1] << 8); 538a399b765Szf pos += 2; 539a399b765Szf left -= 2; 540a399b765Szf } 541a399b765Szf 542a399b765Szf if (left > 0) { 543a399b765Szf /* 544a399b765Szf * RSN IE could include PMKID data, but Authenticator should 545a399b765Szf * never include it, so no need to parse it in the Supplicant. 546a399b765Szf */ 547a399b765Szf wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored", 548a399b765Szf "wpa_parse_wpa_ie_rsn", left); 549a399b765Szf } 550a399b765Szf 551a399b765Szf return (0); 552a399b765Szf } 553a399b765Szf 554a399b765Szf int 555a399b765Szf wpa_parse_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie, 556a399b765Szf size_t wpa_ie_len, struct wpa_ie_data *data) 557a399b765Szf { 558a399b765Szf if (wpa_ie_len >= 1 && wpa_ie[0] == RSN_INFO_ELEM) 559a399b765Szf return (wpa_parse_wpa_ie_rsn(wpa_s, wpa_ie, wpa_ie_len, data)); 560a399b765Szf else 561a399b765Szf return (wpa_parse_wpa_ie_wpa(wpa_s, wpa_ie, wpa_ie_len, data)); 562a399b765Szf } 563a399b765Szf 564a399b765Szf static int 565a399b765Szf wpa_gen_wpa_ie_wpa(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie) 566a399b765Szf { 567a399b765Szf uint8_t *pos; 568a399b765Szf struct wpa_ie_hdr *hdr; 569a399b765Szf 570a399b765Szf hdr = (struct wpa_ie_hdr *)wpa_ie; 571a399b765Szf hdr->elem_id = GENERIC_INFO_ELEM; 572*fb91fd8aSzf (void) memcpy(&hdr->oui, WPA_OUI_AND_TYPE, WPA_SELECTOR_LEN); 573a399b765Szf hdr->version = LE_16(WPA_VERSION); 574a399b765Szf pos = (uint8_t *)(hdr + 1); 575a399b765Szf 576a399b765Szf if (wpa_s->group_cipher == WPA_CIPHER_CCMP) { 577a399b765Szf (void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN); 578a399b765Szf } else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) { 579a399b765Szf (void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN); 580a399b765Szf } else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) { 581a399b765Szf (void) memcpy(pos, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN); 582a399b765Szf } else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) { 583a399b765Szf (void) memcpy(pos, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN); 584a399b765Szf } else { 585a399b765Szf wpa_printf(MSG_WARNING, "Invalid group cipher (%d).", 586a399b765Szf wpa_s->group_cipher); 587a399b765Szf return (-1); 588a399b765Szf } 589a399b765Szf pos += WPA_SELECTOR_LEN; 590a399b765Szf 591a399b765Szf *pos++ = 1; 592a399b765Szf *pos++ = 0; 593a399b765Szf if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) { 594a399b765Szf (void) memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN); 595a399b765Szf } else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) { 596a399b765Szf (void) memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN); 597a399b765Szf } else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) { 598a399b765Szf (void) memcpy(pos, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN); 599a399b765Szf } else { 600a399b765Szf wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).", 601a399b765Szf wpa_s->pairwise_cipher); 602a399b765Szf return (-1); 603a399b765Szf } 604a399b765Szf pos += WPA_SELECTOR_LEN; 605a399b765Szf 606a399b765Szf *pos++ = 1; 607a399b765Szf *pos++ = 0; 608a399b765Szf if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) { 609a399b765Szf (void) memcpy(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, 610a399b765Szf WPA_SELECTOR_LEN); 611a399b765Szf } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) { 612a399b765Szf (void) memcpy(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, 613a399b765Szf WPA_SELECTOR_LEN); 614a399b765Szf } else { 615a399b765Szf wpa_printf(MSG_WARNING, "Invalid key management type (%d).", 616a399b765Szf wpa_s->key_mgmt); 617a399b765Szf return (-1); 618a399b765Szf } 619a399b765Szf pos += WPA_SELECTOR_LEN; 620a399b765Szf 621a399b765Szf /* 622a399b765Szf * WPA Capabilities; use defaults, so no need to include it 623a399b765Szf */ 624a399b765Szf hdr->len = (pos - wpa_ie) - 2; 625a399b765Szf 626a399b765Szf return (pos - wpa_ie); 627a399b765Szf } 628a399b765Szf 629a399b765Szf static int 630a399b765Szf wpa_gen_wpa_ie_rsn(struct wpa_supplicant *wpa_s, uint8_t *rsn_ie) 631a399b765Szf { 632a399b765Szf uint8_t *pos; 633a399b765Szf struct rsn_ie_hdr *hdr; 634a399b765Szf 635a399b765Szf hdr = (struct rsn_ie_hdr *)rsn_ie; 636a399b765Szf hdr->elem_id = RSN_INFO_ELEM; 637a399b765Szf hdr->version = LE_16(RSN_VERSION); 638a399b765Szf pos = (uint8_t *)(hdr + 1); 639a399b765Szf 640a399b765Szf if (wpa_s->group_cipher == WPA_CIPHER_CCMP) { 641a399b765Szf (void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN); 642a399b765Szf } else if (wpa_s->group_cipher == WPA_CIPHER_TKIP) { 643a399b765Szf (void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN); 644a399b765Szf } else if (wpa_s->group_cipher == WPA_CIPHER_WEP104) { 645a399b765Szf (void) memcpy(pos, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN); 646a399b765Szf } else if (wpa_s->group_cipher == WPA_CIPHER_WEP40) { 647a399b765Szf (void) memcpy(pos, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN); 648a399b765Szf } else { 649a399b765Szf wpa_printf(MSG_WARNING, "Invalid group cipher (%d).", 650a399b765Szf wpa_s->group_cipher); 651a399b765Szf return (-1); 652a399b765Szf } 653a399b765Szf pos += RSN_SELECTOR_LEN; 654a399b765Szf 655a399b765Szf *pos++ = 1; 656a399b765Szf *pos++ = 0; 657a399b765Szf if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) { 658a399b765Szf (void) memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN); 659a399b765Szf } else if (wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) { 660a399b765Szf (void) memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN); 661a399b765Szf } else if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) { 662a399b765Szf (void) memcpy(pos, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN); 663a399b765Szf } else { 664a399b765Szf wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).", 665a399b765Szf wpa_s->pairwise_cipher); 666a399b765Szf return (-1); 667a399b765Szf } 668a399b765Szf pos += RSN_SELECTOR_LEN; 669a399b765Szf 670a399b765Szf *pos++ = 1; 671a399b765Szf *pos++ = 0; 672a399b765Szf if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) { 673a399b765Szf (void) memcpy(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, 674a399b765Szf RSN_SELECTOR_LEN); 675a399b765Szf } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) { 676a399b765Szf (void) memcpy(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, 677a399b765Szf RSN_SELECTOR_LEN); 678a399b765Szf } else { 679a399b765Szf wpa_printf(MSG_WARNING, "Invalid key management type (%d).", 680a399b765Szf wpa_s->key_mgmt); 681a399b765Szf return (-1); 682a399b765Szf } 683a399b765Szf pos += RSN_SELECTOR_LEN; 684a399b765Szf 685a399b765Szf /* RSN Capabilities */ 686a399b765Szf *pos++ = 0; 687a399b765Szf *pos++ = 0; 688a399b765Szf 689a399b765Szf if (wpa_s->cur_pmksa) { 690a399b765Szf /* PMKID Count (2 octets, little endian) */ 691a399b765Szf *pos++ = 1; 692a399b765Szf *pos++ = 0; 693a399b765Szf /* PMKID */ 694a399b765Szf (void) memcpy(pos, wpa_s->cur_pmksa->pmkid, PMKID_LEN); 695a399b765Szf pos += PMKID_LEN; 696a399b765Szf } 697a399b765Szf 698a399b765Szf hdr->len = (pos - rsn_ie) - 2; 699a399b765Szf 700a399b765Szf return (pos - rsn_ie); 701a399b765Szf } 702a399b765Szf 703a399b765Szf int 704a399b765Szf wpa_gen_wpa_ie(struct wpa_supplicant *wpa_s, uint8_t *wpa_ie) 705a399b765Szf { 706a399b765Szf if (wpa_s->proto == WPA_PROTO_RSN) 707a399b765Szf return (wpa_gen_wpa_ie_rsn(wpa_s, wpa_ie)); 708a399b765Szf else 709a399b765Szf return (wpa_gen_wpa_ie_wpa(wpa_s, wpa_ie)); 710a399b765Szf } 711a399b765Szf 712a399b765Szf static void 713a399b765Szf wpa_pmk_to_ptk(uint8_t *pmk, uint8_t *addr1, uint8_t *addr2, 714a399b765Szf uint8_t *nonce1, uint8_t *nonce2, uint8_t *ptk, size_t ptk_len) 715a399b765Szf { 716a399b765Szf uint8_t data[2 * IEEE80211_ADDR_LEN + 2 * WPA_PMK_LEN]; 717a399b765Szf 718a399b765Szf /* 719a399b765Szf * PTK = PRF-X(PMK, "Pairwise key expansion", 720a399b765Szf * Min(AA, SA) || Max(AA, SA) || 721a399b765Szf * Min(ANonce, SNonce) || Max(ANonce, SNonce)) 722a399b765Szf */ 723a399b765Szf 724a399b765Szf if (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) < 0) { 725a399b765Szf (void) memcpy(data, addr1, IEEE80211_ADDR_LEN); 726a399b765Szf (void) memcpy(data + IEEE80211_ADDR_LEN, addr2, 727a399b765Szf IEEE80211_ADDR_LEN); 728a399b765Szf } else { 729a399b765Szf (void) memcpy(data, addr2, IEEE80211_ADDR_LEN); 730a399b765Szf (void) memcpy(data + IEEE80211_ADDR_LEN, addr1, 731a399b765Szf IEEE80211_ADDR_LEN); 732a399b765Szf } 733a399b765Szf 734a399b765Szf if (memcmp(nonce1, nonce2, WPA_PMK_LEN) < 0) { 735a399b765Szf (void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce1, 736a399b765Szf WPA_PMK_LEN); 737a399b765Szf (void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN, 738a399b765Szf nonce2, WPA_PMK_LEN); 739a399b765Szf } else { 740a399b765Szf (void) memcpy(data + 2 * IEEE80211_ADDR_LEN, nonce2, 741a399b765Szf WPA_PMK_LEN); 742a399b765Szf (void) memcpy(data + 2 * IEEE80211_ADDR_LEN + WPA_PMK_LEN, 743a399b765Szf nonce1, WPA_PMK_LEN); 744a399b765Szf } 745a399b765Szf 746a399b765Szf sha1_prf(pmk, WPA_PMK_LEN, "Pairwise key expansion", data, 747a399b765Szf sizeof (data), ptk, ptk_len); 748a399b765Szf 749a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: PMK", pmk, WPA_PMK_LEN); 750a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: PTK", ptk, ptk_len); 751a399b765Szf } 752a399b765Szf 753a399b765Szf struct wpa_ssid * 754a399b765Szf wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s) 755a399b765Szf { 756a399b765Szf struct wpa_ssid *entry; 757a399b765Szf uint8_t ssid[MAX_ESSID_LENGTH]; 758a399b765Szf int ssid_len; 759a399b765Szf uint8_t bssid[IEEE80211_ADDR_LEN]; 760a399b765Szf 761a399b765Szf (void) memset(ssid, 0, MAX_ESSID_LENGTH); 762d62bc4baSyz ssid_len = wpa_s->driver->get_ssid(wpa_s->linkid, (char *)ssid); 763a399b765Szf if (ssid_len < 0) { 764a399b765Szf wpa_printf(MSG_WARNING, "Could not read SSID from driver."); 765a399b765Szf return (NULL); 766a399b765Szf } 767a399b765Szf 768d62bc4baSyz if (wpa_s->driver->get_bssid(wpa_s->linkid, (char *)bssid) < 0) { 769a399b765Szf wpa_printf(MSG_WARNING, "Could not read BSSID from driver."); 770a399b765Szf return (NULL); 771a399b765Szf } 772a399b765Szf 773a399b765Szf entry = wpa_s->conf->ssid; 774a399b765Szf wpa_printf(MSG_DEBUG, "entry len=%d ssid=%s," 775a399b765Szf " driver len=%d ssid=%s", 776a399b765Szf entry->ssid_len, entry->ssid, ssid_len, ssid); 777a399b765Szf 778a399b765Szf if (ssid_len == entry->ssid_len && 779a399b765Szf memcmp(ssid, entry->ssid, ssid_len) == 0 && 780a399b765Szf (!entry->bssid_set || 781a399b765Szf memcmp(bssid, entry->bssid, IEEE80211_ADDR_LEN) == 0)) 782a399b765Szf return (entry); 783a399b765Szf 784a399b765Szf return (NULL); 785a399b765Szf } 786a399b765Szf 787a399b765Szf static void 788a399b765Szf wpa_eapol_key_mic(uint8_t *key, int ver, uint8_t *buf, size_t len, uint8_t *mic) 789a399b765Szf { 790a399b765Szf if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) { 791a399b765Szf hmac_md5(key, 16, buf, len, mic); 792a399b765Szf } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 793a399b765Szf uint8_t hash[SHA1_MAC_LEN]; 794a399b765Szf hmac_sha1(key, 16, buf, len, hash); 795a399b765Szf (void) memcpy(mic, hash, MD5_MAC_LEN); 796a399b765Szf } 797a399b765Szf } 798a399b765Szf 799a399b765Szf void 800a399b765Szf wpa_supplicant_key_request(struct wpa_supplicant *wpa_s, 801a399b765Szf int error, int pairwise) 802a399b765Szf { 803a399b765Szf int rlen; 804a399b765Szf struct ieee802_1x_hdr *hdr; 805a399b765Szf struct wpa_eapol_key *reply; 806a399b765Szf unsigned char *rbuf; 807a399b765Szf struct l2_ethhdr *ethhdr; 808a399b765Szf int key_info, ver; 809a399b765Szf uint8_t bssid[IEEE80211_ADDR_LEN]; 810a399b765Szf 811a399b765Szf if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP) 812a399b765Szf ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES; 813a399b765Szf else 814a399b765Szf ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4; 815a399b765Szf 816d62bc4baSyz if (wpa_s->driver->get_bssid(wpa_s->linkid, (char *)bssid) < 0) { 817a399b765Szf wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key " 818a399b765Szf "request"); 819a399b765Szf return; 820a399b765Szf } 821a399b765Szf 822a399b765Szf rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply); 823a399b765Szf rbuf = malloc(rlen); 824a399b765Szf if (rbuf == NULL) 825a399b765Szf return; 826a399b765Szf 827a399b765Szf (void) memset(rbuf, 0, rlen); 828a399b765Szf ethhdr = (struct l2_ethhdr *)rbuf; 829a399b765Szf (void) memcpy(ethhdr->h_dest, bssid, IEEE80211_ADDR_LEN); 830a399b765Szf (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN); 831a399b765Szf ethhdr->h_proto = htons(ETHERTYPE_EAPOL); 832a399b765Szf 833a399b765Szf hdr = (struct ieee802_1x_hdr *)(ethhdr + 1); 834a399b765Szf hdr->version = wpa_s->conf->eapol_version; 835a399b765Szf hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 836a399b765Szf hdr->length = htons(sizeof (*reply)); 837a399b765Szf 838a399b765Szf reply = (struct wpa_eapol_key *)(hdr + 1); 839a399b765Szf reply->type = wpa_s->proto == WPA_PROTO_RSN ? 840d62bc4baSyz EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 841a399b765Szf key_info = WPA_KEY_INFO_REQUEST | ver; 842a399b765Szf if (wpa_s->ptk_set) 843a399b765Szf key_info |= WPA_KEY_INFO_MIC; 844a399b765Szf if (error) 845a399b765Szf key_info |= WPA_KEY_INFO_ERROR; 846a399b765Szf if (pairwise) 847a399b765Szf key_info |= WPA_KEY_INFO_KEY_TYPE; 848a399b765Szf reply->key_info = BE_16(key_info); 849a399b765Szf reply->key_length = 0; 850a399b765Szf (void) memcpy(reply->replay_counter, wpa_s->request_counter, 851d62bc4baSyz WPA_REPLAY_COUNTER_LEN); 852a399b765Szf inc_byte_array(wpa_s->request_counter, WPA_REPLAY_COUNTER_LEN); 853a399b765Szf 854a399b765Szf reply->key_data_length = BE_16(0); 855a399b765Szf 856a399b765Szf if (key_info & WPA_KEY_INFO_MIC) { 857a399b765Szf wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr, 858a399b765Szf rlen - sizeof (*ethhdr), reply->key_mic); 859a399b765Szf } 860a399b765Szf 861a399b765Szf wpa_printf(MSG_INFO, "WPA: Sending EAPOL-Key Request (error=%d " 862a399b765Szf "pairwise=%d ptk_set=%d len=%d)", 863a399b765Szf error, pairwise, wpa_s->ptk_set, rlen); 864a399b765Szf wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key Request", rbuf, rlen); 865a399b765Szf (void) l2_packet_send(wpa_s->l2, rbuf, rlen); 866a399b765Szf free(rbuf); 867a399b765Szf } 868a399b765Szf 869a399b765Szf static void 870a399b765Szf wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s, 871a399b765Szf unsigned char *src_addr, struct wpa_eapol_key *key, int ver) 872a399b765Szf { 873a399b765Szf int rlen; 874a399b765Szf struct ieee802_1x_hdr *hdr; 875a399b765Szf struct wpa_eapol_key *reply; 876a399b765Szf unsigned char *rbuf; 877a399b765Szf struct l2_ethhdr *ethhdr; 878a399b765Szf struct wpa_ssid *ssid; 879a399b765Szf struct wpa_ptk *ptk; 880a399b765Szf uint8_t buf[8], wpa_ie_buf[80], *wpa_ie, *pmkid = NULL; 881a399b765Szf int wpa_ie_len; 882a399b765Szf 883a399b765Szf wpa_s->wpa_state = WPA_4WAY_HANDSHAKE; 884a399b765Szf wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from " 885a399b765Szf MACSTR " (ver=%d)", MAC2STR(src_addr), ver); 886a399b765Szf 887a399b765Szf ssid = wpa_supplicant_get_ssid(wpa_s); 888a399b765Szf if (ssid == NULL) { 889a399b765Szf wpa_printf(MSG_WARNING, 890a399b765Szf "WPA: No SSID info found (msg 1 of 4)."); 891a399b765Szf return; 892a399b765Szf } 893a399b765Szf 894a399b765Szf if (wpa_s->proto == WPA_PROTO_RSN) { 895a399b765Szf /* RSN: msg 1/4 should contain PMKID for the selected PMK */ 896a399b765Szf uint8_t *pos = (uint8_t *)(key + 1); 897a399b765Szf uint8_t *end = pos + BE_16(key->key_data_length); 898a399b765Szf 899a399b765Szf wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", 900a399b765Szf pos, BE_16(key->key_data_length)); 901a399b765Szf 902a399b765Szf while (pos + 1 < end) { 903a399b765Szf if (pos + 2 + pos[1] > end) { 904a399b765Szf wpa_printf(MSG_DEBUG, "RSN: key data " 905a399b765Szf "underflow (ie=%d len=%d)", 906a399b765Szf pos[0], pos[1]); 907a399b765Szf break; 908a399b765Szf } 909a399b765Szf if (pos[0] == GENERIC_INFO_ELEM && 910d62bc4baSyz pos + 1 + RSN_SELECTOR_LEN < end && 911d62bc4baSyz pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN && 912d62bc4baSyz memcmp(pos + 2, RSN_KEY_DATA_PMKID, 913d62bc4baSyz RSN_SELECTOR_LEN) == 0) { 914a399b765Szf pmkid = pos + 2 + RSN_SELECTOR_LEN; 915a399b765Szf wpa_hexdump(MSG_DEBUG, "RSN: PMKID from " 916a399b765Szf "Authenticator", pmkid, PMKID_LEN); 917a399b765Szf break; 918a399b765Szf } else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0) 919a399b765Szf break; 920a399b765Szf pos += 2 + pos[1]; 921a399b765Szf } 922a399b765Szf } 923a399b765Szf 924a399b765Szf wpa_ie = wpa_ie_buf; 925a399b765Szf wpa_ie_len = wpa_gen_wpa_ie(wpa_s, wpa_ie); 926a399b765Szf if (wpa_ie_len < 0) { 927a399b765Szf wpa_printf(MSG_WARNING, "WPA: Failed to generate " 928a399b765Szf "WPA IE (for msg 2 of 4)."); 929a399b765Szf return; 930a399b765Szf } 931a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len); 932a399b765Szf 933a399b765Szf rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply) + wpa_ie_len; 934a399b765Szf rbuf = malloc(rlen); 935a399b765Szf if (rbuf == NULL) 936a399b765Szf return; 937a399b765Szf 938a399b765Szf (void) memset(rbuf, 0, rlen); 939a399b765Szf ethhdr = (struct l2_ethhdr *)rbuf; 940a399b765Szf (void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN); 941a399b765Szf (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN); 942a399b765Szf ethhdr->h_proto = htons(ETHERTYPE_EAPOL); 943a399b765Szf 944a399b765Szf hdr = (struct ieee802_1x_hdr *)(ethhdr + 1); 945a399b765Szf hdr->version = wpa_s->conf->eapol_version; 946a399b765Szf hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 947a399b765Szf hdr->length = htons(sizeof (*reply) + wpa_ie_len); 948a399b765Szf 949a399b765Szf reply = (struct wpa_eapol_key *)(hdr + 1); 950a399b765Szf reply->type = wpa_s->proto == WPA_PROTO_RSN ? 951d62bc4baSyz EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 952d62bc4baSyz reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC); 953a399b765Szf reply->key_length = key->key_length; 954a399b765Szf (void) memcpy(reply->replay_counter, key->replay_counter, 955d62bc4baSyz WPA_REPLAY_COUNTER_LEN); 956a399b765Szf 957a399b765Szf reply->key_data_length = BE_16(wpa_ie_len); 958a399b765Szf (void) memcpy(reply + 1, wpa_ie, wpa_ie_len); 959a399b765Szf 960a399b765Szf if (wpa_s->renew_snonce) { 961a399b765Szf if (random_get_pseudo_bytes(wpa_s->snonce, WPA_NONCE_LEN)) { 962a399b765Szf wpa_printf(MSG_WARNING, "WPA: Failed to get " 963a399b765Szf "random data for SNonce"); 964a399b765Szf free(rbuf); 965a399b765Szf return; 966a399b765Szf } 967a399b765Szf 968a399b765Szf wpa_s->renew_snonce = 0; 969a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", 970a399b765Szf wpa_s->snonce, WPA_NONCE_LEN); 971a399b765Szf } 972a399b765Szf (void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN); 973a399b765Szf ptk = &wpa_s->tptk; 974a399b765Szf (void) memcpy(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN); 975a399b765Szf 976a399b765Szf wpa_pmk_to_ptk(wpa_s->pmk, wpa_s->own_addr, src_addr, 977a399b765Szf wpa_s->snonce, key->key_nonce, (uint8_t *)ptk, sizeof (*ptk)); 978a399b765Szf 979a399b765Szf /* 980a399b765Szf * Supplicant: swap tx/rx Mic keys 981a399b765Szf */ 982a399b765Szf (void) memcpy(buf, ptk->u.auth.tx_mic_key, 8); 983a399b765Szf (void) memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8); 984a399b765Szf (void) memcpy(ptk->u.auth.rx_mic_key, buf, 8); 985a399b765Szf wpa_s->tptk_set = 1; 986a399b765Szf wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, (uint8_t *)hdr, 987d62bc4baSyz rlen - sizeof (*ethhdr), reply->key_mic); 988a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: EAPOL-Key MIC", reply->key_mic, 16); 989a399b765Szf 990a399b765Szf wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4"); 991a399b765Szf wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/4", rbuf, rlen); 992a399b765Szf (void) l2_packet_send(wpa_s->l2, rbuf, rlen); 993a399b765Szf 994a399b765Szf free(rbuf); 995a399b765Szf } 996a399b765Szf 997a399b765Szf static void 998a399b765Szf wpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant *wpa_s, 999a399b765Szf unsigned char *src_addr, struct wpa_eapol_key *key, 1000a399b765Szf uint8_t *gtk, int gtk_len) 1001a399b765Szf { 1002a399b765Szf int keyidx, tx, key_rsc_len = 0, alg; 1003a399b765Szf 1004a399b765Szf wpa_hexdump(MSG_DEBUG, 1005a399b765Szf "WPA: received GTK in pairwise handshake", gtk, gtk_len); 1006a399b765Szf 1007a399b765Szf keyidx = gtk[0] & 0x3; 1008a399b765Szf tx = !!(gtk[0] & BIT(2)); 1009a399b765Szf if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) { 1010a399b765Szf /* 1011a399b765Szf * Ignore Tx bit in GTK IE if a pairwise key is used. 1012a399b765Szf * One AP seemed to set this bit (incorrectly, since Tx 1013a399b765Szf * is only when doing Group Key only APs) and without 1014a399b765Szf * this workaround, the data connection does not work 1015a399b765Szf * because wpa_supplicant configured non-zero keyidx to 1016a399b765Szf * be used for unicast. 1017a399b765Szf */ 1018a399b765Szf wpa_printf(MSG_INFO, "RSN: Tx bit set for GTK IE, but " 1019a399b765Szf "pairwise keys are used - ignore Tx bit"); 1020a399b765Szf tx = 0; 1021a399b765Szf } 1022a399b765Szf 1023a399b765Szf gtk += 2; 1024a399b765Szf gtk_len -= 2; 1025a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, gtk_len); 1026a399b765Szf 1027a399b765Szf switch (wpa_s->group_cipher) { 1028a399b765Szf case WPA_CIPHER_CCMP: 1029a399b765Szf if (gtk_len != 16) { 1030a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP" 1031a399b765Szf " Group Cipher key length %d.", gtk_len); 1032a399b765Szf return; 1033a399b765Szf } 1034a399b765Szf key_rsc_len = 6; 1035a399b765Szf alg = WPA_ALG_CCMP; 1036a399b765Szf break; 1037a399b765Szf case WPA_CIPHER_TKIP: 1038a399b765Szf if (gtk_len != 32) { 1039a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP" 1040a399b765Szf " Group Cipher key length %d.", gtk_len); 1041a399b765Szf return; 1042a399b765Szf } 1043a399b765Szf key_rsc_len = 6; 1044a399b765Szf alg = WPA_ALG_TKIP; 1045a399b765Szf break; 1046a399b765Szf case WPA_CIPHER_WEP104: 1047a399b765Szf if (gtk_len != 13) { 1048a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported " 1049a399b765Szf "WEP104 Group Cipher key length " "%d.", gtk_len); 1050a399b765Szf return; 1051a399b765Szf } 1052a399b765Szf alg = WPA_ALG_WEP; 1053a399b765Szf break; 1054a399b765Szf case WPA_CIPHER_WEP40: 1055a399b765Szf if (gtk_len != 5) { 1056a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported " 1057a399b765Szf "WEP40 Group Cipher key length %d.", gtk_len); 1058a399b765Szf return; 1059a399b765Szf } 1060a399b765Szf alg = WPA_ALG_WEP; 1061a399b765Szf break; 1062a399b765Szf default: 1063a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher " 1064a399b765Szf "%d", wpa_s->group_cipher); 1065a399b765Szf return; 1066a399b765Szf } 1067a399b765Szf 1068a399b765Szf wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver " 1069a399b765Szf "(keyidx=%d tx=%d).", keyidx, tx); 1070a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len); 1071a399b765Szf if (wpa_s->group_cipher == WPA_CIPHER_TKIP) { 1072a399b765Szf uint8_t tmpbuf[8]; 1073a399b765Szf /* 1074a399b765Szf * Swap Tx/Rx keys for Michael MIC 1075a399b765Szf */ 1076a399b765Szf (void) memcpy(tmpbuf, gtk + 16, 8); 1077a399b765Szf (void) memcpy(gtk + 16, gtk + 24, 8); 1078a399b765Szf (void) memcpy(gtk + 24, tmpbuf, 8); 1079a399b765Szf } 1080a399b765Szf if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) { 1081d62bc4baSyz if (wpa_s->driver->set_key(wpa_s->linkid, alg, 1082a399b765Szf (uint8_t *)"\xff\xff\xff\xff\xff\xff", 1083a399b765Szf keyidx, 1, key->key_rsc, 1084a399b765Szf key_rsc_len, gtk, gtk_len) < 0) 1085a399b765Szf wpa_printf(MSG_WARNING, "WPA: Failed to set " 1086a399b765Szf "GTK to the driver (Group only)."); 1087d62bc4baSyz } else if (wpa_s->driver->set_key(wpa_s->linkid, alg, 1088d62bc4baSyz (uint8_t *)"\xff\xff\xff\xff\xff\xff", keyidx, tx, 1089d62bc4baSyz key->key_rsc, key_rsc_len, gtk, gtk_len) < 0) { 1090a399b765Szf wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to " 1091a399b765Szf "the driver."); 1092a399b765Szf } 1093a399b765Szf 1094a399b765Szf wpa_printf(MSG_INFO, "WPA: Key negotiation completed with " 1095d62bc4baSyz MACSTR, MAC2STR(src_addr)); 1096a399b765Szf eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 1097a399b765Szf wpa_supplicant_cancel_auth_timeout(wpa_s); 1098a399b765Szf wpa_s->wpa_state = WPA_COMPLETED; 1099a399b765Szf } 1100a399b765Szf 1101a399b765Szf static void 1102a399b765Szf wpa_supplicant_process_3_of_4(struct wpa_supplicant *wpa_s, 1103a399b765Szf unsigned char *src_addr, struct wpa_eapol_key *key, 1104a399b765Szf int extra_len, int ver) 1105a399b765Szf { 1106a399b765Szf int rlen; 1107a399b765Szf struct ieee802_1x_hdr *hdr; 1108a399b765Szf struct wpa_eapol_key *reply; 1109a399b765Szf unsigned char *rbuf; 1110a399b765Szf struct l2_ethhdr *ethhdr; 1111a399b765Szf int key_info, ie_len = 0, keylen, gtk_len = 0; 1112a399b765Szf uint8_t *ie = NULL, *gtk = NULL, *key_rsc; 1113a399b765Szf uint8_t null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 1114a399b765Szf 1115a399b765Szf wpa_s->wpa_state = WPA_4WAY_HANDSHAKE; 1116a399b765Szf wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from " 1117a399b765Szf MACSTR " (ver=%d)", MAC2STR(src_addr), ver); 1118a399b765Szf 1119a399b765Szf key_info = BE_16(key->key_info); 1120a399b765Szf 1121a399b765Szf if (wpa_s->proto == WPA_PROTO_RSN) { 1122a399b765Szf uint8_t *pos = (uint8_t *)(key + 1); 1123a399b765Szf uint8_t *end = pos + BE_16(key->key_data_length); 1124a399b765Szf while (pos + 1 < end) { 1125a399b765Szf if (pos + 2 + pos[1] > end) { 1126a399b765Szf wpa_printf(MSG_DEBUG, "RSN: key data " 1127a399b765Szf "underflow (ie=%d len=%d)", 1128a399b765Szf pos[0], pos[1]); 1129a399b765Szf break; 1130a399b765Szf } 1131a399b765Szf if (*pos == RSN_INFO_ELEM) { 1132a399b765Szf ie = pos; 1133a399b765Szf ie_len = pos[1] + 2; 1134a399b765Szf } else if (pos[0] == GENERIC_INFO_ELEM && 1135d62bc4baSyz pos + 1 + RSN_SELECTOR_LEN < end && 1136d62bc4baSyz pos[1] > RSN_SELECTOR_LEN + 2 && 1137d62bc4baSyz memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY, 1138d62bc4baSyz RSN_SELECTOR_LEN) == 0) { 1139a399b765Szf if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { 1140a399b765Szf wpa_printf(MSG_WARNING, "WPA: GTK IE " 1141a399b765Szf "in unencrypted key data"); 1142a399b765Szf return; 1143a399b765Szf } 1144a399b765Szf gtk = pos + 2 + RSN_SELECTOR_LEN; 1145a399b765Szf gtk_len = pos[1] - RSN_SELECTOR_LEN; 1146a399b765Szf } else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0) 1147a399b765Szf break; 1148a399b765Szf 1149a399b765Szf pos += 2 + pos[1]; 1150a399b765Szf } 1151a399b765Szf } else { 1152a399b765Szf ie = (uint8_t *)(key + 1); 1153a399b765Szf ie_len = BE_16(key->key_data_length); 1154a399b765Szf if (ie_len > extra_len) { 1155a399b765Szf wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:" 1156a399b765Szf " ie_len=%d > extra_len=%d", 1157a399b765Szf ie_len, extra_len); 1158a399b765Szf return; 1159a399b765Szf } 1160a399b765Szf } 1161a399b765Szf 1162a399b765Szf if (wpa_s->ap_wpa_ie && 1163a399b765Szf (wpa_s->ap_wpa_ie_len != ie_len || 1164d62bc4baSyz memcmp(wpa_s->ap_wpa_ie, ie, ie_len) != 0)) { 1165a399b765Szf wpa_printf(MSG_WARNING, "WPA: WPA IE in 3/4 msg does not match" 1166a399b765Szf " with WPA IE in Beacon/ProbeResp (src=" MACSTR ")", 1167a399b765Szf MAC2STR(src_addr)); 1168a399b765Szf wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp", 1169a399b765Szf wpa_s->ap_wpa_ie, wpa_s->ap_wpa_ie_len); 1170a399b765Szf wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg", ie, ie_len); 1171a399b765Szf wpa_supplicant_disassociate(wpa_s, REASON_IE_IN_4WAY_DIFFERS); 1172a399b765Szf wpa_supplicant_req_scan(wpa_s, 0, 0); 1173a399b765Szf return; 1174a399b765Szf } 1175a399b765Szf 1176a399b765Szf if (memcmp(wpa_s->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) { 1177a399b765Szf wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way " 1178a399b765Szf "Handshake differs from 3 of 4-Way Handshake - drop" 1179a399b765Szf " packet (src=" MACSTR ")", MAC2STR(src_addr)); 1180a399b765Szf return; 1181a399b765Szf } 1182a399b765Szf 1183a399b765Szf keylen = BE_16(key->key_length); 1184a399b765Szf switch (wpa_s->pairwise_cipher) { 1185a399b765Szf case WPA_CIPHER_CCMP: 1186a399b765Szf if (keylen != 16) { 1187a399b765Szf wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length " 1188a399b765Szf "%d (src=" MACSTR ")", 1189a399b765Szf keylen, MAC2STR(src_addr)); 1190a399b765Szf return; 1191a399b765Szf } 1192a399b765Szf break; 1193a399b765Szf case WPA_CIPHER_TKIP: 1194a399b765Szf if (keylen != 32) { 1195a399b765Szf wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length " 1196a399b765Szf "%d (src=" MACSTR ")", 1197a399b765Szf keylen, MAC2STR(src_addr)); 1198a399b765Szf return; 1199a399b765Szf } 1200a399b765Szf break; 1201a399b765Szf } 1202a399b765Szf 1203a399b765Szf rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply); 1204a399b765Szf rbuf = malloc(rlen); 1205a399b765Szf if (rbuf == NULL) 1206a399b765Szf return; 1207a399b765Szf 1208a399b765Szf (void) memset(rbuf, 0, rlen); 1209a399b765Szf ethhdr = (struct l2_ethhdr *)rbuf; 1210a399b765Szf (void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN); 1211a399b765Szf (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN); 1212a399b765Szf ethhdr->h_proto = htons(ETHERTYPE_EAPOL); 1213a399b765Szf 1214a399b765Szf hdr = (struct ieee802_1x_hdr *)(ethhdr + 1); 1215a399b765Szf hdr->version = wpa_s->conf->eapol_version; 1216a399b765Szf hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 1217a399b765Szf hdr->length = htons(sizeof (*reply)); 1218a399b765Szf 1219a399b765Szf reply = (struct wpa_eapol_key *)(hdr + 1); 1220a399b765Szf reply->type = wpa_s->proto == WPA_PROTO_RSN ? 1221d62bc4baSyz EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 1222a399b765Szf reply->key_info = BE_16(ver | WPA_KEY_INFO_KEY_TYPE | 1223d62bc4baSyz WPA_KEY_INFO_MIC | (key_info & WPA_KEY_INFO_SECURE)); 1224a399b765Szf reply->key_length = key->key_length; 1225a399b765Szf (void) memcpy(reply->replay_counter, key->replay_counter, 1226d62bc4baSyz WPA_REPLAY_COUNTER_LEN); 1227a399b765Szf 1228a399b765Szf reply->key_data_length = BE_16(0); 1229a399b765Szf 1230a399b765Szf (void) memcpy(reply->key_nonce, wpa_s->snonce, WPA_NONCE_LEN); 1231a399b765Szf wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr, 1232a399b765Szf rlen - sizeof (*ethhdr), reply->key_mic); 1233a399b765Szf 1234a399b765Szf wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4"); 1235a399b765Szf wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 4/4", rbuf, rlen); 1236a399b765Szf (void) l2_packet_send(wpa_s->l2, rbuf, rlen); 1237a399b765Szf 1238a399b765Szf free(rbuf); 1239a399b765Szf 1240a399b765Szf /* 1241a399b765Szf * SNonce was successfully used in msg 3/4, so mark it to be renewed 1242a399b765Szf * for the next 4-Way Handshake. If msg 3 is received again, the old 1243a399b765Szf * SNonce will still be used to avoid changing PTK. 1244a399b765Szf */ 1245a399b765Szf wpa_s->renew_snonce = 1; 1246a399b765Szf 1247a399b765Szf if (key_info & WPA_KEY_INFO_INSTALL) { 1248a399b765Szf int alg, keylen, rsclen; 1249a399b765Szf wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver."); 1250a399b765Szf switch (wpa_s->pairwise_cipher) { 1251a399b765Szf case WPA_CIPHER_CCMP: 1252a399b765Szf alg = WPA_ALG_CCMP; 1253a399b765Szf keylen = 16; 1254a399b765Szf rsclen = 6; 1255a399b765Szf break; 1256a399b765Szf case WPA_CIPHER_TKIP: 1257a399b765Szf alg = WPA_ALG_TKIP; 1258a399b765Szf keylen = 32; 1259a399b765Szf rsclen = 6; 1260a399b765Szf break; 1261a399b765Szf case WPA_CIPHER_NONE: 1262a399b765Szf wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: " 1263a399b765Szf "NONE - do not use pairwise keys"); 1264a399b765Szf return; 1265a399b765Szf default: 1266a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise " 1267a399b765Szf "cipher %d", wpa_s->pairwise_cipher); 1268a399b765Szf return; 1269a399b765Szf } 1270a399b765Szf if (wpa_s->proto == WPA_PROTO_RSN) { 1271a399b765Szf key_rsc = null_rsc; 1272a399b765Szf } else { 1273a399b765Szf key_rsc = key->key_rsc; 1274a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen); 1275a399b765Szf } 1276a399b765Szf 1277d62bc4baSyz if (wpa_s->driver->set_key(wpa_s->linkid, alg, src_addr, 1278a399b765Szf 0, 1, key_rsc, rsclen, 1279a399b765Szf (uint8_t *)&wpa_s->ptk.tk1, keylen) < 0) { 1280a399b765Szf wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the" 1281a399b765Szf " driver."); 1282a399b765Szf } 1283a399b765Szf } 1284a399b765Szf 1285a399b765Szf wpa_printf(MSG_DEBUG, "%s: key_info=%x gtk=%p\n", 1286a399b765Szf "wpa_supplicant_process_3_of_4", key_info, gtk); 1287a399b765Szf wpa_s->wpa_state = WPA_GROUP_HANDSHAKE; 1288a399b765Szf 1289a399b765Szf if (gtk) 1290a399b765Szf wpa_supplicant_process_3_of_4_gtk(wpa_s, 1291a399b765Szf src_addr, key, gtk, gtk_len); 1292a399b765Szf } 1293a399b765Szf 1294a399b765Szf static void 1295a399b765Szf wpa_supplicant_process_1_of_2(struct wpa_supplicant *wpa_s, 1296a399b765Szf unsigned char *src_addr, struct wpa_eapol_key *key, 1297a399b765Szf int extra_len, int ver) 1298a399b765Szf { 1299a399b765Szf int rlen; 1300a399b765Szf struct ieee802_1x_hdr *hdr; 1301a399b765Szf struct wpa_eapol_key *reply; 1302a399b765Szf unsigned char *rbuf; 1303a399b765Szf struct l2_ethhdr *ethhdr; 1304a399b765Szf int key_info, keylen, keydatalen, maxkeylen, keyidx, key_rsc_len = 0; 1305a399b765Szf int alg, tx; 1306a399b765Szf uint8_t ek[32], tmpbuf[8], gtk[32]; 1307a399b765Szf uint8_t *gtk_ie = NULL; 1308a399b765Szf size_t gtk_ie_len = 0; 1309a399b765Szf 1310a399b765Szf wpa_s->wpa_state = WPA_GROUP_HANDSHAKE; 1311a399b765Szf wpa_printf(MSG_DEBUG, "WPA: RX message 1 of Group Key Handshake from " 1312a399b765Szf MACSTR " (ver=%d)", MAC2STR(src_addr), ver); 1313a399b765Szf 1314a399b765Szf key_info = BE_16(key->key_info); 1315a399b765Szf keydatalen = BE_16(key->key_data_length); 1316a399b765Szf 1317a399b765Szf if (wpa_s->proto == WPA_PROTO_RSN) { 1318a399b765Szf uint8_t *pos = (uint8_t *)(key + 1); 1319a399b765Szf uint8_t *end = pos + keydatalen; 1320a399b765Szf while (pos + 1 < end) { 1321a399b765Szf if (pos + 2 + pos[1] > end) { 1322a399b765Szf wpa_printf(MSG_DEBUG, "RSN: key data " 1323a399b765Szf "underflow (ie=%d len=%d)", 1324a399b765Szf pos[0], pos[1]); 1325a399b765Szf break; 1326a399b765Szf } 1327a399b765Szf if (pos[0] == GENERIC_INFO_ELEM && 1328a399b765Szf pos + 1 + RSN_SELECTOR_LEN < end && 1329a399b765Szf pos[1] > RSN_SELECTOR_LEN + 2 && 1330a399b765Szf memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY, 1331a399b765Szf RSN_SELECTOR_LEN) == 0) { 1332a399b765Szf if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { 1333a399b765Szf wpa_printf(MSG_WARNING, "WPA: GTK IE " 1334a399b765Szf "in unencrypted key data"); 1335a399b765Szf return; 1336a399b765Szf } 1337a399b765Szf gtk_ie = pos + 2 + RSN_SELECTOR_LEN; 1338a399b765Szf gtk_ie_len = pos[1] - RSN_SELECTOR_LEN; 1339a399b765Szf break; 1340d62bc4baSyz } else if (pos[0] == GENERIC_INFO_ELEM && pos[1] == 0) { 1341a399b765Szf break; 1342d62bc4baSyz } 1343a399b765Szf 1344a399b765Szf pos += 2 + pos[1]; 1345a399b765Szf } 1346a399b765Szf 1347a399b765Szf if (gtk_ie == NULL) { 1348a399b765Szf wpa_printf(MSG_INFO, "WPA: No GTK IE in Group Key " 1349a399b765Szf "message 1/2"); 1350a399b765Szf return; 1351a399b765Szf } 1352a399b765Szf maxkeylen = keylen = gtk_ie_len - 2; 1353a399b765Szf } else { 1354a399b765Szf keylen = BE_16(key->key_length); 1355a399b765Szf maxkeylen = keydatalen; 1356a399b765Szf if (keydatalen > extra_len) { 1357a399b765Szf wpa_printf(MSG_INFO, "WPA: Truncated EAPOL-Key packet:" 1358a399b765Szf " key_data_length=%d > extra_len=%d", 1359a399b765Szf keydatalen, extra_len); 1360a399b765Szf return; 1361a399b765Szf } 1362a399b765Szf if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) 1363a399b765Szf maxkeylen -= 8; 1364a399b765Szf } 1365a399b765Szf 1366a399b765Szf switch (wpa_s->group_cipher) { 1367a399b765Szf case WPA_CIPHER_CCMP: 1368a399b765Szf if (keylen != 16 || maxkeylen < 16) { 1369a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported CCMP Group " 1370a399b765Szf "Cipher key length %d (%d).", keylen, maxkeylen); 1371a399b765Szf return; 1372a399b765Szf } 1373a399b765Szf key_rsc_len = 6; 1374a399b765Szf alg = WPA_ALG_CCMP; 1375a399b765Szf break; 1376a399b765Szf case WPA_CIPHER_TKIP: 1377a399b765Szf if (keylen != 32 || maxkeylen < 32) { 1378a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported TKIP Group " 1379a399b765Szf "Cipher key length %d (%d).", keylen, maxkeylen); 1380a399b765Szf return; 1381a399b765Szf } 1382a399b765Szf key_rsc_len = 6; /* key->key_data; */ 1383a399b765Szf alg = WPA_ALG_TKIP; 1384a399b765Szf break; 1385a399b765Szf case WPA_CIPHER_WEP104: 1386a399b765Szf if (keylen != 13 || maxkeylen < 13) { 1387a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported WEP104 Group" 1388a399b765Szf " Cipher key length %d (%d).", keylen, maxkeylen); 1389a399b765Szf return; 1390a399b765Szf } 1391a399b765Szf alg = WPA_ALG_WEP; 1392a399b765Szf break; 1393a399b765Szf case WPA_CIPHER_WEP40: 1394a399b765Szf if (keylen != 5 || maxkeylen < 5) { 1395a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported WEP40 Group " 1396a399b765Szf "Cipher key length %d (%d).", keylen, maxkeylen); 1397a399b765Szf return; 1398a399b765Szf } 1399a399b765Szf alg = WPA_ALG_WEP; 1400a399b765Szf break; 1401a399b765Szf default: 1402a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupport Group Cipher %d", 1403a399b765Szf wpa_s->group_cipher); 1404a399b765Szf return; 1405a399b765Szf } 1406a399b765Szf 1407a399b765Szf if (wpa_s->proto == WPA_PROTO_RSN) { 1408a399b765Szf wpa_hexdump(MSG_DEBUG, 1409a399b765Szf "WPA: received GTK in group key handshake", 1410a399b765Szf gtk_ie, gtk_ie_len); 1411a399b765Szf keyidx = gtk_ie[0] & 0x3; 1412a399b765Szf tx = !!(gtk_ie[0] & BIT(2)); 1413a399b765Szf if (gtk_ie_len - 2 > sizeof (gtk)) { 1414a399b765Szf wpa_printf(MSG_INFO, "WPA: Too long GTK in GTK IE " 1415a399b765Szf "(len=%d)", gtk_ie_len - 2); 1416a399b765Szf return; 1417a399b765Szf } 1418a399b765Szf (void) memcpy(gtk, gtk_ie + 2, gtk_ie_len - 2); 1419a399b765Szf } else { 1420a399b765Szf keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >> 1421d62bc4baSyz WPA_KEY_INFO_KEY_INDEX_SHIFT; 1422a399b765Szf if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) { 1423a399b765Szf (void) memcpy(ek, key->key_iv, 16); 1424a399b765Szf (void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16); 1425a399b765Szf rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen); 1426a399b765Szf (void) memcpy(gtk, key + 1, keylen); 1427a399b765Szf } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 1428a399b765Szf if (keydatalen % 8) { 1429a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported " 1430a399b765Szf "AES-WRAP len %d", keydatalen); 1431a399b765Szf return; 1432a399b765Szf } 1433a399b765Szf if (aes_unwrap(wpa_s->ptk.encr_key, maxkeylen / 8, 1434d62bc4baSyz (uint8_t *)(key + 1), gtk)) { 1435a399b765Szf wpa_printf(MSG_WARNING, "WPA: AES unwrap " 1436a399b765Szf "failed - could not decrypt GTK"); 1437a399b765Szf return; 1438a399b765Szf } 1439a399b765Szf } 1440a399b765Szf tx = !!(key_info & WPA_KEY_INFO_TXRX); 1441a399b765Szf if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) { 1442a399b765Szf /* 1443a399b765Szf * Ignore Tx bit in Group Key message if a pairwise key 1444a399b765Szf * is used. Some APs seem to setting this bit 1445a399b765Szf * (incorrectly, since Tx is only when doing Group Key 1446a399b765Szf * only APs) and without this workaround, the data 1447a399b765Szf * connection does not work because wpa_supplicant 1448a399b765Szf * configured non-zero keyidx to be used for unicast. 1449a399b765Szf */ 1450a399b765Szf wpa_printf(MSG_INFO, "WPA: Tx bit set for GTK, but " 1451a399b765Szf "pairwise keys are used - ignore Tx bit"); 1452a399b765Szf tx = 0; 1453a399b765Szf } 1454a399b765Szf } 1455a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: Group Key", gtk, keylen); 1456a399b765Szf wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver (keyidx=%d " 1457a399b765Szf "tx=%d).", keyidx, tx); 1458a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: RSC", key->key_rsc, key_rsc_len); 1459a399b765Szf if (wpa_s->group_cipher == WPA_CIPHER_TKIP) { 1460a399b765Szf /* 1461a399b765Szf * Swap Tx/Rx keys for Michael MIC 1462a399b765Szf */ 1463a399b765Szf (void) memcpy(tmpbuf, gtk + 16, 8); 1464a399b765Szf (void) memcpy(gtk + 16, gtk + 24, 8); 1465a399b765Szf (void) memcpy(gtk + 24, tmpbuf, 8); 1466a399b765Szf } 1467a399b765Szf if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) { 1468d62bc4baSyz if (wpa_s->driver->set_key(wpa_s->linkid, alg, 1469a399b765Szf (uint8_t *)"\xff\xff\xff\xff\xff\xff", 1470a399b765Szf keyidx, 1, key->key_rsc, 1471a399b765Szf key_rsc_len, gtk, keylen) < 0) 1472a399b765Szf wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the" 1473a399b765Szf " driver (Group only)."); 1474d62bc4baSyz } else if (wpa_s->driver->set_key(wpa_s->linkid, alg, 1475a399b765Szf (uint8_t *)"\xff\xff\xff\xff\xff\xff", 1476a399b765Szf keyidx, tx, 1477a399b765Szf key->key_rsc, key_rsc_len, 1478a399b765Szf gtk, keylen) < 0) { 1479a399b765Szf wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to the " 1480a399b765Szf "driver."); 1481a399b765Szf } 1482a399b765Szf 1483a399b765Szf rlen = sizeof (*ethhdr) + sizeof (*hdr) + sizeof (*reply); 1484a399b765Szf rbuf = malloc(rlen); 1485a399b765Szf if (rbuf == NULL) 1486a399b765Szf return; 1487a399b765Szf 1488a399b765Szf (void) memset(rbuf, 0, rlen); 1489a399b765Szf ethhdr = (struct l2_ethhdr *)rbuf; 1490a399b765Szf (void) memcpy(ethhdr->h_dest, src_addr, IEEE80211_ADDR_LEN); 1491a399b765Szf (void) memcpy(ethhdr->h_source, wpa_s->own_addr, IEEE80211_ADDR_LEN); 1492a399b765Szf ethhdr->h_proto = htons(ETHERTYPE_EAPOL); 1493a399b765Szf 1494a399b765Szf hdr = (struct ieee802_1x_hdr *)(ethhdr + 1); 1495a399b765Szf hdr->version = wpa_s->conf->eapol_version; 1496a399b765Szf hdr->type = IEEE802_1X_TYPE_EAPOL_KEY; 1497a399b765Szf hdr->length = htons(sizeof (*reply)); 1498a399b765Szf 1499a399b765Szf reply = (struct wpa_eapol_key *)(hdr + 1); 1500a399b765Szf reply->type = wpa_s->proto == WPA_PROTO_RSN ? 1501a399b765Szf EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA; 1502a399b765Szf reply->key_info = 1503a399b765Szf BE_16(ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE | 1504a399b765Szf (key_info & WPA_KEY_INFO_KEY_INDEX_MASK)); 1505a399b765Szf reply->key_length = key->key_length; 1506a399b765Szf (void) memcpy(reply->replay_counter, key->replay_counter, 1507a399b765Szf WPA_REPLAY_COUNTER_LEN); 1508a399b765Szf 1509a399b765Szf reply->key_data_length = BE_16(0); 1510a399b765Szf 1511a399b765Szf wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, (uint8_t *)hdr, 1512a399b765Szf rlen - sizeof (*ethhdr), reply->key_mic); 1513a399b765Szf 1514a399b765Szf wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2"); 1515a399b765Szf wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key 2/2", rbuf, rlen); 1516a399b765Szf (void) l2_packet_send(wpa_s->l2, rbuf, rlen); 1517a399b765Szf free(rbuf); 1518a399b765Szf 1519a399b765Szf wpa_printf(MSG_INFO, "WPA: Key negotiation completed with " MACSTR, 1520a399b765Szf MAC2STR(src_addr)); 1521a399b765Szf eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 1522a399b765Szf wpa_supplicant_cancel_auth_timeout(wpa_s); 1523a399b765Szf wpa_s->wpa_state = WPA_COMPLETED; 1524a399b765Szf wpa_printf(MSG_INFO, "-----------------------------------\n"); 1525a399b765Szf } 1526a399b765Szf 1527a399b765Szf static int 1528a399b765Szf wpa_supplicant_verify_eapol_key_mic(struct wpa_supplicant *wpa_s, 1529a399b765Szf struct wpa_eapol_key *key, int ver, uint8_t *buf, size_t len) 1530a399b765Szf { 1531a399b765Szf uint8_t mic[16]; 1532a399b765Szf int ok = 0; 1533a399b765Szf 1534a399b765Szf (void) memcpy(mic, key->key_mic, 16); 1535a399b765Szf if (wpa_s->tptk_set) { 1536a399b765Szf (void) memset(key->key_mic, 0, 16); 1537a399b765Szf wpa_eapol_key_mic(wpa_s->tptk.mic_key, ver, buf, len, 1538a399b765Szf key->key_mic); 1539a399b765Szf if (memcmp(mic, key->key_mic, 16) != 0) { 1540a399b765Szf wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC " 1541a399b765Szf "when using TPTK - ignoring TPTK"); 1542a399b765Szf } else { 1543a399b765Szf ok = 1; 1544a399b765Szf wpa_s->tptk_set = 0; 1545a399b765Szf wpa_s->ptk_set = 1; 1546a399b765Szf (void) memcpy(&wpa_s->ptk, &wpa_s->tptk, 1547a399b765Szf sizeof (wpa_s->ptk)); 1548a399b765Szf } 1549a399b765Szf } 1550a399b765Szf 1551a399b765Szf if (!ok && wpa_s->ptk_set) { 1552a399b765Szf (void) memset(key->key_mic, 0, 16); 1553a399b765Szf wpa_eapol_key_mic(wpa_s->ptk.mic_key, ver, buf, len, 1554a399b765Szf key->key_mic); 1555a399b765Szf if (memcmp(mic, key->key_mic, 16) != 0) { 1556a399b765Szf wpa_printf(MSG_WARNING, "WPA: Invalid EAPOL-Key MIC " 1557a399b765Szf "- dropping packet"); 1558a399b765Szf return (-1); 1559a399b765Szf } 1560a399b765Szf ok = 1; 1561a399b765Szf } 1562a399b765Szf 1563a399b765Szf if (!ok) { 1564a399b765Szf wpa_printf(MSG_WARNING, "WPA: Could not verify EAPOL-Key MIC " 1565a399b765Szf "- dropping packet"); 1566a399b765Szf return (-1); 1567a399b765Szf } 1568a399b765Szf 1569a399b765Szf (void) memcpy(wpa_s->rx_replay_counter, key->replay_counter, 1570a399b765Szf WPA_REPLAY_COUNTER_LEN); 1571a399b765Szf wpa_s->rx_replay_counter_set = 1; 1572a399b765Szf 1573a399b765Szf return (0); 1574a399b765Szf } 1575a399b765Szf 1576a399b765Szf /* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */ 1577a399b765Szf static int 1578a399b765Szf wpa_supplicant_decrypt_key_data(struct wpa_supplicant *wpa_s, 1579a399b765Szf struct wpa_eapol_key *key, int ver) 1580a399b765Szf { 1581a399b765Szf int keydatalen = BE_16(key->key_data_length); 1582a399b765Szf 1583a399b765Szf wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data", 1584a399b765Szf (uint8_t *)(key + 1), keydatalen); 1585a399b765Szf if (!wpa_s->ptk_set) { 1586a399b765Szf wpa_printf(MSG_WARNING, "WPA: PTK not available, " 1587a399b765Szf "cannot decrypt EAPOL-Key key data."); 1588a399b765Szf return (-1); 1589a399b765Szf } 1590a399b765Szf 1591a399b765Szf /* 1592a399b765Szf * Decrypt key data here so that this operation does not need 1593a399b765Szf * to be implemented separately for each message type. 1594a399b765Szf */ 1595a399b765Szf if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) { 1596a399b765Szf uint8_t ek[32]; 1597a399b765Szf (void) memcpy(ek, key->key_iv, 16); 1598a399b765Szf (void) memcpy(ek + 16, wpa_s->ptk.encr_key, 16); 1599a399b765Szf rc4_skip(ek, 32, 256, (uint8_t *)(key + 1), keydatalen); 1600a399b765Szf } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 1601a399b765Szf uint8_t *buf; 1602a399b765Szf if (keydatalen % 8) { 1603a399b765Szf wpa_printf(MSG_WARNING, "WPA: Unsupported " 1604a399b765Szf "AES-WRAP len %d", keydatalen); 1605a399b765Szf return (-1); 1606a399b765Szf } 1607a399b765Szf keydatalen -= 8; /* AES-WRAP adds 8 bytes */ 1608a399b765Szf buf = malloc(keydatalen); 1609a399b765Szf if (buf == NULL) { 1610a399b765Szf wpa_printf(MSG_WARNING, "WPA: No memory for " 1611a399b765Szf "AES-UNWRAP buffer"); 1612a399b765Szf return (-1); 1613a399b765Szf } 1614a399b765Szf if (aes_unwrap(wpa_s->ptk.encr_key, keydatalen / 8, 1615a399b765Szf (uint8_t *)(key + 1), buf)) { 1616a399b765Szf free(buf); 1617a399b765Szf wpa_printf(MSG_WARNING, "WPA: AES unwrap failed - " 1618a399b765Szf "could not decrypt EAPOL-Key key data"); 1619a399b765Szf return (-1); 1620a399b765Szf } 1621a399b765Szf (void) memcpy(key + 1, buf, keydatalen); 1622a399b765Szf free(buf); 1623a399b765Szf key->key_data_length = BE_16(keydatalen); 1624a399b765Szf } 1625a399b765Szf wpa_hexdump(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data", 1626a399b765Szf (uint8_t *)(key + 1), keydatalen); 1627a399b765Szf 1628a399b765Szf return (0); 1629a399b765Szf } 1630a399b765Szf 1631a399b765Szf static void 1632a399b765Szf wpa_sm_rx_eapol(struct wpa_supplicant *wpa_s, 1633a399b765Szf unsigned char *src_addr, unsigned char *buf, size_t len) 1634a399b765Szf { 1635a399b765Szf size_t plen, data_len, extra_len; 1636a399b765Szf struct ieee802_1x_hdr *hdr; 1637a399b765Szf struct wpa_eapol_key *key; 1638a399b765Szf int key_info, ver; 1639a399b765Szf 1640a399b765Szf wpa_printf(MSG_DEBUG, "WPA: EAPOL frame len %u\n ", len); 1641a399b765Szf 1642a399b765Szf hdr = (struct ieee802_1x_hdr *)buf; 1643a399b765Szf key = (struct wpa_eapol_key *)(hdr + 1); 1644a399b765Szf wpa_printf(MSG_DEBUG, "hdr_len=%u, key_len=%u", 1645a399b765Szf sizeof (*hdr), sizeof (*key)); 1646a399b765Szf if (len < sizeof (*hdr) + sizeof (*key)) { 1647a399b765Szf wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short, len %u, " 1648a399b765Szf "expecting at least %u", 1649a399b765Szf len, sizeof (*hdr) + sizeof (*key)); 1650a399b765Szf return; 1651a399b765Szf } 1652a399b765Szf plen = ntohs(hdr->length); 1653a399b765Szf data_len = plen + sizeof (*hdr); 1654a399b765Szf wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d", 1655a399b765Szf hdr->version, hdr->type, plen); 1656a399b765Szf 1657a399b765Szf if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) { 1658a399b765Szf wpa_printf(MSG_DEBUG, "WPA: EAPOL frame (type %u) discarded, " 1659a399b765Szf "not a Key frame", hdr->type); 1660a399b765Szf return; 1661a399b765Szf } 1662a399b765Szf if (plen > len - sizeof (*hdr) || plen < sizeof (*key)) { 1663a399b765Szf wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %u " 1664a399b765Szf "invalid (frame size %u)", plen, len); 1665a399b765Szf return; 1666a399b765Szf } 1667a399b765Szf 1668a399b765Szf wpa_printf(MSG_DEBUG, " EAPOL-Key type=%d", key->type); 1669a399b765Szf if (key->type != EAPOL_KEY_TYPE_WPA && key->type != 1670a399b765Szf EAPOL_KEY_TYPE_RSN) { 1671a399b765Szf wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key type (%d) unknown, " 1672a399b765Szf "discarded", key->type); 1673a399b765Szf return; 1674a399b765Szf } 1675a399b765Szf 1676a399b765Szf wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len); 1677a399b765Szf if (data_len < len) { 1678a399b765Szf wpa_printf(MSG_DEBUG, "WPA: ignoring %d bytes after the IEEE " 1679a399b765Szf "802.1X data", len - data_len); 1680a399b765Szf } 1681a399b765Szf key_info = BE_16(key->key_info); 1682a399b765Szf ver = key_info & WPA_KEY_INFO_TYPE_MASK; 1683a399b765Szf if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && 1684a399b765Szf ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 1685a399b765Szf wpa_printf(MSG_INFO, "WPA: Unsupported EAPOL-Key descriptor " 1686a399b765Szf "version %d.", ver); 1687a399b765Szf return; 1688a399b765Szf } 1689a399b765Szf 1690a399b765Szf if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP && 1691a399b765Szf ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { 1692a399b765Szf wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key " 1693a399b765Szf "descriptor version (%d) is not 2.", ver); 1694a399b765Szf if (wpa_s->group_cipher != WPA_CIPHER_CCMP && 1695a399b765Szf !(key_info & WPA_KEY_INFO_KEY_TYPE)) { 1696a399b765Szf /* 1697a399b765Szf * Earlier versions of IEEE 802.11i did not explicitly 1698a399b765Szf * require version 2 descriptor for all EAPOL-Key 1699a399b765Szf * packets, so allow group keys to use version 1 if 1700a399b765Szf * CCMP is not used for them. 1701a399b765Szf */ 1702a399b765Szf wpa_printf(MSG_INFO, "WPA: Backwards compatibility: " 1703a399b765Szf "allow invalid version for non-CCMP group keys"); 1704a399b765Szf } else 1705a399b765Szf return; 1706a399b765Szf } 1707a399b765Szf 1708a399b765Szf if (wpa_s->rx_replay_counter_set && 1709a399b765Szf memcmp(key->replay_counter, wpa_s->rx_replay_counter, 1710a399b765Szf WPA_REPLAY_COUNTER_LEN) <= 0) { 1711a399b765Szf wpa_printf(MSG_WARNING, "WPA: EAPOL-Key Replay Counter did not" 1712a399b765Szf " increase - dropping packet"); 1713a399b765Szf return; 1714a399b765Szf } 1715a399b765Szf 1716a399b765Szf if (!(key_info & WPA_KEY_INFO_ACK)) { 1717a399b765Szf wpa_printf(MSG_INFO, "WPA: No Ack bit in key_info"); 1718a399b765Szf return; 1719a399b765Szf } 1720a399b765Szf 1721a399b765Szf if (key_info & WPA_KEY_INFO_REQUEST) { 1722a399b765Szf wpa_printf(MSG_INFO, "WPA: EAPOL-Key with Request bit - " 1723a399b765Szf "dropped"); 1724a399b765Szf return; 1725a399b765Szf } 1726a399b765Szf 1727a399b765Szf if ((key_info & WPA_KEY_INFO_MIC) && 1728d62bc4baSyz wpa_supplicant_verify_eapol_key_mic(wpa_s, key, ver, buf, 1729d62bc4baSyz data_len)) { 1730a399b765Szf return; 1731d62bc4baSyz } 1732a399b765Szf 1733a399b765Szf extra_len = data_len - sizeof (*hdr) - sizeof (*key); 1734a399b765Szf 1735a399b765Szf if (wpa_s->proto == WPA_PROTO_RSN && 1736a399b765Szf (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) && 1737a399b765Szf wpa_supplicant_decrypt_key_data(wpa_s, key, ver)) 1738a399b765Szf return; 1739a399b765Szf 1740a399b765Szf if (key_info & WPA_KEY_INFO_KEY_TYPE) { 1741a399b765Szf if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) { 1742a399b765Szf wpa_printf(MSG_WARNING, "WPA: Ignored EAPOL-Key " 1743a399b765Szf "(Pairwise) with non-zero key index"); 1744a399b765Szf return; 1745a399b765Szf } 1746a399b765Szf if (key_info & WPA_KEY_INFO_MIC) { 1747a399b765Szf /* 3/4 4-Way Handshake */ 1748a399b765Szf wpa_supplicant_process_3_of_4(wpa_s, src_addr, key, 1749a399b765Szf extra_len, ver); 1750a399b765Szf } else { 1751a399b765Szf /* 1/4 4-Way Handshake */ 1752a399b765Szf wpa_supplicant_process_1_of_4(wpa_s, src_addr, key, 1753a399b765Szf ver); 1754a399b765Szf } 1755a399b765Szf } else { 1756a399b765Szf if (key_info & WPA_KEY_INFO_MIC) { 1757a399b765Szf /* 1/2 Group Key Handshake */ 1758a399b765Szf wpa_supplicant_process_1_of_2(wpa_s, src_addr, key, 1759a399b765Szf extra_len, ver); 1760a399b765Szf } else { 1761a399b765Szf wpa_printf(MSG_WARNING, "WPA: EAPOL-Key (Group) " 1762a399b765Szf "without Mic bit - dropped"); 1763a399b765Szf } 1764a399b765Szf } 1765a399b765Szf } 1766a399b765Szf 1767a399b765Szf void 1768a399b765Szf wpa_supplicant_rx_eapol(void *ctx, unsigned char *src_addr, 1769a399b765Szf unsigned char *buf, size_t len) 1770a399b765Szf { 1771a399b765Szf struct wpa_supplicant *wpa_s = ctx; 1772a399b765Szf 1773a399b765Szf wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr)); 1774a399b765Szf wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len); 1775a399b765Szf 1776a399b765Szf if (wpa_s->eapol_received == 0) { 1777a399b765Szf /* Timeout for completing IEEE 802.1X and WPA authentication */ 1778a399b765Szf wpa_supplicant_req_auth_timeout( 1779a399b765Szf wpa_s, wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ? 1780a399b765Szf 70 : 10, 0); 1781a399b765Szf } 1782a399b765Szf wpa_s->eapol_received++; 1783a399b765Szf 1784a399b765Szf /* 1785a399b765Szf * Source address of the incoming EAPOL frame could be compared to the 1786a399b765Szf * current BSSID. However, it is possible that a centralized 1787a399b765Szf * Authenticator could be using another MAC address than the BSSID of 1788a399b765Szf * an AP, so just allow any address to be used for now. The replies are 1789a399b765Szf * still sent to the current BSSID (if available), though. 1790a399b765Szf */ 1791a399b765Szf wpa_sm_rx_eapol(wpa_s, src_addr, buf, len); 1792a399b765Szf } 1793