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