From bcfa35e59138d41a4734718cad4d24fa593a2cf1 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 10 Apr 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-04-10 --- pc/screen.h | 1 + pc/vga.c | 16 ++++ pc/vgacyber938x.c | 20 ++++ port/devtls.c | 231 ++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 232 insertions(+), 36 deletions(-) diff --git a/pc/screen.h b/pc/screen.h index eb0c0d7b67a6912bf2555459f5cb9308d5e5cf85..f1b2ee80ed68adb776aceda823dec95195726a69 100644 --- a/pc/screen.h +++ b/pc/screen.h @@ -146,3 +146,4 @@ extern ulong vgapcilinear(VGAscr*, int*, int*, int, int); extern void drawblankscreen(int); extern void vgablank(VGAscr*, int); +extern void addvgaseg(char*, ulong, ulong); diff --git a/pc/vga.c b/pc/vga.c index daf77be4b082a82cc6593ac1a74055d3b32ac54c..682b6ee3cce3343055ab751a8410ee9eae255c34 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -218,3 +218,19 @@ vgablank(VGAscr*, int blank) vgaxo(Crtx, 0x17, crtc17); outs(Crtx, 0x0300); /* end synchronous reset */ } + +void +addvgaseg(char *name, ulong pa, ulong size) +{ + Physseg seg; + + memset(&seg, 0, sizeof seg); + seg.attr = SG_PHYSICAL; + /* can we just seg.name = name; ? */ + seg.name = smalloc(NAMELEN); + snprint(seg.name, NAMELEN, name); + seg.pa = pa; + seg.size = size; + addphysseg(&seg); +} + diff --git a/pc/vgacyber938x.c b/pc/vgacyber938x.c index 00cd74faf7e06de9386a8cfb97124a3ea1fd01f8..dd4b8ce0fcd3ade1a7081ba058ae2dfb5acfcf97 100644 --- a/pc/vgacyber938x.c +++ b/pc/vgacyber938x.c @@ -43,18 +43,27 @@ cyber938xlinear(VGAscr* scr, int* size, int* align) { ulong aperture, oaperture; int oapsize, wasupamem; + int osize; Pcidev *p; + osize = *size; oaperture = scr->aperture; oapsize = scr->apsize; wasupamem = scr->isupamem; if(wasupamem) upafree(oaperture, oapsize); scr->isupamem = 0; + scr->mmio = 0; if(p = pcimatch(nil, 0x1023, 0)){ aperture = p->mem[0].bar & ~0x0F; *size = p->mem[0].size; + /* + * Heuristic to detect the MMIO space. We're flying blind + * here, with only the XFree86 source to guide us. + */ + if(p->mem[1].size == 0x20000) + scr->mmio = (ulong*)(p->mem[1].bar & ~0x0F); } else aperture = 0; @@ -67,6 +76,11 @@ cyber938xlinear(VGAscr* scr, int* size, int* align) else scr->isupamem = 1; + if(aperture) + addvgaseg("cyber938xscreen", aperture, osize); + if(scr->mmio) + addvgaseg("cyber938xmmio", (ulong)scr->mmio, 0x20000); + return aperture; } @@ -191,6 +205,11 @@ cyber938xcurenable(VGAscr* scr) vgaxo(Crtx, 0x50, CursorON); } +static void +cyber938xdrawinit(VGAscr *scr) +{ +} + VGAdev vgacyber938xdev = { "cyber938x", @@ -198,6 +217,7 @@ VGAdev vgacyber938xdev = { 0, /* disable */ cyber938xpage, /* page */ cyber938xlinear, /* linear */ + cyber938xdrawinit, /* drawinit */ }; VGAcur vgacyber938xcur = { diff --git a/port/devtls.c b/port/devtls.c index 13f42e305eaa874e5d66c785296c19710d25fc91..65e864222db64d407a23a2e435613c472177f33d 100644 --- a/port/devtls.c +++ b/port/devtls.c @@ -18,6 +18,7 @@ enum { MaxRecLen = 1<<14, /* max payload length of a record layer message */ MaxCipherRecLen = MaxRecLen + 2048, RecHdrLen = 5, + MaxMacLen = SHA1dlen, /* protocol versions we can accept */ TLSVersion = 0x0301, @@ -73,9 +74,12 @@ enum { struct Secret { DigestState *(*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*); + int (*enc)(Secret*, uchar*, int); + int (*dec)(Secret*, uchar*, int); + int (*unpad)(uchar*, int, int); int maclen; - RC4state rc4; - uchar mackey[64]; + void *enckey; + uchar mackey[MaxMacLen]; }; struct OneWay @@ -222,6 +226,8 @@ static void alertHand(TlsRec*, char *); static TlsRec *newtls(Chan *c); static TlsRec *mktlsrec(void); static DigestState*sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s); +static DigestState*sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s); +static DigestState*nomac(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s); static void sslPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac); static void tlsPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac); static void put64(uchar *p, vlong x); @@ -234,6 +240,14 @@ static void tlsSetState(TlsRec *tr, int new, int old); static void rcvAlert(TlsRec *tr, int err); static void sendAlert(TlsRec *tr, int err); static void rcvError(TlsRec *tr, int err, char *msg, ...); +static int rc4enc(Secret *sec, uchar *buf, int n); +static int des3enc(Secret *sec, uchar *buf, int n); +static int des3dec(Secret *sec, uchar *buf, int n); +static int noenc(Secret *sec, uchar *buf, int n); +static int sslunpad(uchar *buf, int n, int block); +static int tlsunpad(uchar *buf, int n, int block); +static void freeSec(Secret *sec); + #pragma varargck argpos rcvError 3 static char *tlsnames[] = { @@ -457,7 +471,6 @@ tlswstat(Chan *c, char *dp) if(strcmp(tr->user, up->user) != 0) error(Eperm); -//ZZZ propagate chown to tr->datafd? memmove(tr->user, d.uid, NAMELEN); tr->perm = d.mode; } @@ -509,17 +522,17 @@ tlsclose(Chan *c) unlock(&tdlock); if(tr->c != nil && !waserror()){ - checkstate(tr, 0, SOpen|SHandshake|SRClose); + checkstate(tr, t != Qdata, SOpen|SHandshake|SRClose); sendAlert(tr, ECloseNotify); poperror(); } tlshangup(tr); if(tr->c != nil) cclose(tr->c); - free(tr->in.sec); - free(tr->in.new); - free(tr->out.sec); - free(tr->out.new); + freeSec(tr->in.sec); + freeSec(tr->in.new); + freeSec(tr->out.sec); + freeSec(tr->out.new); free(tr); break; } @@ -727,9 +740,11 @@ tlsrecread(TlsRec *tr) b = pullupblock(b, len); p = b->rp; if(in->sec != nil) { + len = (*in->sec->dec)(in->sec, p, len); + if(len < 0) + rcvError(tr, EDecodeError, "incorrectly encrypted message"); if(len <= in->sec->maclen) rcvError(tr, EDecodeError, "record message too short for mac"); - rc4(&in->sec->rc4, p, len); len -= in->sec->maclen; /* update length */ @@ -739,7 +754,7 @@ tlsrecread(TlsRec *tr) (*tr->packMac)(in->sec, in->sec->mackey, seq, header, p, len, hmac); if(memcmp(hmac, p+len, in->sec->maclen) != 0) rcvError(tr, EBadRecordMac, "record mac mismatch"); - b->wp -= in->sec->maclen; + b->wp = b->rp + in->sec->maclen; } qunlock(&in->seclock); poperror(); @@ -758,7 +773,7 @@ tlsrecread(TlsRec *tr) qunlock(&in->seclock); rcvError(tr, EUnexpectedMessage, "unexpected change cipher spec"); } - free(in->sec); + freeSec(in->sec); in->sec = in->new; in->new = nil; in->seq = 0; @@ -1104,22 +1119,27 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) } qlock(&out->seclock); maclen = 0; - if(out->sec != nil) + if(out->sec != nil){ maclen = out->sec->maclen; + block = out->sec->block; + } n = BLEN(bb); if(n > MaxRecLen){ n = MaxRecLen; - nb = allocb(n + RecHdrLen + maclen); + block = n + maclen + block; + block -= n % block; + nb = allocb(block + RecHdrLen); memmove(nb->wp + RecHdrLen, bb->rp, n); - nb->wp += n + RecHdrLen; bb->rp += n; }else{ /* * carefully reuse bb so it will get freed if we're out of memory */ + block = n + maclen + block; + block -= n % block; bb = padblock(bb, RecHdrLen); if(maclen) - nb = padblock(bb, -maclen); + nb = padblock(bb, -(block - n)); else nb = bb; bb = nil; @@ -1133,20 +1153,20 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) if(out->sec != nil){ put64(seq, out->seq); out->seq++; - (*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen, n, nb->wp); - nb->wp += maclen; + (*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen, n, p + RecHdrLen + n); n += maclen; + /* encrypt */ + n = (*out->sec->enc)(out->sec, p + RecHdrLen, n); + nb->wp = nb->rp + n; + /* update length */ put16(p+3, n); - - /* encrypt */ - rc4(&out->sec->rc4, p+RecHdrLen, n); } if(type == RChangeCipherSpec){ if(out->new == nil) error("change cipher without a new cipher"); - free(out->sec); + freeSec(out->sec); out->sec = out->new; out->new = nil; out->seq = 0; @@ -1216,10 +1236,29 @@ initmd5key(Hashalg *ha, int version, Secret *s, uchar *p) memmove(s->mackey, p, ha->maclen); } +static void +initclearmac(Hashalg *, int, Secret *s, uchar *) +{ + s->maclen = 0; + s->mac = nomac; +} + +static void +initsha1key(Hashalg *ha, int version, Secret *s, uchar *p) +{ + s->maclen = ha->maclen; + if(version == SSL3Version) + s->mac = sslmac_sha1; + else + s->mac = hmac_sha1; + memmove(s->mackey, p, ha->maclen); +} + static Hashalg hashtab[] = { - { "clear" }, + { "clear", 0, initclearmac, }, { "md5", MD5dlen, initmd5key, }, + { "sha1", SHA1dlen, initsha1key, }, { 0 } }; @@ -1247,13 +1286,34 @@ struct Encalg static void initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *) { - setupRC4state(&s->rc4, p, ea->keylen); + s->enckey = smalloc(sizeof(RC4state)); + s->enc = rc4enc; + s->dec = rc4enc; + setupRC4state(s->enckey, p, ea->keylen); +} + +static void +initDES3key(Encalg *, Secret *s, uchar *p, uchar *iv) +{ + s->enckey = smalloc(sizeof(DES3state)); + s->enc = des3enc; + s->dec = des3dec; +//ZZZ type hack + setupDES3state(s->enckey, (void*)p, iv); +} + +static void +initclearenc(Encalg *, Secret *s, uchar *, uchar *) +{ + s->enc = noenc; + s->dec = noenc; } static Encalg encrypttab[] = { - { "clear" }, - { "rc4_128", 128/8, 0, initRC4key, }, + { "clear", 0, 0, initclearenc }, + { "rc4_128", 128/8, 0, initRC4key }, + { "3des_ede_cbc", 3 * 8, 8, initDES3key }, { 0 } }; @@ -1275,7 +1335,7 @@ tlswrite(Chan *c, void *a, long n, vlong off) Encalg *ea; Hashalg *ha; TlsRec *volatile tr; - Secret *tos, *toc; + Secret *volatile tos, *volatile toc; Block *volatile b; Cmdbuf *volatile cb; int m; @@ -1369,11 +1429,11 @@ tlswrite(Chan *c, void *a, long n, vlong off) error("must set fd and version before secrets"); if(tr->in.new != nil){ - free(tr->in.new); + freeSec(tr->in.new); tr->in.new = nil; } if(tr->out.new != nil){ - free(tr->out.new); + freeSec(tr->out.new); tr->out.new = nil; } @@ -1383,7 +1443,11 @@ tlswrite(Chan *c, void *a, long n, vlong off) p = cb->f[4]; m = (strlen(p)*3)/2; x = smalloc(m); + tos = nil; + toc = nil; if(waserror()){ + freeSec(tos); + freeSec(toc); free(x); nexterror(); } @@ -1393,14 +1457,16 @@ tlswrite(Chan *c, void *a, long n, vlong off) tos = smalloc(sizeof(Secret)); toc = smalloc(sizeof(Secret)); - if(ha->initkey){ - (*ha->initkey)(ha, tr->version, tos, &x[0]); - (*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]); - } - if(ea->initkey){ - (*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(!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(strtol(cb->f[3], nil, 0) == 0){ tr->in.new = tos; tr->out.new = toc; @@ -1408,6 +1474,13 @@ tlswrite(Chan *c, void *a, long n, vlong off) tr->in.new = toc; tr->out.new = tos; } + if(tr->version == SSL3Version){ + toc->unpad = sslunpad; + tos->unpad = sslunpad; + }else{ + toc->unpad = tlsunpad; + tos->unpad = tlsunpad; + } free(x); poperror(); @@ -1690,6 +1763,92 @@ mktlsrec(void) return tr; } +static void +freeSec(Secret *s) +{ + if(s != nil){ + free(s->enckey); + free(s); + } +} + +static int +noenc(Secret *, uchar *, int n) +{ + return n; +} + +static int +rc4enc(Secret *sec, uchar *buf, int n) +{ + rc4(sec->enckey, buf, n); + return n; +} + +static int +tlsunpad(uchar *buf, int n, int block) +{ + int pad, nn; + + pad = buf[n - 1]; + nn = n - 1 - pad; + if(nn <= 0 || n % block) + return -1; + while(--n > nn) + if(pad != buf[n - 1]) + return -1; + return nn; +} + +static int +sslunpad(uchar *buf, int n, int block) +{ + int pad, nn; + + pad = buf[n - 1]; + nn = n - 1 - pad; + if(nn <= 0 || n % block) + return -1; + return nn; +} + +static int +blockpad(uchar *buf, int n, int block) +{ + int pad, nn; + + nn = n + block; + nn -= nn % block; + pad = nn - (n + 1); + while(n < nn) + buf[n++] = pad; + return nn; +} + +static int +des3enc(Secret *sec, uchar *buf, int n) +{ + n = blockpad(buf, n, 8); + if(n < 0 || (n & 7)) + return -1; + des3CBCencrypt(buf, n, sec->enckey); + return n; +} + +static int +des3dec(Secret *sec, uchar *buf, int n) +{ + if(n & 7) + return -1; + des3CBCdecrypt(buf, n, sec->enckey); + return (*sec->unpad)(buf, n, 8); +} +static DigestState* +nomac(uchar *, ulong, uchar *, ulong, uchar *, DigestState *) +{ + return nil; +} + /* * sslmac: mac calculations for ssl 3.0 only; tls 1.0 uses the standard hmac. */