ref: ee89c82dd35475b93dd67773b7d10e461921a734
parent: 8a64413eca370d914c1520dfeaa1359cd7f16517
author: cinap_lenrek <[email protected]>
date: Sat Dec 30 20:49:58 EST 2017
wifi: get rid of custom hextob() routine, use dec16(), avoid copies in parsekey()
--- a/sys/src/9/pc/wifi.c
+++ b/sys/src/9/pc/wifi.c
@@ -806,29 +806,6 @@
return wifi;
}
-static int
-hextob(char *s, char **sp, uchar *b, int n)
-{
- int r;
-
- n <<= 1;
- for(r = 0; r < n && *s; s++){
- *b <<= 4;
- if(*s >= '0' && *s <= '9')
- *b |= (*s - '0');
- else if(*s >= 'a' && *s <= 'f')
- *b |= 10+(*s - 'a');
- else if(*s >= 'A' && *s <= 'F')
- *b |= 10+(*s - 'A');
- else break;
- if((++r & 1) == 0)
- b++;
- }
- if(sp != nil)
- *sp = s;
- return r >> 1;
-}
-
static char *ciphers[] = {
[0] "clear",
[TKIP] "tkip",
@@ -838,45 +815,55 @@
static Wkey*
parsekey(char *s)
{
- char buf[256], *p;
+ static char Ebadkey[] = "bad key";
uchar key[32];
- int i, n;
+ int len, cipher;
+ char *e;
Wkey *k;
- strncpy(buf, s, sizeof(buf)-1);
- buf[sizeof(buf)-1] = 0;
- if((p = strchr(buf, ':')) != nil)
- *p++ = 0;
- else
- p = buf;
- n = hextob(p, &p, key, sizeof(key));
- for(i=0; i<nelem(ciphers); i++)
- if(strcmp(ciphers[i], buf) == 0)
- break;
- switch(i){
- case 0:
- k = secalloc(sizeof(Wkey));
- break;
+ for(cipher=0; cipher<nelem(ciphers); cipher++){
+ if(strncmp(s, ciphers[cipher], len = strlen(ciphers[cipher])) == 0){
+ if(cipher == 0) /* clear */
+ return nil;
+ if(s[len] == ':'){
+ s += len+1;
+ break;
+ }
+ }
+ }
+ if(cipher >= nelem(ciphers))
+ error(Ebadkey);
+
+ if((e = strchr(s, '@')) == nil)
+ e = strchr(s, 0);
+
+ len = dec16(key, sizeof(key), s, e - s);
+
+ switch(cipher){
case TKIP:
- if(n != 32)
- return nil;
- k = secalloc(sizeof(Wkey) + n);
- memmove(k->key, key, n);
+ if(len != 32)
+ error(Ebadkey);
+ k = secalloc(sizeof(Wkey) + len);
+ memmove(k->key, key, len);
break;
case CCMP:
- if(n != 16)
- return nil;
+ if(len != 16)
+ error(Ebadkey);
k = secalloc(sizeof(Wkey) + sizeof(AESstate));
- setupAESstate((AESstate*)k->key, key, n, nil);
+ setupAESstate((AESstate*)k->key, key, len, nil);
break;
default:
+ error(Ebadkey);
return nil;
}
+
memset(key, 0, sizeof(key));
- if(*p == '@')
- k->tsc = strtoull(++p, nil, 16);
- k->len = n;
- k->cipher = i;
+
+ if(*e++ == '@')
+ k->tsc = strtoull(e, nil, 16);
+ k->len = len;
+ k->cipher = cipher;
+
return k;
}
@@ -998,7 +985,7 @@
if(cb->f[1] == nil)
wn->rsnelen = 0;
else
- wn->rsnelen = hextob(cb->f[1], nil, wn->rsne, sizeof(wn->rsne));
+ wn->rsnelen = dec16(wn->rsne, sizeof(wn->rsne), cb->f[1], strlen(cb->f[1]));
if(wn->aid == 0){
setstatus(wifi, wn, Sconn);
sendauth(wifi, wn);
@@ -1012,13 +999,7 @@
if(cb->f[1] == nil)
error(Ebadarg);
k = parsekey(cb->f[1]);
- if(k == nil)
- error("bad key");
memset(cb->f[1], 0, strlen(cb->f[1]));
- if(k->cipher == 0){
- secfree(k);
- k = nil;
- }
if(ct->index < CMtxkey0)
kk = &wn->rxkey[ct->index - CMrxkey0];
else