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