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 #ifndef __WPA_IMPL_H 12a399b765Szf162725 #define __WPA_IMPL_H 13a399b765Szf162725 14a399b765Szf162725 #include <net/wpa.h> 15d62bc4baSyz147064 #include <libdladm.h> 16fb91fd8aSzf162725 #include <libdllink.h> 17a399b765Szf162725 18a399b765Szf162725 #ifdef __cplusplus 19a399b765Szf162725 extern "C" { 20a399b765Szf162725 #endif 21a399b765Szf162725 22a399b765Szf162725 #define BIT(n) (1 << (n)) 23a399b765Szf162725 24a399b765Szf162725 #define WPA_CIPHER_NONE BIT(0) 25a399b765Szf162725 #define WPA_CIPHER_WEP40 BIT(1) 26a399b765Szf162725 #define WPA_CIPHER_WEP104 BIT(2) 27a399b765Szf162725 #define WPA_CIPHER_TKIP BIT(3) 28a399b765Szf162725 #define WPA_CIPHER_CCMP BIT(4) 29a399b765Szf162725 30a399b765Szf162725 #define WPA_KEY_MGMT_IEEE8021X BIT(0) 31a399b765Szf162725 #define WPA_KEY_MGMT_PSK BIT(1) 32a399b765Szf162725 #define WPA_KEY_MGMT_NONE BIT(2) 33a399b765Szf162725 #define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3) 34a399b765Szf162725 35a399b765Szf162725 #define WPA_PROTO_WPA BIT(0) 36a399b765Szf162725 #define WPA_PROTO_RSN BIT(1) 37a399b765Szf162725 38a399b765Szf162725 #pragma pack(1) 39a399b765Szf162725 struct ieee802_1x_hdr { 40a399b765Szf162725 uint8_t version; 41a399b765Szf162725 uint8_t type; 42a399b765Szf162725 uint16_t length; 43a399b765Szf162725 /* followed by length octets of data */ 44a399b765Szf162725 }; 45a399b765Szf162725 #pragma pack() 46a399b765Szf162725 47a399b765Szf162725 #define EAPOL_VERSION 2 48a399b765Szf162725 49a399b765Szf162725 enum { IEEE802_1X_TYPE_EAP_PACKET = 0, 50a399b765Szf162725 IEEE802_1X_TYPE_EAPOL_START = 1, 51a399b765Szf162725 IEEE802_1X_TYPE_EAPOL_LOGOFF = 2, 52a399b765Szf162725 IEEE802_1X_TYPE_EAPOL_KEY = 3, 53a399b765Szf162725 IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT = 4 54a399b765Szf162725 }; 55a399b765Szf162725 56a399b765Szf162725 enum { EAPOL_KEY_TYPE_RC4 = 1, 57a399b765Szf162725 EAPOL_KEY_TYPE_RSN = 2, 58a399b765Szf162725 EAPOL_KEY_TYPE_WPA = 254 59a399b765Szf162725 }; 60a399b765Szf162725 61a399b765Szf162725 #define WPA_NONCE_LEN 32 62a399b765Szf162725 #define WPA_REPLAY_COUNTER_LEN 8 63a399b765Szf162725 #define MAX_PSK_LENGTH 64 64a399b765Szf162725 #define WPA_PMK_LEN 32 65a399b765Szf162725 66a399b765Szf162725 #pragma pack(1) 67a399b765Szf162725 struct wpa_eapol_key { 68a399b765Szf162725 uint8_t type; 69a399b765Szf162725 uint16_t key_info; 70a399b765Szf162725 uint16_t key_length; 71a399b765Szf162725 uint8_t replay_counter[WPA_REPLAY_COUNTER_LEN]; 72a399b765Szf162725 uint8_t key_nonce[WPA_NONCE_LEN]; 73a399b765Szf162725 uint8_t key_iv[16]; 74a399b765Szf162725 uint8_t key_rsc[8]; 75a399b765Szf162725 uint8_t key_id[8]; /* Reserved in IEEE 802.11i/RSN */ 76a399b765Szf162725 uint8_t key_mic[16]; 77a399b765Szf162725 uint16_t key_data_length; 78a399b765Szf162725 /* followed by key_data_length bytes of key_data */ 79a399b765Szf162725 }; 80a399b765Szf162725 #pragma pack() 81a399b765Szf162725 82a399b765Szf162725 #define WPA_KEY_INFO_TYPE_MASK (BIT(0) | BIT(1) | BIT(2)) 83a399b765Szf162725 #define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 BIT(0) 84a399b765Szf162725 #define WPA_KEY_INFO_TYPE_HMAC_SHA1_AES BIT(1) 85a399b765Szf162725 #define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1: Pairwise, 0: Group key */ 86a399b765Szf162725 /* bit4..5 is used in WPA, but is reserved in IEEE 802.11i/RSN */ 87a399b765Szf162725 #define WPA_KEY_INFO_KEY_INDEX_MASK (BIT(4) | BIT(5)) 88a399b765Szf162725 #define WPA_KEY_INFO_KEY_INDEX_SHIFT 4 89a399b765Szf162725 #define WPA_KEY_INFO_INSTALL BIT(6) /* pairwise */ 90a399b765Szf162725 #define WPA_KEY_INFO_TXRX BIT(6) /* group */ 91a399b765Szf162725 #define WPA_KEY_INFO_ACK BIT(7) 92a399b765Szf162725 #define WPA_KEY_INFO_MIC BIT(8) 93a399b765Szf162725 #define WPA_KEY_INFO_SECURE BIT(9) 94a399b765Szf162725 #define WPA_KEY_INFO_ERROR BIT(10) 95a399b765Szf162725 #define WPA_KEY_INFO_REQUEST BIT(11) 96a399b765Szf162725 #define WPA_KEY_INFO_ENCR_KEY_DATA BIT(12) /* IEEE 802.11i/RSN only */ 97a399b765Szf162725 98a399b765Szf162725 #define WPA_CAPABILITY_PREAUTH BIT(0) 99a399b765Szf162725 100a399b765Szf162725 #define GENERIC_INFO_ELEM 0xdd 101a399b765Szf162725 #define RSN_INFO_ELEM 0x30 102a399b765Szf162725 103a399b765Szf162725 #define MAX_LOGBUF 4096 104a399b765Szf162725 #define MAX_SCANRESULTS 64 105a399b765Szf162725 106a399b765Szf162725 enum { 107a399b765Szf162725 REASON_UNSPECIFIED = 1, 108a399b765Szf162725 REASON_DEAUTH_LEAVING = 3, 109a399b765Szf162725 REASON_INVALID_IE = 13, 110a399b765Szf162725 REASON_MICHAEL_MIC_FAILURE = 14, 111a399b765Szf162725 REASON_4WAY_HANDSHAKE_TIMEOUT = 15, 112a399b765Szf162725 REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, 113a399b765Szf162725 REASON_IE_IN_4WAY_DIFFERS = 17, 114a399b765Szf162725 REASON_GROUP_CIPHER_NOT_VALID = 18, 115a399b765Szf162725 REASON_PAIRWISE_CIPHER_NOT_VALID = 19, 116a399b765Szf162725 REASON_AKMP_NOT_VALID = 20, 117a399b765Szf162725 REASON_UNSUPPORTED_RSN_IE_VERSION = 21, 118a399b765Szf162725 REASON_INVALID_RSN_IE_CAPAB = 22, 119a399b765Szf162725 REASON_IEEE_802_1X_AUTH_FAILED = 23, 120a399b765Szf162725 REASON_CIPHER_SUITE_REJECTED = 24 121a399b765Szf162725 }; 122a399b765Szf162725 123a399b765Szf162725 /* 124a399b765Szf162725 * wpa_supplicant 125a399b765Szf162725 */ 126a399b765Szf162725 #define PMKID_LEN 16 127a399b765Szf162725 #define PMK_LEN 32 128a399b765Szf162725 129a399b765Szf162725 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] 130a399b765Szf162725 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" 131a399b765Szf162725 132a399b765Szf162725 struct rsn_pmksa_cache { 133a399b765Szf162725 struct rsn_pmksa_cache *next; 134a399b765Szf162725 uint8_t pmkid[PMKID_LEN]; 135a399b765Szf162725 uint8_t pmk[PMK_LEN]; 136a399b765Szf162725 time_t expiration; 137a399b765Szf162725 int akmp; /* WPA_KEY_MGMT_* */ 138a399b765Szf162725 uint8_t aa[IEEE80211_ADDR_LEN]; 139a399b765Szf162725 }; 140a399b765Szf162725 141a399b765Szf162725 struct rsn_pmksa_candidate { 142a399b765Szf162725 struct rsn_pmksa_candidate *next; 143a399b765Szf162725 uint8_t bssid[IEEE80211_ADDR_LEN]; 144a399b765Szf162725 }; 145a399b765Szf162725 146a399b765Szf162725 147a399b765Szf162725 #pragma pack(1) 148a399b765Szf162725 struct wpa_ptk { 149a399b765Szf162725 uint8_t mic_key[16]; /* EAPOL-Key MIC Key (MK) */ 150a399b765Szf162725 uint8_t encr_key[16]; /* EAPOL-Key Encryption Key (EK) */ 151a399b765Szf162725 uint8_t tk1[16]; /* Temporal Key 1 (TK1) */ 152a399b765Szf162725 union { 153a399b765Szf162725 uint8_t tk2[16]; /* Temporal Key 2 (TK2) */ 154a399b765Szf162725 struct { 155a399b765Szf162725 uint8_t tx_mic_key[8]; 156a399b765Szf162725 uint8_t rx_mic_key[8]; 157a399b765Szf162725 } auth; 158a399b765Szf162725 } u; 159a399b765Szf162725 }; 160a399b765Szf162725 #pragma pack() 161a399b765Szf162725 162a399b765Szf162725 163a399b765Szf162725 struct wpa_supplicant { 164a399b765Szf162725 struct l2_packet_data *l2; 165a399b765Szf162725 unsigned char own_addr[IEEE80211_ADDR_LEN]; 166a399b765Szf162725 167*4ac67f02SAnurag S. Maskey /* The handle required for libdladm calls */ 168*4ac67f02SAnurag S. Maskey dladm_handle_t handle; 169*4ac67f02SAnurag S. Maskey 170d62bc4baSyz147064 datalink_id_t linkid; 171fb91fd8aSzf162725 char kname[DLADM_SECOBJ_NAME_MAX]; 172a399b765Szf162725 173a399b765Szf162725 uint8_t pmk[PMK_LEN]; 174a399b765Szf162725 175a399b765Szf162725 uint8_t snonce[WPA_NONCE_LEN]; 176a399b765Szf162725 uint8_t anonce[WPA_NONCE_LEN]; 177a399b765Szf162725 /* ANonce from the last 1/4 msg */ 178a399b765Szf162725 179a399b765Szf162725 struct wpa_ptk ptk, tptk; 180a399b765Szf162725 int ptk_set, tptk_set; 181a399b765Szf162725 int renew_snonce; 182a399b765Szf162725 183a399b765Szf162725 struct wpa_config *conf; 184a399b765Szf162725 185a399b765Szf162725 uint8_t request_counter[WPA_REPLAY_COUNTER_LEN]; 186a399b765Szf162725 uint8_t rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; 187a399b765Szf162725 int rx_replay_counter_set; 188a399b765Szf162725 189a399b765Szf162725 uint8_t bssid[IEEE80211_ADDR_LEN]; 190a399b765Szf162725 int reassociate; /* reassociation requested */ 191a399b765Szf162725 192a399b765Szf162725 uint8_t *ap_wpa_ie; 193a399b765Szf162725 size_t ap_wpa_ie_len; 194a399b765Szf162725 195a399b765Szf162725 /* 196a399b765Szf162725 * Selected configuration 197a399b765Szf162725 * based on Beacon/ProbeResp WPA IE 198a399b765Szf162725 */ 199a399b765Szf162725 int proto; 200a399b765Szf162725 int pairwise_cipher; 201a399b765Szf162725 int group_cipher; 202a399b765Szf162725 int key_mgmt; 203a399b765Szf162725 204a399b765Szf162725 struct wpa_driver_ops *driver; 205a399b765Szf162725 206a399b765Szf162725 enum { 207a399b765Szf162725 WPA_DISCONNECTED, 208a399b765Szf162725 WPA_SCANNING, 209a399b765Szf162725 WPA_ASSOCIATING, 210a399b765Szf162725 WPA_ASSOCIATED, 211a399b765Szf162725 WPA_4WAY_HANDSHAKE, 212a399b765Szf162725 WPA_GROUP_HANDSHAKE, 213a399b765Szf162725 WPA_COMPLETED 214a399b765Szf162725 } wpa_state; 215a399b765Szf162725 216a399b765Szf162725 struct rsn_pmksa_cache *pmksa; /* PMKSA cache */ 217a399b765Szf162725 int pmksa_count; /* number of entries in PMKSA cache */ 218a399b765Szf162725 struct rsn_pmksa_cache *cur_pmksa; /* current PMKSA entry */ 219a399b765Szf162725 struct rsn_pmksa_candidate *pmksa_candidates; 220a399b765Szf162725 221a399b765Szf162725 /* 222a399b765Szf162725 * number of EAPOL packets received after the 223a399b765Szf162725 * previous association event 224a399b765Szf162725 */ 225a399b765Szf162725 int eapol_received; 226a399b765Szf162725 }; 227a399b765Szf162725 228a399b765Szf162725 struct wpa_ie_data { 229a399b765Szf162725 int proto; 230a399b765Szf162725 int pairwise_cipher; 231a399b765Szf162725 int group_cipher; 232a399b765Szf162725 int key_mgmt; 233a399b765Szf162725 int capabilities; 234a399b765Szf162725 }; 235a399b765Szf162725 236a399b765Szf162725 /* WPA configuration */ 237a399b765Szf162725 struct wpa_ssid { 238a399b765Szf162725 uint8_t *ssid; 239a399b765Szf162725 size_t ssid_len; 240a399b765Szf162725 241a399b765Szf162725 uint8_t bssid[IEEE80211_ADDR_LEN]; 242a399b765Szf162725 int bssid_set; 243a399b765Szf162725 244a399b765Szf162725 uint8_t psk[PMK_LEN]; 245a399b765Szf162725 int psk_set; 246a399b765Szf162725 char *passphrase; 247a399b765Szf162725 248a399b765Szf162725 /* Bitfields of allowed Pairwise/Group Ciphers, WPA_CIPHER_* */ 249a399b765Szf162725 int pairwise_cipher; 250a399b765Szf162725 int group_cipher; 251a399b765Szf162725 252a399b765Szf162725 int key_mgmt; 253a399b765Szf162725 int proto; /* Bitfield of allowed protocols (WPA_PROTO_*) */ 254a399b765Szf162725 }; 255a399b765Szf162725 256a399b765Szf162725 struct wpa_config { 257a399b765Szf162725 struct wpa_ssid *ssid; /* global network list */ 258a399b765Szf162725 int eapol_version; 259a399b765Szf162725 /* int ap_scan; */ 260a399b765Szf162725 }; 261a399b765Szf162725 262a399b765Szf162725 struct wpa_config *wpa_config_read(void *); 263a399b765Szf162725 void wpa_config_free(struct wpa_config *); 264a399b765Szf162725 265a399b765Szf162725 /* 266a399b765Szf162725 * Debugging function - conditional printf and hex dump. 267a399b765Szf162725 * Driver wrappers can use these for debugging purposes. 268a399b765Szf162725 */ 269a399b765Szf162725 enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR }; 270a399b765Szf162725 271a399b765Szf162725 void wpa_printf(int, char *, ...); 272a399b765Szf162725 void wpa_hexdump(int, const char *, const uint8_t *, size_t); 273a399b765Szf162725 274a399b765Szf162725 void wpa_event_handler(void *, wpa_event_type); 275a399b765Szf162725 void wpa_supplicant_rx_eapol(void *, unsigned char *, unsigned char *, size_t); 276a399b765Szf162725 277a399b765Szf162725 void wpa_supplicant_scan(void *, void *); 278a399b765Szf162725 void wpa_supplicant_req_scan(struct wpa_supplicant *, int, int); 279a399b765Szf162725 280a399b765Szf162725 void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *, int, int); 281a399b765Szf162725 void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *); 282a399b765Szf162725 void wpa_supplicant_disassociate(struct wpa_supplicant *, int); 283a399b765Szf162725 284a399b765Szf162725 void pmksa_cache_free(struct wpa_supplicant *); 285a399b765Szf162725 void pmksa_candidate_free(struct wpa_supplicant *); 286a399b765Szf162725 struct rsn_pmksa_cache *pmksa_cache_get(struct wpa_supplicant *, 287a399b765Szf162725 uint8_t *, uint8_t *); 288a399b765Szf162725 289a399b765Szf162725 int wpa_parse_wpa_ie(struct wpa_supplicant *, uint8_t *, 290a399b765Szf162725 size_t, struct wpa_ie_data *); 291a399b765Szf162725 int wpa_gen_wpa_ie(struct wpa_supplicant *, uint8_t *); 292a399b765Szf162725 293a399b765Szf162725 #ifdef __cplusplus 294a399b765Szf162725 } 295a399b765Szf162725 #endif 296a399b765Szf162725 297a399b765Szf162725 #endif /* __WPA_IMPL_H */ 298