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