shithub: riscv

Download patch

ref: b9214d6662c78c808f6fb788747c364028a8ff24
parent: 33d00fce10a2ffa65c80d20559e0aee74da8c8d8
author: cinap_lenrek <[email protected]>
date: Sun Mar 24 17:59:47 EDT 2013

wifi: cleanup

cleanup wifiencrypt()/wifidecrypt() routines moving tkip
and ccmp in separate routines so we dont use less stack
space.

--- a/sys/src/9/pc/wifi.c
+++ b/sys/src/9/pc/wifi.c
@@ -664,54 +664,23 @@
 	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]);
+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);
 
-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 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 @@
 		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 @@
 		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,32 +766,10 @@
 			(uvlong)b->rp[0]<<8 |
 			(uvlong)b->rp[2];
 		b->rp += 8;
-		if(tsc <= k->tsc || BLEN(b) < 8+4 || k->len != 32)
+		if(tsc <= k->tsc || 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(tkipdecrypt(k, w, b, tsc) != 0)
 			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)
-			goto drop;
 		break;
 	case CCMP:
 		tsc =	(uvlong)b->rp[7]<<40 |
@@ -867,13 +781,13 @@
 		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 @@
 	w = (Wifipkt*)b->rp;
 	w->fc[1] &= ~0x40;
 	return b;
-drop:
-	freeb(b);
-	return nil;
 }
 
 static u16int Sbox[256] = {
@@ -1043,6 +954,14 @@
 	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 @@
 	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 @@
 	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 @@
 	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,
@@ -1254,4 +1245,31 @@
 	*p++ = 0;
 
 	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);
 }