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