2 #include "../port/lib.h"
8 #include "../port/error.h"
9 #include "../port/netif.h"
10 #include "../port/etherif.h"
11 #include "../port/wifi.h"
15 typedef struct SNAP SNAP;
26 WIFIHDRSIZE = 2+2+3*6+2,
30 static char Sconn[] = "connecting";
31 static char Sauth[] = "authenticated";
32 static char Sneedauth[] = "need authentication";
33 static char Sunauth[] = "unauthenticated";
35 static char Sassoc[] = "associated";
36 static char Sunassoc[] = "unassociated";
37 static char Sblocked[] = "blocked"; /* no keys negotiated. only pass EAPOL frames */
39 static uchar basicrates[] = {
40 0x80 | 2, /* 1.0 Mb/s */
41 0x80 | 4, /* 2.0 Mb/s */
42 0x80 | 11, /* 5.5 Mb/s */
43 0x80 | 22, /* 11.0 Mb/s */
48 static Block* wifidecrypt(Wifi *, Wnode *, Block *);
49 static Block* wifiencrypt(Wifi *, Wnode *, Block *);
50 static void freewifikeys(Wifi *, Wnode *);
52 static void dmatproxy(Block *bp, int upstream, uchar proxy[Eaddrlen], DMAT *t);
57 if((w->fc[1] & 0x02) == 0)
59 if((w->fc[1] & 0x01) == 0)
66 if((w->fc[1] & 0x01) != 0)
72 wifihdrlen(Wifipkt *w)
77 if((w->fc[0] & 0x0c) == 0x08)
78 if((w->fc[0] & 0xf0) == 0x80){ /* QOS */
83 if((w->fc[1] & 3) == 0x03)
102 wifiiq(Wifi *wifi, Block *b)
109 if(b->flag & Btimestamp)
110 assert(b->rp - b->base >= 8);
111 if(BLEN(b) < WIFIHDRSIZE)
114 hdrlen = wifihdrlen(w);
117 if(memcmp(srcaddr(w), wifi->ether->ea, Eaddrlen) == 0)
124 switch(w->fc[0] & 0x0c){
125 case 0x00: /* management */
126 if((w->fc[1] & 3) != 0x00) /* STA->STA */
130 case 0x04: /* control */
132 case 0x08: /* data */
133 b->flag &= ~Btimestamp;
135 switch(w->fc[0] & 0xf0){
142 if(BLEN(b) < SNAPHDRSIZE)
144 memmove(&s, b->rp, SNAPHDRSIZE);
145 if(s.dsap != 0xAA || s.ssap != 0xAA || s.control != 3)
147 if(s.orgcode[0] != 0 || s.orgcode[1] != 0 || s.orgcode[2] != 0)
149 b->rp += SNAPHDRSIZE-ETHERHDRSIZE;
151 e = (Etherpkt*)b->rp;
152 memmove(e->d, dstaddr(&h), Eaddrlen);
153 memmove(e->s, srcaddr(&h), Eaddrlen);
154 memmove(e->type, s.type, 2);
155 dmatproxy(b, 0, wifi->ether->ea, &wifi->dmat);
156 etheriq(wifi->ether, b);
164 wifitx(Wifi *wifi, Wnode *wn, Block *b)
169 wn->lastsend = MACHP(0)->ticks;
171 seq = incref(&wifi->txseq);
180 if((w->fc[0] & 0x0c) != 0x00){
181 b = wifiencrypt(wifi, wn, b);
186 if((wn->txcount++ & 255) == 255 && wn->actrate != nil && wn->actrate != wn->maxrate){
189 for(a = wn->maxrate, p = wifi->rates; *p; p++){
190 if(*p < *a && *p > *wn->actrate && (wn->validrates & (1UL << p-wifi->rates)) != 0)
196 (*wifi->transmit)(wifi, wn, b);
200 nodelookup(Wifi *wifi, uchar *bssid, int new)
204 if(memcmp(bssid, wifi->ether->bcast, Eaddrlen) == 0)
206 if((wn = wifi->bss) != nil){
207 if(memcmp(wn->bssid, bssid, Eaddrlen) == 0)
210 if((nn = wifi->node) == wn)
212 for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){
215 if(memcmp(wn->bssid, bssid, Eaddrlen) == 0)
217 if((long)(wn->lastsend - nn->lastsend) < 0
218 || (long)(wn->lastseen - nn->lastseen) < 0)
223 freewifikeys(wifi, nn);
224 memset(nn, 0, sizeof(Wnode));
225 memmove(nn->bssid, bssid, Eaddrlen);
230 wifitxfail(Wifi *wifi, Block *b)
238 wn = nodelookup(wifi, w->a1, 0);
242 if(wn->actrate != nil && wn->minrate != wn->actrate){
245 for(a = wn->minrate, p = wifi->rates; *p; p++){
246 if(*p > *a && *p < *wn->actrate && (wn->validrates & (1UL << p-wifi->rates)) != 0)
254 putrates(uchar *p, uchar *rates, ulong valid, ulong basic)
260 for(i = n = 0; i < 32 && rates[i] != 0; i++)
267 /* supported rates */
270 for(i = j = 0; j < n; i++){
271 if(basic & (1UL<<i)){
272 *p++ = rates[i] | 0x80;
276 for(i = 0; j < n; i++){
277 if(valid & (1UL<<i)){
278 *p++ = rates[i] & 0x7f;
285 /* truncate supported rates element */
290 /* extended supported rates */
293 for(i = j = 0; j < n; i++){
294 if(basic & (1UL<<i)){
295 *p++ = rates[i] | 0x80;
299 for(i = 0; j < n; i++){
300 if(valid & (1UL<<i)){
301 *p++ = rates[i] & 0x7f;
311 wifiprobe(Wifi *wifi, Wnode *wn)
318 n = strlen(wifi->essid);
320 /* no specific essid, just tell driver to tune channel */
321 (*wifi->transmit)(wifi, wn, nil);
325 b = allocb(WIFIHDRSIZE + 512);
328 w->fc[0] = 0x40; /* probe request */
329 w->fc[1] = 0x00; /* STA->STA */
330 memmove(w->a1, wifi->ether->bcast, Eaddrlen); /* ??? */
331 memmove(w->a2, wifi->ether->ea, Eaddrlen);
332 memmove(w->a3, wifi->ether->bcast, Eaddrlen);
333 b->wp += WIFIHDRSIZE;
338 memmove(p, wifi->essid, n);
341 p = putrates(p, wifi->rates, wn->validrates, wn->basicrates);
343 *p++ = 3; /* ds parameter set */
352 sendauth(Wifi *wifi, Wnode *bss)
358 b = allocb(WIFIHDRSIZE + 3*2);
360 w->fc[0] = 0xB0; /* auth request */
361 w->fc[1] = 0x00; /* STA->STA */
362 memmove(w->a1, bss->bssid, Eaddrlen); /* ??? */
363 memmove(w->a2, wifi->ether->ea, Eaddrlen);
364 memmove(w->a3, bss->bssid, Eaddrlen);
365 b->wp += WIFIHDRSIZE;
371 *p++ = 0; /* status */
377 wifitx(wifi, bss, b);
381 sendassoc(Wifi *wifi, Wnode *bss)
388 b = allocb(WIFIHDRSIZE + 512);
390 w->fc[0] = 0x00; /* assoc request */
391 w->fc[1] = 0x00; /* STA->STA */
392 memmove(w->a1, bss->bssid, Eaddrlen); /* ??? */
393 memmove(w->a2, wifi->ether->ea, Eaddrlen);
394 memmove(w->a3, bss->bssid, Eaddrlen);
396 b->wp += WIFIHDRSIZE;
401 cap |= (1<<5); // Short Preamble
402 cap |= (1<<10) & bss->cap; // Short Slot Time
410 n = strlen(bss->ssid);
413 memmove(p, bss->ssid, n);
416 p = putrates(p, wifi->rates, bss->validrates, bss->basicrates);
420 memmove(p, bss->rsne, n);
425 wifitx(wifi, bss, b);
429 setstatus(Wifi *wifi, Wnode *wn, char *new)
435 if(wifi->debug && new != old)
436 print("#l%d: status %E: %.12ld %.12ld: %s -> %s (from pc=%#p)\n",
439 TK2MS(MACHP(0)->ticks), TK2MS(MACHP(0)->ticks - wn->lastsend),
445 recvassoc(Wifi *wifi, Wnode *wn, uchar *d, int len)
457 wn->aid = d[0] | d[1]<<8;
459 setstatus(wifi, wn, Sblocked);
461 setstatus(wifi, wn, Sassoc);
465 setstatus(wifi, wn, Sunassoc);
470 recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len)
472 static uchar wpa1oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
483 wn->ival = d[0] | d[1]<<8;
485 wn->cap = d[0] | d[1]<<8;
492 for(e = d + len; d+2 <= e; d = x){
496 break; /* truncated */
501 while(len < Essidlen && d+len < x && d[len] != 0)
505 if(len != strlen(wn->ssid) || strncmp(wn->ssid, (char*)d, len) != 0){
506 strncpy(wn->ssid, (char*)d, len);
510 case 1: /* supported rates */
511 case 50: /* extended rates */
512 if(wifi->rates == nil)
516 for(p = wifi->rates; *p != 0; p++){
518 wn->validrates |= 1UL << p-wifi->rates;
520 wn->basicrates |= 1UL << p-wifi->rates;
521 if(wn->minrate == nil || t < *wn->minrate)
523 if(wn->maxrate == nil || t > *wn->maxrate)
530 if(wn->actrate == nil)
531 wn->actrate = wn->maxrate;
533 case 3: /* DSPARAMS */
540 wn->dtimcount = d[0];
542 wn->dtimperiod = d[1];
544 case 221: /* vendor specific */
546 if(rsnset || len < sizeof(wpa1oui) || memcmp(d, wpa1oui, sizeof(wpa1oui)) != 0)
549 case 48: /* RSN information */
551 memmove(wn->brsne, &d[-2], len);
560 freewifikeys(Wifi *wifi, Wnode *wn)
565 for(i=0; i<nelem(wn->rxkey); i++){
566 secfree(wn->rxkey[i]);
569 for(i=0; i<nelem(wn->txkey); i++){
570 secfree(wn->txkey[i]);
573 wunlock(&wifi->crypt);
577 wifideauth(Wifi *wifi, Wnode *wn)
583 /* deassociate node, clear keys */
584 setstatus(wifi, wn, Sunauth);
585 freewifikeys(wifi, wn);
586 memset(&wifi->dmat, 0, sizeof(wifi->dmat));
590 /* notify driver about node aid association */
591 (*wifi->transmit)(wifi, wn, nil);
593 /* notify aux/wpa with a zero length packet that we got deassociated from the ap */
595 for(i=0; i<ether->nfile; i++){
597 if(f == nil || f->in == nil || f->inuse == 0 || f->type != 0x888e)
606 /* check if a node qualifies as our bss matching bssid and essid */
608 goodbss(Wifi *wifi, Wnode *wn)
610 if(memcmp(wifi->bssid, wifi->ether->bcast, Eaddrlen) != 0){
611 if(memcmp(wifi->bssid, wn->bssid, Eaddrlen) != 0)
612 return 0; /* bssid doesnt match */
613 } else if(wifi->essid[0] == 0)
614 return 0; /* both bssid and essid unspecified */
615 if(wifi->essid[0] != 0 && strcmp(wifi->essid, wn->ssid) != 0)
616 return 0; /* essid doesnt match */
638 if((b = qbread(wifi->iq, 100000)) == nil)
643 if((wn = nodelookup(wifi, w->a2, 0)) == nil)
645 wn->lastseen = MACHP(0)->ticks;
646 if((b = wifidecrypt(wifi, wn, b)) != nil){
650 b->flag &= ~Btimestamp;
657 if((w->fc[0] & 0x0c) != 0x00)
660 switch(w->fc[0] & 0xf0){
661 case 0x50: /* probe response */
663 print("#l%d: got probe from %E\n", wifi->ether->ctlrno, w->a3);
665 case 0x80: /* beacon */
666 if((wn = nodelookup(wifi, w->a3, 1)) == nil)
668 wn->lastseen = MACHP(0)->ticks;
669 if(b->flag & Btimestamp)
670 wn->rs = getts(b->rp - 8);
671 b->rp += wifihdrlen(w);
672 recvbeacon(wifi, wn, b->rp, BLEN(b));
675 && TK2MS(MACHP(0)->ticks - wn->lastsend) > 1000
676 && goodbss(wifi, wn)){
677 setstatus(wifi, wn, Sconn);
679 wifi->lastauth = wn->lastsend;
684 if(memcmp(w->a1, wifi->ether->ea, Eaddrlen))
686 if((wn = nodelookup(wifi, w->a3, 0)) == nil)
688 wn->lastseen = MACHP(0)->ticks;
689 if(b->flag & Btimestamp)
690 wn->rs = getts(b->rp - 8);
691 switch(w->fc[0] & 0xf0){
692 case 0x10: /* assoc response */
693 case 0x30: /* reassoc response */
694 b->rp += wifihdrlen(w);
695 recvassoc(wifi, wn, b->rp, BLEN(b));
696 /* notify driver about node aid association */
698 (*wifi->transmit)(wifi, wn, nil);
700 case 0xb0: /* auth */
702 print("#l%d: got auth from %E\n", wifi->ether->ctlrno, wn->bssid);
703 if(wn->brsnelen > 0 && wn->rsnelen == 0)
704 setstatus(wifi, wn, Sneedauth);
706 setstatus(wifi, wn, Sauth);
707 if(wifi->bss == nil && goodbss(wifi, wn)){
709 if(wn->status == Sauth)
713 case 0xc0: /* deauth */
715 print("#l%d: got deauth from %E\n", wifi->ether->ctlrno, wn->bssid);
716 wifideauth(wifi, wn);
720 pexit("wifi in queue closed", 1);
724 wifietheroq(Wifi *wifi, Block *b)
732 if(BLEN(b) < ETHERHDRSIZE)
734 if((wn = wifi->bss) == nil)
737 dmatproxy(b, 1, wifi->ether->ea, &wifi->dmat);
739 memmove(&e, b->rp, ETHERHDRSIZE);
740 b->rp += ETHERHDRSIZE;
741 if(wn->status == Sblocked){
742 /* only pass EAPOL frames when port is blocked */
743 if((e.type[0]<<8 | e.type[1]) != 0x888e)
745 } else if(wn->status != Sassoc)
748 h.fc[0] = 0x08; /* data */
749 memmove(h.a1, wn->bssid, Eaddrlen);
750 if(memcmp(e.s, wifi->ether->ea, Eaddrlen) == 0) {
751 h.fc[1] = 0x01; /* STA->AP */
753 h.fc[1] = 0x03; /* AP->AP (WDS) */
754 memmove(h.a2, wifi->ether->ea, Eaddrlen);
756 memmove(dstaddr(&h), e.d, Eaddrlen);
757 memmove(srcaddr(&h), e.s, Eaddrlen);
759 hdrlen = wifihdrlen(&h);
760 b = padblock(b, hdrlen + SNAPHDRSIZE);
761 memmove(b->rp, &h, hdrlen);
762 s = (SNAP*)(b->rp + hdrlen);
763 s->dsap = s->ssap = 0xAA;
768 memmove(s->type, e.type, 2);
787 while((b = qbread(ether->oq, 1000000)) != nil)
788 wifietheroq(wifi, b);
789 pexit("ether out queue closed", 1);
806 memset(wn, 0, sizeof(*wn));
807 memmove(wn->bssid, ether->bcast, Eaddrlen);
812 /* scan for access point */
813 while(wifi->bss == nil){
815 wnscan.channel = 1 + ((wnscan.channel+4) % 13);
816 wifiprobe(wifi, &wnscan);
818 tsleep(&up->sleep, return0, 0, 200);
819 now = MACHP(0)->ticks;
820 } while(TK2MS(now-wifi->lastauth) < 1000);
823 /* maintain access point */
825 while((wn = wifi->bss) != nil){
826 ether->link = (wn->status == Sassoc) || (wn->status == Sblocked);
827 if(ether->link && (rate = wn->actrate) != nil)
828 ether->mbps = ((*rate & 0x7f)+3)/4;
829 now = MACHP(0)->ticks;
830 if(wn->status != Sneedauth && TK2SEC(now - wn->lastseen) > 20 || goodbss(wifi, wn) == 0){
831 wifideauth(wifi, wn);
835 if(TK2MS(now - wn->lastsend) > 1000){
836 if((wn->status == Sauth || wn->status == Sblocked) && (++tmout & 7) == 0)
837 wifideauth(wifi, wn); /* stuck in auth, start over */
838 if(wn->status == Sconn || wn->status == Sunauth)
840 if(wn->status == Sauth){
844 tsleep(&up->sleep, return0, 0, 500);
850 wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
855 wifi = malloc(sizeof(Wifi));
858 wifi->iq = qopen(ether->limit, 0, 0, 0);
864 wifi->transmit = transmit;
866 wifi->rates = basicrates;
869 memmove(wifi->bssid, ether->bcast, Eaddrlen);
871 wifi->lastauth = MACHP(0)->ticks;
873 snprint(name, sizeof(name), "#l%dwifi", ether->ctlrno);
874 kproc(name, wifiproc, wifi);
875 snprint(name, sizeof(name), "#l%dwifo", ether->ctlrno);
876 kproc(name, wifoproc, wifi);
877 snprint(name, sizeof(name), "#l%dwifs", ether->ctlrno);
878 kproc(name, wifsproc, wifi);
883 static char *ciphers[] = {
892 static char Ebadkey[] = "bad key";
898 for(cipher=0; cipher<nelem(ciphers); cipher++){
899 if(strncmp(s, ciphers[cipher], len = strlen(ciphers[cipher])) == 0){
900 if(cipher == 0) /* clear */
908 if(cipher >= nelem(ciphers))
911 if((e = strchr(s, '@')) == nil)
914 len = dec16(key, sizeof(key), s, e - s);
920 k = secalloc(sizeof(Wkey) + len);
921 memmove(k->key, key, len);
926 k = secalloc(sizeof(Wkey) + sizeof(AESstate));
927 setupAESstate((AESstate*)k->key, key, len, nil);
934 memset(key, 0, sizeof(key));
937 k->tsc = strtoull(e, nil, 16);
945 wificfg(Wifi *wifi, char *opt)
950 if(strncmp(opt, "debug=", 6))
951 if(strncmp(opt, "essid=", 6))
952 if(strncmp(opt, "bssid=", 6))
954 if((p = strchr(opt, '=')) == nil)
958 n = snprint(buf, sizeof(buf), "%.*s %q", utfnlen(opt, p - opt), opt, p+1);
959 wifictl(wifi, buf, n);
976 static Cmdtab wifictlmsg[] =
983 CMrxkey0, "rxkey0", 0, /* group keys */
984 CMrxkey1, "rxkey1", 0,
985 CMrxkey2, "rxkey2", 0,
986 CMrxkey3, "rxkey3", 0,
988 CMrxkey4, "rxkey", 0, /* peerwise keys */
989 CMtxkey0, "txkey", 0,
991 CMtxkey0, "txkey0", 0,
995 wifictl(Wifi *wifi, void *buf, long n)
997 uchar addr[Eaddrlen];
1009 print("#l%d: wifictl: %.*s\n", wifi->ether->ctlrno, utfnlen(buf, n), buf);
1010 memmove(addr, wifi->ether->bcast, Eaddrlen);
1012 cb = parsecmd(buf, n);
1013 ct = lookupcmd(cb, wifictlmsg, nelem(wifictlmsg));
1014 if(ct->index >= CMauth){
1015 if(cb->nf > 1 && (ct->index == CMbssid || ct->index >= CMrxkey0)){
1016 if(parseether(addr, cb->f[1]) == 0){
1019 wn = nodelookup(wifi, addr, 0);
1022 if(wn == nil && ct->index != CMbssid)
1023 error("missing node");
1028 wifi->debug = atoi(cb->f[1]);
1031 print("#l%d: debug: %d\n", wifi->ether->ctlrno, wifi->debug);
1035 strncpy(wifi->essid, cb->f[1], Essidlen);
1041 if(goodbss(wifi, wn))
1043 wifideauth(wifi, wn);
1046 if(wifi->essid[0] == 0 && memcmp(wifi->bssid, wifi->ether->bcast, Eaddrlen) == 0)
1048 for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++)
1049 if(goodbss(wifi, wn)){
1050 setstatus(wifi, wn, Sconn);
1055 memmove(wifi->bssid, addr, Eaddrlen);
1058 freewifikeys(wifi, wn);
1062 wn->rsnelen = dec16(wn->rsne, sizeof(wn->rsne), cb->f[1], strlen(cb->f[1]));
1064 setstatus(wifi, wn, Sconn);
1067 setstatus(wifi, wn, Sauth);
1068 sendassoc(wifi, wn);
1071 case CMrxkey0: case CMrxkey1: case CMrxkey2: case CMrxkey3: case CMrxkey4:
1075 k = parsekey(cb->f[1]);
1076 memset(cb->f[1], 0, strlen(cb->f[1]));
1077 if(ct->index < CMtxkey0)
1078 kk = &wn->rxkey[ct->index - CMrxkey0];
1080 kk = &wn->txkey[ct->index - CMtxkey0];
1081 wlock(&wifi->crypt);
1084 wunlock(&wifi->crypt);
1085 if(ct->index >= CMtxkey0 && wn->status == Sblocked)
1086 setstatus(wifi, wn, Sassoc);
1095 wifistat(Wifi *wifi, void *buf, long n, ulong off)
1097 static uchar zeros[Eaddrlen];
1098 char essid[Essidlen+1];
1105 p = s = smalloc(4096);
1110 strncpy(essid, wn->ssid, Essidlen);
1111 essid[Essidlen] = 0;
1112 p = seprint(p, e, "essid: %s\n", essid);
1113 p = seprint(p, e, "bssid: %E\n", wn->bssid);
1114 p = seprint(p, e, "status: %s\n", wn->status);
1115 p = seprint(p, e, "channel: %.2d\n", wn->channel);
1117 /* only print key ciphers and key length */
1118 rlock(&wifi->crypt);
1119 for(i = 0; i<nelem(wn->rxkey); i++){
1120 if((k = wn->rxkey[i]) != nil)
1121 p = seprint(p, e, "rxkey%d: %s:[%d]\n", i,
1122 ciphers[k->cipher], k->len);
1124 for(i = 0; i<nelem(wn->txkey); i++){
1125 if((k = wn->txkey[i]) != nil)
1126 p = seprint(p, e, "txkey%d: %s:[%d]\n", i,
1127 ciphers[k->cipher], k->len);
1129 runlock(&wifi->crypt);
1131 if(wn->brsnelen > 0){
1132 p = seprint(p, e, "brsne: ");
1133 for(i=0; i<wn->brsnelen; i++)
1134 p = seprint(p, e, "%.2X", wn->brsne[i]);
1135 p = seprint(p, e, "\n");
1138 p = seprint(p, e, "essid: %s\n", wifi->essid);
1139 p = seprint(p, e, "bssid: %E\n", wifi->bssid);
1142 now = MACHP(0)->ticks;
1143 for(wn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){
1144 if(wn->lastseen == 0)
1146 strncpy(essid, wn->ssid, Essidlen);
1147 essid[Essidlen] = 0;
1148 p = seprint(p, e, "node: %E %.4x %-11ld %.2d %s\n",
1149 wn->bssid, wn->cap, TK2MS(now - wn->lastseen), wn->channel, essid);
1151 n = readstr(off, buf, n, s);
1156 static void tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1157 static int tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1158 static void ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1159 static int ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
1162 wifiencrypt(Wifi *wifi, Wnode *wn, Block *b)
1169 rlock(&wifi->crypt);
1174 runlock(&wifi->crypt);
1178 n = wifihdrlen((Wifipkt*)b->rp);
1181 b = padblock(b, -(8+4));
1183 w = (Wifipkt*)b->rp;
1184 memmove(w, b->rp+8, n);
1192 b->rp[1] = (b->rp[0] | 0x20) & 0x7f;
1194 b->rp[3] = kid<<6 | 0x20;
1200 tkipencrypt(k, w, b, tsc);
1206 b->rp[3] = kid<<6 | 0x20;
1212 ccmpencrypt(k, w, b, tsc);
1215 runlock(&wifi->crypt);
1223 wifidecrypt(Wifi *wifi, Wnode *wn, Block *b)
1230 rlock(&wifi->crypt);
1232 w = (Wifipkt*)b->rp;
1239 if((b->rp[3] & 0x20) == 0)
1241 if((w->a1[0] & 1) == 0)
1242 kid = 4; /* use peerwise key for non-unicast */
1249 tsc = (uvlong)b->rp[7]<<40 |
1250 (uvlong)b->rp[6]<<32 |
1251 (uvlong)b->rp[5]<<24 |
1252 (uvlong)b->rp[4]<<16 |
1253 (uvlong)b->rp[0]<<8 |
1258 if(tkipdecrypt(k, w, b, tsc) != 0)
1262 tsc = (uvlong)b->rp[7]<<40 |
1263 (uvlong)b->rp[6]<<32 |
1264 (uvlong)b->rp[5]<<24 |
1265 (uvlong)b->rp[4]<<16 |
1266 (uvlong)b->rp[1]<<8 |
1271 if(ccmpdecrypt(k, w, b, tsc) != 0)
1276 runlock(&wifi->crypt);
1280 runlock(&wifi->crypt);
1284 memmove(b->rp, w, n);
1285 w = (Wifipkt*)b->rp;
1290 static u16int Sbox[256] = {
1291 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
1292 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
1293 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
1294 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
1295 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
1296 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
1297 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
1298 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
1299 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
1300 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
1301 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
1302 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
1303 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
1304 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
1305 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
1306 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
1307 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
1308 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
1309 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
1310 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
1311 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
1312 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
1313 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
1314 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
1315 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
1316 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
1317 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
1318 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
1319 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
1320 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
1321 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
1322 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A
1326 tkipk2tk(uchar key[16], u16int tk[8])
1328 tk[0] = (u16int)key[1]<<8 | key[0];
1329 tk[1] = (u16int)key[3]<<8 | key[2];
1330 tk[2] = (u16int)key[5]<<8 | key[4];
1331 tk[3] = (u16int)key[7]<<8 | key[6];
1332 tk[4] = (u16int)key[9]<<8 | key[8];
1333 tk[5] = (u16int)key[11]<<8 | key[10];
1334 tk[6] = (u16int)key[13]<<8 | key[12];
1335 tk[7] = (u16int)key[15]<<8 | key[14];
1339 tkipphase1(u32int tscu, uchar ta[Eaddrlen], u16int tk[8], u16int p1k[5])
1341 u16int *k, i, x0, x1, x2;
1345 p1k[2] = (u16int)ta[1]<<8 | ta[0];
1346 p1k[3] = (u16int)ta[3]<<8 | ta[2];
1347 p1k[4] = (u16int)ta[5]<<8 | ta[4];
1354 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1358 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1362 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1366 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1370 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1378 tkipphase2(u16int tscl, u16int p1k[5], u16int tk[8], uchar rc4key[16])
1380 u16int ppk[6], x0, x1, x2;
1387 ppk[5] = p1k[4] + tscl;
1389 x0 = ppk[5] ^ tk[0];
1391 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1393 x0 = ppk[0] ^ tk[1];
1395 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1397 x0 = ppk[1] ^ tk[2];
1399 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1401 x0 = ppk[2] ^ tk[3];
1403 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1405 x0 = ppk[3] ^ tk[4];
1407 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1409 x0 = ppk[4] ^ tk[5];
1411 x2 = Sbox[x0 & 0xFF] ^ ((x1>>8) | (x1<<8));
1414 x2 = ppk[5] ^ tk[6];
1415 ppk[0] += (x2 >> 1) | (x2 << 15);
1416 x2 = ppk[0] ^ tk[7];
1417 ppk[1] += (x2 >> 1) | (x2 << 15);
1420 ppk[2] += (x2 >> 1) | (x2 << 15);
1422 ppk[3] += (x2 >> 1) | (x2 << 15);
1424 ppk[4] += (x2 >> 1) | (x2 << 15);
1426 ppk[5] += (x2 >> 1) | (x2 << 15);
1428 rc4key[0] = tscl >> 8;
1429 rc4key[1] = (rc4key[0] | 0x20) & 0x7F;
1431 rc4key[3] = (ppk[5] ^ tk[0]) >> 1;
1433 rc4key[5] = ppk[0] >> 8;
1435 rc4key[7] = ppk[1] >> 8;
1437 rc4key[9] = ppk[2] >> 8;
1438 rc4key[10] = ppk[3];
1439 rc4key[11] = ppk[3] >> 8;
1440 rc4key[12] = ppk[4];
1441 rc4key[13] = ppk[4] >> 8;
1442 rc4key[14] = ppk[5];
1443 rc4key[15] = ppk[5] >> 8;
1446 typedef struct MICstate MICstate;
1456 micsetup(MICstate *s, uchar key[8])
1458 s->l = (u32int)key[0] |
1460 (u32int)key[2]<<16 |
1462 s->r = (u32int)key[4] |
1464 (u32int)key[6]<<16 |
1471 micupdate(MICstate *s, uchar *data, ulong len)
1473 u32int l, r, m, n, e;
1482 m |= (u32int)*data++ << 24;
1486 r ^= (l << 17) | (l >> 15);
1488 r ^= ((l & 0x00FF00FFUL)<<8) | ((l & 0xFF00FF00UL)>>8);
1490 r ^= (l << 3) | (l >> 29);
1492 r ^= (l >> 2) | (l << 30);
1502 micfinish(MICstate *s, uchar mic[8])
1504 static uchar pad[8] = { 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
1506 micupdate(s, pad, sizeof(pad));
1518 static uchar pad4[4] = { 0x00, 0x00, 0x00, 0x00, };
1521 tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1523 u16int tk[8], p1k[5];
1529 micsetup(&ms, k->key+24);
1530 micupdate(&ms, dstaddr(w), Eaddrlen);
1531 micupdate(&ms, srcaddr(w), Eaddrlen);
1532 micupdate(&ms, pad4, 4);
1533 micupdate(&ms, b->rp, BLEN(b));
1534 micfinish(&ms, b->wp);
1537 crc = ethercrc(b->rp, BLEN(b));
1545 tkipk2tk(k->key, tk);
1546 tkipphase1(tsc >> 16, w->a2, tk, p1k);
1547 tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
1548 setupRC4state(&rs, seed, sizeof(seed));
1549 rc4(&rs, b->rp, BLEN(b));
1553 tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1555 uchar seed[16], mic[8];
1556 u16int tk[8], p1k[5];
1564 tkipk2tk(k->key, tk);
1565 tkipphase1(tsc >> 16, w->a2, tk, p1k);
1566 tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
1567 setupRC4state(&rs, seed, sizeof(seed));
1568 rc4(&rs, b->rp, BLEN(b));
1571 crc = (ulong)b->wp[0] |
1572 (ulong)b->wp[1]<<8 |
1573 (ulong)b->wp[2]<<16 |
1574 (ulong)b->wp[3]<<24;
1576 crc ^= ethercrc(b->rp, BLEN(b));
1579 micsetup(&ms, k->key+16);
1580 micupdate(&ms, dstaddr(w), Eaddrlen);
1581 micupdate(&ms, srcaddr(w), Eaddrlen);
1582 micupdate(&ms, pad4, 4);
1583 micupdate(&ms, b->rp, BLEN(b));
1584 micfinish(&ms, mic);
1586 return tsmemcmp(b->wp, mic, 8) | crc;
1590 putbe(uchar *p, int L, uint v)
1593 *p++ = (v >> L*8) & 0xFF;
1598 xblock(int L, int M, uchar *N, uchar *a, int la, int lm, uchar t[16], AESstate *s)
1600 uchar l[8], *p, *x, *e;
1602 assert(M >= 4 && M <= 16);
1603 assert(L >= 2 && L <= 4);
1605 t[0] = ((la > 0)<<6) | ((M-2)/2)<<3 | (L-1); /* flags */
1606 memmove(&t[1], N, 15-L);
1607 putbe(&t[16-L], L, lm);
1608 aes_encrypt(s->ekey, s->rounds, t, t);
1611 assert(la < 0xFF00);
1612 for(p = l, e = putbe(l, 2, la), x = t; p < e; x++, p++)
1614 for(e = a + la; a < e; x = t){
1615 for(; a < e && x < &t[16]; x++, a++)
1617 aes_encrypt(s->ekey, s->rounds, t, t);
1623 sblock(int L, uchar *N, uint i, uchar b[16], AESstate *s)
1625 b[0] = L-1; /* flags */
1626 memmove(&b[1], N, 15-L);
1627 putbe(&b[16-L], L, i);
1628 aes_encrypt(s->ekey, s->rounds, b, b);
1633 aesCCMencrypt(int L, int M, uchar *N /* N[15-L] */,
1634 uchar *a /* a[la] */, int la,
1635 uchar *m /* m[lm+M] */, int lm,
1638 uchar t[16], b[16], *p, *x;
1641 xblock(L, M, N, a, la, lm, t, s);
1643 for(i = 1; lm >= 16; i++, m += 16, lm -= 16){
1644 sblock(L, N, i, b, s);
1646 *((u32int*)&t[0]) ^= *((u32int*)&m[0]);
1647 *((u32int*)&m[0]) ^= *((u32int*)&b[0]);
1648 *((u32int*)&t[4]) ^= *((u32int*)&m[4]);
1649 *((u32int*)&m[4]) ^= *((u32int*)&b[4]);
1650 *((u32int*)&t[8]) ^= *((u32int*)&m[8]);
1651 *((u32int*)&m[8]) ^= *((u32int*)&b[8]);
1652 *((u32int*)&t[12]) ^= *((u32int*)&m[12]);
1653 *((u32int*)&m[12]) ^= *((u32int*)&b[12]);
1655 aes_encrypt(s->ekey, s->rounds, t, t);
1658 for(p = sblock(L, N, i, b, s), x = t; p < &b[lm]; x++, m++, p++){
1662 aes_encrypt(s->ekey, s->rounds, t, t);
1665 for(p = sblock(L, N, 0, b, s), x = t; p < &b[M]; x++, p++)
1672 aesCCMdecrypt(int L, int M, uchar *N /* N[15-L] */,
1673 uchar *a /* a[la] */, int la,
1674 uchar *m /* m[lm+M] */, int lm,
1677 uchar t[16], b[16], *p, *x;
1680 xblock(L, M, N, a, la, lm, t, s);
1682 for(i = 1; lm >= 16; i++, m += 16, lm -= 16){
1683 sblock(L, N, i, b, s);
1685 *((u32int*)&m[0]) ^= *((u32int*)&b[0]);
1686 *((u32int*)&t[0]) ^= *((u32int*)&m[0]);
1687 *((u32int*)&m[4]) ^= *((u32int*)&b[4]);
1688 *((u32int*)&t[4]) ^= *((u32int*)&m[4]);
1689 *((u32int*)&m[8]) ^= *((u32int*)&b[8]);
1690 *((u32int*)&t[8]) ^= *((u32int*)&m[8]);
1691 *((u32int*)&m[12]) ^= *((u32int*)&b[12]);
1692 *((u32int*)&t[12]) ^= *((u32int*)&m[12]);
1694 aes_encrypt(s->ekey, s->rounds, t, t);
1697 for(p = sblock(L, N, i, b, s), x = t; p < &b[lm]; x++, m++, p++){
1701 aes_encrypt(s->ekey, s->rounds, t, t);
1704 for(p = sblock(L, N, 0, b, s), x = t; p < &b[M]; x++, p++)
1707 return tsmemcmp(m, t, M);
1711 setupCCMP(Wifipkt *w, uvlong tsc, uchar nonce[13], uchar auth[32])
1715 nonce[0] = ((w->fc[0] & 0x0c) == 0x00) << 4;
1716 memmove(&nonce[1], w->a2, Eaddrlen);
1717 nonce[7] = tsc >> 40;
1718 nonce[8] = tsc >> 32;
1719 nonce[9] = tsc >> 24;
1720 nonce[10] = tsc >> 16;
1721 nonce[11] = tsc >> 8;
1725 *p++ = (w->fc[0] & (((w->fc[0] & 0x0c) == 0x08) ? 0x0f : 0xff));
1726 *p++ = (w->fc[1] & ~0x38) | 0x40;
1727 memmove(p, w->a1, Eaddrlen); p += Eaddrlen;
1728 memmove(p, w->a2, Eaddrlen); p += Eaddrlen;
1729 memmove(p, w->a3, Eaddrlen); p += Eaddrlen;
1730 *p++ = w->seq[0] & 0x0f;
1732 if((w->fc[1] & 3) == 0x03) {
1733 memmove(p, w->a4, Eaddrlen);
1741 ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1743 uchar auth[32], nonce[13];
1745 aesCCMencrypt(2, 8, nonce, auth,
1746 setupCCMP(w, tsc, nonce, auth),
1747 b->rp, BLEN(b), (AESstate*)k->key);
1752 ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
1754 uchar auth[32], nonce[13];
1760 return aesCCMdecrypt(2, 8, nonce, auth,
1761 setupCCMP(w, tsc, nonce, auth),
1762 b->rp, BLEN(b), (AESstate*)k->key);
1766 * Dynamic Mac Address Translation (DMAT)
1768 * Wifi does not allow spoofing of the source mac which breaks
1769 * bridging. To solve this we proxy mac addresses, maintaining
1770 * a translation table from ip address to destination mac address.
1771 * Upstream ARP and NDP packets get ther source mac address changed
1772 * to proxy and a translation entry is added with the original mac
1773 * for downstream translation. The proxy does not appear in the
1776 #include "../ip/ip.h"
1777 #include "../ip/ipv6.h"
1780 dmatproxy(Block *bp, int upstream, uchar proxy[Eaddrlen], DMAT *t)
1782 static uchar arp4[] = {
1788 uchar ip[IPaddrlen], mac[Eaddrlen], *targ, *end, *a, *o;
1795 pkt = (Etherpkt*)bp->rp;
1801 memmove(pkt->s, proxy, Eaddrlen);
1802 else if(t->map == 0 || (pkt->d[0]&1) != 0 || memcmp(pkt->d, proxy, Eaddrlen) != 0)
1806 switch(pkt->type[0]<<8 | pkt->type[1]){
1815 if(a+IP4HDR > end || (a[0]&15) < IP_HLEN4)
1817 v4tov6(ip, a+12+4*(upstream==0));
1824 memmove(ip, a+8+16*(upstream==0), 16);
1838 case 133: /* Router Solicitation */
1841 case 134: /* Router Advertisement */
1844 case 136: /* Neighbor Advertisement */
1847 case 135: /* Neighbor Solicitation */
1850 case 137: /* Redirect */
1854 memset(mac, 0xFF, Eaddrlen);
1855 csum = (a[2]<<8 | a[3])^0xFFFF;
1856 while(o+8 <= end && o[1] != 0){
1860 for(i=0; i<Eaddrlen; i += 2)
1861 csum += (o[2+i]<<8 | o[3+i])^0xFFFF;
1862 memmove(mac, o+2, Eaddrlen);
1863 memmove(o+2, proxy, Eaddrlen);
1864 for(i=0; i<Eaddrlen; i += 2)
1865 csum += (o[2+i]<<8 | o[3+i]);
1870 while((c = csum >> 16) != 0)
1871 csum = (csum & 0xFFFF) + c;
1876 case UDP: /* for BOOTP */
1878 || (a[0]<<8 | a[1]) != 68
1879 || (a[2]<<8 | a[3]) != 67
1882 || a[10] != Eaddrlen
1883 || (a[18]&0x80) != 0
1884 || memcmp(a+36, proxy, Eaddrlen) == 0)
1887 csum = (a[6]<<8 | a[7])^0xFFFF;
1889 /* set the broadcast flag so response reaches us */
1890 csum += (a[18]<<8)^0xFFFF;
1894 while((c = csum >> 16) != 0)
1895 csum = (csum & 0xFFFF) + c;
1905 if(a+26 > end || memcmp(a, arp4, sizeof(arp4)) != 0 || (a[7] != 1 && a[7] != 2))
1907 v4tov6(ip, a+14+10*(upstream==0));
1909 memmove(mac, a+8, Eaddrlen);
1910 memmove(a+8, proxy, Eaddrlen);
1916 h = ( (ip[IPaddrlen-1] ^ proxy[2])<<24 |
1917 (ip[IPaddrlen-2] ^ proxy[3])<<16 |
1918 (ip[IPaddrlen-3] ^ proxy[4])<<8 |
1919 (ip[IPaddrlen-4] ^ proxy[5]) ) % nelem(t->tab);
1924 if((mac[0]&1) != 0 || memcmp(mac, proxy, Eaddrlen) == 0)
1926 for(i=0; te->valid && i<nelem(t->tab); i++){
1927 if(memcmp(te->ip, ip, IPaddrlen) == 0)
1929 if(++te >= &t->tab[nelem(t->tab)])
1932 memmove(te->mac, mac, Eaddrlen);
1933 memmove(te->ip, ip, IPaddrlen);
1937 memmove(ip, targ, IPaddrlen);
1942 if((t->map>>h & 1) == 0)
1944 for(i=0; te->valid && i<nelem(t->tab); i++){
1945 if(memcmp(te->ip, ip, IPaddrlen) == 0){
1946 memmove(pkt->d, te->mac, Eaddrlen);
1949 if(++te >= &t->tab[nelem(t->tab)])