2 #include "../port/lib.h"
8 #include "../port/error.h"
9 #include "../port/netif.h"
16 typedef struct SNAP SNAP;
27 WIFIHDRSIZE = 2+2+3*6+2,
31 static char Sconn[] = "connecting";
32 static char Sauth[] = "authenticated";
33 static char Sneedauth[] = "need authentication";
34 static char Sunauth[] = "unauthenticated";
36 static char Sassoc[] = "associated";
37 static char Sunassoc[] = "unassociated";
38 static char Sblocked[] = "blocked"; /* no keys negotiated. only pass EAPOL frames */
40 static uchar basicrates[] = {
41 0x80 | 2, /* 1.0 Mb/s */
42 0x80 | 4, /* 2.0 Mb/s */
43 0x80 | 11, /* 5.5 Mb/s */
44 0x80 | 22, /* 11.0 Mb/s */
49 static Block* wifidecrypt(Wifi *, Wnode *, Block *);
50 static Block* wifiencrypt(Wifi *, Wnode *, Block *);
51 static void freewifikeys(Wifi *, Wnode *);
56 if((w->fc[1] & 0x02) == 0)
58 if((w->fc[1] & 0x01) == 0)
65 if((w->fc[1] & 0x01) != 0)
71 wifihdrlen(Wifipkt *w)
76 if((w->fc[0] & 0x0c) == 0x08)
77 if((w->fc[0] & 0xf0) == 0x80){ /* QOS */
82 if((w->fc[1] & 3) == 0x03)
88 wifiiq(Wifi *wifi, Block *b)
95 if(BLEN(b) < WIFIHDRSIZE)
98 hdrlen = wifihdrlen(w);
106 switch(w->fc[0] & 0x0c){
107 case 0x00: /* management */
108 if((w->fc[1] & 3) != 0x00) /* STA->STA */
112 case 0x04: /* control */
114 case 0x08: /* data */
116 switch(w->fc[0] & 0xf0){
123 if(BLEN(b) < SNAPHDRSIZE)
125 memmove(&s, b->rp, SNAPHDRSIZE);
126 if(s.dsap != 0xAA || s.ssap != 0xAA || s.control != 3)
128 if(s.orgcode[0] != 0 || s.orgcode[1] != 0 || s.orgcode[2] != 0)
130 b->rp += SNAPHDRSIZE-ETHERHDRSIZE;
132 e = (Etherpkt*)b->rp;
133 memmove(e->d, dstaddr(&h), Eaddrlen);
134 memmove(e->s, srcaddr(&h), Eaddrlen);
135 memmove(e->type, s.type, 2);
136 etheriq(wifi->ether, b, 1);
144 wifitx(Wifi *wifi, Wnode *wn, Block *b)
149 wn->lastsend = MACHP(0)->ticks;
151 seq = incref(&wifi->txseq);
160 if((w->fc[0] & 0x0c) != 0x00){
161 b = wifiencrypt(wifi, wn, b);
166 if((wn->txcount++ & 255) == 255){
167 if(wn->actrate != nil && wn->actrate < wn->maxrate)
171 (*wifi->transmit)(wifi, wn, b);
175 nodelookup(Wifi *wifi, uchar *bssid, int new)
179 if(memcmp(bssid, wifi->ether->bcast, Eaddrlen) == 0)
181 if((wn = wifi->bss) != nil){
182 if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){
183 wn->lastseen = MACHP(0)->ticks;
187 if((nn = wifi->node) == wn)
189 for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){
192 if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){
193 wn->lastseen = MACHP(0)->ticks;
196 if((long)(wn->lastseen - nn->lastseen) < 0)
201 freewifikeys(wifi, nn);
202 memset(nn, 0, sizeof(Wnode));
203 memmove(nn->bssid, bssid, Eaddrlen);
204 nn->lastseen = MACHP(0)->ticks;
209 wifitxfail(Wifi *wifi, Block *b)
217 wn = nodelookup(wifi, w->a1, 0);
221 if(wn->actrate != nil && wn->actrate > wn->minrate)
226 putrates(uchar *p, uchar *rates)
230 n = m = strlen((char*)rates);
233 /* supported rates */
236 memmove(p, rates, n);
239 /* extended supported rates */
242 memmove(p, rates, m);
249 wifiprobe(Wifi *wifi, Wnode *wn)
256 n = strlen(wifi->essid);
258 /* no specific essid, just tell driver to tune channel */
259 (*wifi->transmit)(wifi, wn, nil);
263 b = allocb(WIFIHDRSIZE + 512);
265 w->fc[0] = 0x40; /* probe request */
266 w->fc[1] = 0x00; /* STA->STA */
267 memmove(w->a1, wifi->ether->bcast, Eaddrlen); /* ??? */
268 memmove(w->a2, wifi->ether->ea, Eaddrlen);
269 memmove(w->a3, wifi->ether->bcast, Eaddrlen);
270 b->wp += WIFIHDRSIZE;
275 memmove(p, wifi->essid, n);
278 p = putrates(p, wifi->rates);
280 *p++ = 3; /* ds parameter set */
289 sendauth(Wifi *wifi, Wnode *bss)
295 b = allocb(WIFIHDRSIZE + 3*2);
297 w->fc[0] = 0xB0; /* auth request */
298 w->fc[1] = 0x00; /* STA->STA */
299 memmove(w->a1, bss->bssid, Eaddrlen); /* ??? */
300 memmove(w->a2, wifi->ether->ea, Eaddrlen);
301 memmove(w->a3, bss->bssid, Eaddrlen);
302 b->wp += WIFIHDRSIZE;
308 *p++ = 0; /* status */
314 wifitx(wifi, bss, b);
318 sendassoc(Wifi *wifi, Wnode *bss)
325 b = allocb(WIFIHDRSIZE + 512);
327 w->fc[0] = 0x00; /* assoc request */
328 w->fc[1] = 0x00; /* STA->STA */
329 memmove(w->a1, bss->bssid, Eaddrlen); /* ??? */
330 memmove(w->a2, wifi->ether->ea, Eaddrlen);
331 memmove(w->a3, bss->bssid, Eaddrlen);
332 b->wp += WIFIHDRSIZE;
334 *p++ = 1; /* capinfo */
336 *p++ = 16; /* interval */
339 n = strlen(bss->ssid);
342 memmove(p, bss->ssid, n);
345 p = putrates(p, wifi->rates);
349 memmove(p, bss->rsne, n);
354 wifitx(wifi, bss, b);
358 setstatus(Wifi *wifi, Wnode *wn, char *new)
364 if(wifi->debug && new != old)
365 print("#l%d: status %E: %s -> %s (from pc=%#p)\n",
373 recvassoc(Wifi *wifi, Wnode *wn, uchar *d, int len)
385 wn->aid = d[0] | d[1]<<8;
387 setstatus(wifi, wn, Sblocked);
389 setstatus(wifi, wn, Sassoc);
393 setstatus(wifi, wn, Sunassoc);
398 recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len)
400 static uchar wpa1oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
408 d += 8; /* timestamp */
409 wn->ival = d[0] | d[1]<<8;
411 wn->cap = d[0] | d[1]<<8;
415 for(e = d + len; d+2 <= e; d = x){
419 break; /* truncated */
424 while(len < Essidlen && d+len < x && d[len] != 0)
428 if(len != strlen(wn->ssid) || strncmp(wn->ssid, (char*)d, len) != 0){
429 strncpy(wn->ssid, (char*)d, len);
433 case 1: /* supported rates */
434 case 50: /* extended rates */
435 if(wn->minrate != nil || wn->maxrate != nil || wifi->rates == nil)
436 break; /* already set */
439 for(p = wifi->rates; *p != 0; p++){
440 if((*p & 0x7f) == t){
441 if(wn->minrate == nil || t < (*wn->minrate & 0x7f))
443 if(wn->maxrate == nil || t > (*wn->maxrate & 0x7f))
448 wn->actrate = wn->maxrate;
451 case 3: /* DSPARAMS */
455 case 221: /* vendor specific */
457 if(rsnset || len < sizeof(wpa1oui) || memcmp(d, wpa1oui, sizeof(wpa1oui)) != 0)
460 case 48: /* RSN information */
462 memmove(wn->brsne, &d[-2], len);
471 freewifikeys(Wifi *wifi, Wnode *wn)
476 for(i=0; i<nelem(wn->rxkey); i++){
477 secfree(wn->rxkey[i]);
480 for(i=0; i<nelem(wn->txkey); i++){
481 secfree(wn->txkey[i]);
484 wunlock(&wifi->crypt);
488 wifideauth(Wifi *wifi, Wnode *wn)
494 /* deassociate node, clear keys */
495 setstatus(wifi, wn, Sunauth);
496 freewifikeys(wifi, wn);
500 /* notify driver about node aid association */
501 (*wifi->transmit)(wifi, wn, nil);
503 /* notify aux/wpa with a zero length write that we got deassociated from the ap */
505 for(i=0; i<ether->nfile; i++){
507 if(f == nil || f->in == nil || f->inuse == 0 || f->type != 0x888e)
514 /* check if a node qualifies as our bss matching bssid and essid */
516 goodbss(Wifi *wifi, Wnode *wn)
518 if(memcmp(wifi->bssid, wifi->ether->bcast, Eaddrlen) != 0){
519 if(memcmp(wifi->bssid, wn->bssid, Eaddrlen) != 0)
520 return 0; /* bssid doesnt match */
521 } else if(wifi->essid[0] == 0)
522 return 0; /* both bssid and essid unspecified */
523 if(wifi->essid[0] != 0 && strcmp(wifi->essid, wn->ssid) != 0)
524 return 0; /* essid doesnt match */
546 if((b = qbread(wifi->iq, 100000)) == nil)
551 if((wn = nodelookup(wifi, w->a2, 0)) == nil)
553 if((b = wifidecrypt(wifi, wn, b)) != nil){
563 if((w->fc[0] & 0x0c) != 0x00)
566 switch(w->fc[0] & 0xf0){
567 case 0x50: /* probe response */
569 print("#l%d: got probe from %E\n", wifi->ether->ctlrno, w->a3);
571 case 0x80: /* beacon */
572 if((wn = nodelookup(wifi, w->a3, 1)) == nil)
574 b->rp += wifihdrlen(w);
575 recvbeacon(wifi, wn, b->rp, BLEN(b));
578 && TK2MS(MACHP(0)->ticks - wn->lastsend) > 1000
579 && goodbss(wifi, wn)){
580 setstatus(wifi, wn, Sconn);
582 wifi->lastauth = wn->lastsend;
587 if(memcmp(w->a1, wifi->ether->ea, Eaddrlen))
589 if((wn = nodelookup(wifi, w->a3, 0)) == nil)
591 switch(w->fc[0] & 0xf0){
592 case 0x10: /* assoc response */
593 case 0x30: /* reassoc response */
594 b->rp += wifihdrlen(w);
595 recvassoc(wifi, wn, b->rp, BLEN(b));
596 /* notify driver about node aid association */
598 (*wifi->transmit)(wifi, wn, nil);
600 case 0xb0: /* auth */
602 print("#l%d: got auth from %E\n", wifi->ether->ctlrno, wn->bssid);
603 if(wn->brsnelen > 0 && wn->rsnelen == 0)
604 setstatus(wifi, wn, Sneedauth);
606 setstatus(wifi, wn, Sauth);
607 if(wifi->bss == nil && goodbss(wifi, wn)){
609 if(wn->status == Sauth)
613 case 0xc0: /* deauth */
615 print("#l%d: got deauth from %E\n", wifi->ether->ctlrno, wn->bssid);
616 wifideauth(wifi, wn);
620 pexit("wifi in queue closed", 1);
624 wifietheroq(Wifi *wifi, Block *b)
632 if(BLEN(b) < ETHERHDRSIZE)
634 if((wn = wifi->bss) == nil)
637 memmove(&e, b->rp, ETHERHDRSIZE);
638 b->rp += ETHERHDRSIZE;
640 if(wn->status == Sblocked){
641 /* only pass EAPOL frames when port is blocked */
642 if((e.type[0]<<8 | e.type[1]) != 0x888e)
644 } else if(wn->status != Sassoc)
647 h.fc[0] = 0x08; /* data */
648 memmove(h.a1, wn->bssid, Eaddrlen);
649 if(memcmp(e.s, wifi->ether->ea, Eaddrlen) == 0) {
650 h.fc[1] = 0x01; /* STA->AP */
652 h.fc[1] = 0x03; /* AP->AP (WDS) */
653 memmove(h.a2, wifi->ether->ea, Eaddrlen);
655 memmove(dstaddr(&h), e.d, Eaddrlen);
656 memmove(srcaddr(&h), e.s, Eaddrlen);
658 hdrlen = wifihdrlen(&h);
659 b = padblock(b, hdrlen + SNAPHDRSIZE);
660 memmove(b->rp, &h, hdrlen);
661 s = (SNAP*)(b->rp + hdrlen);
662 s->dsap = s->ssap = 0xAA;
667 memmove(s->type, e.type, 2);
686 while((b = qbread(ether->oq, 1000000)) != nil)
687 wifietheroq(wifi, b);
688 pexit("ether out queue closed", 1);
705 memset(wn, 0, sizeof(*wn));
706 memmove(wn->bssid, ether->bcast, Eaddrlen);
711 /* scan for access point */
712 while(wifi->bss == nil){
714 wnscan.channel = 1 + ((wnscan.channel+4) % 13);
715 wifiprobe(wifi, &wnscan);
717 tsleep(&up->sleep, return0, 0, 200);
718 now = MACHP(0)->ticks;
719 } while(TK2MS(now-wifi->lastauth) < 1000);
722 /* maintain access point */
724 while((wn = wifi->bss) != nil){
725 ether->link = (wn->status == Sassoc) || (wn->status == Sblocked);
726 if(ether->link && (rate = wn->actrate) != nil)
727 ether->mbps = ((*rate & 0x7f)+1)/2;
728 now = MACHP(0)->ticks;
729 if(wn->status != Sneedauth && TK2SEC(now - wn->lastseen) > 60 || goodbss(wifi, wn) == 0){
730 wifideauth(wifi, wn);
734 if(TK2MS(now - wn->lastsend) > 1000){
735 if(wn->status == Sauth && (++tmout & 7) == 0)
736 wifideauth(wifi, wn); /* stuck in auth, start over */
737 if(wn->status == Sconn || wn->status == Sunauth)
739 if(wn->status == Sauth)
742 tsleep(&up->sleep, return0, 0, 500);
748 wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
753 wifi = malloc(sizeof(Wifi));
756 wifi->iq = qopen(ether->limit, 0, 0, 0);
762 wifi->transmit = transmit;
764 wifi->rates = basicrates;
767 memmove(wifi->bssid, ether->bcast, Eaddrlen);
769 wifi->lastauth = MACHP(0)->ticks;
771 snprint(name, sizeof(name), "#l%dwifi", ether->ctlrno);
772 kproc(name, wifiproc, wifi);
773 snprint(name, sizeof(name), "#l%dwifo", ether->ctlrno);
774 kproc(name, wifoproc, wifi);
775 snprint(name, sizeof(name), "#l%dwifs", ether->ctlrno);
776 kproc(name, wifsproc, wifi);
782 hextob(char *s, char **sp, uchar *b, int n)
787 for(r = 0; r < n && *s; s++){
789 if(*s >= '0' && *s <= '9')
791 else if(*s >= 'a' && *s <= 'f')
793 else if(*s >= 'A' && *s <= 'F')
804 static char *ciphers[] = {
818 strncpy(buf, s, sizeof(buf)-1);
819 buf[sizeof(buf)-1] = 0;
820 if((p = strchr(buf, ':')) != nil)
824 n = hextob(p, &p, key, sizeof(key));
825 for(i=0; i<nelem(ciphers); i++)
826 if(strcmp(ciphers[i], buf) == 0)
830 k = secalloc(sizeof(Wkey));
835 k = secalloc(sizeof(Wkey) + n);
836 memmove(k->key, key, n);
841 k = secalloc(sizeof(Wkey) + sizeof(AESstate));
842 setupAESstate((AESstate*)k->key, key, n, nil);
847 memset(key, 0, sizeof(key));
849 k->tsc = strtoull(++p, nil, 16);
856 wificfg(Wifi *wifi, char *opt)
861 if(strncmp(opt, "debug=", 6))
862 if(strncmp(opt, "essid=", 6))
863 if(strncmp(opt, "bssid=", 6))
865 if((p = strchr(opt, '=')) == nil)
869 n = snprint(buf, sizeof(buf), "%.*s %q", (int)(p - opt), opt, p+1);
870 wifictl(wifi, buf, n);
887 static Cmdtab wifictlmsg[] =
894 CMrxkey0, "rxkey0", 0, /* group keys */
895 CMrxkey1, "rxkey1", 0,
896 CMrxkey2, "rxkey2", 0,
897 CMrxkey3, "rxkey3", 0,
899 CMrxkey4, "rxkey", 0, /* peerwise keys */
900 CMtxkey0, "txkey", 0,
902 CMtxkey0, "txkey0", 0,
906 wifictl(Wifi *wifi, void *buf, long n)
908 uchar addr[Eaddrlen];
920 print("#l%d: wifictl: %.*s\n", wifi->ether->ctlrno, (int)n, buf);
921 memmove(addr, wifi->ether->bcast, Eaddrlen);
923 cb = parsecmd(buf, n);
924 ct = lookupcmd(cb, wifictlmsg, nelem(wifictlmsg));
925 if(ct->index >= CMauth){
926 if(cb->nf > 1 && (ct->index == CMbssid || ct->index >= CMrxkey0)){
927 if(parseether(addr, cb->f[1]) == 0){
930 wn = nodelookup(wifi, addr, 0);
933 if(wn == nil && ct->index != CMbssid)
934 error("missing node");
939 wifi->debug = atoi(cb->f[1]);
942 print("#l%d: debug: %d\n", wifi->ether->ctlrno, wifi->debug);
946 strncpy(wifi->essid, cb->f[1], Essidlen);
952 if(goodbss(wifi, wn))
954 wifideauth(wifi, wn);
957 if(wifi->essid[0] == 0 && memcmp(wifi->bssid, wifi->ether->bcast, Eaddrlen) == 0)
959 for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++)
960 if(goodbss(wifi, wn)){
961 setstatus(wifi, wn, Sconn);
966 memmove(wifi->bssid, addr, Eaddrlen);
969 freewifikeys(wifi, wn);
973 wn->rsnelen = hextob(cb->f[1], nil, wn->rsne, sizeof(wn->rsne));
975 setstatus(wifi, wn, Sconn);
978 setstatus(wifi, wn, Sauth);
982 case CMrxkey0: case CMrxkey1: case CMrxkey2: case CMrxkey3: case CMrxkey4:
986 k = parsekey(cb->f[1]);
989 memset(cb->f[1], 0, strlen(cb->f[1]));
994 if(ct->index < CMtxkey0)
995 kk = &wn->rxkey[ct->index - CMrxkey0];
997 kk = &wn->txkey[ct->index - CMtxkey0];
1001 wunlock(&wifi->crypt);
1002 if(ct->index >= CMtxkey0 && wn->status == Sblocked)
1003 setstatus(wifi, wn, Sassoc);
1012 wifistat(Wifi *wifi, void *buf, long n, ulong off)
1014 static uchar zeros[Eaddrlen];
1021 p = s = smalloc(4096);
1026 p = seprint(p, e, "essid: %s\n", wn->ssid);
1027 p = seprint(p, e, "bssid: %E\n", wn->bssid);
1028 p = seprint(p, e, "status: %s\n", wn->status);
1029 p = seprint(p, e, "channel: %.2d\n", wn->channel);
1031 /* only print key ciphers and key length */
1032 rlock(&wifi->crypt);
1033 for(i = 0; i<nelem(wn->rxkey); i++){
1034 if((k = wn->rxkey[i]) != nil)
1035 p = seprint(p, e, "rxkey%d: %s:[%d]\n", i,
1036 ciphers[k->cipher], k->len);
1038 for(i = 0; i<nelem(wn->txkey); i++){
1039 if((k = wn->txkey[i]) != nil)
1040 p = seprint(p, e, "txkey%d: %s:[%d]\n", i,
1041 ciphers[k->cipher], k->len);
1043 runlock(&wifi->crypt);
1045 if(wn->brsnelen > 0){
1046 p = seprint(p, e, "brsne: ");
1047 for(i=0; i<wn->brsnelen; i++)
1048 p = seprint(p, e, "%.2X", wn->brsne[i]);
1049 p = seprint(p, e, "\n");
1052 p = seprint(p, e, "essid: %s\n", wifi->essid);
1053 p = seprint(p, e, "bssid: %E\n", wifi->bssid);
1056 now = MACHP(0)->ticks;
1057 for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){
1058 if(wn->lastseen == 0)
1060 p = seprint(p, e, "node: %E %.4x %-11ld %.2d %s\n",
1061 wn->bssid, wn->cap, TK2MS(now - wn->lastseen), wn->channel, wn->ssid);
1063 n = readstr(off, buf, n, s);
1068 static void tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1069 static int tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1070 static void ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1071 static int ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1074 wifiencrypt(Wifi *wifi, Wnode *wn, Block *b)
1081 rlock(&wifi->crypt);
1086 runlock(&wifi->crypt);
1090 n = wifihdrlen((Wifipkt*)b->rp);
1093 b = padblock(b, -(8+4));
1095 w = (Wifipkt*)b->rp;
1096 memmove(w, b->rp+8, n);
1104 b->rp[1] = (b->rp[0] | 0x20) & 0x7f;
1106 b->rp[3] = kid<<6 | 0x20;
1112 tkipencrypt(k, w, b, tsc);
1118 b->rp[3] = kid<<6 | 0x20;
1124 ccmpencrypt(k, w, b, tsc);
1127 runlock(&wifi->crypt);
1135 wifidecrypt(Wifi *wifi, Wnode *wn, Block *b)
1142 rlock(&wifi->crypt);
1144 w = (Wifipkt*)b->rp;
1151 if((b->rp[3] & 0x20) == 0)
1153 if((w->a1[0] & 1) == 0)
1154 kid = 4; /* use peerwise key for non-unicast */
1161 tsc = (uvlong)b->rp[7]<<40 |
1162 (uvlong)b->rp[6]<<32 |
1163 (uvlong)b->rp[5]<<24 |
1164 (uvlong)b->rp[4]<<16 |
1165 (uvlong)b->rp[0]<<8 |
1170 if(tkipdecrypt(k, w, b, tsc) != 0)
1174 tsc = (uvlong)b->rp[7]<<40 |
1175 (uvlong)b->rp[6]<<32 |
1176 (uvlong)b->rp[5]<<24 |
1177 (uvlong)b->rp[4]<<16 |
1178 (uvlong)b->rp[1]<<8 |
1183 if(ccmpdecrypt(k, w, b, tsc) != 0)
1188 runlock(&wifi->crypt);
1192 runlock(&wifi->crypt);
1196 memmove(b->rp, w, n);
1197 w = (Wifipkt*)b->rp;
1202 static u16int Sbox[256] = {
1203 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
1204 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
1205 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
1206 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
1207 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
1208 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
1209 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
1210 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
1211 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
1212 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
1213 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
1214 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
1215 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
1216 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
1217 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
1218 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
1219 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
1220 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
1221 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
1222 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
1223 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
1224 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
1225 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
1226 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
1227 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
1228 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
1229 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
1230 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
1231 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
1232 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
1233 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
1234 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A
1238 tkipk2tk(uchar key[16], u16int tk[8])
1240 tk[0] = (u16int)key[1]<<8 | key[0];
1241 tk[1] = (u16int)key[3]<<8 | key[2];
1242 tk[2] = (u16int)key[5]<<8 | key[4];
1243 tk[3] = (u16int)key[7]<<8 | key[6];
1244 tk[4] = (u16int)key[9]<<8 | key[8];
1245 tk[5] = (u16int)key[11]<<8 | key[10];
1246 tk[6] = (u16int)key[13]<<8 | key[12];
1247 tk[7] = (u16int)key[15]<<8 | key[14];
1251 tkipphase1(u32int tscu, uchar ta[Eaddrlen], u16int tk[8], u16int p1k[5])
1253 u16int *k, i, x0, x1, x2;
1257 p1k[2] = (u16int)ta[1]<<8 | ta[0];
1258 p1k[3] = (u16int)ta[3]<<8 | ta[2];
1259 p1k[4] = (u16int)ta[5]<<8 | ta[4];
1266 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1270 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1274 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1278 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1282 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1290 tkipphase2(u16int tscl, u16int p1k[5], u16int tk[8], uchar rc4key[16])
1292 u16int ppk[6], x0, x1, x2;
1299 ppk[5] = p1k[4] + tscl;
1301 x0 = ppk[5] ^ tk[0];
1303 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1305 x0 = ppk[0] ^ tk[1];
1307 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1309 x0 = ppk[1] ^ tk[2];
1311 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1313 x0 = ppk[2] ^ tk[3];
1315 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1317 x0 = ppk[3] ^ tk[4];
1319 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1321 x0 = ppk[4] ^ tk[5];
1323 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1326 x2 = ppk[5] ^ tk[6];
1327 ppk[0] += (x2 >> 1) | (x2 << 15);
1328 x2 = ppk[0] ^ tk[7];
1329 ppk[1] += (x2 >> 1) | (x2 << 15);
1332 ppk[2] += (x2 >> 1) | (x2 << 15);
1334 ppk[3] += (x2 >> 1) | (x2 << 15);
1336 ppk[4] += (x2 >> 1) | (x2 << 15);
1338 ppk[5] += (x2 >> 1) | (x2 << 15);
1340 rc4key[0] = tscl >> 8;
1341 rc4key[1] = (rc4key[0] | 0x20) & 0x7F;
1343 rc4key[3] = (ppk[5] ^ tk[0]) >> 1;
1345 rc4key[5] = ppk[0] >> 8;
1347 rc4key[7] = ppk[1] >> 8;
1349 rc4key[9] = ppk[2] >> 8;
1350 rc4key[10] = ppk[3];
1351 rc4key[11] = ppk[3] >> 8;
1352 rc4key[12] = ppk[4];
1353 rc4key[13] = ppk[4] >> 8;
1354 rc4key[14] = ppk[5];
1355 rc4key[15] = ppk[5] >> 8;
1358 typedef struct MICstate MICstate;
1368 micsetup(MICstate *s, uchar key[8])
1370 s->l = (u32int)key[0] |
1372 (u32int)key[2]<<16 |
1374 s->r = (u32int)key[4] |
1376 (u32int)key[6]<<16 |
1383 micupdate(MICstate *s, uchar *data, ulong len)
1385 u32int l, r, m, n, e;
1394 m |= (u32int)*data++ << 24;
1398 r ^= (l << 17) | (l >> 15);
1400 r ^= ((l & 0x00FF00FFUL)<<8) | ((l & 0xFF00FF00UL)>>8);
1402 r ^= (l << 3) | (l >> 29);
1404 r ^= (l >> 2) | (l << 30);
1414 micfinish(MICstate *s, uchar mic[8])
1416 static uchar pad[8] = { 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
1418 micupdate(s, pad, sizeof(pad));
1430 static uchar pad4[4] = { 0x00, 0x00, 0x00, 0x00, };
1433 tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1435 u16int tk[8], p1k[5];
1441 micsetup(&ms, k->key+24);
1442 micupdate(&ms, dstaddr(w), Eaddrlen);
1443 micupdate(&ms, srcaddr(w), Eaddrlen);
1444 micupdate(&ms, pad4, 4);
1445 micupdate(&ms, b->rp, BLEN(b));
1446 micfinish(&ms, b->wp);
1449 crc = ethercrc(b->rp, BLEN(b));
1457 tkipk2tk(k->key, tk);
1458 tkipphase1(tsc >> 16, w->a2, tk, p1k);
1459 tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
1460 setupRC4state(&rs, seed, sizeof(seed));
1461 rc4(&rs, b->rp, BLEN(b));
1465 tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1467 uchar seed[16], mic[8];
1468 u16int tk[8], p1k[5];
1476 tkipk2tk(k->key, tk);
1477 tkipphase1(tsc >> 16, w->a2, tk, p1k);
1478 tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
1479 setupRC4state(&rs, seed, sizeof(seed));
1480 rc4(&rs, b->rp, BLEN(b));
1483 crc = (ulong)b->wp[0] |
1484 (ulong)b->wp[1]<<8 |
1485 (ulong)b->wp[2]<<16 |
1486 (ulong)b->wp[3]<<24;
1488 crc ^= ethercrc(b->rp, BLEN(b));
1491 micsetup(&ms, k->key+16);
1492 micupdate(&ms, dstaddr(w), Eaddrlen);
1493 micupdate(&ms, srcaddr(w), Eaddrlen);
1494 micupdate(&ms, pad4, 4);
1495 micupdate(&ms, b->rp, BLEN(b));
1496 micfinish(&ms, mic);
1498 return tsmemcmp(b->wp, mic, 8) | crc;
1502 putbe(uchar *p, int L, uint v)
1505 *p++ = (v >> L*8) & 0xFF;
1510 xblock(int L, int M, uchar *N, uchar *a, int la, int lm, uchar t[16], AESstate *s)
1512 uchar l[8], *p, *x, *e;
1514 assert(M >= 4 && M <= 16);
1515 assert(L >= 2 && L <= 4);
1517 t[0] = ((la > 0)<<6) | ((M-2)/2)<<3 | (L-1); /* flags */
1518 memmove(&t[1], N, 15-L);
1519 putbe(&t[16-L], L, lm);
1520 aes_encrypt(s->ekey, s->rounds, t, t);
1523 assert(la < 0xFF00);
1524 for(p = l, e = putbe(l, 2, la), x = t; p < e; x++, p++)
1526 for(e = a + la; a < e; x = t){
1527 for(; a < e && x < &t[16]; x++, a++)
1529 aes_encrypt(s->ekey, s->rounds, t, t);
1535 sblock(int L, uchar *N, uint i, uchar b[16], AESstate *s)
1537 b[0] = L-1; /* flags */
1538 memmove(&b[1], N, 15-L);
1539 putbe(&b[16-L], L, i);
1540 aes_encrypt(s->ekey, s->rounds, b, b);
1545 aesCCMencrypt(int L, int M, uchar *N /* N[15-L] */,
1546 uchar *a /* a[la] */, int la,
1547 uchar *m /* m[lm+M] */, int lm,
1550 uchar t[16], b[16], *p, *x;
1553 xblock(L, M, N, a, la, lm, t, s);
1555 for(i = 1; lm >= 16; i++, m += 16, lm -= 16){
1556 sblock(L, N, i, b, s);
1558 *((u32int*)&t[0]) ^= *((u32int*)&m[0]);
1559 *((u32int*)&m[0]) ^= *((u32int*)&b[0]);
1560 *((u32int*)&t[4]) ^= *((u32int*)&m[4]);
1561 *((u32int*)&m[4]) ^= *((u32int*)&b[4]);
1562 *((u32int*)&t[8]) ^= *((u32int*)&m[8]);
1563 *((u32int*)&m[8]) ^= *((u32int*)&b[8]);
1564 *((u32int*)&t[12]) ^= *((u32int*)&m[12]);
1565 *((u32int*)&m[12]) ^= *((u32int*)&b[12]);
1567 aes_encrypt(s->ekey, s->rounds, t, t);
1570 for(p = sblock(L, N, i, b, s), x = t; p < &b[lm]; x++, m++, p++){
1574 aes_encrypt(s->ekey, s->rounds, t, t);
1577 for(p = sblock(L, N, 0, b, s), x = t; p < &b[M]; x++, p++)
1584 aesCCMdecrypt(int L, int M, uchar *N /* N[15-L] */,
1585 uchar *a /* a[la] */, int la,
1586 uchar *m /* m[lm+M] */, int lm,
1589 uchar t[16], b[16], *p, *x;
1592 xblock(L, M, N, a, la, lm, t, s);
1594 for(i = 1; lm >= 16; i++, m += 16, lm -= 16){
1595 sblock(L, N, i, b, s);
1597 *((u32int*)&m[0]) ^= *((u32int*)&b[0]);
1598 *((u32int*)&t[0]) ^= *((u32int*)&m[0]);
1599 *((u32int*)&m[4]) ^= *((u32int*)&b[4]);
1600 *((u32int*)&t[4]) ^= *((u32int*)&m[4]);
1601 *((u32int*)&m[8]) ^= *((u32int*)&b[8]);
1602 *((u32int*)&t[8]) ^= *((u32int*)&m[8]);
1603 *((u32int*)&m[12]) ^= *((u32int*)&b[12]);
1604 *((u32int*)&t[12]) ^= *((u32int*)&m[12]);
1606 aes_encrypt(s->ekey, s->rounds, t, t);
1609 for(p = sblock(L, N, i, b, s), x = t; p < &b[lm]; x++, m++, p++){
1613 aes_encrypt(s->ekey, s->rounds, t, t);
1616 for(p = sblock(L, N, 0, b, s), x = t; p < &b[M]; x++, p++)
1619 return tsmemcmp(m, t, M);
1623 setupCCMP(Wifipkt *w, uvlong tsc, uchar nonce[13], uchar auth[32])
1627 nonce[0] = ((w->fc[0] & 0x0c) == 0x00) << 4;
1628 memmove(&nonce[1], w->a2, Eaddrlen);
1629 nonce[7] = tsc >> 40;
1630 nonce[8] = tsc >> 32;
1631 nonce[9] = tsc >> 24;
1632 nonce[10] = tsc >> 16;
1633 nonce[11] = tsc >> 8;
1637 *p++ = (w->fc[0] & (((w->fc[0] & 0x0c) == 0x08) ? 0x0f : 0xff));
1638 *p++ = (w->fc[1] & ~0x38) | 0x40;
1639 memmove(p, w->a1, Eaddrlen); p += Eaddrlen;
1640 memmove(p, w->a2, Eaddrlen); p += Eaddrlen;
1641 memmove(p, w->a3, Eaddrlen); p += Eaddrlen;
1642 *p++ = w->seq[0] & 0x0f;
1644 if((w->fc[1] & 3) == 0x03) {
1645 memmove(p, w->a4, Eaddrlen);
1653 ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1655 uchar auth[32], nonce[13];
1657 aesCCMencrypt(2, 8, nonce, auth,
1658 setupCCMP(w, tsc, nonce, auth),
1659 b->rp, BLEN(b), (AESstate*)k->key);
1664 ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1666 uchar auth[32], nonce[13];
1672 return aesCCMdecrypt(2, 8, nonce, auth,
1673 setupCCMP(w, tsc, nonce, auth),
1674 b->rp, BLEN(b), (AESstate*)k->key);