]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/port/devtls.c
devproc: return process id when reading /proc/n/ctl file
[plan9front.git] / sys / src / 9 / port / devtls.c
index a30a60b35f1c20ec9c09780c6056ac3dca0cdba9..177d8ecb4243f2be49f892b4fd988265ec995527 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  devtls - record layer for transport layer security 1.0 and secure sockets layer 3.0
+ *  devtls - record layer for transport layer security 1.2 and secure sockets layer 3.0
  */
 #include       "u.h"
 #include       "../port/lib.h"
@@ -83,17 +83,18 @@ struct Secret
 {
        char            *encalg;        /* name of encryption alg */
        char            *hashalg;       /* name of hash alg */
-       int             (*enc)(Secret*, uchar*, int);
-       int             (*dec)(Secret*, uchar*, int);
-       int             (*unpad)(uchar*, int, int);
-       DigestState     *(*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
 
        int             (*aead_enc)(Secret*, uchar*, int, uchar*, uchar*, int);
        int             (*aead_dec)(Secret*, uchar*, int, uchar*, uchar*, int);
 
+       int             (*enc)(Secret*, uchar*, int);
+       int             (*dec)(Secret*, uchar*, int);
+       int             (*unpad)(uchar*, int, int);
+       DigestState*    (*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+
        int             block;          /* encryption block len, 0 if none */
-       int             maclen;
-       int             recivlen;
+       int             maclen;         /* # bytes of record mac / authentication tag */
+       int             recivlen;       /* # bytes of record iv for AEAD ciphers */
        void            *enckey;
        uchar           mackey[MaxMacLen];
 };
@@ -236,7 +237,6 @@ static void put64(uchar *p, u64int);
 static void    put32(uchar *p, u32int);
 static void    put24(uchar *p, int);
 static void    put16(uchar *p, int);
-static u32int  get32(uchar *p);
 static int     get16(uchar *p);
 static void    tlsSetState(TlsRec *tr, int new, int old);
 static void    rcvAlert(TlsRec *tr, int err);
@@ -423,21 +423,7 @@ static Chan*
 tlsopen(Chan *c, int omode)
 {
        TlsRec *tr, **pp;
-       int t, perm;
-
-       perm = 0;
-       omode &= 3;
-       switch(omode) {
-       case OREAD:
-               perm = 4;
-               break;
-       case OWRITE:
-               perm = 2;
-               break;
-       case ORDWR:
-               perm = 6;
-               break;
-       }
+       int t;
 
        t = TYPE(c->qid);
        switch(t) {
@@ -470,10 +456,7 @@ tlsopen(Chan *c, int omode)
                tr = *pp;
                if(tr == nil)
                        error("must open connection using clone");
-               if((perm & (tr->perm>>6)) != perm
-               && (strcmp(up->user, tr->user) != 0
-                   || (perm & tr->perm) != perm))
-                       error(Eperm);
+               devpermcheck(tr->user, tr->perm, omode);
                if(t == Qhand){
                        if(waserror()){
                                unlock(&tr->hqlock);
@@ -533,7 +516,7 @@ tlswstat(Chan *c, uchar *dp, int n)
                error(Eshortstat);
        if(!emptystr(d->uid))
                kstrdup(&tr->user, d->uid);
-       if(d->mode != ~0UL)
+       if(d->mode != -1)
                tr->perm = d->mode;
 
        free(d);
@@ -1196,7 +1179,9 @@ tlsread(Chan *c, void *a, long n, vlong off)
                if(tr->out.sec != nil)
                        s = seprint(s, e, "EncOut: %s\nHashOut: %s\n", tr->out.sec->encalg, tr->out.sec->hashalg);
                if(tr->out.new != nil)
-                       seprint(s, e, "NewEncOut: %s\nNewHashOut: %s\n", tr->out.new->encalg, tr->out.new->hashalg);
+                       s = seprint(s, e, "NewEncOut: %s\nNewHashOut: %s\n", tr->out.new->encalg, tr->out.new->hashalg);
+               if(tr->c != nil)
+                       seprint(s, e, "Chan: %s\n", chanpath(tr->c));
                qunlock(&tr->in.seclock);
                qunlock(&tr->out.seclock);
                n = readstr(offset, a, n, buf);
@@ -1248,13 +1233,6 @@ tlsread(Chan *c, void *a, long n, vlong off)
        return n;
 }
 
-static void
-randfill(uchar *buf, int len)
-{
-       while(len-- > 0)
-               *buf++ = nrand(256);
-}
-
 /*
  *  write a block in tls records
  */
@@ -1339,7 +1317,7 @@ if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
                                n = (*sec->aead_enc)(sec, aad, aadlen, p + RecHdrLen, p + RecHdrLen + ivlen, n) + ivlen;
                        else {
                                if(ivlen > 0)
-                                       randfill(p + RecHdrLen, ivlen);
+                                       prng(p + RecHdrLen, ivlen);
                                packMac(sec, aad, aadlen, p + RecHdrLen + ivlen, n, p + RecHdrLen + ivlen + n);
                                n = (*sec->enc)(sec, p + RecHdrLen, ivlen + n + maclen);
                        }
@@ -1428,7 +1406,6 @@ initmd5key(Hashalg *ha, int version, Secret *s, uchar *p)
 static void
 initclearmac(Hashalg *, int, Secret *s, uchar *)
 {
-       s->maclen = 0;
        s->mac = nomac;
 }
 
@@ -1486,17 +1463,16 @@ struct Encalg
 static void
 initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *)
 {
-       s->enckey = smalloc(sizeof(RC4state));
+       s->enckey = secalloc(sizeof(RC4state));
        s->enc = rc4enc;
        s->dec = rc4enc;
-       s->block = 0;
        setupRC4state(s->enckey, p, ea->keylen);
 }
 
 static void
 initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
 {
-       s->enckey = smalloc(sizeof(DES3state));
+       s->enckey = secalloc(sizeof(DES3state));
        s->enc = des3enc;
        s->dec = des3dec;
        s->block = 8;
@@ -1506,7 +1482,7 @@ initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv)
 static void
 initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-       s->enckey = smalloc(sizeof(AESstate));
+       s->enckey = secalloc(sizeof(AESstate));
        s->enc = aesenc;
        s->dec = aesdec;
        s->block = 16;
@@ -1516,13 +1492,9 @@ initAESkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 static void
 initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-       s->enckey = smalloc(sizeof(Chachastate));
-       s->enc = noenc;
-       s->dec = noenc;
-       s->mac = nomac;
+       s->enckey = secalloc(sizeof(Chachastate));
        s->aead_enc = ccpoly_aead_enc;
        s->aead_dec = ccpoly_aead_dec;
-       s->block = 0;
        s->maclen = Poly1305dlen;
        if(ea->ivlen == 0) {
                /* older draft version, iv is 64-bit sequence number */
@@ -1537,17 +1509,13 @@ initccpolykey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 static void
 initaesgcmkey(Encalg *ea, Secret *s, uchar *p, uchar *iv)
 {
-       s->enckey = smalloc(sizeof(AESGCMstate));
-       s->enc = noenc;
-       s->dec = noenc;
-       s->mac = nomac;
+       s->enckey = secalloc(sizeof(AESGCMstate));
        s->aead_enc = aesgcm_aead_enc;
        s->aead_dec = aesgcm_aead_dec;
-       s->block = 0;
        s->maclen = 16;
        s->recivlen = 8;
        memmove(s->mackey, iv, ea->ivlen);
-       randfill(s->mackey + ea->ivlen, s->recivlen);
+       prng(s->mackey + ea->ivlen, s->recivlen);
        setupAESGCMstate(s->enckey, p, ea->keylen, nil, 0);
 }
 
@@ -1556,7 +1524,6 @@ initclearenc(Encalg *, Secret *s, uchar *, uchar *)
 {
        s->enc = noenc;
        s->dec = noenc;
-       s->block = 0;
 }
 
 static Encalg encrypttab[] =
@@ -1698,32 +1665,33 @@ tlswrite(Chan *c, void *a, long n, vlong off)
                ea = parseencalg(cb->f[2]);
 
                p = cb->f[4];
-               m = (strlen(p)*3)/2;
-               x = smalloc(m);
-               tos = nil;
-               toc = nil;
+               m = (strlen(p)*3)/2 + 1;
+               x = secalloc(m);
+               tos = secalloc(sizeof(Secret));
+               toc = secalloc(sizeof(Secret));
                if(waserror()){
+                       secfree(x);
                        freeSec(tos);
                        freeSec(toc);
-                       free(x);
                        nexterror();
                }
+
                m = dec64(x, m, p, strlen(p));
+               memset(p, 0, strlen(p));
                if(m < 2 * ha->maclen + 2 * ea->keylen + 2 * ea->ivlen)
                        error("not enough secret data provided");
 
-               tos = smalloc(sizeof(Secret));
-               toc = smalloc(sizeof(Secret));
                if(!ha->initkey || !ea->initkey)
                        error("misimplemented secret algorithm");
+
                (*ha->initkey)(ha, tr->version, tos, &x[0]);
                (*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]);
                (*ea->initkey)(ea, tos, &x[2 * ha->maclen], &x[2 * ha->maclen + 2 * ea->keylen]);
                (*ea->initkey)(ea, toc, &x[2 * ha->maclen + ea->keylen], &x[2 * ha->maclen + 2 * ea->keylen + ea->ivlen]);
 
-               if(!tos->mac || !tos->enc || !tos->dec
-               || !toc->mac || !toc->enc || !toc->dec)
-                       error("missing algorithm implementations");
+               if(!tos->aead_enc || !tos->aead_dec || !toc->aead_enc || !toc->aead_dec)
+                       if(!tos->mac || !tos->enc || !tos->dec || !toc->mac || !toc->enc || !toc->dec)
+                               error("missing algorithm implementations");
 
                if(strtol(cb->f[3], nil, 0) == 0){
                        tr->in.new = tos;
@@ -1744,7 +1712,7 @@ tlswrite(Chan *c, void *a, long n, vlong off)
                tos->encalg = ea->name;
                tos->hashalg = ha->name;
 
-               free(x);
+               secfree(x);
                poperror();
        }else if(strcmp(cb->f[0], "changecipher") == 0){
                if(cb->nf != 1)
@@ -1825,12 +1793,8 @@ tlsinit(void)
        struct Hashalg *h;
        int n;
        char *cp;
-       static int already;
 
-       if(!already){
-               fmtinstall('H', encodefmt);
-               already = 1;
-       }
+       fmtinstall('H', encodefmt);
 
        tlsdevs = smalloc(sizeof(TlsRec*) * maxtlsdevs);
        trnames = smalloc((sizeof *trnames) * maxtlsdevs);
@@ -1897,7 +1861,7 @@ buftochan(char *p)
        fd = strtoul(p, 0, 0);
        if(fd < 0)
                error(Ebadarg);
-       c = fdtochan(fd, -1, 0, 1);     /* error check and inc ref */
+       c = fdtochan(fd, ORDWR, 1, 1);  /* error check and inc ref */
        return c;
 }
 
@@ -2073,10 +2037,10 @@ tlsstate(int s)
 static void
 freeSec(Secret *s)
 {
-       if(s != nil){
-               free(s->enckey);
-               free(s);
-       }
+       if(s == nil)
+               return;
+       secfree(s->enckey);
+       secfree(s);
 }
 
 static int
@@ -2180,6 +2144,8 @@ ccpoly_aead_setiv(Secret *sec, uchar seq[8])
                iv[i+(ChachaIVlen-8)] ^= seq[i];
 
        chacha_setiv(cs, iv);
+
+       memset(iv, 0, sizeof(iv));
 }
 
 static int
@@ -2214,6 +2180,7 @@ aesgcm_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data,
        for(i=0; i<8; i++) iv[4+i] ^= aad[i];
        memmove(reciv, iv+4, 8);
        aesgcm_setiv(sec->enckey, iv, 12);
+       memset(iv, 0, sizeof(iv));
        aesgcm_encrypt(data, len, aad, aadlen, data+len, sec->enckey);
        return len + sec->maclen;
 }
@@ -2229,6 +2196,7 @@ aesgcm_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data,
        memmove(iv, sec->mackey, 4);
        memmove(iv+4, reciv, 8);
        aesgcm_setiv(sec->enckey, iv, 12);
+       memset(iv, 0, sizeof(iv));
        if(aesgcm_decrypt(data, len, aad, aadlen, data+len, sec->enckey) != 0)
                return -1;
        return len;
@@ -2356,12 +2324,6 @@ put16(uchar *p, int x)
        p[1] = x;
 }
 
-static u32int
-get32(uchar *p)
-{
-       return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
-}
-
 static int
 get16(uchar *p)
 {