1 /* 2 * devssl - secure sockets layer 3 */ 4 #include "u.h" 5 #include "lib.h" 6 #include "dat.h" 7 #include "fns.h" 8 #include "error.h" 9 10 #include "libsec.h" 11 12 #define NOSPOOKS 1 13 14 typedef struct OneWay OneWay; 15 struct OneWay 16 { 17 QLock q; 18 QLock ctlq; 19 20 void *state; /* encryption state */ 21 int slen; /* hash data length */ 22 uchar *secret; /* secret */ 23 ulong mid; /* message id */ 24 }; 25 26 enum 27 { 28 /* connection states */ 29 Sincomplete= 0, 30 Sclear= 1, 31 Sencrypting= 2, 32 Sdigesting= 4, 33 Sdigenc= Sencrypting|Sdigesting, 34 35 /* encryption algorithms */ 36 Noencryption= 0, 37 DESCBC= 1, 38 DESECB= 2, 39 RC4= 3 40 }; 41 42 typedef struct Dstate Dstate; 43 struct Dstate 44 { 45 Chan *c; /* io channel */ 46 uchar state; /* state of connection */ 47 int ref; /* serialized by dslock for atomic destroy */ 48 49 uchar encryptalg; /* encryption algorithm */ 50 ushort blocklen; /* blocking length */ 51 52 ushort diglen; /* length of digest */ 53 DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*); /* hash func */ 54 55 /* for SSL format */ 56 int max; /* maximum unpadded data per msg */ 57 int maxpad; /* maximum padded data per msg */ 58 59 /* input side */ 60 OneWay in; 61 Block *processed; 62 Block *unprocessed; 63 64 /* output side */ 65 OneWay out; 66 67 /* protections */ 68 char *user; 69 int perm; 70 }; 71 72 enum 73 { 74 Maxdmsg= 1<<16, 75 Maxdstate= 128, /* must be a power of 2 */ 76 }; 77 78 Lock dslock; 79 int dshiwat; 80 char *dsname[Maxdstate]; 81 Dstate *dstate[Maxdstate]; 82 char *encalgs; 83 char *hashalgs; 84 85 enum{ 86 Qtopdir = 1, /* top level directory */ 87 Qprotodir, 88 Qclonus, 89 Qconvdir, /* directory for a conversation */ 90 Qdata, 91 Qctl, 92 Qsecretin, 93 Qsecretout, 94 Qencalgs, 95 Qhashalgs, 96 }; 97 98 #define TYPE(x) ((x).path & 0xf) 99 #define CONV(x) (((x).path >> 5)&(Maxdstate-1)) 100 #define QID(c, y) (((c)<<5) | (y)) 101 102 static void ensure(Dstate*, Block**, int); 103 static void consume(Block**, uchar*, int); 104 static void setsecret(OneWay*, uchar*, int); 105 static Block* encryptb(Dstate*, Block*, int); 106 static Block* decryptb(Dstate*, Block*); 107 static Block* digestb(Dstate*, Block*, int); 108 static void checkdigestb(Dstate*, Block*); 109 static Chan* buftochan(char*); 110 static void sslhangup(Dstate*); 111 static Dstate* dsclone(Chan *c); 112 static void dsnew(Chan *c, Dstate **); 113 static long sslput(Dstate *s, Block * volatile b); 114 115 char *sslnames[] = { 116 /* unused */ 0, 117 /* topdir */ 0, 118 /* protodir */ 0, 119 "clone", 120 /* convdir */ 0, 121 "data", 122 "ctl", 123 "secretin", 124 "secretout", 125 "encalgs", 126 "hashalgs", 127 }; 128 129 static int 130 sslgen(Chan *c, char *n, Dirtab *d, int nd, int s, Dir *dp) 131 { 132 Qid q; 133 Dstate *ds; 134 char name[16], *p, *nm; 135 int ft; 136 137 USED(n); 138 USED(nd); 139 USED(d); 140 141 q.type = QTFILE; 142 q.vers = 0; 143 144 ft = TYPE(c->qid); 145 switch(ft) { 146 case Qtopdir: 147 if(s == DEVDOTDOT){ 148 q.path = QID(0, Qtopdir); 149 q.type = QTDIR; 150 devdir(c, q, "#D", 0, eve, 0555, dp); 151 return 1; 152 } 153 if(s > 0) 154 return -1; 155 q.path = QID(0, Qprotodir); 156 q.type = QTDIR; 157 devdir(c, q, "ssl", 0, eve, 0555, dp); 158 return 1; 159 case Qprotodir: 160 if(s == DEVDOTDOT){ 161 q.path = QID(0, Qtopdir); 162 q.type = QTDIR; 163 devdir(c, q, ".", 0, eve, 0555, dp); 164 return 1; 165 } 166 if(s < dshiwat) { 167 q.path = QID(s, Qconvdir); 168 q.type = QTDIR; 169 ds = dstate[s]; 170 if(ds != 0) 171 nm = ds->user; 172 else 173 nm = eve; 174 if(dsname[s] == nil){ 175 sprint(name, "%d", s); 176 kstrdup(&dsname[s], name); 177 } 178 devdir(c, q, dsname[s], 0, nm, 0555, dp); 179 return 1; 180 } 181 if(s > dshiwat) 182 return -1; 183 q.path = QID(0, Qclonus); 184 devdir(c, q, "clone", 0, eve, 0555, dp); 185 return 1; 186 case Qconvdir: 187 if(s == DEVDOTDOT){ 188 q.path = QID(0, Qprotodir); 189 q.type = QTDIR; 190 devdir(c, q, "ssl", 0, eve, 0555, dp); 191 return 1; 192 } 193 ds = dstate[CONV(c->qid)]; 194 if(ds != 0) 195 nm = ds->user; 196 else 197 nm = eve; 198 switch(s) { 199 default: 200 return -1; 201 case 0: 202 q.path = QID(CONV(c->qid), Qctl); 203 p = "ctl"; 204 break; 205 case 1: 206 q.path = QID(CONV(c->qid), Qdata); 207 p = "data"; 208 break; 209 case 2: 210 q.path = QID(CONV(c->qid), Qsecretin); 211 p = "secretin"; 212 break; 213 case 3: 214 q.path = QID(CONV(c->qid), Qsecretout); 215 p = "secretout"; 216 break; 217 case 4: 218 q.path = QID(CONV(c->qid), Qencalgs); 219 p = "encalgs"; 220 break; 221 case 5: 222 q.path = QID(CONV(c->qid), Qhashalgs); 223 p = "hashalgs"; 224 break; 225 } 226 devdir(c, q, p, 0, nm, 0660, dp); 227 return 1; 228 case Qclonus: 229 devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, eve, 0555, dp); 230 return 1; 231 default: 232 ds = dstate[CONV(c->qid)]; 233 if(ds != 0) 234 nm = ds->user; 235 else 236 nm = eve; 237 devdir(c, c->qid, sslnames[TYPE(c->qid)], 0, nm, 0660, dp); 238 return 1; 239 } 240 return -1; 241 } 242 243 static Chan* 244 sslattach(char *spec) 245 { 246 Chan *c; 247 248 c = devattach('D', spec); 249 c->qid.path = QID(0, Qtopdir); 250 c->qid.vers = 0; 251 c->qid.type = QTDIR; 252 return c; 253 } 254 255 static Walkqid* 256 sslwalk(Chan *c, Chan *nc, char **name, int nname) 257 { 258 return devwalk(c, nc, name, nname, nil, 0, sslgen); 259 } 260 261 static int 262 sslstat(Chan *c, uchar *db, int n) 263 { 264 return devstat(c, db, n, nil, 0, sslgen); 265 } 266 267 static Chan* 268 sslopen(Chan *c, int omode) 269 { 270 Dstate *s, **pp; 271 int perm; 272 int ft; 273 274 perm = 0; 275 omode &= 3; 276 switch(omode) { 277 case OREAD: 278 perm = 4; 279 break; 280 case OWRITE: 281 perm = 2; 282 break; 283 case ORDWR: 284 perm = 6; 285 break; 286 } 287 288 ft = TYPE(c->qid); 289 switch(ft) { 290 default: 291 panic("sslopen"); 292 case Qtopdir: 293 case Qprotodir: 294 case Qconvdir: 295 if(omode != OREAD) 296 error(Eperm); 297 break; 298 case Qclonus: 299 s = dsclone(c); 300 if(s == 0) 301 error(Enodev); 302 break; 303 case Qctl: 304 case Qdata: 305 case Qsecretin: 306 case Qsecretout: 307 if(waserror()) { 308 unlock(&dslock); 309 nexterror(); 310 } 311 lock(&dslock); 312 pp = &dstate[CONV(c->qid)]; 313 s = *pp; 314 if(s == 0) 315 dsnew(c, pp); 316 else { 317 if((perm & (s->perm>>6)) != perm 318 && (strcmp(up->user, s->user) != 0 319 || (perm & s->perm) != perm)) 320 error(Eperm); 321 322 s->ref++; 323 } 324 unlock(&dslock); 325 poperror(); 326 break; 327 case Qencalgs: 328 case Qhashalgs: 329 if(omode != OREAD) 330 error(Eperm); 331 break; 332 } 333 c->mode = openmode(omode); 334 c->flag |= COPEN; 335 c->offset = 0; 336 return c; 337 } 338 339 static int 340 sslwstat(Chan *c, uchar *db, int n) 341 { 342 Dir *dir; 343 Dstate *s; 344 int m; 345 346 s = dstate[CONV(c->qid)]; 347 if(s == 0) 348 error(Ebadusefd); 349 if(strcmp(s->user, up->user) != 0) 350 error(Eperm); 351 352 dir = smalloc(sizeof(Dir)+n); 353 m = convM2D(db, n, &dir[0], (char*)&dir[1]); 354 if(m == 0){ 355 free(dir); 356 error(Eshortstat); 357 } 358 359 if(!emptystr(dir->uid)) 360 kstrdup(&s->user, dir->uid); 361 if(dir->mode != ~0) 362 s->perm = dir->mode; 363 364 free(dir); 365 return m; 366 } 367 368 static void 369 sslclose(Chan *c) 370 { 371 Dstate *s; 372 int ft; 373 374 ft = TYPE(c->qid); 375 switch(ft) { 376 case Qctl: 377 case Qdata: 378 case Qsecretin: 379 case Qsecretout: 380 if((c->flag & COPEN) == 0) 381 break; 382 383 s = dstate[CONV(c->qid)]; 384 if(s == 0) 385 break; 386 387 lock(&dslock); 388 if(--s->ref > 0) { 389 unlock(&dslock); 390 break; 391 } 392 dstate[CONV(c->qid)] = 0; 393 unlock(&dslock); 394 395 if(s->user != nil) 396 free(s->user); 397 sslhangup(s); 398 if(s->c) 399 cclose(s->c); 400 if(s->in.secret) 401 free(s->in.secret); 402 if(s->out.secret) 403 free(s->out.secret); 404 if(s->in.state) 405 free(s->in.state); 406 if(s->out.state) 407 free(s->out.state); 408 free(s); 409 410 } 411 } 412 413 /* 414 * make sure we have at least 'n' bytes in list 'l' 415 */ 416 static void 417 ensure(Dstate *s, Block **l, int n) 418 { 419 int sofar, i; 420 Block *b, *bl; 421 422 sofar = 0; 423 for(b = *l; b; b = b->next){ 424 sofar += BLEN(b); 425 if(sofar >= n) 426 return; 427 l = &b->next; 428 } 429 430 while(sofar < n){ 431 bl = devtab[s->c->type]->bread(s->c, Maxdmsg, 0); 432 if(bl == 0) 433 nexterror(); 434 *l = bl; 435 i = 0; 436 for(b = bl; b; b = b->next){ 437 i += BLEN(b); 438 l = &b->next; 439 } 440 if(i == 0) 441 error(Ehungup); 442 sofar += i; 443 } 444 } 445 446 /* 447 * copy 'n' bytes from 'l' into 'p' and free 448 * the bytes in 'l' 449 */ 450 static void 451 consume(Block **l, uchar *p, int n) 452 { 453 Block *b; 454 int i; 455 456 for(; *l && n > 0; n -= i){ 457 b = *l; 458 i = BLEN(b); 459 if(i > n) 460 i = n; 461 memmove(p, b->rp, i); 462 b->rp += i; 463 p += i; 464 if(BLEN(b) < 0) 465 panic("consume"); 466 if(BLEN(b)) 467 break; 468 *l = b->next; 469 freeb(b); 470 } 471 } 472 473 /* 474 * give back n bytes 475 static void 476 regurgitate(Dstate *s, uchar *p, int n) 477 { 478 Block *b; 479 480 if(n <= 0) 481 return; 482 b = s->unprocessed; 483 if(s->unprocessed == nil || b->rp - b->base < n) { 484 b = allocb(n); 485 memmove(b->wp, p, n); 486 b->wp += n; 487 b->next = s->unprocessed; 488 s->unprocessed = b; 489 } else { 490 b->rp -= n; 491 memmove(b->rp, p, n); 492 } 493 } 494 */ 495 496 /* 497 * remove at most n bytes from the queue, if discard is set 498 * dump the remainder 499 */ 500 static Block* 501 qtake(Block **l, int n, int discard) 502 { 503 Block *nb, *b, *first; 504 int i; 505 506 first = *l; 507 for(b = first; b; b = b->next){ 508 i = BLEN(b); 509 if(i == n){ 510 if(discard){ 511 freeblist(b->next); 512 *l = 0; 513 } else 514 *l = b->next; 515 b->next = 0; 516 return first; 517 } else if(i > n){ 518 i -= n; 519 if(discard){ 520 freeblist(b->next); 521 b->wp -= i; 522 *l = 0; 523 } else { 524 nb = allocb(i); 525 memmove(nb->wp, b->rp+n, i); 526 nb->wp += i; 527 b->wp -= i; 528 nb->next = b->next; 529 *l = nb; 530 } 531 b->next = 0; 532 if(BLEN(b) < 0) 533 panic("qtake"); 534 return first; 535 } else 536 n -= i; 537 if(BLEN(b) < 0) 538 panic("qtake"); 539 } 540 *l = 0; 541 return first; 542 } 543 544 /* 545 * We can't let Eintr's lose data since the program 546 * doing the read may be able to handle it. The only 547 * places Eintr is possible is during the read's in consume. 548 * Therefore, we make sure we can always put back the bytes 549 * consumed before the last ensure. 550 */ 551 static Block* 552 sslbread(Chan *c, long n, ulong o) 553 { 554 Dstate * volatile s; 555 Block *b; 556 uchar consumed[3], *p; 557 int toconsume; 558 int len, pad; 559 560 USED(o); 561 s = dstate[CONV(c->qid)]; 562 if(s == 0) 563 panic("sslbread"); 564 if(s->state == Sincomplete) 565 error(Ebadusefd); 566 567 qlock(&s->in.q); 568 if(waserror()){ 569 qunlock(&s->in.q); 570 nexterror(); 571 } 572 573 if(s->processed == 0){ 574 /* 575 * Read in the whole message. Until we've got it all, 576 * it stays on s->unprocessed, so that if we get Eintr, 577 * we'll pick up where we left off. 578 */ 579 ensure(s, &s->unprocessed, 3); 580 s->unprocessed = pullupblock(s->unprocessed, 2); 581 p = s->unprocessed->rp; 582 if(p[0] & 0x80){ 583 len = ((p[0] & 0x7f)<<8) | p[1]; 584 ensure(s, &s->unprocessed, len); 585 pad = 0; 586 toconsume = 2; 587 } else { 588 s->unprocessed = pullupblock(s->unprocessed, 3); 589 len = ((p[0] & 0x3f)<<8) | p[1]; 590 pad = p[2]; 591 if(pad > len){ 592 print("pad %d buf len %d\n", pad, len); 593 error("bad pad in ssl message"); 594 } 595 toconsume = 3; 596 } 597 ensure(s, &s->unprocessed, toconsume+len); 598 599 /* skip header */ 600 consume(&s->unprocessed, consumed, toconsume); 601 602 /* grab the next message and decode/decrypt it */ 603 b = qtake(&s->unprocessed, len, 0); 604 605 if(blocklen(b) != len) 606 print("devssl: sslbread got wrong count %d != %d", blocklen(b), len); 607 608 if(waserror()){ 609 qunlock(&s->in.ctlq); 610 if(b != nil) 611 freeb(b); 612 nexterror(); 613 } 614 qlock(&s->in.ctlq); 615 switch(s->state){ 616 case Sencrypting: 617 if(b == nil) 618 error("ssl message too short (encrypting)"); 619 b = decryptb(s, b); 620 break; 621 case Sdigesting: 622 b = pullupblock(b, s->diglen); 623 if(b == nil) 624 error("ssl message too short (digesting)"); 625 checkdigestb(s, b); 626 pullblock(&b, s->diglen); 627 len -= s->diglen; 628 break; 629 case Sdigenc: 630 b = decryptb(s, b); 631 b = pullupblock(b, s->diglen); 632 if(b == nil) 633 error("ssl message too short (dig+enc)"); 634 checkdigestb(s, b); 635 pullblock(&b, s->diglen); 636 len -= s->diglen; 637 break; 638 } 639 640 /* remove pad */ 641 if(pad) 642 s->processed = qtake(&b, len - pad, 1); 643 else 644 s->processed = b; 645 b = nil; 646 s->in.mid++; 647 qunlock(&s->in.ctlq); 648 poperror(); 649 } 650 651 /* return at most what was asked for */ 652 b = qtake(&s->processed, n, 0); 653 654 qunlock(&s->in.q); 655 poperror(); 656 657 return b; 658 } 659 660 static long 661 sslread(Chan *c, void *a, long n, vlong off) 662 { 663 Block * volatile b; 664 Block *nb; 665 uchar *va; 666 int i; 667 char buf[128]; 668 ulong offset = off; 669 int ft; 670 671 if(c->qid.type & QTDIR) 672 return devdirread(c, a, n, 0, 0, sslgen); 673 674 ft = TYPE(c->qid); 675 switch(ft) { 676 default: 677 error(Ebadusefd); 678 case Qctl: 679 ft = CONV(c->qid); 680 sprint(buf, "%d", ft); 681 return readstr(offset, a, n, buf); 682 case Qdata: 683 b = sslbread(c, n, offset); 684 break; 685 case Qencalgs: 686 return readstr(offset, a, n, encalgs); 687 break; 688 case Qhashalgs: 689 return readstr(offset, a, n, hashalgs); 690 break; 691 } 692 693 if(waserror()){ 694 freeblist(b); 695 nexterror(); 696 } 697 698 n = 0; 699 va = a; 700 for(nb = b; nb; nb = nb->next){ 701 i = BLEN(nb); 702 memmove(va+n, nb->rp, i); 703 n += i; 704 } 705 706 freeblist(b); 707 poperror(); 708 709 return n; 710 } 711 712 /* 713 * this algorithm doesn't have to be great since we're just 714 * trying to obscure the block fill 715 */ 716 static void 717 randfill(uchar *buf, int len) 718 { 719 while(len-- > 0) 720 *buf++ = fastrand(); 721 } 722 723 static long 724 sslbwrite(Chan *c, Block *b, ulong o) 725 { 726 Dstate * volatile s; 727 long rv; 728 729 USED(o); 730 s = dstate[CONV(c->qid)]; 731 if(s == nil) 732 panic("sslbwrite"); 733 734 if(s->state == Sincomplete){ 735 freeb(b); 736 error(Ebadusefd); 737 } 738 739 /* lock so split writes won't interleave */ 740 if(waserror()){ 741 qunlock(&s->out.q); 742 nexterror(); 743 } 744 qlock(&s->out.q); 745 746 rv = sslput(s, b); 747 748 poperror(); 749 qunlock(&s->out.q); 750 751 return rv; 752 } 753 754 /* 755 * use SSL record format, add in count, digest and/or encrypt. 756 * the write is interruptable. if it is interrupted, we'll 757 * get out of sync with the far side. not much we can do about 758 * it since we don't know if any bytes have been written. 759 */ 760 static long 761 sslput(Dstate *s, Block * volatile b) 762 { 763 Block *nb; 764 int h, n, m, pad, rv; 765 uchar *p; 766 int offset; 767 768 if(waserror()){ 769 iprint("error: %s\n", up->errstr); 770 if(b != nil) 771 free(b); 772 nexterror(); 773 } 774 775 rv = 0; 776 while(b != nil){ 777 m = n = BLEN(b); 778 h = s->diglen + 2; 779 780 /* trim to maximum block size */ 781 pad = 0; 782 if(m > s->max){ 783 m = s->max; 784 } else if(s->blocklen != 1){ 785 pad = (m + s->diglen)%s->blocklen; 786 if(pad){ 787 if(m > s->maxpad){ 788 pad = 0; 789 m = s->maxpad; 790 } else { 791 pad = s->blocklen - pad; 792 h++; 793 } 794 } 795 } 796 797 rv += m; 798 if(m != n){ 799 nb = allocb(m + h + pad); 800 memmove(nb->wp + h, b->rp, m); 801 nb->wp += m + h; 802 b->rp += m; 803 } else { 804 /* add header space */ 805 nb = padblock(b, h); 806 b = 0; 807 } 808 m += s->diglen; 809 810 /* SSL style count */ 811 if(pad){ 812 nb = padblock(nb, -pad); 813 randfill(nb->wp, pad); 814 nb->wp += pad; 815 m += pad; 816 817 p = nb->rp; 818 p[0] = (m>>8); 819 p[1] = m; 820 p[2] = pad; 821 offset = 3; 822 } else { 823 p = nb->rp; 824 p[0] = (m>>8) | 0x80; 825 p[1] = m; 826 offset = 2; 827 } 828 829 switch(s->state){ 830 case Sencrypting: 831 nb = encryptb(s, nb, offset); 832 break; 833 case Sdigesting: 834 nb = digestb(s, nb, offset); 835 break; 836 case Sdigenc: 837 nb = digestb(s, nb, offset); 838 nb = encryptb(s, nb, offset); 839 break; 840 } 841 842 s->out.mid++; 843 844 m = BLEN(nb); 845 devtab[s->c->type]->bwrite(s->c, nb, s->c->offset); 846 s->c->offset += m; 847 } 848 849 poperror(); 850 return rv; 851 } 852 853 static void 854 setsecret(OneWay *w, uchar *secret, int n) 855 { 856 if(w->secret) 857 free(w->secret); 858 859 w->secret = smalloc(n); 860 memmove(w->secret, secret, n); 861 w->slen = n; 862 } 863 864 static void 865 initDESkey(OneWay *w) 866 { 867 if(w->state){ 868 free(w->state); 869 w->state = 0; 870 } 871 872 w->state = smalloc(sizeof(DESstate)); 873 if(w->slen >= 16) 874 setupDESstate(w->state, w->secret, w->secret+8); 875 else if(w->slen >= 8) 876 setupDESstate(w->state, w->secret, 0); 877 else 878 error("secret too short"); 879 } 880 881 /* 882 * 40 bit DES is the same as 56 bit DES. However, 883 * 16 bits of the key are masked to zero. 884 */ 885 static void 886 initDESkey_40(OneWay *w) 887 { 888 uchar key[8]; 889 890 if(w->state){ 891 free(w->state); 892 w->state = 0; 893 } 894 895 if(w->slen >= 8){ 896 memmove(key, w->secret, 8); 897 key[0] &= 0x0f; 898 key[2] &= 0x0f; 899 key[4] &= 0x0f; 900 key[6] &= 0x0f; 901 } 902 903 w->state = malloc(sizeof(DESstate)); 904 if(w->slen >= 16) 905 setupDESstate(w->state, key, w->secret+8); 906 else if(w->slen >= 8) 907 setupDESstate(w->state, key, 0); 908 else 909 error("secret too short"); 910 } 911 912 static void 913 initRC4key(OneWay *w) 914 { 915 if(w->state){ 916 free(w->state); 917 w->state = 0; 918 } 919 920 w->state = smalloc(sizeof(RC4state)); 921 setupRC4state(w->state, w->secret, w->slen); 922 } 923 924 /* 925 * 40 bit RC4 is the same as n-bit RC4. However, 926 * we ignore all but the first 40 bits of the key. 927 */ 928 static void 929 initRC4key_40(OneWay *w) 930 { 931 if(w->state){ 932 free(w->state); 933 w->state = 0; 934 } 935 936 if(w->slen > 5) 937 w->slen = 5; 938 939 w->state = malloc(sizeof(RC4state)); 940 setupRC4state(w->state, w->secret, w->slen); 941 } 942 943 /* 944 * 128 bit RC4 is the same as n-bit RC4. However, 945 * we ignore all but the first 128 bits of the key. 946 */ 947 static void 948 initRC4key_128(OneWay *w) 949 { 950 if(w->state){ 951 free(w->state); 952 w->state = 0; 953 } 954 955 if(w->slen > 16) 956 w->slen = 16; 957 958 w->state = malloc(sizeof(RC4state)); 959 setupRC4state(w->state, w->secret, w->slen); 960 } 961 962 963 typedef struct Hashalg Hashalg; 964 struct Hashalg 965 { 966 char *name; 967 int diglen; 968 DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*); 969 }; 970 971 Hashalg hashtab[] = 972 { 973 { "md4", MD4dlen, md4, }, 974 { "md5", MD5dlen, md5, }, 975 { "sha1", SHA1dlen, sha1, }, 976 { "sha", SHA1dlen, sha1, }, 977 { 0 } 978 }; 979 980 static int 981 parsehashalg(char *p, Dstate *s) 982 { 983 Hashalg *ha; 984 985 for(ha = hashtab; ha->name; ha++){ 986 if(strcmp(p, ha->name) == 0){ 987 s->hf = ha->hf; 988 s->diglen = ha->diglen; 989 s->state &= ~Sclear; 990 s->state |= Sdigesting; 991 return 0; 992 } 993 } 994 return -1; 995 } 996 997 typedef struct Encalg Encalg; 998 struct Encalg 999 { 1000 char *name; 1001 int blocklen; 1002 int alg; 1003 void (*keyinit)(OneWay*); 1004 }; 1005 1006 #ifdef NOSPOOKS 1007 Encalg encrypttab[] = 1008 { 1009 { "descbc", 8, DESCBC, initDESkey, }, /* DEPRECATED -- use des_56_cbc */ 1010 { "desecb", 8, DESECB, initDESkey, }, /* DEPRECATED -- use des_56_ecb */ 1011 { "des_56_cbc", 8, DESCBC, initDESkey, }, 1012 { "des_56_ecb", 8, DESECB, initDESkey, }, 1013 { "des_40_cbc", 8, DESCBC, initDESkey_40, }, 1014 { "des_40_ecb", 8, DESECB, initDESkey_40, }, 1015 { "rc4", 1, RC4, initRC4key_40, }, /* DEPRECATED -- use rc4_X */ 1016 { "rc4_256", 1, RC4, initRC4key, }, 1017 { "rc4_128", 1, RC4, initRC4key_128, }, 1018 { "rc4_40", 1, RC4, initRC4key_40, }, 1019 { 0 } 1020 }; 1021 #else 1022 Encalg encrypttab[] = 1023 { 1024 { "des_40_cbc", 8, DESCBC, initDESkey_40, }, 1025 { "des_40_ecb", 8, DESECB, initDESkey_40, }, 1026 { "rc4", 1, RC4, initRC4key_40, }, /* DEPRECATED -- use rc4_X */ 1027 { "rc4_40", 1, RC4, initRC4key_40, }, 1028 { 0 } 1029 }; 1030 #endif /* NOSPOOKS */ 1031 1032 static int 1033 parseencryptalg(char *p, Dstate *s) 1034 { 1035 Encalg *ea; 1036 1037 for(ea = encrypttab; ea->name; ea++){ 1038 if(strcmp(p, ea->name) == 0){ 1039 s->encryptalg = ea->alg; 1040 s->blocklen = ea->blocklen; 1041 (*ea->keyinit)(&s->in); 1042 (*ea->keyinit)(&s->out); 1043 s->state &= ~Sclear; 1044 s->state |= Sencrypting; 1045 return 0; 1046 } 1047 } 1048 return -1; 1049 } 1050 1051 static long 1052 sslwrite(Chan *c, void *a, long n, vlong o) 1053 { 1054 Dstate * volatile s; 1055 Block * volatile b; 1056 int m, t; 1057 char *p, *np, *e, buf[128]; 1058 uchar *x; 1059 1060 USED(o); 1061 s = dstate[CONV(c->qid)]; 1062 if(s == 0) 1063 panic("sslwrite"); 1064 1065 t = TYPE(c->qid); 1066 if(t == Qdata){ 1067 if(s->state == Sincomplete) 1068 error(Ebadusefd); 1069 1070 /* lock should a write gets split over multiple records */ 1071 if(waserror()){ 1072 qunlock(&s->out.q); 1073 nexterror(); 1074 } 1075 qlock(&s->out.q); 1076 p = a; 1077 if(0) iprint("write %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n", 1078 n, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 1079 e = p + n; 1080 do { 1081 m = e - p; 1082 if(m > s->max) 1083 m = s->max; 1084 1085 b = allocb(m); 1086 if(waserror()){ 1087 freeb(b); 1088 nexterror(); 1089 } 1090 memmove(b->wp, p, m); 1091 poperror(); 1092 b->wp += m; 1093 1094 sslput(s, b); 1095 1096 p += m; 1097 } while(p < e); 1098 p = a; 1099 if(0) iprint("wrote %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n", 1100 n, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 1101 poperror(); 1102 qunlock(&s->out.q); 1103 return n; 1104 } 1105 1106 /* mutex with operations using what we're about to change */ 1107 if(waserror()){ 1108 qunlock(&s->in.ctlq); 1109 qunlock(&s->out.q); 1110 nexterror(); 1111 } 1112 qlock(&s->in.ctlq); 1113 qlock(&s->out.q); 1114 1115 switch(t){ 1116 default: 1117 panic("sslwrite"); 1118 case Qsecretin: 1119 setsecret(&s->in, a, n); 1120 goto out; 1121 case Qsecretout: 1122 setsecret(&s->out, a, n); 1123 goto out; 1124 case Qctl: 1125 break; 1126 } 1127 1128 if(n >= sizeof(buf)) 1129 error("arg too long"); 1130 strncpy(buf, a, n); 1131 buf[n] = 0; 1132 p = strchr(buf, '\n'); 1133 if(p) 1134 *p = 0; 1135 p = strchr(buf, ' '); 1136 if(p) 1137 *p++ = 0; 1138 1139 if(strcmp(buf, "fd") == 0){ 1140 s->c = buftochan(p); 1141 1142 /* default is clear (msg delimiters only) */ 1143 s->state = Sclear; 1144 s->blocklen = 1; 1145 s->diglen = 0; 1146 s->maxpad = s->max = (1<<15) - s->diglen - 1; 1147 s->in.mid = 0; 1148 s->out.mid = 0; 1149 } else if(strcmp(buf, "alg") == 0 && p != 0){ 1150 s->blocklen = 1; 1151 s->diglen = 0; 1152 1153 if(s->c == 0) 1154 error("must set fd before algorithm"); 1155 1156 s->state = Sclear; 1157 s->maxpad = s->max = (1<<15) - s->diglen - 1; 1158 if(strcmp(p, "clear") == 0){ 1159 goto out; 1160 } 1161 1162 if(s->in.secret && s->out.secret == 0) 1163 setsecret(&s->out, s->in.secret, s->in.slen); 1164 if(s->out.secret && s->in.secret == 0) 1165 setsecret(&s->in, s->out.secret, s->out.slen); 1166 if(s->in.secret == 0 || s->out.secret == 0) 1167 error("algorithm but no secret"); 1168 1169 s->hf = 0; 1170 s->encryptalg = Noencryption; 1171 s->blocklen = 1; 1172 1173 for(;;){ 1174 np = strchr(p, ' '); 1175 if(np) 1176 *np++ = 0; 1177 1178 if(parsehashalg(p, s) < 0) 1179 if(parseencryptalg(p, s) < 0) 1180 error("bad algorithm"); 1181 1182 if(np == 0) 1183 break; 1184 p = np; 1185 } 1186 1187 if(s->hf == 0 && s->encryptalg == Noencryption) 1188 error("bad algorithm"); 1189 1190 if(s->blocklen != 1){ 1191 s->max = (1<<15) - s->diglen - 1; 1192 s->max -= s->max % s->blocklen; 1193 s->maxpad = (1<<14) - s->diglen - 1; 1194 s->maxpad -= s->maxpad % s->blocklen; 1195 } else 1196 s->maxpad = s->max = (1<<15) - s->diglen - 1; 1197 } else if(strcmp(buf, "secretin") == 0 && p != 0) { 1198 m = (strlen(p)*3)/2; 1199 x = smalloc(m); 1200 t = dec64(x, m, p, strlen(p)); 1201 setsecret(&s->in, x, t); 1202 free(x); 1203 } else if(strcmp(buf, "secretout") == 0 && p != 0) { 1204 m = (strlen(p)*3)/2 + 1; 1205 x = smalloc(m); 1206 t = dec64(x, m, p, strlen(p)); 1207 setsecret(&s->out, x, t); 1208 free(x); 1209 } else 1210 error(Ebadarg); 1211 1212 out: 1213 qunlock(&s->in.ctlq); 1214 qunlock(&s->out.q); 1215 poperror(); 1216 return n; 1217 } 1218 1219 static void 1220 sslinit(void) 1221 { 1222 struct Encalg *e; 1223 struct Hashalg *h; 1224 int n; 1225 char *cp; 1226 1227 n = 1; 1228 for(e = encrypttab; e->name != nil; e++) 1229 n += strlen(e->name) + 1; 1230 cp = encalgs = smalloc(n); 1231 for(e = encrypttab;;){ 1232 strcpy(cp, e->name); 1233 cp += strlen(e->name); 1234 e++; 1235 if(e->name == nil) 1236 break; 1237 *cp++ = ' '; 1238 } 1239 *cp = 0; 1240 1241 n = 1; 1242 for(h = hashtab; h->name != nil; h++) 1243 n += strlen(h->name) + 1; 1244 cp = hashalgs = smalloc(n); 1245 for(h = hashtab;;){ 1246 strcpy(cp, h->name); 1247 cp += strlen(h->name); 1248 h++; 1249 if(h->name == nil) 1250 break; 1251 *cp++ = ' '; 1252 } 1253 *cp = 0; 1254 } 1255 1256 Dev ssldevtab = { 1257 'D', 1258 "ssl", 1259 1260 devreset, 1261 sslinit, 1262 devshutdown, 1263 sslattach, 1264 sslwalk, 1265 sslstat, 1266 sslopen, 1267 devcreate, 1268 sslclose, 1269 sslread, 1270 sslbread, 1271 sslwrite, 1272 sslbwrite, 1273 devremove, 1274 sslwstat, 1275 }; 1276 1277 static Block* 1278 encryptb(Dstate *s, Block *b, int offset) 1279 { 1280 uchar *p, *ep, *p2, *ip, *eip; 1281 DESstate *ds; 1282 1283 switch(s->encryptalg){ 1284 case DESECB: 1285 ds = s->out.state; 1286 ep = b->rp + BLEN(b); 1287 for(p = b->rp + offset; p < ep; p += 8) 1288 block_cipher(ds->expanded, p, 0); 1289 break; 1290 case DESCBC: 1291 ds = s->out.state; 1292 ep = b->rp + BLEN(b); 1293 for(p = b->rp + offset; p < ep; p += 8){ 1294 p2 = p; 1295 ip = ds->ivec; 1296 for(eip = ip+8; ip < eip; ) 1297 *p2++ ^= *ip++; 1298 block_cipher(ds->expanded, p, 0); 1299 memmove(ds->ivec, p, 8); 1300 } 1301 break; 1302 case RC4: 1303 rc4(s->out.state, b->rp + offset, BLEN(b) - offset); 1304 break; 1305 } 1306 return b; 1307 } 1308 1309 static Block* 1310 decryptb(Dstate *s, Block *bin) 1311 { 1312 Block *b, **l; 1313 uchar *p, *ep, *tp, *ip, *eip; 1314 DESstate *ds; 1315 uchar tmp[8]; 1316 int i; 1317 1318 l = &bin; 1319 for(b = bin; b; b = b->next){ 1320 /* make sure we have a multiple of s->blocklen */ 1321 if(s->blocklen > 1){ 1322 i = BLEN(b); 1323 if(i % s->blocklen){ 1324 *l = b = pullupblock(b, i + s->blocklen - (i%s->blocklen)); 1325 if(b == 0) 1326 error("ssl encrypted message too short"); 1327 } 1328 } 1329 l = &b->next; 1330 1331 /* decrypt */ 1332 switch(s->encryptalg){ 1333 case DESECB: 1334 ds = s->in.state; 1335 ep = b->rp + BLEN(b); 1336 for(p = b->rp; p < ep; p += 8) 1337 block_cipher(ds->expanded, p, 1); 1338 break; 1339 case DESCBC: 1340 ds = s->in.state; 1341 ep = b->rp + BLEN(b); 1342 for(p = b->rp; p < ep;){ 1343 memmove(tmp, p, 8); 1344 block_cipher(ds->expanded, p, 1); 1345 tp = tmp; 1346 ip = ds->ivec; 1347 for(eip = ip+8; ip < eip; ){ 1348 *p++ ^= *ip; 1349 *ip++ = *tp++; 1350 } 1351 } 1352 break; 1353 case RC4: 1354 rc4(s->in.state, b->rp, BLEN(b)); 1355 break; 1356 } 1357 } 1358 return bin; 1359 } 1360 1361 static Block* 1362 digestb(Dstate *s, Block *b, int offset) 1363 { 1364 uchar *p; 1365 DigestState ss; 1366 uchar msgid[4]; 1367 ulong n, h; 1368 OneWay *w; 1369 1370 w = &s->out; 1371 1372 memset(&ss, 0, sizeof(ss)); 1373 h = s->diglen + offset; 1374 n = BLEN(b) - h; 1375 1376 /* hash secret + message */ 1377 (*s->hf)(w->secret, w->slen, 0, &ss); 1378 (*s->hf)(b->rp + h, n, 0, &ss); 1379 1380 /* hash message id */ 1381 p = msgid; 1382 n = w->mid; 1383 *p++ = n>>24; 1384 *p++ = n>>16; 1385 *p++ = n>>8; 1386 *p = n; 1387 (*s->hf)(msgid, 4, b->rp + offset, &ss); 1388 1389 return b; 1390 } 1391 1392 static void 1393 checkdigestb(Dstate *s, Block *bin) 1394 { 1395 uchar *p; 1396 DigestState ss; 1397 uchar msgid[4]; 1398 int n, h; 1399 OneWay *w; 1400 uchar digest[128]; 1401 Block *b; 1402 1403 w = &s->in; 1404 1405 memset(&ss, 0, sizeof(ss)); 1406 1407 /* hash secret */ 1408 (*s->hf)(w->secret, w->slen, 0, &ss); 1409 1410 /* hash message */ 1411 h = s->diglen; 1412 for(b = bin; b; b = b->next){ 1413 n = BLEN(b) - h; 1414 if(n < 0) 1415 panic("checkdigestb"); 1416 (*s->hf)(b->rp + h, n, 0, &ss); 1417 h = 0; 1418 } 1419 1420 /* hash message id */ 1421 p = msgid; 1422 n = w->mid; 1423 *p++ = n>>24; 1424 *p++ = n>>16; 1425 *p++ = n>>8; 1426 *p = n; 1427 (*s->hf)(msgid, 4, digest, &ss); 1428 1429 if(memcmp(digest, bin->rp, s->diglen) != 0) 1430 error("bad digest"); 1431 } 1432 1433 /* get channel associated with an fd */ 1434 static Chan* 1435 buftochan(char *p) 1436 { 1437 Chan *c; 1438 int fd; 1439 1440 if(p == 0) 1441 error(Ebadarg); 1442 fd = strtoul(p, 0, 0); 1443 if(fd < 0) 1444 error(Ebadarg); 1445 c = fdtochan(fd, -1, 0, 1); /* error check and inc ref */ 1446 if(devtab[c->type] == &ssldevtab){ 1447 cclose(c); 1448 error("cannot ssl encrypt devssl files"); 1449 } 1450 return c; 1451 } 1452 1453 /* hand up a digest connection */ 1454 static void 1455 sslhangup(Dstate *s) 1456 { 1457 Block *b; 1458 1459 qlock(&s->in.q); 1460 for(b = s->processed; b; b = s->processed){ 1461 s->processed = b->next; 1462 freeb(b); 1463 } 1464 if(s->unprocessed){ 1465 freeb(s->unprocessed); 1466 s->unprocessed = 0; 1467 } 1468 s->state = Sincomplete; 1469 qunlock(&s->in.q); 1470 } 1471 1472 static Dstate* 1473 dsclone(Chan *ch) 1474 { 1475 int i; 1476 Dstate *ret; 1477 1478 if(waserror()) { 1479 unlock(&dslock); 1480 nexterror(); 1481 } 1482 lock(&dslock); 1483 ret = nil; 1484 for(i=0; i<Maxdstate; i++){ 1485 if(dstate[i] == nil){ 1486 dsnew(ch, &dstate[i]); 1487 ret = dstate[i]; 1488 break; 1489 } 1490 } 1491 unlock(&dslock); 1492 poperror(); 1493 return ret; 1494 } 1495 1496 static void 1497 dsnew(Chan *ch, Dstate **pp) 1498 { 1499 Dstate *s; 1500 int t; 1501 1502 *pp = s = malloc(sizeof(*s)); 1503 if(!s) 1504 error(Enomem); 1505 if(pp - dstate >= dshiwat) 1506 dshiwat++; 1507 memset(s, 0, sizeof(*s)); 1508 s->state = Sincomplete; 1509 s->ref = 1; 1510 kstrdup(&s->user, up->user); 1511 s->perm = 0660; 1512 t = TYPE(ch->qid); 1513 if(t == Qclonus) 1514 t = Qctl; 1515 ch->qid.path = QID(pp - dstate, t); 1516 ch->qid.vers = 0; 1517 } 1518