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