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