From 500be379339ec608b7109957ed85b216c2ec4d3e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 15 Dec 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-12-15 --- port/devssl.c | 393 +++++++++++++++++++++++++++----------------------- 1 file changed, 216 insertions(+), 177 deletions(-) diff --git a/port/devssl.c b/port/devssl.c index 7a7194d47a6998332beb036d3bfe549f8cbbc82f..98ce6247c8fcffbebd07a569d0dfeccf179f811c 100644 --- a/port/devssl.c +++ b/port/devssl.c @@ -159,24 +159,6 @@ sslwstat(Chan *c, char *dp) error(Eperm); } -static void -dighangup(Dstate *s) -{ - Block *b; - - qlock(&s->in); - for(b = s->processed; b; b = s->processed){ - s->processed = b->next; - freeb(b); - } - if(s->unprocessed){ - freeb(s->unprocessed); - s->unprocessed = 0; - } - s->state = Closed; - qunlock(&s->in); -} - void sslclose(Chan *c) { @@ -335,62 +317,175 @@ sslwrite(Chan *c, char *a, long n, ulong offset) return n; } -void -digestb(Dstate *s, Block *b, OneWay *w) +/* + * use SSL record format, add in count and digest or encrypt + */ +long +sslbwrite(Chan *c, Block *b, ulong offset) { + Dstate *s; Block *nb; - uchar *p; - DigestState ss; - uchar msgid[4]; - ulong n, h; + int h, n, m, pad, rv; - memset(&ss, 0, sizeof(ss)); - h = s->diglen + 2; - n = BLEN(b) - h; + s = c->aux; + if(s == 0 || s->state != Established) + error(Ebadusefd); - /* hash secret + message */ - (*s->hf)(w->secret, w->slen, 0, &ss); - (*s->hf)(nb->rp + h, n, 0, &ss); + if(waserror()){ + qunlock(&s->out); + if(b) + freeb(b); + dighangup(s); + nexterror(); + } + qlock(&s->out); - /* hash message id */ - p = msgid; - n = w->mid++; - *p++ = n>>24; - *p++ = n>>16; - *p++ = n>>8; - *p = n; - (*s->func)(msgid, 4, nb->rp + 2, &ss); + rv = 0; + while(b){ + m = n = BLEN(b); + h = s->diglen + 2; + + /* padded blocks are shorter than unpadded ones (strange) */ + pad = 0; + if(m > s->max){ + m = s->max; + } else if(s->blocklen != 1){ + pad = m%s->blocklen; + if(pad){ + pad = s->blocklen - pad; + if(m > s->maxpad){ + pad = 0; + m = s->maxpad; + } + } + } + + rv += m; + if(m != n){ + nb = allocb(m + h + pad); + memmove(nb->wp + h, m, b->rp); + nb->wp += m + h; + b->rp += m; + } else { + /* add header */ + nb = padblock(b, h); + nb->rp -= h; + + /* add pad */ + if(pad) + nb = padblock(nb, -pad); + b = 0; + } + m += s->diglen; + + /* SSL style count */ + if(pad){ + memset(nb->wp, 0, pad); + m += pad; + nb->wp += pad; + } else + m |= 0x8000; + np->rp[0] = (m>>8); + np->rp[1] = m; + + if(encryptalg) + encryptb(s, nb); + else + digestb(s, nb); + + (*devtab[s->c->type].bwrite)(s->c, nb, offset); + + } + qunlock(&s->out); + poperror(); + + return rv; } -long -encryptb(Dstate *s, Block *b) +Block* +sslbread(Chan *c, long n, ulong offset) { - ulong n, h; - int j; - uchar *p, *ep, *ip; - DESstate *ds; + Block *bp, **l; + uchar count[2]; + int len; + int pad; - h = s->diglen + 2; + USED(offset); - switch(s->encryptalg){ - case DESEBC: - ds = s->out.state; - ep = b->rp + BLEN(b); - for(p = b->rp + h; p < ep; p += 8) - block_cipher(ds->expanded, p, 0); - break; - case DESCBC: - ds = s->out.state; - ep = b->rp + BLEN(b); - for(p = b->rp + h; p < ep; p += 8) - bCBCEncrypt(p, ds->ivec, ds->expanded, 8); - break; + s = c->aux; + if(s == 0 || s->state != Established) + error(Ebadusefd); + + if(waserror()){ + qunlock(&s->in); + dighangup(s); + nexterror(); } + qlock(&s->in); + + if(s->processed == 0){ + /* read in the whole message */ + s->processed = s->unprocessed; + s->unprocessed =- 0; + ensure(s, &s->processed, 2); + consume(&s->processed, count, 2); + if(count[0] & 0x80){ + len = ((count[0] & 0x7f)<<8) | count[1]; + pad = 0; + } else { + len = ((count[0] & 0x3f)<<8) | count[1]; + ensure(s, &s->processed, 1); + consume(&s->processed, count, 1); + pad = count[0]; + } + ensure(s, &s->processed, len); + + /* put remainder on unprocessed */ + i = 0; + for(b = s->processed; b; b = b->next){ + i = BLEN(b); + if(i >= len) + break; + (*s->func)(b->rp, i, 0, &ss); + len -= i; + } + if(b == 0) + panic("digestbread"); + if(i > len){ + i -= len; + s->unprocessed = allocb(i); + memmove(s->unprocessed->wp, b->rp+len, i); + s->unprocessed->wp += i; + b->wp -= i; + } + + if(s->encrypalg) + decryptb(s, len); + else + checkdigestb(s, len); + + if(pad){ + for(b = s->processed; b; b = b->next){ + } + + b = s->processed; + if(BLEN(b) > n){ + b = allocb(n); + memmove(b->wp, s->processed->rp, n); + b->wp += n; + s->processed->rp += n; + } else + s->processed = b->next; + + qunlock(&s->in); + poperror(); + + return b; } -long -decryptb(Dstate *s, Block *b) +Block* +decryptb(Dstate *s, Block *b, int len) { ulong n, h; uchar *p, *ep; @@ -549,55 +644,64 @@ digestbread(Dstate *s, long n) return b; } -static Block* -sslbread(Chan *c, long n, ulong offset) +void +digestb(Dstate *s, Block *b) { - Block *bp; - uchar count[2]; - int len; - int pad; - - USED(offset); + Block *nb; + uchar *p; + DigestState ss; + uchar msgid[4]; + ulong n, h; + OneWay *w; - s = c->aux; - if(s == 0 || s->state != Established) - error(Ebadusefd); + w = &s->out; - if(waserror()){ - qunlock(&s->in); - dighangup(s); - nexterror(); - } + memset(&ss, 0, sizeof(ss)); + h = s->diglen + 2; + n = BLEN(b) - h; - qlock(&s->in); + /* hash secret + message */ + (*s->hf)(w->secret, w->slen, 0, &ss); + (*s->hf)(nb->rp + h, n, 0, &ss); - /* get the whole message */ - ensure(s, &s->unprocessed, 2); - consume(&s->unprocessed, count, 2); - if(count[0] & 0x80){ - len = ((count[0] & 0x7f)<<8) | count[1]; - pad = 0; - } else { - len = ((count[0] & 0x3f)<<8) | count[1]; - ensure(s, &s->unprocessed, 1); - consume(&s->unprocessed, count, 1); - pad = count[0]; - } - ensure(s, &s->unprocessed, len); - - if(s->encrypalg) - b = decryptb(s, len); - else - b = digestb(s, len); + /* hash message id */ + p = msgid; + n = w->mid++; + *p++ = n>>24; + *p++ = n>>16; + *p++ = n>>8; + *p = n; + (*s->func)(msgid, 4, nb->rp + 2, &ss); +} - if(pad) +long +encryptb(Dstate *s, Block *b) +{ + ulong n, h; + int j; + uchar *p, *ep, *ip; + DESstate *ds; - qunlock(&s->in); - poperror(); + h = s->diglen + 2; - return b; + switch(s->encryptalg){ + case DESEBC: + ds = s->out.state; + ep = b->rp + BLEN(b); + for(p = b->rp + h; p < ep; p += 8) + block_cipher(ds->expanded, p, 0); + break; + case DESCBC: + ds = s->out.state; + ep = b->rp + BLEN(b); + for(p = b->rp + h; p < ep; p += 8) + bCBCEncrypt(p, ds->ivec, ds->expanded, 8); + break; + } + } +/* get channel associated with an fd */ static Chan* buftochan(char *a, long n) { @@ -615,88 +719,23 @@ buftochan(char *a, long n) return c; } -/* - * use SSL record format, add in count and digest or encrypt - */ -long -sslbwrite(Chan *c, Block *b, ulong offset) +/* hand up a digest connection */ +static void +dighangup(Dstate *s) { - Dstate *s; - Block *nb; - int h, n, m, pad, rv; - - s = c->aux; - if(s == 0 || s->state != Established) - error(Ebadusefd); + Block *b; - if(waserror()){ - qunlock(&s->out); - if(b) - freeb(b); - dighangup(s); - nexterror(); + qlock(&s->in); + for(b = s->processed; b; b = s->processed){ + s->processed = b->next; + freeb(b); } - qlock(&s->out); - - rv = 0; - while(b){ - m = n = BLEN(b); - h = s->diglen + 2; - - /* padded blocks are shorter than unpadded ones (strange) */ - pad = 0; - if(m > s->max){ - m = s->max; - } else if(s->blocklen != 1){ - pad = m%s->blocklen; - if(pad){ - pad = s->blocklen - pad; - if(m > s->maxpad){ - pad = 0; - m = s->maxpad; - } - } - } - - rv += m; - if(m != n){ - nb = allocb(m + h + pad); - memmove(nb->wp + h, m, nb->rptr); - nb->wp += m + h; - b->rp += m; - } else { - /* add header */ - nb = padblock(b, h); - nb->rp -= h; - - /* add pad */ - if(pad) - nb = padblock(nb, -pad); - b = 0; - } - - /* SSL style count */ - if(pad){ - memset(nb->wp, 0, pad); - m += pad; - nb->wp += pad; - } else - m |= 0x8000; - np->rp[0] = (m>>8); - np->rp[1] = m; - - if(encryptalg) - encryptb(s, nb); - else - digestb(s, nb); - - (*devtab[s->c->type].bwrite)(s->c, nb, offset); - + if(s->unprocessed){ + freeb(s->unprocessed); + s->unprocessed = 0; } - qunlock(&s->out); - poperror(); - - return rv; + s->state = Closed; + qunlock(&s->in); } /*