This source file includes following definitions.
- arc4_ctxlen
- arc4_setkey
- arc4_encrypt
- awi_wep_setnwkey
- awi_wep_getnwkey
- awi_wep_getalgo
- awi_wep_setalgo
- awi_wep_setkey
- awi_wep_getkey
- awi_wep_encrypt
- awi_crc_init
- awi_crc_update
- awi_null_ctxlen
- awi_null_setkey
- awi_null_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/mbuf.h>
57 #include <sys/malloc.h>
58 #include <sys/proc.h>
59 #include <sys/socket.h>
60 #include <sys/errno.h>
61 #include <sys/sockio.h>
62 #if defined(__FreeBSD__) && __FreeBSD__ >= 4
63 #include <sys/bus.h>
64 #else
65 #include <sys/device.h>
66 #endif
67
68 #include <net/if.h>
69 #include <net/if_dl.h>
70 #ifdef __FreeBSD__
71 #include <net/ethernet.h>
72 #include <net/if_arp.h>
73 #elif defined(__OpenBSD__)
74 #include <netinet/in.h>
75 #include <netinet/if_ether.h>
76 #else
77 #include <net/if_ether.h>
78 #endif
79 #include <net/if_media.h>
80 #include <net80211/ieee80211.h>
81 #include <net80211/ieee80211_ioctl.h>
82
83 #include <machine/cpu.h>
84 #include <machine/bus.h>
85 #ifdef __FreeBSD__
86 #include <machine/clock.h>
87 #endif
88
89 #if defined(__NetBSD__) || defined(__OpenBSD__)
90 #include <dev/ic/am79c930reg.h>
91 #include <dev/ic/am79c930var.h>
92 #include <dev/ic/awireg.h>
93 #include <dev/ic/awivar.h>
94 #include <dev/rndvar.h>
95 #endif
96
97 #ifdef __OpenBSD__
98 #include <dev/rndvar.h>
99 #endif
100
101 #ifdef __OpenBSD__
102 #include <dev/rndvar.h>
103 #endif
104
105 #ifdef __NetBSD__
106 #include <crypto/arc4/arc4.h>
107 #endif
108
109 #ifdef __FreeBSD__
110 #include <dev/awi/am79c930reg.h>
111 #include <dev/awi/am79c930var.h>
112 #include <dev/awi/awireg.h>
113 #include <dev/awi/awivar.h>
114
115 #include <crypto/rc4/rc4.h>
116 static __inline int
117 arc4_ctxlen(void)
118 {
119 return sizeof(struct rc4_state);
120 }
121
122 static __inline void
123 arc4_setkey(void *ctx, u_int8_t *key, int keylen)
124 {
125 rc4_init(ctx, key, keylen);
126 }
127
128 static __inline void
129 arc4_encrypt(void *ctx, u_int8_t *dst, u_int8_t *src, int len)
130 {
131 rc4_crypt(ctx, dst, src, len);
132 }
133 #endif
134
135 static void awi_crc_init(void);
136 static u_int32_t awi_crc_update(u_int32_t crc, u_int8_t *buf, int len);
137
138 static int awi_null_ctxlen(void);
139 static void awi_null_setkey(void *ctx, u_int8_t *key, int keylen);
140 static void awi_null_copy(void *ctx, u_int8_t *dst, u_int8_t *src, int len);
141
142
143
144 static struct awi_wep_algo awi_wep_algo[] = {
145
146 { "no" },
147
148 #if 0
149
150 { "arc4", arc4_ctxlen, arc4_setkey,
151 arc4_encrypt, arc4_encrypt },
152 #endif
153
154 { "null", awi_null_ctxlen, awi_null_setkey,
155 awi_null_copy, awi_null_copy },
156
157 };
158
159 int
160 awi_wep_setnwkey(sc, nwkey)
161 struct awi_softc *sc;
162 struct ieee80211_nwkey *nwkey;
163 {
164 int i, len, error;
165 u_int8_t keybuf[AWI_MAX_KEYLEN];
166
167 if (nwkey->i_defkid <= 0 ||
168 nwkey->i_defkid > IEEE80211_WEP_NKID)
169 return EINVAL;
170 error = 0;
171 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
172 if (nwkey->i_key[i].i_keydat == NULL)
173 continue;
174 len = nwkey->i_key[i].i_keylen;
175 if (len > sizeof(keybuf)) {
176 error = EINVAL;
177 break;
178 }
179 error = copyin(nwkey->i_key[i].i_keydat, keybuf, len);
180 if (error)
181 break;
182 error = awi_wep_setkey(sc, i, keybuf, len);
183 if (error)
184 break;
185 }
186 if (error == 0) {
187 sc->sc_wep_defkid = nwkey->i_defkid - 1;
188 error = awi_wep_setalgo(sc, nwkey->i_wepon);
189 if (error == 0 && sc->sc_enabled) {
190 awi_stop(sc);
191 error = awi_init(sc);
192 }
193 }
194 return error;
195 }
196
197 int
198 awi_wep_getnwkey(sc, nwkey)
199 struct awi_softc *sc;
200 struct ieee80211_nwkey *nwkey;
201 {
202 int i, len, error, suerr;
203 u_int8_t keybuf[AWI_MAX_KEYLEN];
204
205 nwkey->i_wepon = awi_wep_getalgo(sc);
206 nwkey->i_defkid = sc->sc_wep_defkid + 1;
207
208 #ifdef __FreeBSD__
209 suerr = suser(curproc);
210 #else
211 #ifdef __OpenBSD__
212 suerr = suser(curproc, 0);
213 #else
214 suerr = suser(curproc->p_ucred, &curproc->p_acflag);
215 #endif
216 #endif
217 error = 0;
218 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
219 if (nwkey->i_key[i].i_keydat == NULL)
220 continue;
221 if (suerr) {
222 error = suerr;
223 break;
224 }
225 len = sizeof(keybuf);
226 error = awi_wep_getkey(sc, i, keybuf, &len);
227 if (error)
228 break;
229 if (nwkey->i_key[i].i_keylen < len) {
230 error = ENOSPC;
231 break;
232 }
233 nwkey->i_key[i].i_keylen = len;
234 error = copyout(keybuf, nwkey->i_key[i].i_keydat, len);
235 if (error)
236 break;
237 }
238 return error;
239 }
240
241 int
242 awi_wep_getalgo(sc)
243 struct awi_softc *sc;
244 {
245
246 if (sc->sc_wep_algo == NULL)
247 return 0;
248 return sc->sc_wep_algo - awi_wep_algo;
249 }
250
251 int
252 awi_wep_setalgo(sc, algo)
253 struct awi_softc *sc;
254 int algo;
255 {
256 struct awi_wep_algo *awa;
257 int ctxlen;
258
259 awi_crc_init();
260 if (algo < 0 || algo >= sizeof(awi_wep_algo)/sizeof(awi_wep_algo[0]))
261 return EINVAL;
262 awa = &awi_wep_algo[algo];
263 if (awa->awa_name == NULL)
264 return EINVAL;
265 if (awa->awa_ctxlen == NULL) {
266 awa = NULL;
267 ctxlen = 0;
268 } else
269 ctxlen = awa->awa_ctxlen();
270 if (sc->sc_wep_ctx != NULL) {
271 free(sc->sc_wep_ctx, M_DEVBUF);
272 sc->sc_wep_ctx = NULL;
273 }
274 if (ctxlen) {
275 sc->sc_wep_ctx = malloc(ctxlen, M_DEVBUF, M_NOWAIT);
276 if (sc->sc_wep_ctx == NULL)
277 return ENOMEM;
278 }
279 sc->sc_wep_algo = awa;
280 return 0;
281 }
282
283 int
284 awi_wep_setkey(sc, kid, key, keylen)
285 struct awi_softc *sc;
286 int kid;
287 unsigned char *key;
288 int keylen;
289 {
290
291 if (kid < 0 || kid >= IEEE80211_WEP_NKID)
292 return EINVAL;
293 if (keylen < 0 || keylen + IEEE80211_WEP_IVLEN > AWI_MAX_KEYLEN)
294 return EINVAL;
295 sc->sc_wep_keylen[kid] = keylen;
296 if (keylen > 0)
297 memcpy(sc->sc_wep_key[kid] + IEEE80211_WEP_IVLEN, key, keylen);
298 return 0;
299 }
300
301 int
302 awi_wep_getkey(sc, kid, key, keylen)
303 struct awi_softc *sc;
304 int kid;
305 unsigned char *key;
306 int *keylen;
307 {
308
309 if (kid < 0 || kid >= IEEE80211_WEP_NKID)
310 return EINVAL;
311 if (*keylen < sc->sc_wep_keylen[kid])
312 return ENOSPC;
313 *keylen = sc->sc_wep_keylen[kid];
314 if (*keylen > 0)
315 memcpy(key, sc->sc_wep_key[kid] + IEEE80211_WEP_IVLEN, *keylen);
316 return 0;
317 }
318
319 struct mbuf *
320 awi_wep_encrypt(sc, m0, txflag)
321 struct awi_softc *sc;
322 struct mbuf *m0;
323 int txflag;
324 {
325 struct mbuf *m, *n, *n0;
326 struct ieee80211_frame *wh;
327 struct awi_wep_algo *awa;
328 int left, len, moff, noff, keylen, kid;
329 u_int32_t iv, crc;
330 u_int8_t *key, *ivp;
331 void *ctx;
332 u_int8_t crcbuf[IEEE80211_WEP_CRCLEN];
333
334 n0 = NULL;
335 awa = sc->sc_wep_algo;
336 if (awa == NULL)
337 goto fail;
338 ctx = sc->sc_wep_ctx;
339 m = m0;
340 left = m->m_pkthdr.len;
341 MGET(n, M_DONTWAIT, m->m_type);
342 n0 = n;
343 if (n == NULL)
344 goto fail;
345 M_DUP_PKTHDR(n, m);
346 len = IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
347 IEEE80211_WEP_CRCLEN;
348 if (txflag) {
349 n->m_pkthdr.len += len;
350 } else {
351 wh = mtod(n, struct ieee80211_frame *);
352 n->m_pkthdr.len -= len;
353 left -= len;
354 }
355 n->m_len = MHLEN;
356 if (n->m_pkthdr.len >= MINCLSIZE) {
357 MCLGET(n, M_DONTWAIT);
358 if (n->m_flags & M_EXT)
359 n->m_len = n->m_ext.ext_size;
360 }
361 len = sizeof(struct ieee80211_frame);
362 memcpy(mtod(n, caddr_t), mtod(m, caddr_t), len);
363 left -= len;
364 moff = len;
365 noff = len;
366 if (txflag) {
367 kid = sc->sc_wep_defkid;
368 wh = mtod(n, struct ieee80211_frame *);
369 wh->i_fc[1] |= IEEE80211_FC1_WEP;
370 iv = arc4random();
371
372
373
374
375 ivp = mtod(n, u_int8_t *) + noff;
376 ivp[0] = (iv >> 16) & 0xff;
377 ivp[1] = (iv >> 8) & 0xff;
378 ivp[2] = iv & 0xff;
379 ivp[3] = kid & 0x03;
380 noff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
381 } else {
382 ivp = mtod(m, u_int8_t *) + moff;
383 moff += IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;
384 kid = ivp[IEEE80211_WEP_IVLEN] & 0x03;
385 }
386 key = sc->sc_wep_key[kid];
387 keylen = sc->sc_wep_keylen[kid];
388
389 key[0] = ivp[0];
390 key[1] = ivp[1];
391 key[2] = ivp[2];
392 awa->awa_setkey(ctx, key, IEEE80211_WEP_IVLEN + keylen);
393
394
395 crc = ~0;
396 while (left > 0) {
397 len = m->m_len - moff;
398 if (len == 0) {
399 m = m->m_next;
400 moff = 0;
401 continue;
402 }
403 if (len > n->m_len - noff) {
404 len = n->m_len - noff;
405 if (len == 0) {
406 MGET(n->m_next, M_DONTWAIT, n->m_type);
407 if (n->m_next == NULL)
408 goto fail;
409 n = n->m_next;
410 n->m_len = MLEN;
411 if (left >= MINCLSIZE) {
412 MCLGET(n, M_DONTWAIT);
413 if (n->m_flags & M_EXT)
414 n->m_len = n->m_ext.ext_size;
415 }
416 noff = 0;
417 continue;
418 }
419 }
420 if (len > left)
421 len = left;
422 if (txflag) {
423 awa->awa_encrypt(ctx, mtod(n, caddr_t) + noff,
424 mtod(m, caddr_t) + moff, len);
425 crc = awi_crc_update(crc, mtod(m, caddr_t) + moff, len);
426 } else {
427 awa->awa_decrypt(ctx, mtod(n, caddr_t) + noff,
428 mtod(m, caddr_t) + moff, len);
429 crc = awi_crc_update(crc, mtod(n, caddr_t) + noff, len);
430 }
431 left -= len;
432 moff += len;
433 noff += len;
434 }
435 crc = ~crc;
436 if (txflag) {
437 LE_WRITE_4(crcbuf, crc);
438 if (n->m_len >= noff + sizeof(crcbuf))
439 n->m_len = noff + sizeof(crcbuf);
440 else {
441 n->m_len = noff;
442 MGET(n->m_next, M_DONTWAIT, n->m_type);
443 if (n->m_next == NULL)
444 goto fail;
445 n = n->m_next;
446 n->m_len = sizeof(crcbuf);
447 noff = 0;
448 }
449 awa->awa_encrypt(ctx, mtod(n, caddr_t) + noff, crcbuf,
450 sizeof(crcbuf));
451 } else {
452 n->m_len = noff;
453 noff = 0;
454 for (; noff < sizeof(crcbuf); noff += len, m = m->m_next) {
455 if (m->m_len < moff + len)
456 len = m->m_len - moff;
457 if (len == 0)
458 continue;
459 awa->awa_decrypt(ctx, crcbuf + noff,
460 mtod(m, caddr_t) + moff, len);
461 }
462 if (crc != LE_READ_4(crcbuf))
463 goto fail;
464 }
465 m_freem(m0);
466 return n0;
467
468 fail:
469 m_freem(m0);
470 m_freem(n0);
471 return NULL;
472 }
473
474
475
476
477
478
479 static u_int32_t awi_crc_table[256];
480 static int awi_crc_table_computed = 0;
481
482
483 static void
484 awi_crc_init()
485 {
486 u_int32_t c;
487 int n, k;
488
489 if (awi_crc_table_computed)
490 return;
491 for (n = 0; n < 256; n++) {
492 c = (u_int32_t)n;
493 for (k = 0; k < 8; k++) {
494 if (c & 1)
495 c = 0xedb88320UL ^ (c >> 1);
496 else
497 c = c >> 1;
498 }
499 awi_crc_table[n] = c;
500 }
501 awi_crc_table_computed = 1;
502 }
503
504
505
506
507
508
509
510 static u_int32_t
511 awi_crc_update(crc, buf, len)
512 u_int32_t crc;
513 u_int8_t *buf;
514 int len;
515 {
516 u_int8_t *endbuf;
517
518 for (endbuf = buf + len; buf < endbuf; buf++)
519 crc = awi_crc_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
520 return crc;
521 }
522
523
524
525
526
527 static int
528 awi_null_ctxlen()
529 {
530
531 return 0;
532 }
533
534 static void
535 awi_null_setkey(ctx, key, keylen)
536 void *ctx;
537 u_char *key;
538 int keylen;
539 {
540 }
541
542 static void
543 awi_null_copy(ctx, dst, src, len)
544 void *ctx;
545 u_char *dst;
546 u_char *src;
547 int len;
548 {
549
550 memcpy(dst, src, len);
551 }