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