1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2001 Atsushi Onoe
8  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * Alternatively, this software may be distributed under the terms of the
23  * GNU General Public License ("GPL") version 2 as published by the Free
24  * Software Foundation.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #pragma ident	"%Z%%M%	%I%	%E% SMI"
39 
40 /*
41  * IEEE 802.11i TKIP crypto support.
42  */
43 #include <sys/byteorder.h>
44 #include <sys/crypto/common.h>
45 #include <sys/crypto/api.h>
46 #include <sys/crc32.h>
47 #include <sys/random.h>
48 #include "net80211_impl.h"
49 
50 static void *tkip_attach(struct ieee80211com *, struct ieee80211_key *);
51 static void tkip_detach(struct ieee80211_key *);
52 static int tkip_setkey(struct ieee80211_key *);
53 static int tkip_encap(struct ieee80211_key *, mblk_t *, uint8_t);
54 static int tkip_decap(struct ieee80211_key *, mblk_t *, int);
55 static int tkip_enmic(struct ieee80211_key *, mblk_t *, int);
56 static int tkip_demic(struct ieee80211_key *, mblk_t *, int);
57 
58 const struct ieee80211_cipher tkip  = {
59 	"TKIP",
60 	IEEE80211_CIPHER_TKIP,
61 	IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
62 	    IEEE80211_WEP_EXTIVLEN,
63 	IEEE80211_WEP_CRCLEN,
64 	IEEE80211_WEP_MICLEN,
65 	tkip_attach,
66 	tkip_detach,
67 	tkip_setkey,
68 	tkip_encap,
69 	tkip_decap,
70 	tkip_enmic,
71 	tkip_demic,
72 };
73 
74 struct tkip_ctx {
75 	struct ieee80211com	*tc_ic;		/* for diagnostics */
76 	uint16_t		tx_ttak[5];
77 	int			tx_phase1_done;
78 	uint8_t			tx_rc4key[16];
79 	uint16_t		rx_ttak[5];
80 	int			rx_phase1_done;
81 	uint8_t			rx_rc4key[16];
82 	uint64_t		rx_rsc;		/* held until MIC verified */
83 };
84 
85 /* ARGSUSED */
86 static void *
87 tkip_attach(struct ieee80211com *ic, struct ieee80211_key *k)
88 {
89 	struct tkip_ctx *ctx;
90 
91 	ctx = kmem_zalloc(sizeof (struct tkip_ctx), KM_SLEEP);
92 	if (ctx == NULL)
93 		return (NULL);
94 
95 	ctx->tc_ic = ic;
96 	return (ctx);
97 }
98 
99 static void
100 tkip_detach(struct ieee80211_key *k)
101 {
102 	struct tkip_ctx *ctx = k->wk_private;
103 
104 	if (ctx != NULL)
105 		kmem_free(ctx, sizeof (struct tkip_ctx));
106 }
107 
108 static int
109 tkip_setkey(struct ieee80211_key *k)
110 {
111 	if (k->wk_keylen != (128/NBBY))
112 		return (0);
113 
114 	k->wk_keytsc = 1;		/* TSC starts at 1 */
115 	return (1);
116 }
117 
118 /*
119  * Add privacy headers appropriate for the specified key.
120  */
121 static int
122 tkip_encap(struct ieee80211_key *k, mblk_t *mp, uint8_t keyid)
123 {
124 	struct tkip_ctx *ctx = k->wk_private;
125 	struct ieee80211com *ic = ctx->tc_ic;
126 	uint8_t *ivp;
127 	int hdrlen;
128 
129 	/*
130 	 * Handle TKIP counter measures requirement.
131 	 */
132 	if (ic->ic_flags & IEEE80211_F_COUNTERM)
133 		return (0);
134 
135 	hdrlen = ieee80211_hdrspace(mp->b_rptr);
136 	/*
137 	 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
138 	 */
139 	ivp = mp->b_rptr;
140 	ivp += hdrlen;
141 
142 	ivp[0] = k->wk_keytsc >> 8;		/* TSC1 */
143 	ivp[1] = (ivp[0] | 0x20) & 0x7f;	/* WEP seed */
144 	ivp[2] = k->wk_keytsc >> 0;		/* TSC0 */
145 	ivp[3] = keyid | IEEE80211_WEP_EXTIV;	/* KeyID | ExtID */
146 	ivp[4] = k->wk_keytsc >> 16;		/* TSC2 */
147 	ivp[5] = k->wk_keytsc >> 24;		/* TSC3 */
148 	ivp[6] = k->wk_keytsc >> 32;		/* TSC4 */
149 	ivp[7] = k->wk_keytsc >> 40;		/* TSC5 */
150 
151 	/*
152 	 * NB: software TKIP is not supported.
153 	 */
154 	if (k->wk_flags & IEEE80211_KEY_SWCRYPT)
155 		return (0);
156 	else
157 		k->wk_keytsc++;		/* wrap at 48 bits */
158 
159 	return (1);
160 }
161 
162 uint64_t
163 ieee80211_read_6(uint8_t b0, uint8_t b1, uint8_t b2,
164     uint8_t b3, uint8_t b4, uint8_t b5)
165 {
166 	uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
167 	uint16_t iv16 = (b4 << 0) | (b5 << 8);
168 	return ((((uint64_t)iv16) << 32) | iv32);
169 }
170 
171 /*
172  * Validate and strip privacy headers (and trailer) for a
173  * received frame.  If necessary, decrypt the frame using
174  * the specified key.
175  */
176 static int
177 tkip_decap(struct ieee80211_key *k, mblk_t *mp, int hdrlen)
178 {
179 	struct tkip_ctx *ctx = k->wk_private;
180 	struct ieee80211com *ic = ctx->tc_ic;
181 	struct ieee80211_frame tmp;
182 	uint8_t *ivp;
183 	uint64_t pn;
184 
185 	/*
186 	 * Header should have extended IV and sequence number;
187 	 * verify the former and validate the latter.
188 	 */
189 	ivp = mp->b_rptr + hdrlen;
190 	if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
191 		/*
192 		 * No extended IV; discard frame.
193 		 */
194 		return (0);
195 	}
196 	/*
197 	 * Handle TKIP counter measures requirement.
198 	 */
199 	if (ic->ic_flags & IEEE80211_F_COUNTERM)
200 		return (0);
201 
202 	/* NB: assume IEEEE80211_WEP_MINLEN covers the extended IV */
203 	pn = ieee80211_read_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]);
204 	ctx->rx_rsc = pn;
205 	if (ctx->rx_rsc <= k->wk_keyrsc)
206 		return (0);
207 	/*
208 	 * NB: We can't update the rsc in the key until MIC is verified.
209 	 *
210 	 * We assume we are not preempted between doing the check above
211 	 * and updating wk_keyrsc when stripping the MIC in tkip_demic.
212 	 * Otherwise we might process another packet and discard it as
213 	 * a replay.
214 	 */
215 
216 	/*
217 	 * NB: software TKIP is not supported.
218 	 */
219 	if (k->wk_flags & IEEE80211_KEY_SWCRYPT)
220 		return (0);
221 
222 	/*
223 	 * Copy up 802.11 header and strip crypto bits.
224 	 */
225 	bcopy(mp->b_rptr, &tmp, hdrlen);
226 	bcopy(&tmp, mp->b_rptr + tkip.ic_header, hdrlen);
227 	mp->b_rptr += tkip.ic_header;
228 	mp->b_wptr -= tkip.ic_trailer;
229 
230 	return (1);
231 }
232 
233 /*
234  * Add MIC to the frame as needed.
235  */
236 /* ARGSUSED */
237 static int
238 tkip_enmic(struct ieee80211_key *k, mblk_t *mp, int force)
239 {
240 	return (1);
241 }
242 
243 /*
244  * Verify and strip MIC from the frame.
245  */
246 /* ARGSUSED */
247 static int
248 tkip_demic(struct ieee80211_key *k, mblk_t *mp, int force)
249 {
250 	struct tkip_ctx *ctx = k->wk_private;
251 
252 	/*
253 	 * NB: software TKIP is not supported.
254 	 */
255 	if (k->wk_flags & IEEE80211_KEY_SWMIC)
256 		return (0);
257 	/*
258 	 * Strip MIC from the tail.
259 	 */
260 	mp->b_wptr -= tkip.ic_miclen;
261 	/*
262 	 * Ok to update rsc now that MIC has been verified.
263 	 */
264 	k->wk_keyrsc = ctx->rx_rsc;
265 
266 	return (1);
267 }
268