xref: /dflybsd-src/sys/netproto/802_11/ieee80211_crypto.h (revision 805c8e8e4093ceca2e27510ad3a66d4de8060a55)
132176cfdSRui Paulo /*-
2f186073cSJoerg Sonnenberger  * Copyright (c) 2001 Atsushi Onoe
332176cfdSRui Paulo  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
4f186073cSJoerg Sonnenberger  * All rights reserved.
5f186073cSJoerg Sonnenberger  *
6f186073cSJoerg Sonnenberger  * Redistribution and use in source and binary forms, with or without
7f186073cSJoerg Sonnenberger  * modification, are permitted provided that the following conditions
8f186073cSJoerg Sonnenberger  * are met:
9f186073cSJoerg Sonnenberger  * 1. Redistributions of source code must retain the above copyright
10f186073cSJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer.
11f186073cSJoerg Sonnenberger  * 2. Redistributions in binary form must reproduce the above copyright
12f186073cSJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer in the
13f186073cSJoerg Sonnenberger  *    documentation and/or other materials provided with the distribution.
14f186073cSJoerg Sonnenberger  *
15f186073cSJoerg Sonnenberger  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16f186073cSJoerg Sonnenberger  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17f186073cSJoerg Sonnenberger  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18f186073cSJoerg Sonnenberger  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19f186073cSJoerg Sonnenberger  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20f186073cSJoerg Sonnenberger  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21f186073cSJoerg Sonnenberger  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22f186073cSJoerg Sonnenberger  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23f186073cSJoerg Sonnenberger  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24f186073cSJoerg Sonnenberger  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25f186073cSJoerg Sonnenberger  *
26085ff963SMatthew Dillon  * $FreeBSD$
27f186073cSJoerg Sonnenberger  */
28841ab66cSSepherosa Ziehau #ifndef _NET80211_IEEE80211_CRYPTO_H_
29841ab66cSSepherosa Ziehau #define _NET80211_IEEE80211_CRYPTO_H_
30f186073cSJoerg Sonnenberger 
31f186073cSJoerg Sonnenberger /*
32f186073cSJoerg Sonnenberger  * 802.11 protocol crypto-related definitions.
33f186073cSJoerg Sonnenberger  */
34f186073cSJoerg Sonnenberger #define	IEEE80211_KEYBUF_SIZE	16
35841ab66cSSepherosa Ziehau #define	IEEE80211_MICBUF_SIZE	(8+8)	/* space for both tx+rx keys */
36f186073cSJoerg Sonnenberger 
37841ab66cSSepherosa Ziehau /*
38841ab66cSSepherosa Ziehau  * Old WEP-style key.  Deprecated.
39841ab66cSSepherosa Ziehau  */
40f186073cSJoerg Sonnenberger struct ieee80211_wepkey {
41841ab66cSSepherosa Ziehau 	u_int		wk_len;		/* key length in bytes */
42f186073cSJoerg Sonnenberger 	uint8_t		wk_key[IEEE80211_KEYBUF_SIZE];
43f186073cSJoerg Sonnenberger };
44f186073cSJoerg Sonnenberger 
4532176cfdSRui Paulo struct ieee80211_rsnparms {
4632176cfdSRui Paulo 	uint8_t		rsn_mcastcipher;	/* mcast/group cipher */
4732176cfdSRui Paulo 	uint8_t		rsn_mcastkeylen;	/* mcast key length */
4832176cfdSRui Paulo 	uint8_t		rsn_ucastcipher;	/* selected unicast cipher */
4932176cfdSRui Paulo 	uint8_t		rsn_ucastkeylen;	/* unicast key length */
5032176cfdSRui Paulo 	uint8_t		rsn_keymgmt;		/* selected key mgmt algo */
5132176cfdSRui Paulo 	uint16_t	rsn_caps;		/* capabilities */
5232176cfdSRui Paulo };
5332176cfdSRui Paulo 
54841ab66cSSepherosa Ziehau struct ieee80211_cipher;
55841ab66cSSepherosa Ziehau 
56841ab66cSSepherosa Ziehau /*
57841ab66cSSepherosa Ziehau  * Crypto key state.  There is sufficient room for all supported
58841ab66cSSepherosa Ziehau  * ciphers (see below).  The underlying ciphers are handled
59841ab66cSSepherosa Ziehau  * separately through loadable cipher modules that register with
60841ab66cSSepherosa Ziehau  * the generic crypto support.  A key has a reference to an instance
61841ab66cSSepherosa Ziehau  * of the cipher; any per-key state is hung off wk_private by the
62841ab66cSSepherosa Ziehau  * cipher when it is attached.  Ciphers are automatically called
63841ab66cSSepherosa Ziehau  * to detach and cleanup any such state when the key is deleted.
64841ab66cSSepherosa Ziehau  *
65841ab66cSSepherosa Ziehau  * The generic crypto support handles encap/decap of cipher-related
66841ab66cSSepherosa Ziehau  * frame contents for both hardware- and software-based implementations.
67841ab66cSSepherosa Ziehau  * A key requiring software crypto support is automatically flagged and
68841ab66cSSepherosa Ziehau  * the cipher is expected to honor this and do the necessary work.
69841ab66cSSepherosa Ziehau  * Ciphers such as TKIP may also support mixed hardware/software
70841ab66cSSepherosa Ziehau  * encrypt/decrypt and MIC processing.
71841ab66cSSepherosa Ziehau  */
72841ab66cSSepherosa Ziehau typedef uint16_t ieee80211_keyix;	/* h/w key index */
73841ab66cSSepherosa Ziehau 
74841ab66cSSepherosa Ziehau struct ieee80211_key {
75841ab66cSSepherosa Ziehau 	uint8_t		wk_keylen;	/* key length in bytes */
7632176cfdSRui Paulo 	uint8_t		wk_pad;
77841ab66cSSepherosa Ziehau 	uint16_t	wk_flags;
7832176cfdSRui Paulo #define	IEEE80211_KEY_XMIT	0x0001	/* key used for xmit */
7932176cfdSRui Paulo #define	IEEE80211_KEY_RECV	0x0002	/* key used for recv */
8032176cfdSRui Paulo #define	IEEE80211_KEY_GROUP	0x0004	/* key used for WPA group operation */
81085ff963SMatthew Dillon #define	IEEE80211_KEY_NOREPLAY	0x0008	/* ignore replay failures */
8232176cfdSRui Paulo #define	IEEE80211_KEY_SWENCRYPT	0x0010	/* host-based encrypt */
8332176cfdSRui Paulo #define	IEEE80211_KEY_SWDECRYPT	0x0020	/* host-based decrypt */
8432176cfdSRui Paulo #define	IEEE80211_KEY_SWENMIC	0x0040	/* host-based enmic */
8532176cfdSRui Paulo #define	IEEE80211_KEY_SWDEMIC	0x0080	/* host-based demic */
8632176cfdSRui Paulo #define	IEEE80211_KEY_DEVKEY	0x0100	/* device key request completed */
8732176cfdSRui Paulo #define	IEEE80211_KEY_CIPHER0	0x1000	/* cipher-specific action 0 */
8832176cfdSRui Paulo #define	IEEE80211_KEY_CIPHER1	0x2000	/* cipher-specific action 1 */
89841ab66cSSepherosa Ziehau 	ieee80211_keyix	wk_keyix;	/* h/w key index */
90841ab66cSSepherosa Ziehau 	ieee80211_keyix	wk_rxkeyix;	/* optional h/w rx key index */
91841ab66cSSepherosa Ziehau 	uint8_t		wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
92841ab66cSSepherosa Ziehau #define	wk_txmic	wk_key+IEEE80211_KEYBUF_SIZE+0	/* XXX can't () right */
93841ab66cSSepherosa Ziehau #define	wk_rxmic	wk_key+IEEE80211_KEYBUF_SIZE+8	/* XXX can't () right */
9432176cfdSRui Paulo 					/* key receive sequence counter */
9532176cfdSRui Paulo 	uint64_t	wk_keyrsc[IEEE80211_TID_SIZE];
96841ab66cSSepherosa Ziehau 	uint64_t	wk_keytsc;	/* key transmit sequence counter */
97841ab66cSSepherosa Ziehau 	const struct ieee80211_cipher *wk_cipher;
98841ab66cSSepherosa Ziehau 	void		*wk_private;	/* private cipher state */
9932176cfdSRui Paulo 	uint8_t		wk_macaddr[IEEE80211_ADDR_LEN];
100841ab66cSSepherosa Ziehau };
101841ab66cSSepherosa Ziehau #define	IEEE80211_KEY_COMMON 		/* common flags passed in by apps */\
102085ff963SMatthew Dillon 	(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \
103085ff963SMatthew Dillon 	 IEEE80211_KEY_NOREPLAY)
10432176cfdSRui Paulo #define	IEEE80211_KEY_DEVICE		/* flags owned by device driver */\
10532176cfdSRui Paulo 	(IEEE80211_KEY_DEVKEY|IEEE80211_KEY_CIPHER0|IEEE80211_KEY_CIPHER1)
10632176cfdSRui Paulo 
10732176cfdSRui Paulo #define	IEEE80211_KEY_SWCRYPT \
10832176cfdSRui Paulo 	(IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT)
10932176cfdSRui Paulo #define	IEEE80211_KEY_SWMIC	(IEEE80211_KEY_SWENMIC | IEEE80211_KEY_SWDEMIC)
11032176cfdSRui Paulo 
11132176cfdSRui Paulo #define	IEEE80211_KEY_BITS \
11232176cfdSRui Paulo 	"\20\1XMIT\2RECV\3GROUP\4SWENCRYPT\5SWDECRYPT\6SWENMIC\7SWDEMIC" \
11332176cfdSRui Paulo 	"\10DEVKEY\11CIPHER0\12CIPHER1"
11432176cfdSRui Paulo 
11532176cfdSRui Paulo #define	IEEE80211_KEYIX_NONE	((ieee80211_keyix) -1)
116841ab66cSSepherosa Ziehau 
117841ab66cSSepherosa Ziehau /*
118841ab66cSSepherosa Ziehau  * NB: these values are ordered carefully; there are lots of
11932176cfdSRui Paulo  * of implications in any reordering.  Beware that 4 is used
12032176cfdSRui Paulo  * only to indicate h/w TKIP MIC support in driver capabilities;
12132176cfdSRui Paulo  * there is no separate cipher support (it's rolled into the
12232176cfdSRui Paulo  * TKIP cipher support).
123841ab66cSSepherosa Ziehau  */
124841ab66cSSepherosa Ziehau #define	IEEE80211_CIPHER_WEP		0
125841ab66cSSepherosa Ziehau #define	IEEE80211_CIPHER_TKIP		1
126841ab66cSSepherosa Ziehau #define	IEEE80211_CIPHER_AES_OCB	2
127841ab66cSSepherosa Ziehau #define	IEEE80211_CIPHER_AES_CCM	3
12832176cfdSRui Paulo #define	IEEE80211_CIPHER_TKIPMIC	4	/* TKIP MIC capability */
129841ab66cSSepherosa Ziehau #define	IEEE80211_CIPHER_CKIP		5
130841ab66cSSepherosa Ziehau #define	IEEE80211_CIPHER_NONE		6	/* pseudo value */
131841ab66cSSepherosa Ziehau 
132841ab66cSSepherosa Ziehau #define	IEEE80211_CIPHER_MAX		(IEEE80211_CIPHER_NONE+1)
133841ab66cSSepherosa Ziehau 
13432176cfdSRui Paulo /* capability bits in ic_cryptocaps/iv_cryptocaps */
13532176cfdSRui Paulo #define	IEEE80211_CRYPTO_WEP		(1<<IEEE80211_CIPHER_WEP)
13632176cfdSRui Paulo #define	IEEE80211_CRYPTO_TKIP		(1<<IEEE80211_CIPHER_TKIP)
13732176cfdSRui Paulo #define	IEEE80211_CRYPTO_AES_OCB	(1<<IEEE80211_CIPHER_AES_OCB)
13832176cfdSRui Paulo #define	IEEE80211_CRYPTO_AES_CCM	(1<<IEEE80211_CIPHER_AES_CCM)
13932176cfdSRui Paulo #define	IEEE80211_CRYPTO_TKIPMIC	(1<<IEEE80211_CIPHER_TKIPMIC)
14032176cfdSRui Paulo #define	IEEE80211_CRYPTO_CKIP		(1<<IEEE80211_CIPHER_CKIP)
14132176cfdSRui Paulo 
14232176cfdSRui Paulo #define	IEEE80211_CRYPTO_BITS \
14332176cfdSRui Paulo 	"\20\1WEP\2TKIP\3AES\4AES_CCM\5TKIPMIC\6CKIP"
144841ab66cSSepherosa Ziehau 
145841ab66cSSepherosa Ziehau #if defined(__KERNEL__) || defined(_KERNEL)
146841ab66cSSepherosa Ziehau 
147841ab66cSSepherosa Ziehau struct ieee80211com;
14832176cfdSRui Paulo struct ieee80211vap;
149841ab66cSSepherosa Ziehau struct ieee80211_node;
150841ab66cSSepherosa Ziehau struct mbuf;
151841ab66cSSepherosa Ziehau 
152*805c8e8eSzrj #ifdef MALLOC_DECLARE
15332176cfdSRui Paulo MALLOC_DECLARE(M_80211_CRYPTO);
154*805c8e8eSzrj #endif
155841ab66cSSepherosa Ziehau 
156841ab66cSSepherosa Ziehau void	ieee80211_crypto_attach(struct ieee80211com *);
157841ab66cSSepherosa Ziehau void	ieee80211_crypto_detach(struct ieee80211com *);
15832176cfdSRui Paulo void	ieee80211_crypto_vattach(struct ieee80211vap *);
15932176cfdSRui Paulo void	ieee80211_crypto_vdetach(struct ieee80211vap *);
16032176cfdSRui Paulo int	ieee80211_crypto_newkey(struct ieee80211vap *,
161841ab66cSSepherosa Ziehau 		int cipher, int flags, struct ieee80211_key *);
16232176cfdSRui Paulo int	ieee80211_crypto_delkey(struct ieee80211vap *,
163841ab66cSSepherosa Ziehau 		struct ieee80211_key *);
16432176cfdSRui Paulo int	ieee80211_crypto_setkey(struct ieee80211vap *, struct ieee80211_key *);
16532176cfdSRui Paulo void	ieee80211_crypto_delglobalkeys(struct ieee80211vap *);
16632176cfdSRui Paulo void	ieee80211_crypto_reload_keys(struct ieee80211com *);
1676bd66811SSepherosa Ziehau 
168841ab66cSSepherosa Ziehau /*
169841ab66cSSepherosa Ziehau  * Template for a supported cipher.  Ciphers register with the
170841ab66cSSepherosa Ziehau  * crypto code and are typically loaded as separate modules
171841ab66cSSepherosa Ziehau  * (the null cipher is always present).
172841ab66cSSepherosa Ziehau  * XXX may need refcnts
173841ab66cSSepherosa Ziehau  */
174841ab66cSSepherosa Ziehau struct ieee80211_cipher {
175841ab66cSSepherosa Ziehau 	const char *ic_name;		/* printable name */
176841ab66cSSepherosa Ziehau 	u_int	ic_cipher;		/* IEEE80211_CIPHER_* */
177841ab66cSSepherosa Ziehau 	u_int	ic_header;		/* size of privacy header (bytes) */
178841ab66cSSepherosa Ziehau 	u_int	ic_trailer;		/* size of privacy trailer (bytes) */
179841ab66cSSepherosa Ziehau 	u_int	ic_miclen;		/* size of mic trailer (bytes) */
18032176cfdSRui Paulo 	void*	(*ic_attach)(struct ieee80211vap *, struct ieee80211_key *);
181841ab66cSSepherosa Ziehau 	void	(*ic_detach)(struct ieee80211_key *);
182841ab66cSSepherosa Ziehau 	int	(*ic_setkey)(struct ieee80211_key *);
1834f655ef5SMatthew Dillon 	void	(*ic_setiv)(struct ieee80211_key *, uint8_t *);
1844f655ef5SMatthew Dillon 	int	(*ic_encap)(struct ieee80211_key *, struct mbuf *);
185841ab66cSSepherosa Ziehau 	int	(*ic_decap)(struct ieee80211_key *, struct mbuf *, int);
186841ab66cSSepherosa Ziehau 	int	(*ic_enmic)(struct ieee80211_key *, struct mbuf *, int);
187841ab66cSSepherosa Ziehau 	int	(*ic_demic)(struct ieee80211_key *, struct mbuf *, int);
188841ab66cSSepherosa Ziehau };
189841ab66cSSepherosa Ziehau extern	const struct ieee80211_cipher ieee80211_cipher_none;
190841ab66cSSepherosa Ziehau 
19132176cfdSRui Paulo #define	IEEE80211_KEY_UNDEFINED(k) \
19232176cfdSRui Paulo 	((k)->wk_cipher == &ieee80211_cipher_none)
19332176cfdSRui Paulo 
194841ab66cSSepherosa Ziehau void	ieee80211_crypto_register(const struct ieee80211_cipher *);
195841ab66cSSepherosa Ziehau void	ieee80211_crypto_unregister(const struct ieee80211_cipher *);
196841ab66cSSepherosa Ziehau int	ieee80211_crypto_available(u_int cipher);
197841ab66cSSepherosa Ziehau 
1984f655ef5SMatthew Dillon uint8_t	ieee80211_crypto_get_keyid(struct ieee80211vap *vap,
1994f655ef5SMatthew Dillon 		struct ieee80211_key *k);
2004f655ef5SMatthew Dillon struct ieee80211_key *ieee80211_crypto_get_txkey(struct ieee80211_node *,
2014f655ef5SMatthew Dillon 		struct mbuf *);
20232176cfdSRui Paulo struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_node *,
20332176cfdSRui Paulo 		struct mbuf *);
20432176cfdSRui Paulo struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *,
20532176cfdSRui Paulo 		struct mbuf *, int);
206841ab66cSSepherosa Ziehau 
207841ab66cSSepherosa Ziehau /*
208841ab66cSSepherosa Ziehau  * Check and remove any MIC.
209841ab66cSSepherosa Ziehau  */
210841ab66cSSepherosa Ziehau static __inline int
ieee80211_crypto_demic(struct ieee80211vap * vap,struct ieee80211_key * k,struct mbuf * m,int force)21132176cfdSRui Paulo ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
212841ab66cSSepherosa Ziehau 	struct mbuf *m, int force)
213841ab66cSSepherosa Ziehau {
214841ab66cSSepherosa Ziehau 	const struct ieee80211_cipher *cip = k->wk_cipher;
215841ab66cSSepherosa Ziehau 	return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1);
216841ab66cSSepherosa Ziehau }
217841ab66cSSepherosa Ziehau 
218841ab66cSSepherosa Ziehau /*
219841ab66cSSepherosa Ziehau  * Add any MIC.
220841ab66cSSepherosa Ziehau  */
221841ab66cSSepherosa Ziehau static __inline int
ieee80211_crypto_enmic(struct ieee80211vap * vap,struct ieee80211_key * k,struct mbuf * m,int force)22232176cfdSRui Paulo ieee80211_crypto_enmic(struct ieee80211vap *vap,
223841ab66cSSepherosa Ziehau 	struct ieee80211_key *k, struct mbuf *m, int force)
224841ab66cSSepherosa Ziehau {
225841ab66cSSepherosa Ziehau 	const struct ieee80211_cipher *cip = k->wk_cipher;
226841ab66cSSepherosa Ziehau 	return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m, force) : 1);
227841ab66cSSepherosa Ziehau }
228841ab66cSSepherosa Ziehau 
229841ab66cSSepherosa Ziehau /*
23032176cfdSRui Paulo  * Reset key state to an unused state.  The crypto
23132176cfdSRui Paulo  * key allocation mechanism insures other state (e.g.
23232176cfdSRui Paulo  * key data) is properly setup before a key is used.
23332176cfdSRui Paulo  */
23432176cfdSRui Paulo static __inline void
ieee80211_crypto_resetkey(struct ieee80211vap * vap,struct ieee80211_key * k,ieee80211_keyix ix)23532176cfdSRui Paulo ieee80211_crypto_resetkey(struct ieee80211vap *vap,
23632176cfdSRui Paulo 	struct ieee80211_key *k, ieee80211_keyix ix)
23732176cfdSRui Paulo {
23832176cfdSRui Paulo 	k->wk_cipher = &ieee80211_cipher_none;
23932176cfdSRui Paulo 	k->wk_private = k->wk_cipher->ic_attach(vap, k);
24032176cfdSRui Paulo 	k->wk_keyix = k->wk_rxkeyix = ix;
24132176cfdSRui Paulo 	k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
24232176cfdSRui Paulo }
24332176cfdSRui Paulo 
24432176cfdSRui Paulo /*
245841ab66cSSepherosa Ziehau  * Crypt-related notification methods.
246841ab66cSSepherosa Ziehau  */
24732176cfdSRui Paulo void	ieee80211_notify_replay_failure(struct ieee80211vap *,
248841ab66cSSepherosa Ziehau 		const struct ieee80211_frame *, const struct ieee80211_key *,
24932176cfdSRui Paulo 		uint64_t rsc, int tid);
25032176cfdSRui Paulo void	ieee80211_notify_michael_failure(struct ieee80211vap *,
251841ab66cSSepherosa Ziehau 		const struct ieee80211_frame *, u_int keyix);
252841ab66cSSepherosa Ziehau #endif /* defined(__KERNEL__) || defined(_KERNEL) */
253841ab66cSSepherosa Ziehau #endif /* _NET80211_IEEE80211_CRYPTO_H_ */
254