git: 9front

Download patch

ref: 16bc3fe59231f6784307cd70abd79980c92f468e
parent: 3273c3eb7853c90d9afc42c1a81d897cc27ad4a5
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sat Mar 23 18:09:46 EDT 2013

wpa: fix rsc for wpa2

in wpa2, the rsc field of the eapol message3 is the packet number for
*group* messages that the ap will use as there is no separate group
key message. in wpa1, we use it for the peerwise key.

--- a/sys/src/cmd/aux/wpa.c
+++ b/sys/src/cmd/aux/wpa.c
@@ -438,7 +438,7 @@
 	for(;;){
 		uchar smac[Eaddrlen], amac[Eaddrlen], snonce[Noncelen], anonce[Noncelen], *p, *e, *m;
 		int proto, flags, vers, datalen;
-		uvlong repc, rsc;
+		uvlong repc, rsc, tsc;
 		Keydescr *kd;
 
 		if((n = read(fd, buf, sizeof(buf))) < 0)
@@ -471,13 +471,6 @@
 		if(kd->type[0] != 0xFE && kd->type[0] != 0x02)
 			continue;
 
-		rsc =	(uvlong)kd->rsc[0] |
-			(uvlong)kd->rsc[1]<<8 |
-			(uvlong)kd->rsc[2]<<16 |
-			(uvlong)kd->rsc[3]<<24 |
-			(uvlong)kd->rsc[4]<<32 |
-			(uvlong)kd->rsc[5]<<40;
-
 		vers = kd->flags[1] & 7;
 		flags = kd->flags[0]<<8 | kd->flags[1];
 		datalen = kd->datalen[0]<<8 | kd->datalen[1];
@@ -523,6 +516,13 @@
 			}
 			lastrepc = repc;
 
+			rsc =	(uvlong)kd->rsc[0] |
+				(uvlong)kd->rsc[1]<<8 |
+				(uvlong)kd->rsc[2]<<16 |
+				(uvlong)kd->rsc[3]<<24 |
+				(uvlong)kd->rsc[4]<<32 |
+				(uvlong)kd->rsc[5]<<40;
+
 			if(datalen > 0 && (flags & Fenc) != 0){
 				if(vers == 1)
 					datalen = rc4unwrap(ptk+16, kd->eapoliv, kd->data, datalen);
@@ -571,16 +571,22 @@
 			}
 
 			if((flags & (Fptk|Fack)) == (Fptk|Fack)){
+				if(vers != 1)	/* in WPA2, RSC is for group key only */
+					tsc = 0LL;
+				else {
+					tsc = rsc;
+					rsc = 0LL;
+				}
 				/* install peerwise receive key */
 				if(fprint(cfd, "rxkey %.*H %s:%.*H@%llux", Eaddrlen, amac,
-					peercipher->name, peercipher->keylen, ptk+32, rsc) < 0)
+					peercipher->name, peercipher->keylen, ptk+32, tsc) < 0)
 					sysfatal("write rxkey: %r");
 
 				/* pick random 16bit tsc value for transmit */
-				rsc = 1 + (truerand() & 0x7fff);
+				tsc = 1 + (truerand() & 0x7fff);
 				memset(kd->rsc, 0, sizeof(kd->rsc));
-				kd->rsc[0] = rsc;
-				kd->rsc[1] = rsc>>8;
+				kd->rsc[0] = tsc;
+				kd->rsc[1] = tsc>>8;
 				memset(kd->eapoliv, 0, sizeof(kd->eapoliv));
 				memset(kd->nonce, 0, sizeof(kd->nonce));
 				reply(smac, amac, flags & ~(Fack|Fenc|Fsec), kd, nil, 0);
@@ -588,11 +594,8 @@
 
 				/* install peerwise transmit key */ 
 				if(fprint(cfd, "txkey %.*H %s:%.*H@%llux", Eaddrlen, amac,
-					peercipher->name, peercipher->keylen, ptk+32, rsc) < 0)
+					peercipher->name, peercipher->keylen, ptk+32, tsc) < 0)
 					sysfatal("write txkey: %r");
-
-				/* reset rsc for group key */
-				rsc = 0;
 			} else
 			if((flags & (Fptk|Fsec|Fack)) == (Fsec|Fack)){
 				if(kd->type[0] == 0xFE){
--