1 | /* $NetBSD: ieee80211_crypto.h,v 1.11 2009/01/03 03:43:23 yamt Exp $ */ |
2 | /*- |
3 | * Copyright (c) 2001 Atsushi Onoe |
4 | * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. The name of the author may not be used to endorse or promote products |
16 | * derived from this software without specific prior written permission. |
17 | * |
18 | * Alternatively, this software may be distributed under the terms of the |
19 | * GNU General Public License ("GPL") version 2 as published by the Free |
20 | * Software Foundation. |
21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | * |
33 | * $FreeBSD: src/sys/net80211/ieee80211_crypto.h,v 1.10 2005/08/08 18:46:35 sam Exp $ |
34 | */ |
35 | #ifndef _NET80211_IEEE80211_CRYPTO_H_ |
36 | #define _NET80211_IEEE80211_CRYPTO_H_ |
37 | |
38 | /* |
39 | * 802.11 protocol crypto-related definitions. |
40 | */ |
41 | #define IEEE80211_KEYBUF_SIZE 16 |
42 | #define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx+rx keys */ |
43 | |
44 | /* |
45 | * Old WEP-style key. Deprecated. |
46 | */ |
47 | struct ieee80211_wepkey { |
48 | u_int wk_len; /* key length in bytes */ |
49 | u_int8_t wk_key[IEEE80211_KEYBUF_SIZE]; |
50 | }; |
51 | |
52 | struct ieee80211_cipher; |
53 | |
54 | /* |
55 | * Crypto key state. There is sufficient room for all supported |
56 | * ciphers (see below). The underlying ciphers are handled |
57 | * separately through loadable cipher modules that register with |
58 | * the generic crypto support. A key has a reference to an instance |
59 | * of the cipher; any per-key state is hung off wk_private by the |
60 | * cipher when it is attached. Ciphers are automatically called |
61 | * to detach and cleanup any such state when the key is deleted. |
62 | * |
63 | * The generic crypto support handles encap/decap of cipher-related |
64 | * frame contents for both hardware- and software-based implementations. |
65 | * A key requiring software crypto support is automatically flagged and |
66 | * the cipher is expected to honor this and do the necessary work. |
67 | * Ciphers such as TKIP may also support mixed hardware/software |
68 | * encrypt/decrypt and MIC processing. |
69 | */ |
70 | typedef u_int16_t ieee80211_keyix; /* h/w key index */ |
71 | |
72 | struct ieee80211_key { |
73 | u_int8_t wk_keylen; /* key length in bytes */ |
74 | u_int8_t wk_pad; |
75 | u_int16_t wk_flags; |
76 | #define IEEE80211_KEY_XMIT 0x01 /* key used for xmit */ |
77 | #define IEEE80211_KEY_RECV 0x02 /* key used for recv */ |
78 | #define IEEE80211_KEY_GROUP 0x04 /* key used for WPA group operation */ |
79 | #define IEEE80211_KEY_SWCRYPT 0x10 /* host-based encrypt/decrypt */ |
80 | #define IEEE80211_KEY_SWMIC 0x20 /* host-based enmic/demic */ |
81 | ieee80211_keyix wk_keyix; /* h/w key index */ |
82 | ieee80211_keyix wk_rxkeyix; /* optional h/w rx key index */ |
83 | u_int8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; |
84 | #define wk_txmic wk_key+IEEE80211_KEYBUF_SIZE+0 /* XXX can't () right */ |
85 | #define wk_rxmic wk_key+IEEE80211_KEYBUF_SIZE+8 /* XXX can't () right */ |
86 | u_int64_t wk_keyrsc; /* key receive sequence counter */ |
87 | u_int64_t wk_keytsc; /* key transmit sequence counter */ |
88 | const struct ieee80211_cipher *wk_cipher; |
89 | void *wk_private; /* private cipher state */ |
90 | }; |
91 | #define IEEE80211_KEY_COMMON /* common flags passed in by apps */\ |
92 | (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP) |
93 | |
94 | /* |
95 | * NB: these values are ordered carefully; there are lots of |
96 | * of implications in any reordering. In particular beware |
97 | * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY. |
98 | */ |
99 | #define IEEE80211_CIPHER_WEP 0 |
100 | #define IEEE80211_CIPHER_TKIP 1 |
101 | #define IEEE80211_CIPHER_AES_OCB 2 |
102 | #define IEEE80211_CIPHER_AES_CCM 3 |
103 | #define IEEE80211_CIPHER_CKIP 5 |
104 | #define IEEE80211_CIPHER_NONE 6 /* pseudo value */ |
105 | |
106 | #define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) |
107 | |
108 | #define IEEE80211_KEYIX_NONE ((ieee80211_keyix) -1) |
109 | #define IEEE80211_KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none) |
110 | |
111 | #if defined(__KERNEL__) || defined(_KERNEL) |
112 | |
113 | struct ieee80211com; |
114 | struct ieee80211_node; |
115 | struct mbuf; |
116 | |
117 | /* |
118 | * Crypto state kept in each ieee80211com. Some of this |
119 | * can/should be shared when virtual AP's are supported. |
120 | * |
121 | * XXX save reference to ieee80211com to properly encapsulate state. |
122 | * XXX split out crypto capabilities from ic_caps |
123 | */ |
124 | struct ieee80211_crypto_state { |
125 | struct ieee80211_key cs_nw_keys[IEEE80211_WEP_NKID]; |
126 | ieee80211_keyix cs_def_txkey; /* default/group tx key index */ |
127 | u_int16_t cs_max_keyix; /* max h/w key index */ |
128 | |
129 | int (*cs_key_alloc)(struct ieee80211com *, |
130 | const struct ieee80211_key *, |
131 | ieee80211_keyix *, ieee80211_keyix *); |
132 | int (*cs_key_delete)(struct ieee80211com *, |
133 | const struct ieee80211_key *); |
134 | int (*cs_key_set)(struct ieee80211com *, |
135 | const struct ieee80211_key *, |
136 | const u_int8_t mac[IEEE80211_ADDR_LEN]); |
137 | void (*cs_key_update_begin)(struct ieee80211com *); |
138 | void (*cs_key_update_end)(struct ieee80211com *); |
139 | }; |
140 | |
141 | void ieee80211_crypto_attach(struct ieee80211com *); |
142 | void ieee80211_crypto_detach(struct ieee80211com *); |
143 | int ieee80211_crypto_newkey(struct ieee80211com *, |
144 | int cipher, int flags, struct ieee80211_key *); |
145 | int ieee80211_crypto_delkey(struct ieee80211com *, |
146 | struct ieee80211_key *); |
147 | int ieee80211_crypto_setkey(struct ieee80211com *, |
148 | struct ieee80211_key *, const u_int8_t macaddr[IEEE80211_ADDR_LEN]); |
149 | void ieee80211_crypto_delglobalkeys(struct ieee80211com *); |
150 | |
151 | /* |
152 | * Template for a supported cipher. Ciphers register with the |
153 | * crypto code and are typically loaded as separate modules |
154 | * (the null cipher is always present). |
155 | * XXX may need refcnts |
156 | */ |
157 | struct ieee80211_cipher { |
158 | const char *ic_name; /* printable name */ |
159 | u_int ic_cipher; /* IEEE80211_CIPHER_* */ |
160 | u_int ; /* size of privacy header (bytes) */ |
161 | u_int ic_trailer; /* size of privacy trailer (bytes) */ |
162 | u_int ic_miclen; /* size of mic trailer (bytes) */ |
163 | void* (*ic_attach)(struct ieee80211com *, struct ieee80211_key *); |
164 | void (*ic_detach)(struct ieee80211_key *); |
165 | int (*ic_setkey)(struct ieee80211_key *); |
166 | int (*ic_encap)(struct ieee80211_key *, struct mbuf *, |
167 | u_int8_t keyid); |
168 | int (*ic_decap)(struct ieee80211_key *, struct mbuf *, int); |
169 | int (*ic_enmic)(struct ieee80211_key *, struct mbuf *, int); |
170 | int (*ic_demic)(struct ieee80211_key *, struct mbuf *, int); |
171 | }; |
172 | extern const struct ieee80211_cipher ieee80211_cipher_none; |
173 | extern const struct ieee80211_cipher ieee80211_cipher_wep; |
174 | extern const struct ieee80211_cipher ieee80211_cipher_tkip; |
175 | extern const struct ieee80211_cipher ieee80211_cipher_ccmp; |
176 | |
177 | void ieee80211_crypto_register(const struct ieee80211_cipher *); |
178 | void ieee80211_crypto_unregister(const struct ieee80211_cipher *); |
179 | int ieee80211_crypto_available(u_int cipher); |
180 | |
181 | struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211com *, |
182 | struct ieee80211_node *, struct mbuf *); |
183 | struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211com *, |
184 | struct ieee80211_node *, struct mbuf *, int); |
185 | |
186 | /* |
187 | * Check and remove any MIC. |
188 | */ |
189 | static __inline int |
190 | ieee80211_crypto_demic(struct ieee80211com *ic, |
191 | struct ieee80211_key *k, struct mbuf *m, int force) |
192 | { |
193 | const struct ieee80211_cipher *cip = k->wk_cipher; |
194 | return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1); |
195 | } |
196 | |
197 | /* |
198 | * Add any MIC. |
199 | */ |
200 | static __inline int |
201 | ieee80211_crypto_enmic(struct ieee80211com *ic, |
202 | struct ieee80211_key *k, struct mbuf *m, int force) |
203 | { |
204 | const struct ieee80211_cipher *cip = k->wk_cipher; |
205 | return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m, force) : 1); |
206 | } |
207 | |
208 | /* |
209 | * Reset key state to an unused state. The crypto |
210 | * key allocation mechanism insures other state (e.g. |
211 | * key data) is properly setup before a key is used. |
212 | */ |
213 | static __inline void |
214 | ieee80211_crypto_resetkey(struct ieee80211com *ic, |
215 | struct ieee80211_key *k, ieee80211_keyix ix) |
216 | { |
217 | k->wk_cipher = &ieee80211_cipher_none; |
218 | k->wk_private = k->wk_cipher->ic_attach(ic, k); |
219 | k->wk_keyix = k->wk_rxkeyix = ix; |
220 | k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; |
221 | } |
222 | |
223 | /* |
224 | * Crypt-related notification methods. |
225 | */ |
226 | void ieee80211_notify_replay_failure(struct ieee80211com *, |
227 | const struct ieee80211_frame *, const struct ieee80211_key *, |
228 | u_int64_t rsc); |
229 | void ieee80211_notify_michael_failure(struct ieee80211com *, |
230 | const struct ieee80211_frame *, u_int keyix); |
231 | #endif /* defined(__KERNEL__) || defined(_KERNEL) */ |
232 | #endif /* !_NET80211_IEEE80211_CRYPTO_H_ */ |
233 | |