2 * devssl - secure sockets layer
5 #include "../port/lib.h"
9 #include "../port/error.h"
15 typedef struct OneWay OneWay;
21 void *state; /* encryption state */
22 int slen; /* hash data length */
23 uchar *secret; /* secret */
24 ulong mid; /* message id */
29 /* connection states */
34 Sdigenc= Sencrypting|Sdigesting,
36 /* encryption algorithms */
43 typedef struct Dstate Dstate;
46 Chan *c; /* io channel */
47 uchar state; /* state of connection */
48 int ref; /* serialized by dslock for atomic destroy */
50 uchar encryptalg; /* encryption algorithm */
51 ushort blocklen; /* blocking length */
53 ushort diglen; /* length of digest */
54 DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*); /* hash func */
57 int max; /* maximum unpadded data per msg */
58 int maxpad; /* maximum padded data per msg */
76 Maxdstate= 512, /* max. open ssl conn's; must be a power of 2 */
81 static char *dsname[Maxdstate];
82 static Dstate *dstate[Maxdstate];
84 static char *hashalgs;
87 Qtopdir = 1, /* top level directory */
90 Qconvdir, /* directory for a conversation */
99 #define TYPE(x) ((x).path & 0xf)
100 #define CONV(x) (((x).path >> 5)&(Maxdstate-1))
101 #define QID(c, y) (((c)<<5) | (y))
103 static void ensure(Dstate*, Block**, int);
104 static void consume(Block**, uchar*, int);
105 static void setsecret(OneWay*, uchar*, int);
106 static Block* encryptb(Dstate*, Block*, int);
107 static Block* decryptb(Dstate*, Block*);
108 static Block* digestb(Dstate*, Block*, int);
109 static void checkdigestb(Dstate*, Block*);
110 static Chan* buftochan(char*);
111 static void sslhangup(Dstate*);
112 static Dstate* dsclone(Chan *c);
113 static void dsnew(Chan *c, Dstate **);
114 static long sslput(Dstate *s, Block * volatile b);
120 [Qsecretin] "secretin",
121 [Qsecretout] "secretout",
122 [Qencalgs] "encalgs",
123 [Qhashalgs] "hashalgs",
127 sslgen(Chan *c, char*, Dirtab *d, int nd, int s, Dir *dp)
131 char name[16], *p, *nm;
144 q.path = QID(0, Qtopdir);
146 devdir(c, q, "#D", 0, eve, 0555, dp);
151 q.path = QID(0, Qprotodir);
153 devdir(c, q, "ssl", 0, eve, 0555, dp);
157 q.path = QID(0, Qtopdir);
159 devdir(c, q, ".", 0, eve, 0555, dp);
163 q.path = QID(s, Qconvdir);
170 if(dsname[s] == nil){
171 sprint(name, "%d", s);
172 kstrdup(&dsname[s], name);
174 devdir(c, q, dsname[s], 0, nm, 0555, dp);
179 q.path = QID(0, Qclonus);
180 devdir(c, q, "clone", 0, eve, 0555, dp);
184 q.path = QID(0, Qprotodir);
186 devdir(c, q, "ssl", 0, eve, 0555, dp);
189 ds = dstate[CONV(c->qid)];
198 q.path = QID(CONV(c->qid), Qctl);
202 q.path = QID(CONV(c->qid), Qdata);
206 q.path = QID(CONV(c->qid), Qsecretin);
210 q.path = QID(CONV(c->qid), Qsecretout);
214 q.path = QID(CONV(c->qid), Qencalgs);
218 q.path = QID(CONV(c->qid), Qhashalgs);
222 devdir(c, q, p, 0, nm, 0660, dp);
225 devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, eve, 0555, dp);
228 ds = dstate[CONV(c->qid)];
233 devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, nm, 0660, dp);
239 sslattach(char *spec)
243 c = devattach('D', spec);
244 c->qid.path = QID(0, Qtopdir);
251 sslwalk(Chan *c, Chan *nc, char **name, int nname)
253 return devwalk(c, nc, name, nname, nil, 0, sslgen);
257 sslstat(Chan *c, uchar *db, int n)
259 return devstat(c, db, n, nil, 0, sslgen);
263 sslopen(Chan *c, int omode)
307 pp = &dstate[CONV(c->qid)];
312 if((perm & (s->perm>>6)) != perm
313 && (strcmp(up->user, s->user) != 0
314 || (perm & s->perm) != perm))
328 c->mode = openmode(omode);
335 sslwstat(Chan *c, uchar *db, int n)
341 s = dstate[CONV(c->qid)];
344 if(strcmp(s->user, up->user) != 0)
347 dir = smalloc(sizeof(Dir)+n);
348 m = convM2D(db, n, &dir[0], (char*)&dir[1]);
354 if(!emptystr(dir->uid))
355 kstrdup(&s->user, dir->uid);
356 if(dir->mode != ~0UL)
375 if((c->flag & COPEN) == 0)
378 s = dstate[CONV(c->qid)];
387 dstate[CONV(c->qid)] = 0;
409 * make sure we have at least 'n' bytes in list 'l'
412 ensure(Dstate *s, Block **l, int n)
418 for(b = *l; b; b = b->next){
426 bl = devtab[s->c->type]->bread(s->c, Maxdmsg, 0);
431 for(b = bl; b; b = b->next){
442 * copy 'n' bytes from 'l' into 'p' and free
446 consume(Block **l, uchar *p, int n)
451 for(; *l && n > 0; n -= i){
456 memmove(p, b->rp, i);
471 regurgitate(Dstate *s, uchar *p, int n)
478 if(s->unprocessed == nil || b->rp - b->base < n) {
480 memmove(b->wp, p, n);
482 b->next = s->unprocessed;
486 memmove(b->rp, p, n);
492 * remove at most n bytes from the queue, if discard is set
496 qtake(Block **l, int n, int discard)
498 Block *nb, *b, *first;
502 for(b = first; b; b = b->next){
520 memmove(nb->wp, b->rp+n, i);
540 * We can't let Eintr's lose data since the program
541 * doing the read may be able to handle it. The only
542 * places Eintr is possible is during the read's in consume.
543 * Therefore, we make sure we can always put back the bytes
544 * consumed before the last ensure.
547 sslbread(Chan *c, long n, ulong)
551 uchar consumed[3], *p;
555 s = dstate[CONV(c->qid)];
558 if(s->state == Sincomplete)
567 if(s->processed == 0){
569 * Read in the whole message. Until we've got it all,
570 * it stays on s->unprocessed, so that if we get Eintr,
571 * we'll pick up where we left off.
573 ensure(s, &s->unprocessed, 3);
574 s->unprocessed = pullupblock(s->unprocessed, 2);
575 p = s->unprocessed->rp;
577 len = ((p[0] & 0x7f)<<8) | p[1];
578 ensure(s, &s->unprocessed, len);
582 s->unprocessed = pullupblock(s->unprocessed, 3);
583 len = ((p[0] & 0x3f)<<8) | p[1];
586 print("pad %d buf len %d\n", pad, len);
587 error("bad pad in ssl message");
591 ensure(s, &s->unprocessed, toconsume+len);
594 consume(&s->unprocessed, consumed, toconsume);
596 /* grab the next message and decode/decrypt it */
597 b = qtake(&s->unprocessed, len, 0);
599 if(blocklen(b) != len)
600 print("devssl: sslbread got wrong count %d != %d", blocklen(b), len);
603 qunlock(&s->in.ctlq);
612 error("ssl message too short (encrypting)");
616 b = pullupblock(b, s->diglen);
618 error("ssl message too short (digesting)");
620 pullblock(&b, s->diglen);
625 b = pullupblock(b, s->diglen);
627 error("ssl message too short (dig+enc)");
629 pullblock(&b, s->diglen);
636 s->processed = qtake(&b, len - pad, 1);
641 qunlock(&s->in.ctlq);
645 /* return at most what was asked for */
646 b = qtake(&s->processed, n, 0);
655 sslread(Chan *c, void *a, long n, vlong off)
665 if(c->qid.type & QTDIR)
666 return devdirread(c, a, n, 0, 0, sslgen);
674 sprint(buf, "%d", ft);
675 return readstr(offset, a, n, buf);
677 b = sslbread(c, n, offset);
680 return readstr(offset, a, n, encalgs);
683 return readstr(offset, a, n, hashalgs);
694 for(nb = b; nb; nb = nb->next){
696 memmove(va+n, nb->rp, i);
707 * this algorithm doesn't have to be great since we're just
708 * trying to obscure the block fill
711 randfill(uchar *buf, int len)
718 sslbwrite(Chan *c, Block *b, ulong)
723 s = dstate[CONV(c->qid)];
727 if(s->state == Sincomplete){
732 /* lock so split writes won't interleave */
748 * use SSL record format, add in count, digest and/or encrypt.
749 * the write is interruptable. if it is interrupted, we'll
750 * get out of sync with the far side. not much we can do about
751 * it since we don't know if any bytes have been written.
754 sslput(Dstate *s, Block * volatile b)
757 int h, n, m, pad, rv;
772 /* trim to maximum block size */
776 } else if(s->blocklen != 1){
777 pad = (m + s->diglen)%s->blocklen;
783 pad = s->blocklen - pad;
791 nb = allocb(m + h + pad);
792 memmove(nb->wp + h, b->rp, m);
796 /* add header space */
802 /* SSL style count */
804 nb = padblock(nb, -pad);
805 randfill(nb->wp, pad);
816 p[0] = (m>>8) | 0x80;
823 nb = encryptb(s, nb, offset);
826 nb = digestb(s, nb, offset);
829 nb = digestb(s, nb, offset);
830 nb = encryptb(s, nb, offset);
837 devtab[s->c->type]->bwrite(s->c, nb, s->c->offset);
846 setsecret(OneWay *w, uchar *secret, int n)
851 w->secret = smalloc(n);
852 memmove(w->secret, secret, n);
857 initDESkey(OneWay *w)
864 w->state = smalloc(sizeof(DESstate));
866 setupDESstate(w->state, w->secret, w->secret+8);
867 else if(w->slen >= 8)
868 setupDESstate(w->state, w->secret, 0);
870 error("secret too short");
874 * 40 bit DES is the same as 56 bit DES. However,
875 * 16 bits of the key are masked to zero.
878 initDESkey_40(OneWay *w)
888 memmove(key, w->secret, 8);
895 w->state = smalloc(sizeof(DESstate));
897 setupDESstate(w->state, key, w->secret+8);
898 else if(w->slen >= 8)
899 setupDESstate(w->state, key, 0);
901 error("secret too short");
905 initRC4key(OneWay *w)
912 w->state = smalloc(sizeof(RC4state));
913 setupRC4state(w->state, w->secret, w->slen);
917 * 40 bit RC4 is the same as n-bit RC4. However,
918 * we ignore all but the first 40 bits of the key.
921 initRC4key_40(OneWay *w)
931 w->state = smalloc(sizeof(RC4state));
932 setupRC4state(w->state, w->secret, w->slen);
936 * 128 bit RC4 is the same as n-bit RC4. However,
937 * we ignore all but the first 128 bits of the key.
940 initRC4key_128(OneWay *w)
950 w->state = smalloc(sizeof(RC4state));
951 setupRC4state(w->state, w->secret, w->slen);
955 typedef struct Hashalg Hashalg;
960 DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*);
965 { "md4", MD4dlen, md4, },
966 { "md5", MD5dlen, md5, },
967 { "sha1", SHA1dlen, sha1, },
968 { "sha", SHA1dlen, sha1, },
973 parsehashalg(char *p, Dstate *s)
977 for(ha = hashtab; ha->name; ha++){
978 if(strcmp(p, ha->name) == 0){
980 s->diglen = ha->diglen;
982 s->state |= Sdigesting;
989 typedef struct Encalg Encalg;
995 void (*keyinit)(OneWay*);
999 Encalg encrypttab[] =
1001 { "descbc", 8, DESCBC, initDESkey, }, /* DEPRECATED -- use des_56_cbc */
1002 { "desecb", 8, DESECB, initDESkey, }, /* DEPRECATED -- use des_56_ecb */
1003 { "des_56_cbc", 8, DESCBC, initDESkey, },
1004 { "des_56_ecb", 8, DESECB, initDESkey, },
1005 { "des_40_cbc", 8, DESCBC, initDESkey_40, },
1006 { "des_40_ecb", 8, DESECB, initDESkey_40, },
1007 { "rc4", 1, RC4, initRC4key_40, }, /* DEPRECATED -- use rc4_X */
1008 { "rc4_256", 1, RC4, initRC4key, },
1009 { "rc4_128", 1, RC4, initRC4key_128, },
1010 { "rc4_40", 1, RC4, initRC4key_40, },
1014 Encalg encrypttab[] =
1016 { "des_40_cbc", 8, DESCBC, initDESkey_40, },
1017 { "des_40_ecb", 8, DESECB, initDESkey_40, },
1018 { "rc4", 1, RC4, initRC4key_40, }, /* DEPRECATED -- use rc4_X */
1019 { "rc4_40", 1, RC4, initRC4key_40, },
1025 parseencryptalg(char *p, Dstate *s)
1029 for(ea = encrypttab; ea->name; ea++){
1030 if(strcmp(p, ea->name) == 0){
1031 s->encryptalg = ea->alg;
1032 s->blocklen = ea->blocklen;
1033 (*ea->keyinit)(&s->in);
1034 (*ea->keyinit)(&s->out);
1035 s->state &= ~Sclear;
1036 s->state |= Sencrypting;
1044 sslwrite(Chan *c, void *a, long n, vlong)
1046 Dstate * volatile s;
1049 char *p, *np, *e, buf[128];
1052 s = dstate[CONV(c->qid)];
1058 if(s->state == Sincomplete)
1061 /* lock should a write gets split over multiple records */
1080 memmove(b->wp, p, m);
1094 /* mutex with operations using what we're about to change */
1096 qunlock(&s->in.ctlq);
1107 setsecret(&s->in, a, n);
1110 setsecret(&s->out, a, n);
1116 if(n >= sizeof(buf))
1117 error("arg too long");
1120 p = strchr(buf, '\n');
1123 p = strchr(buf, ' ');
1127 if(strcmp(buf, "fd") == 0){
1128 s->c = buftochan(p);
1130 /* default is clear (msg delimiters only) */
1134 s->maxpad = s->max = (1<<15) - s->diglen - 1;
1137 } else if(strcmp(buf, "alg") == 0 && p != 0){
1142 error("must set fd before algorithm");
1145 s->maxpad = s->max = (1<<15) - s->diglen - 1;
1146 if(strcmp(p, "clear") == 0){
1150 if(s->in.secret && s->out.secret == 0)
1151 setsecret(&s->out, s->in.secret, s->in.slen);
1152 if(s->out.secret && s->in.secret == 0)
1153 setsecret(&s->in, s->out.secret, s->out.slen);
1154 if(s->in.secret == 0 || s->out.secret == 0)
1155 error("algorithm but no secret");
1158 s->encryptalg = Noencryption;
1162 np = strchr(p, ' ');
1166 if(parsehashalg(p, s) < 0)
1167 if(parseencryptalg(p, s) < 0)
1168 error("bad algorithm");
1175 if(s->hf == 0 && s->encryptalg == Noencryption)
1176 error("bad algorithm");
1178 if(s->blocklen != 1){
1179 s->max = (1<<15) - s->diglen - 1;
1180 s->max -= s->max % s->blocklen;
1181 s->maxpad = (1<<14) - s->diglen - 1;
1182 s->maxpad -= s->maxpad % s->blocklen;
1184 s->maxpad = s->max = (1<<15) - s->diglen - 1;
1185 } else if(strcmp(buf, "secretin") == 0 && p != 0) {
1186 m = (strlen(p)*3)/2;
1188 t = dec64(x, m, p, strlen(p));
1193 setsecret(&s->in, x, t);
1195 } else if(strcmp(buf, "secretout") == 0 && p != 0) {
1196 m = (strlen(p)*3)/2 + 1;
1198 t = dec64(x, m, p, strlen(p));
1203 setsecret(&s->out, x, t);
1209 qunlock(&s->in.ctlq);
1224 for(e = encrypttab; e->name != nil; e++)
1225 n += strlen(e->name) + 1;
1226 cp = encalgs = smalloc(n);
1227 for(e = encrypttab;;){
1228 strcpy(cp, e->name);
1229 cp += strlen(e->name);
1238 for(h = hashtab; h->name != nil; h++)
1239 n += strlen(h->name) + 1;
1240 cp = hashalgs = smalloc(n);
1242 strcpy(cp, h->name);
1243 cp += strlen(h->name);
1274 encryptb(Dstate *s, Block *b, int offset)
1276 uchar *p, *ep, *p2, *ip, *eip;
1279 switch(s->encryptalg){
1282 ep = b->rp + BLEN(b);
1283 for(p = b->rp + offset; p < ep; p += 8)
1284 block_cipher(ds->expanded, p, 0);
1288 ep = b->rp + BLEN(b);
1289 for(p = b->rp + offset; p < ep; p += 8){
1292 for(eip = ip+8; ip < eip; )
1294 block_cipher(ds->expanded, p, 0);
1295 memmove(ds->ivec, p, 8);
1299 rc4(s->out.state, b->rp + offset, BLEN(b) - offset);
1306 decryptb(Dstate *s, Block *bin)
1309 uchar *p, *ep, *tp, *ip, *eip;
1315 for(b = bin; b; b = b->next){
1316 /* make sure we have a multiple of s->blocklen */
1317 if(s->blocklen > 1){
1319 if(i % s->blocklen){
1320 *l = b = pullupblock(b, i + s->blocklen - (i%s->blocklen));
1322 error("ssl encrypted message too short");
1328 switch(s->encryptalg){
1331 ep = b->rp + BLEN(b);
1332 for(p = b->rp; p < ep; p += 8)
1333 block_cipher(ds->expanded, p, 1);
1337 ep = b->rp + BLEN(b);
1338 for(p = b->rp; p < ep;){
1340 block_cipher(ds->expanded, p, 1);
1343 for(eip = ip+8; ip < eip; ){
1350 rc4(s->in.state, b->rp, BLEN(b));
1358 digestb(Dstate *s, Block *b, int offset)
1368 memset(&ss, 0, sizeof(ss));
1369 h = s->diglen + offset;
1372 /* hash secret + message */
1373 (*s->hf)(w->secret, w->slen, 0, &ss);
1374 (*s->hf)(b->rp + h, n, 0, &ss);
1376 /* hash message id */
1383 (*s->hf)(msgid, 4, b->rp + offset, &ss);
1389 checkdigestb(Dstate *s, Block *bin)
1401 memset(&ss, 0, sizeof(ss));
1404 (*s->hf)(w->secret, w->slen, 0, &ss);
1408 for(b = bin; b; b = b->next){
1411 panic("checkdigestb");
1412 (*s->hf)(b->rp + h, n, 0, &ss);
1416 /* hash message id */
1423 (*s->hf)(msgid, 4, digest, &ss);
1425 if(memcmp(digest, bin->rp, s->diglen) != 0)
1426 error("bad digest");
1429 /* get channel associated with an fd */
1438 fd = strtoul(p, 0, 0);
1441 c = fdtochan(fd, -1, 0, 1); /* error check and inc ref */
1442 if(devtab[c->type] == &ssldevtab){
1444 error("cannot ssl encrypt devssl files");
1449 /* hand up a digest connection */
1451 sslhangup(Dstate *s)
1456 for(b = s->processed; b; b = s->processed){
1457 s->processed = b->next;
1461 freeb(s->unprocessed);
1464 s->state = Sincomplete;
1480 for(i=0; i<Maxdstate; i++){
1481 if(dstate[i] == nil){
1482 dsnew(ch, &dstate[i]);
1493 dsnew(Chan *ch, Dstate **pp)
1498 *pp = s = malloc(sizeof(*s));
1501 if(pp - dstate >= dshiwat)
1503 memset(s, 0, sizeof(*s));
1504 s->state = Sincomplete;
1506 kstrdup(&s->user, up->user);
1511 ch->qid.path = QID(pp - dstate, t);