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