]> git.lizzy.rs Git - plan9front.git/commitdiff
wifi: cleanup
authorcinap_lenrek <cinap_lenrek@gmx.de>
Sun, 24 Mar 2013 20:59:47 +0000 (21:59 +0100)
committercinap_lenrek <cinap_lenrek@gmx.de>
Sun, 24 Mar 2013 20:59:47 +0000 (21:59 +0100)
cleanup wifiencrypt()/wifidecrypt() routines moving tkip
and ccmp in separate routines so we dont use less stack
space.

sys/src/9/pc/wifi.c

index 938df8dbb38c408e9936ae40b79311d9a67fe117..84631a7b946a2b346be6fba4946b2032fa49d0ea 100644 (file)
@@ -664,54 +664,23 @@ wifistat(Wifi *wifi, void *buf, long n, ulong off)
        return n;
 }
 
-static void tkipk2tk(uchar key[16], u16int tk[8]);
-static void tkipphase1(u32int tscu, uchar ta[Eaddrlen], u16int tk[8], u16int p1k[5]);
-static void tkipphase2(u16int tscl, u16int p1k[5], u16int tk[8], uchar rc4key[16]);
-
-typedef struct MICstate MICstate;
-struct MICstate
-{
-       u32int  l;
-       u32int  r;
-       u32int  m;
-       u32int  n;
-};
-
-static void micsetup(MICstate *s, uchar key[8]);
-static void micupdate(MICstate *s, uchar *data, ulong len);
-static void micfinish(MICstate *s, uchar mic[8]);
-
-static uchar pad4[4] = { 0x00, 0x00, 0x00, 0x00, };
-
-static int setupCCMP(Wkey *k, Wifipkt *w, uvlong tsc, uchar nonce[13], uchar auth[30], AESstate *as);
-
-void aesCCMencrypt(int L, int M, uchar *N /* N[15-L] */,
-       uchar *a /* a[la] */, int la,
-       uchar *m /* m[lm+M] */, int lm,
-       AESstate *s);
-int aesCCMdecrypt(int L, int M, uchar *N /* N[15-L] */,
-       uchar *a /* a[la] */, int la,
-       uchar *m /* m[lm+M] */, int lm,
-       AESstate *s);
+static void tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
+static int tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
+static void ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
+static int ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
 
 static Block*
 wifiencrypt(Wifi *, Wnode *wn, Block *b)
 {
-       uchar auth[32], seed[16];
-       u16int tk[8], p1k[5];
        uvlong tsc;
-       ulong crc;
-       AESstate as;
-       RC4state rs;
-       MICstate ms;
-       Wifipkt *w;
        int n, kid;
+       Wifipkt *w;
        Wkey *k;
 
        kid = 0;
        k = &wn->txkey[kid];
        if(k->cipher == 0)
-               goto pass;
+               return b;
 
        n = wifihdrlen((Wifipkt*)b->rp);
 
@@ -735,30 +704,9 @@ wifiencrypt(Wifi *, Wnode *wn, Block *b)
                b->rp[6] = tsc>>32;
                b->rp[7] = tsc>>40;
                b->rp += 8;
-
                if(k->len != 32)
                        goto drop;
-               micsetup(&ms, k->key+24);
-               micupdate(&ms, dstaddr(w), Eaddrlen);
-               micupdate(&ms, srcaddr(w), Eaddrlen);
-               micupdate(&ms, pad4, 4);
-               micupdate(&ms, b->rp, BLEN(b));
-               micfinish(&ms, b->wp);
-               b->wp += 8;
-
-               crc = ethercrc(b->rp, BLEN(b));
-               crc = ~crc;
-               b->wp[0] = crc;
-               b->wp[1] = crc>>8;
-               b->wp[2] = crc>>16;
-               b->wp[3] = crc>>24;
-               b->wp += 4;
-
-               tkipk2tk(k->key, tk);
-               tkipphase1(tsc >> 16, w->a2, tk, p1k);
-               tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
-               setupRC4state(&rs, seed, sizeof(seed));
-               rc4(&rs, b->rp, BLEN(b));
+               tkipencrypt(k, w, b, tsc);
                break;
        case CCMP:
                b->rp[0] = tsc;
@@ -770,39 +718,27 @@ wifiencrypt(Wifi *, Wnode *wn, Block *b)
                b->rp[6] = tsc>>32;
                b->rp[7] = tsc>>40;
                b->rp += 8;
-
                if(k->len != 16)
                        goto drop;
-               aesCCMencrypt(2, 8, seed, auth, setupCCMP(k, w, tsc, seed, auth, &as),
-                       b->rp, BLEN(b), &as);
-               b->wp += 8;
+               ccmpencrypt(k, w, b, tsc);
                break;
        default:
-               goto drop;
+       drop:
+               free(b);
+               return nil;
        }
 
        b->rp = (uchar*)w;
        w->fc[1] |= 0x40;
-
-pass:
        return b;
-drop:
-       free(b);
-       return nil;
 }
 
 static Block*
 wifidecrypt(Wifi *, Wnode *wn, Block *b)
 {
-       uchar auth[32], seed[16], mic[8];
-       u16int tk[8], p1k[5];
-       RC4state rs;
-       AESstate as;
-       MICstate ms;
        uvlong tsc;
-       ulong crc;
-       Wifipkt *w;
        int n, kid;
+       Wifipkt *w;
        Wkey *k;
 
        w = (Wifipkt*)b->rp;
@@ -830,31 +766,9 @@ wifidecrypt(Wifi *, Wnode *wn, Block *b)
                        (uvlong)b->rp[0]<<8 |
                        (uvlong)b->rp[2];
                b->rp += 8;
-               if(tsc <= k->tsc || BLEN(b) < 8+4 || k->len != 32)
-                       goto drop;
-               tkipk2tk(k->key, tk);
-               tkipphase1(tsc >> 16, w->a2, tk, p1k);
-               tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
-               setupRC4state(&rs, seed, sizeof(seed));
-               rc4(&rs, b->rp, BLEN(b));
-
-               b->wp -= 4;
-               crc =   (ulong)b->wp[0] |
-                       (ulong)b->wp[1]<<8 |
-                       (ulong)b->wp[2]<<16 |
-                       (ulong)b->wp[3]<<24;
-               crc = ~crc;
-               if(ethercrc(b->rp, BLEN(b)) != crc)
+               if(tsc <= k->tsc || k->len != 32)
                        goto drop;
-
-               b->wp -= 8;
-               micsetup(&ms, k->key+16);
-               micupdate(&ms, dstaddr(w), Eaddrlen);
-               micupdate(&ms, srcaddr(w), Eaddrlen);
-               micupdate(&ms, pad4, 4);
-               micupdate(&ms, b->rp, BLEN(b));
-               micfinish(&ms, mic);
-               if(memcmp(b->wp, mic, 8) != 0)
+               if(tkipdecrypt(k, w, b, tsc) != 0)
                        goto drop;
                break;
        case CCMP:
@@ -867,13 +781,13 @@ wifidecrypt(Wifi *, Wnode *wn, Block *b)
                b->rp += 8;
                if(tsc <= k->tsc || k->len != 16)
                        goto drop;
-               b->wp -= 8;
-               if(aesCCMdecrypt(2, 8, seed, auth, setupCCMP(k, w, tsc, seed, auth, &as),
-                       b->rp, BLEN(b), &as) != 0)
+               if(ccmpdecrypt(k, w, b, tsc) != 0)
                        goto drop;
                break;
        default:
-               goto drop;
+       drop:
+               freeb(b);
+               return nil;
        }
 
        k->tsc = tsc;
@@ -882,9 +796,6 @@ wifidecrypt(Wifi *, Wnode *wn, Block *b)
        w = (Wifipkt*)b->rp;
        w->fc[1] &= ~0x40;
        return b;
-drop:
-       freeb(b);
-       return nil;
 }
 
 static u16int Sbox[256] = {
@@ -1043,6 +954,14 @@ tkipphase2(u16int tscl, u16int p1k[5], u16int tk[8], uchar rc4key[16])
        rc4key[15] = ppk[5] >> 8;
 }
 
+typedef struct MICstate MICstate;
+struct MICstate
+{
+       u32int  l;
+       u32int  r;
+       u32int  m;
+       u32int  n;
+};
 
 static void
 micsetup(MICstate *s, uchar key[8])
@@ -1107,6 +1026,78 @@ micfinish(MICstate *s, uchar mic[8])
        mic[7] = s->r>>24;
 }
 
+static uchar pad4[4] = { 0x00, 0x00, 0x00, 0x00, };
+
+static void
+tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+{
+       u16int tk[8], p1k[5];
+       uchar seed[16];
+       RC4state rs;
+       MICstate ms;
+       ulong crc;
+
+       micsetup(&ms, k->key+24);
+       micupdate(&ms, dstaddr(w), Eaddrlen);
+       micupdate(&ms, srcaddr(w), Eaddrlen);
+       micupdate(&ms, pad4, 4);
+       micupdate(&ms, b->rp, BLEN(b));
+       micfinish(&ms, b->wp);
+       b->wp += 8;
+
+       crc = ethercrc(b->rp, BLEN(b));
+       crc = ~crc;
+       b->wp[0] = crc;
+       b->wp[1] = crc>>8;
+       b->wp[2] = crc>>16;
+       b->wp[3] = crc>>24;
+       b->wp += 4;
+
+       tkipk2tk(k->key, tk);
+       tkipphase1(tsc >> 16, w->a2, tk, p1k);
+       tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
+       setupRC4state(&rs, seed, sizeof(seed));
+       rc4(&rs, b->rp, BLEN(b));
+}
+
+static int
+tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+{
+       uchar seed[16], mic[8];
+       u16int tk[8], p1k[5];
+       RC4state rs;
+       MICstate ms;
+       ulong crc;
+
+       if(BLEN(b) < 8+4)
+               return -1;
+
+       tkipk2tk(k->key, tk);
+       tkipphase1(tsc >> 16, w->a2, tk, p1k);
+       tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
+       setupRC4state(&rs, seed, sizeof(seed));
+       rc4(&rs, b->rp, BLEN(b));
+
+       b->wp -= 4;
+       crc =   (ulong)b->wp[0] |
+               (ulong)b->wp[1]<<8 |
+               (ulong)b->wp[2]<<16 |
+               (ulong)b->wp[3]<<24;
+       crc = ~crc;
+       if(ethercrc(b->rp, BLEN(b)) != crc)
+               return -1;
+
+       b->wp -= 8;
+       micsetup(&ms, k->key+16);
+       micupdate(&ms, dstaddr(w), Eaddrlen);
+       micupdate(&ms, srcaddr(w), Eaddrlen);
+       micupdate(&ms, pad4, 4);
+       micupdate(&ms, b->rp, BLEN(b));
+       micfinish(&ms, mic);
+
+       return memcmp(b->wp, mic, 8) != 0;
+}
+
 static uchar*
 putbe(uchar *p, int L, uint v)
 {
@@ -1150,7 +1141,7 @@ sblock(int L, uchar *N, uint i, uchar b[16], AESstate *s)
        return b;
 };
 
-void
+static void
 aesCCMencrypt(int L, int M, uchar *N /* N[15-L] */,
        uchar *a /* a[la] */, int la,
        uchar *m /* m[lm+M] */, int lm,
@@ -1189,7 +1180,7 @@ aesCCMencrypt(int L, int M, uchar *N /* N[15-L] */,
        memmove(m, t, M);
 }
 
-int
+static int
 aesCCMdecrypt(int L, int M, uchar *N /* N[15-L] */,
        uchar *a /* a[la] */, int la,
        uchar *m /* m[lm+M] */, int lm,
@@ -1255,3 +1246,30 @@ setupCCMP(Wkey *k, Wifipkt *w, uvlong tsc, uchar nonce[13], uchar auth[32], AESs
 
        return p - auth;
 }
+
+static void
+ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+{
+       uchar auth[32], nonce[13];
+       AESstate as;
+
+       aesCCMencrypt(2, 8, nonce, auth,
+               setupCCMP(k, w, tsc, nonce, auth, &as),
+               b->rp, BLEN(b), &as);
+       b->wp += 8;
+}
+
+static int
+ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+{
+       uchar auth[32], nonce[13];
+       AESstate as;
+
+       if(BLEN(b) < 8)
+               return -1;
+
+       b->wp -= 8;
+       return aesCCMdecrypt(2, 8, nonce, auth,
+               setupCCMP(k, w, tsc, nonce, auth, &as),
+               b->rp, BLEN(b), &as);
+}