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