From 75de3080a8cf1b6b1dd15d390c97236eeb66502b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 18 Dec 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-12-18 --- pc/devata.c | 20 ++++--- port/devssl.c | 146 ++++++++++++++++++++++++++++---------------------- 2 files changed, 95 insertions(+), 71 deletions(-) diff --git a/pc/devata.c b/pc/devata.c index e6f997bdd15e148ef33df22a06817c32ee90a3b0..7ded22646623e7c1c89d805b764dc234cde6d61e 100644 --- a/pc/devata.c +++ b/pc/devata.c @@ -1384,25 +1384,31 @@ atapart(Drive *dp) sprint(namebuf, "%spartition", dp->vol); if((p = getconf(namebuf)) == 0){ /* - * read last sector from disk, null terminate. This used - * to be the sector we used for the partition tables. + * Read second last sector from disk, null terminate. + * The last sector used to hold the partition tables. * However, this sector is special on some PC's so we've * started to use the second last sector as the partition * table instead. To avoid reconfiguring all our old systems - * we first look to see if there is a valid partition - * table in the last sector. If so, we use it. Otherwise - * we switch to the second last. + * we still check if there is a valid partition table in + * the last sector if none is found in the second last. */ - ataxfer(dp, &dp->p[1], Cread, 0, dp->bytes, buf); + ataxfer(dp, &dp->p[0], Cread, dp->p[0].end-1, dp->bytes, buf); buf[dp->bytes-1] = 0; n = getfields((char*)buf, line, Npart+1, "\n"); - if(n == 0 || strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1)){ + if(n > 0 && strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1) == 0){ dp->p[0].end--; dp->p[1].start--; dp->p[1].end--; + } + else{ ataxfer(dp, &dp->p[1], Cread, 0, dp->bytes, buf); buf[dp->bytes-1] = 0; n = getfields((char*)buf, line, Npart+1, "\n"); + if(n == 0 || strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1)){ + dp->p[0].end--; + dp->p[1].start--; + dp->p[1].end--; + } } } else{ diff --git a/port/devssl.c b/port/devssl.c index a89a8d895ce9278f8edae020c7d802f2d1539ea5..0633dee1111f5be333a63b1cd30aea47d8e3e960 100644 --- a/port/devssl.c +++ b/port/devssl.c @@ -34,7 +34,9 @@ enum Closed= 5, /* encryption algorithms */ + Noencryption= 0, DESCBC= 1, + DESECB= 2, }; typedef struct Dstate Dstate; @@ -43,11 +45,12 @@ struct Dstate Chan *c; /* io channel */ uchar state; /* state of connection */ uchar encryptalg; /* encryption algorithm */ - ushort blocking; /* blocking length */ + ushort blocklen; /* blocking length */ ushort diglen; /* length of digest */ DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*); /* hash func */ + /* for SSL format */ int max; /* maximum unpadded data per msg */ int maxpad; /* maximum padded data per msg */ @@ -88,7 +91,7 @@ void producerand(void); static void ensure(Dstate*, Block**, int); static void consume(Block**, uchar*, int); -static void setsecret(OneWay*, uchar*, int); +static void setsecret(Dstate*, OneWay*, uchar*, int); static Block* encryptb(Dstate*, Block*, int); static Block* decryptb(Dstate*, Block*); static Block* digestb(Dstate*, Block*, int); @@ -217,10 +220,10 @@ sslread(Chan *c, void *a, long n, ulong offset) Block* sslbread(Chan *c, long n, ulong offset) { - Block *bp, **l; + Dstate *s; + Block *b; uchar count[2]; - int len; - int pad; + int i, len, pad; USED(offset); @@ -235,23 +238,24 @@ sslbread(Chan *c, long n, ulong offset) } qlock(&s->in); - if(s->processed == 0){ + b = s->processed; + if(b == 0){ /* read in the whole message */ s->processed = s->unprocessed; - s->unprocessed =- 0; + s->unprocessed = 0; ensure(s, &s->processed, 2); consume(&s->processed, count, 2); if(count[0] & 0x80){ len = ((count[0] & 0x7f)<<8) | count[1]; + ensure(s, &s->processed, len); pad = 0; } else { len = ((count[0] & 0x3f)<<8) | count[1]; - ensure(s, &s->processed, 1); + ensure(s, &s->processed, len+1); consume(&s->processed, count, 1); pad = count[0]; } - ensure(s, &s->processed, len); /* trade memory bandwidth for less processing complexity */ b = s->processed = pullupblock(s->processed, len); @@ -266,19 +270,22 @@ sslbread(Chan *c, long n, ulong offset) b->wp -= i; } - if(s->encrypalg) + if(s->encryptalg) b = decryptb(s, b); - else + else { + if(BLEN(b) < s->diglen) + error("baddigest"); checkdigestb(s, b); + b->rp += s->diglen; + } /* remove pad */ - if(b->wp - b->rp > pad) + if(b->wp - b->rp < pad) panic("sslbread"); b->wp -= pad; s->processed = b; } - b = s->processed; if(BLEN(b) > n){ b = allocb(n); memmove(b->wp, s->processed->rp, n); @@ -294,12 +301,12 @@ sslbread(Chan *c, long n, ulong offset) } long -sslwrite(Chan *c, char *a, long n, ulong offset) +sslwrite(Chan *c, void *a, long n, ulong offset) { Dstate *s; Block *b; - int m, sofar; - char buf[32]; + int m; + char *p, *e, buf[32]; switch(c->qid.path & ~CHDIR){ case Qclone: @@ -330,8 +337,8 @@ sslwrite(Chan *c, char *a, long n, ulong offset) } else if(strcmp(buf, "descbc") == 0){ s->encryptalg = DESCBC; s->blocklen = 8; - } else if(strcmp(buf, "desebc") == 0){ - s->encryptalg = DESEBC; + } else if(strcmp(buf, "desecb") == 0){ + s->encryptalg = DESECB; s->blocklen = 8; } else error(Ebadarg); @@ -344,12 +351,12 @@ sslwrite(Chan *c, char *a, long n, ulong offset) break; case Secretinwait: /* get secret for incoming messages */ - setsecret(&s->in, a, n); + setsecret(s, &s->in, a, n); s->state = Secretoutwait; break; case Secretoutwait: /* get secret for outgoing messages */ - setsecret(&s->out, a, n); + setsecret(s, &s->out, a, n); if(s->blocklen != 1){ s->max = (1<<15) - s->diglen; s->max -= s->max % s->blocklen; @@ -360,9 +367,9 @@ sslwrite(Chan *c, char *a, long n, ulong offset) s->state = Established; break; case Established: - sofar = 0; - do { - m = n - sofar; + p = a; + for(e = p + n; p < e; p += m){ + m = e - p; if(m > s->max) m = s->max; @@ -371,14 +378,12 @@ sslwrite(Chan *c, char *a, long n, ulong offset) freeb(b); nexterror(); } - memmove(b->wp, a+sofar, m); + memmove(b->wp, p, m); poperror(); b->wp += m; sslbwrite(c, b, offset); - - sofar += m; - } while(sofar < n); + } break; default: error(Ebadusefd); @@ -416,17 +421,19 @@ sslbwrite(Chan *c, Block *b, ulong offset) m = n = BLEN(b); h = s->diglen + 2; - /* padded blocks are shorter than unpadded ones (strange) */ + /* trim to maximum block size */ 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; + } else { + pad = s->blocklen - pad; + h++; } } } @@ -434,42 +441,40 @@ sslbwrite(Chan *c, Block *b, ulong offset) rv += m; if(m != n){ nb = allocb(m + h + pad); - memmove(nb->wp + h, m, b->rp); + memmove(nb->wp + h, b->rp, m); nb->wp += m + h; b->rp += m; } else { - /* add header */ + /* add header space */ nb = padblock(b, h); nb->rp -= h; - - /* add pad */ - if(pad) - nb = padblock(nb, -pad); b = 0; } m += s->diglen; /* SSL style count */ - p = np->rp; if(pad){ + nb = padblock(nb, -pad); memset(nb->wp, 0, pad); + b->wp += pad; m += pad; - nb->wp += pad; + + p = nb->rp; p[0] = (m>>8); p[1] = m; p[2] = pad; offset = 3; } else { - m |= 0x8000; - p[0] = (m>>8); + p = nb->rp; + p[0] = (m>>8) | 0x80; p[1] = m; offset = 2; } - if(encryptalg) + if(s->encryptalg) nb = encryptb(s, nb, offset); else - nb = digestb(s, nb, ofsetf); + nb = digestb(s, nb, offset); (*devtab[s->c->type].bwrite)(s->c, nb, offset); @@ -538,7 +543,7 @@ consume(Block **l, uchar *p, int n) } static void -setsecret(OneWay *w, uchar *secret, int n) +setsecret(Dstate *s, OneWay *w, uchar *secret, int n) { w->secret = smalloc(n); memmove(w->secret, secret, n); @@ -546,11 +551,15 @@ setsecret(OneWay *w, uchar *secret, int n) w->mid = 0; switch(s->encryptalg){ - case DESCBC: + case DESECB: + if(n < 8) + error("secret too small"); w->state = smalloc(sizeof(DESstate)); setupDESstate(w->state, secret, 0); break; case DESCBC: + if(n < 16) + error("secret too small"); w->state = smalloc(sizeof(DESstate)); setupDESstate(w->state, secret, secret+8); break; @@ -560,13 +569,11 @@ setsecret(OneWay *w, uchar *secret, int n) static Block* encryptb(Dstate *s, Block *b, int offset) { - ulong n; - int j; - uchar *p, *ep; + uchar *p, *ep, *p2, *ip, *eip; DESstate *ds; switch(s->encryptalg){ - case DESEBC: + case DESECB: ds = s->out.state; ep = b->rp + BLEN(b); for(p = b->rp + offset; p < ep; p += 8) @@ -575,8 +582,14 @@ encryptb(Dstate *s, Block *b, int offset) case DESCBC: ds = s->out.state; ep = b->rp + BLEN(b); - for(p = b->rp + offset; p < ep; p += 8) - bCBCEncrypt(p, ds->ivec, ds->expanded, 8); + for(p = b->rp + offset; p < ep; p += 8){ + p2 = p; + ip = ds->ivec; + for(eip = ip+8; ip < eip; ) + *p2++ ^= *ip++; + block_cipher(ds->expanded, p, 0); + memmove(ds->ivec, p, 8); + } break; } return b; @@ -585,13 +598,12 @@ encryptb(Dstate *s, Block *b, int offset) static Block* decryptb(Dstate *s, Block *b) { - ulong n, h; - int j; - uchar *p, *ep; + uchar *p, *ep, *tp, *ip, *eip; DESstate *ds; + uchar tmp[8]; switch(s->encryptalg){ - case DESEBC: + case DESECB: ds = s->out.state; ep = b->rp + BLEN(b); for(p = b->rp + s->diglen; p < ep; p += 8) @@ -600,8 +612,16 @@ decryptb(Dstate *s, Block *b) case DESCBC: ds = s->out.state; ep = b->rp + BLEN(b); - for(p = b->rp + s->diglen; p < ep; p += 8) - bCBCDecrypt(p, ds->ivec, ds->expanded, 8); + for(p = b->rp + s->diglen; p < ep;){ + memmove(tmp, p, 8); + block_cipher(ds->expanded, p, 1); + tp = tmp; + ip = ds->ivec; + for(eip = ip+8; ip < eip; ){ + *p++ ^= *ip; + *ip++ = *tp++; + } + } break; } return b; @@ -610,7 +630,6 @@ decryptb(Dstate *s, Block *b) static Block* digestb(Dstate *s, Block *b, int offset) { - Block *nb; uchar *p; DigestState ss; uchar msgid[4]; @@ -625,7 +644,7 @@ digestb(Dstate *s, Block *b, int offset) /* hash secret + message */ (*s->hf)(w->secret, w->slen, 0, &ss); - (*s->hf)(nb->rp + h, n, 0, &ss); + (*s->hf)(b->rp + h, n, 0, &ss); /* hash message id */ p = msgid; @@ -634,19 +653,18 @@ digestb(Dstate *s, Block *b, int offset) *p++ = n>>16; *p++ = n>>8; *p = n; - (*s->func)(msgid, 4, nb->rp+offset, &ss); + (*s->hf)(msgid, 4, b->rp + offset, &ss); - retrn b; + return b; } static void checkdigestb(Dstate *s, Block *b) { - Block *nb; uchar *p; DigestState ss; uchar msgid[4]; - ulong n, h; + int n, h; OneWay *w; uchar digest[128]; @@ -658,7 +676,7 @@ checkdigestb(Dstate *s, Block *b) /* hash secret + message */ (*s->hf)(w->secret, w->slen, 0, &ss); - (*s->hf)(nb->rp + h, n, 0, &ss); + (*s->hf)(b->rp + h, n, 0, &ss); /* hash message id */ p = msgid; @@ -667,9 +685,9 @@ checkdigestb(Dstate *s, Block *b) *p++ = n>>16; *p++ = n>>8; *p = n; - (*s->func)(msgid, 4, digest, &ss); + (*s->hf)(msgid, 4, digest, &ss); - if(memcmp(digest, nb->rp, s->diglen) != 0) + if(memcmp(digest, b->rp, s->diglen) != 0) error("bad digest"); }