1 /* 2 * Encapsulating Security Payload for IPsec for IPv4, rfc1827. 3 * rfc2104 defines hmac computation. 4 * currently only implements tunnel mode. 5 * TODO: verify aes algorithms; 6 * transport mode (host-to-host) 7 */ 8 #include "u.h" 9 #include "../port/lib.h" 10 #include "mem.h" 11 #include "dat.h" 12 #include "fns.h" 13 #include "../port/error.h" 14 15 #include "ip.h" 16 #include "ipv6.h" 17 #include "libsec.h" 18 19 #define BITS2BYTES(bi) (((bi) + BI2BY - 1) / BI2BY) 20 #define BYTES2BITS(by) ((by) * BI2BY) 21 22 typedef struct Algorithm Algorithm; 23 typedef struct Esp4hdr Esp4hdr; 24 typedef struct Esp6hdr Esp6hdr; 25 typedef struct Espcb Espcb; 26 typedef struct Esphdr Esphdr; 27 typedef struct Esppriv Esppriv; 28 typedef struct Esptail Esptail; 29 typedef struct Userhdr Userhdr; 30 31 enum { 32 Encrypt, 33 Decrypt, 34 35 IP_ESPPROTO = 50, /* IP v4 and v6 protocol number */ 36 Esp4hdrlen = IP4HDR + 8, 37 Esp6hdrlen = IP6HDR + 8, 38 39 Esptaillen = 2, /* does not include pad or auth data */ 40 Userhdrlen = 4, /* user-visible header size - if enabled */ 41 42 Desblk = BITS2BYTES(64), 43 Des3keysz = BITS2BYTES(192), 44 45 Aesblk = BITS2BYTES(128), 46 Aeskeysz = BITS2BYTES(128), 47 }; 48 49 struct Esphdr 50 { 51 uchar espspi[4]; /* Security parameter index */ 52 uchar espseq[4]; /* Sequence number */ 53 uchar payload[]; 54 }; 55 56 /* 57 * tunnel-mode (network-to-network, etc.) layout is: 58 * new IP hdrs | ESP hdr | 59 * enc { orig IP hdrs | TCP/UDP hdr | user data | ESP trailer } | ESP ICV 60 * 61 * transport-mode (host-to-host) layout would be: 62 * orig IP hdrs | ESP hdr | 63 * enc { TCP/UDP hdr | user data | ESP trailer } | ESP ICV 64 */ 65 struct Esp4hdr 66 { 67 /* ipv4 header */ 68 uchar vihl; /* Version and header length */ 69 uchar tos; /* Type of service */ 70 uchar length[2]; /* packet length */ 71 uchar id[2]; /* Identification */ 72 uchar frag[2]; /* Fragment information */ 73 uchar Unused; 74 uchar espproto; /* Protocol */ 75 uchar espplen[2]; /* Header plus data length */ 76 uchar espsrc[4]; /* Ip source */ 77 uchar espdst[4]; /* Ip destination */ 78 79 Esphdr; 80 }; 81 82 /* tunnel-mode layout */ 83 struct Esp6hdr 84 { 85 IPV6HDR; 86 Esphdr; 87 }; 88 89 struct Esptail 90 { 91 uchar pad; 92 uchar nexthdr; 93 }; 94 95 /* IP-version-dependent data */ 96 typedef struct Versdep Versdep; 97 struct Versdep 98 { 99 ulong version; 100 ulong iphdrlen; 101 ulong hdrlen; /* iphdrlen + esp hdr len */ 102 ulong spi; 103 uchar laddr[IPaddrlen]; 104 uchar raddr[IPaddrlen]; 105 }; 106 107 /* header as seen by the user */ 108 struct Userhdr 109 { 110 uchar nexthdr; /* next protocol */ 111 uchar unused[3]; 112 }; 113 114 struct Esppriv 115 { 116 ulong in; 117 ulong inerrors; 118 }; 119 120 /* 121 * protocol specific part of Conv 122 */ 123 struct Espcb 124 { 125 int incoming; 126 int header; /* user-level header */ 127 ulong spi; 128 ulong seq; /* last seq sent */ 129 ulong window; /* for replay attacks */ 130 131 char *espalg; 132 void *espstate; /* other state for esp */ 133 int espivlen; /* in bytes */ 134 int espblklen; 135 int (*cipher)(Espcb*, uchar *buf, int len); 136 137 char *ahalg; 138 void *ahstate; /* other state for esp */ 139 int ahlen; /* auth data length in bytes */ 140 int ahblklen; 141 int (*auth)(Espcb*, uchar *buf, int len, uchar *hash); 142 DigestState *ds; 143 }; 144 145 struct Algorithm 146 { 147 char *name; 148 int keylen; /* in bits */ 149 void (*init)(Espcb*, char* name, uchar *key, unsigned keylen); 150 }; 151 152 static Conv* convlookup(Proto *esp, ulong spi); 153 static char *setalg(Espcb *ecb, char **f, int n, Algorithm *alg); 154 static void espkick(void *x); 155 156 static void nullespinit(Espcb*, char*, uchar *key, unsigned keylen); 157 static void des3espinit(Espcb*, char*, uchar *key, unsigned keylen); 158 static void aescbcespinit(Espcb*, char*, uchar *key, unsigned keylen); 159 static void aesctrespinit(Espcb*, char*, uchar *key, unsigned keylen); 160 static void desespinit(Espcb *ecb, char *name, uchar *k, unsigned n); 161 162 static void nullahinit(Espcb*, char*, uchar *key, unsigned keylen); 163 static void shaahinit(Espcb*, char*, uchar *key, unsigned keylen); 164 static void aesahinit(Espcb*, char*, uchar *key, unsigned keylen); 165 static void md5ahinit(Espcb*, char*, uchar *key, unsigned keylen); 166 167 static Algorithm espalg[] = 168 { 169 "null", 0, nullespinit, 170 "des3_cbc", 192, des3espinit, /* new rfc2451, des-ede3 */ 171 "aes_128_cbc", 128, aescbcespinit, /* new rfc3602 */ 172 "aes_ctr", 128, aesctrespinit, /* new rfc3686 */ 173 "des_56_cbc", 64, desespinit, /* rfc2405, deprecated */ 174 /* rc4 was never required, was used in original bandt */ 175 // "rc4_128", 128, rc4espinit, 176 nil, 0, nil, 177 }; 178 179 static Algorithm ahalg[] = 180 { 181 "null", 0, nullahinit, 182 "hmac_sha1_96", 128, shaahinit, /* rfc2404 */ 183 "aes_xcbc_mac_96", 128, aesahinit, /* new rfc3566 */ 184 "hmac_md5_96", 128, md5ahinit, /* rfc2403 */ 185 nil, 0, nil, 186 }; 187 188 static char* 189 espconnect(Conv *c, char **argv, int argc) 190 { 191 char *p, *pp, *e = nil; 192 ulong spi; 193 Espcb *ecb = (Espcb*)c->ptcl; 194 195 switch(argc) { 196 default: 197 e = "bad args to connect"; 198 break; 199 case 2: 200 p = strchr(argv[1], '!'); 201 if(p == nil){ 202 e = "malformed address"; 203 break; 204 } 205 *p++ = 0; 206 if (parseip(c->raddr, argv[1]) == -1) { 207 e = Ebadip; 208 break; 209 } 210 findlocalip(c->p->f, c->laddr, c->raddr); 211 ecb->incoming = 0; 212 ecb->seq = 0; 213 if(strcmp(p, "*") == 0) { 214 qlock(c->p); 215 for(;;) { 216 spi = nrand(1<<16) + 256; 217 if(convlookup(c->p, spi) == nil) 218 break; 219 } 220 qunlock(c->p); 221 ecb->spi = spi; 222 ecb->incoming = 1; 223 qhangup(c->wq, nil); 224 } else { 225 spi = strtoul(p, &pp, 10); 226 if(pp == p) { 227 e = "malformed address"; 228 break; 229 } 230 ecb->spi = spi; 231 qhangup(c->rq, nil); 232 } 233 nullespinit(ecb, "null", nil, 0); 234 nullahinit(ecb, "null", nil, 0); 235 } 236 Fsconnected(c, e); 237 238 return e; 239 } 240 241 242 static int 243 espstate(Conv *c, char *state, int n) 244 { 245 return snprint(state, n, "%s", c->inuse?"Open\n":"Closed\n"); 246 } 247 248 static void 249 espcreate(Conv *c) 250 { 251 c->rq = qopen(64*1024, Qmsg, 0, 0); 252 c->wq = qopen(64*1024, Qkick, espkick, c); 253 } 254 255 static void 256 espclose(Conv *c) 257 { 258 Espcb *ecb; 259 260 qclose(c->rq); 261 qclose(c->wq); 262 qclose(c->eq); 263 ipmove(c->laddr, IPnoaddr); 264 ipmove(c->raddr, IPnoaddr); 265 266 ecb = (Espcb*)c->ptcl; 267 free(ecb->espstate); 268 free(ecb->ahstate); 269 memset(ecb, 0, sizeof(Espcb)); 270 } 271 272 static int 273 convipvers(Conv *c) 274 { 275 if((memcmp(c->raddr, v4prefix, IPv4off) == 0 && 276 memcmp(c->laddr, v4prefix, IPv4off) == 0) || 277 ipcmp(c->raddr, IPnoaddr) == 0) 278 return V4; 279 else 280 return V6; 281 } 282 283 static int 284 pktipvers(Fs *f, Block **bpp) 285 { 286 if (*bpp == nil || BLEN(*bpp) == 0) { 287 /* get enough to identify the IP version */ 288 *bpp = pullupblock(*bpp, IP4HDR); 289 if(*bpp == nil) { 290 netlog(f, Logesp, "esp: short packet\n"); 291 return 0; 292 } 293 } 294 return (((Esp4hdr*)(*bpp)->rp)->vihl & 0xf0) == IP_VER4? V4: V6; 295 } 296 297 static void 298 getverslens(int version, Versdep *vp) 299 { 300 vp->version = version; 301 switch(vp->version) { 302 case V4: 303 vp->iphdrlen = IP4HDR; 304 vp->hdrlen = Esp4hdrlen; 305 break; 306 case V6: 307 vp->iphdrlen = IP6HDR; 308 vp->hdrlen = Esp6hdrlen; 309 break; 310 default: 311 panic("esp: getverslens version %d wrong", version); 312 } 313 } 314 315 static void 316 getpktspiaddrs(uchar *pkt, Versdep *vp) 317 { 318 Esp4hdr *eh4; 319 Esp6hdr *eh6; 320 321 switch(vp->version) { 322 case V4: 323 eh4 = (Esp4hdr*)pkt; 324 v4tov6(vp->raddr, eh4->espsrc); 325 v4tov6(vp->laddr, eh4->espdst); 326 vp->spi = nhgetl(eh4->espspi); 327 break; 328 case V6: 329 eh6 = (Esp6hdr*)pkt; 330 ipmove(vp->raddr, eh6->src); 331 ipmove(vp->laddr, eh6->dst); 332 vp->spi = nhgetl(eh6->espspi); 333 break; 334 default: 335 panic("esp: getpktspiaddrs vp->version %ld wrong", vp->version); 336 } 337 } 338 339 /* 340 * encapsulate next IP packet on x's write queue in IP/ESP packet 341 * and initiate output of the result. 342 */ 343 static void 344 espkick(void *x) 345 { 346 int nexthdr, payload, pad, align; 347 uchar *auth; 348 Block *bp; 349 Conv *c = x; 350 Esp4hdr *eh4; 351 Esp6hdr *eh6; 352 Espcb *ecb; 353 Esptail *et; 354 Userhdr *uh; 355 Versdep vers; 356 357 getverslens(convipvers(c), &vers); 358 bp = qget(c->wq); 359 if(bp == nil) 360 return; 361 362 qlock(c); 363 ecb = c->ptcl; 364 365 if(ecb->header) { 366 /* make sure the message has a User header */ 367 bp = pullupblock(bp, Userhdrlen); 368 if(bp == nil) { 369 qunlock(c); 370 return; 371 } 372 uh = (Userhdr*)bp->rp; 373 nexthdr = uh->nexthdr; 374 bp->rp += Userhdrlen; 375 } else { 376 nexthdr = 0; /* what should this be? */ 377 } 378 379 payload = BLEN(bp) + ecb->espivlen; 380 381 /* Make space to fit ip header */ 382 bp = padblock(bp, vers.hdrlen + ecb->espivlen); 383 getpktspiaddrs(bp->rp, &vers); 384 385 align = 4; 386 if(ecb->espblklen > align) 387 align = ecb->espblklen; 388 if(align % ecb->ahblklen != 0) 389 panic("espkick: ahblklen is important after all"); 390 pad = (align-1) - (payload + Esptaillen-1)%align; 391 392 /* 393 * Make space for tail 394 * this is done by calling padblock with a negative size 395 * Padblock does not change bp->wp! 396 */ 397 bp = padblock(bp, -(pad+Esptaillen+ecb->ahlen)); 398 bp->wp += pad+Esptaillen+ecb->ahlen; 399 400 et = (Esptail*)(bp->rp + vers.hdrlen + payload + pad); 401 402 /* fill in tail */ 403 et->pad = pad; 404 et->nexthdr = nexthdr; 405 406 /* encrypt the payload */ 407 ecb->cipher(ecb, bp->rp + vers.hdrlen, payload + pad + Esptaillen); 408 auth = bp->rp + vers.hdrlen + payload + pad + Esptaillen; 409 410 /* fill in head; construct a new IP header and an ESP header */ 411 if (vers.version == V4) { 412 eh4 = (Esp4hdr *)bp->rp; 413 eh4->vihl = IP_VER4; 414 v6tov4(eh4->espsrc, c->laddr); 415 v6tov4(eh4->espdst, c->raddr); 416 eh4->espproto = IP_ESPPROTO; 417 eh4->frag[0] = 0; 418 eh4->frag[1] = 0; 419 420 hnputl(eh4->espspi, ecb->spi); 421 hnputl(eh4->espseq, ++ecb->seq); 422 } else { 423 eh6 = (Esp6hdr *)bp->rp; 424 eh6->vcf[0] = IP_VER6; 425 ipmove(eh6->src, c->laddr); 426 ipmove(eh6->dst, c->raddr); 427 eh6->proto = IP_ESPPROTO; 428 429 hnputl(eh6->espspi, ecb->spi); 430 hnputl(eh6->espseq, ++ecb->seq); 431 } 432 433 /* compute secure hash */ 434 ecb->auth(ecb, bp->rp + vers.iphdrlen, (vers.hdrlen - vers.iphdrlen) + 435 payload + pad + Esptaillen, auth); 436 437 qunlock(c); 438 /* print("esp: pass down: %uld\n", BLEN(bp)); */ 439 if (vers.version == V4) 440 ipoput4(c->p->f, bp, 0, c->ttl, c->tos, c); 441 else 442 ipoput6(c->p->f, bp, 0, c->ttl, c->tos, c); 443 } 444 445 /* 446 * decapsulate IP packet from IP/ESP packet in bp and 447 * pass the result up the spi's Conv's read queue. 448 */ 449 void 450 espiput(Proto *esp, Ipifc*, Block *bp) 451 { 452 int payload, nexthdr; 453 uchar *auth, *espspi; 454 Conv *c; 455 Espcb *ecb; 456 Esptail *et; 457 Fs *f; 458 Userhdr *uh; 459 Versdep vers; 460 461 f = esp->f; 462 463 getverslens(pktipvers(f, &bp), &vers); 464 465 bp = pullupblock(bp, vers.hdrlen + Esptaillen); 466 if(bp == nil) { 467 netlog(f, Logesp, "esp: short packet\n"); 468 return; 469 } 470 getpktspiaddrs(bp->rp, &vers); 471 472 qlock(esp); 473 /* Look for a conversation structure for this port */ 474 c = convlookup(esp, vers.spi); 475 if(c == nil) { 476 qunlock(esp); 477 netlog(f, Logesp, "esp: no conv %I -> %I!%lud\n", vers.raddr, 478 vers.laddr, vers.spi); 479 icmpnoconv(f, bp); 480 freeblist(bp); 481 return; 482 } 483 484 qlock(c); 485 qunlock(esp); 486 487 ecb = c->ptcl; 488 /* too hard to do decryption/authentication on block lists */ 489 if(bp->next) 490 bp = concatblock(bp); 491 492 if(BLEN(bp) < vers.hdrlen + ecb->espivlen + Esptaillen + ecb->ahlen) { 493 qunlock(c); 494 netlog(f, Logesp, "esp: short block %I -> %I!%lud\n", vers.raddr, 495 vers.laddr, vers.spi); 496 freeb(bp); 497 return; 498 } 499 500 auth = bp->wp - ecb->ahlen; 501 espspi = vers.version == V4? ((Esp4hdr*)bp->rp)->espspi: 502 ((Esp6hdr*)bp->rp)->espspi; 503 504 /* compute secure hash and authenticate */ 505 if(!ecb->auth(ecb, espspi, auth - espspi, auth)) { 506 qunlock(c); 507 print("esp: bad auth %I -> %I!%ld\n", vers.raddr, vers.laddr, vers.spi); 508 netlog(f, Logesp, "esp: bad auth %I -> %I!%lud\n", vers.raddr, 509 vers.laddr, vers.spi); 510 freeb(bp); 511 return; 512 } 513 514 payload = BLEN(bp) - vers.hdrlen - ecb->ahlen; 515 if(payload <= 0 || payload % 4 != 0 || payload % ecb->espblklen != 0) { 516 qunlock(c); 517 netlog(f, Logesp, "esp: bad length %I -> %I!%lud payload=%d BLEN=%lud\n", 518 vers.raddr, vers.laddr, vers.spi, payload, BLEN(bp)); 519 freeb(bp); 520 return; 521 } 522 523 /* decrypt payload */ 524 if(!ecb->cipher(ecb, bp->rp + vers.hdrlen, payload)) { 525 qunlock(c); 526 print("esp: cipher failed %I -> %I!%ld: %s\n", vers.raddr, vers.laddr, vers.spi, up->errstr); 527 netlog(f, Logesp, "esp: cipher failed %I -> %I!%lud: %s\n", 528 vers.raddr, vers.laddr, vers.spi, up->errstr); 529 freeb(bp); 530 return; 531 } 532 533 payload -= Esptaillen; 534 et = (Esptail*)(bp->rp + vers.hdrlen + payload); 535 payload -= et->pad + ecb->espivlen; 536 nexthdr = et->nexthdr; 537 if(payload <= 0) { 538 qunlock(c); 539 netlog(f, Logesp, "esp: short packet after decrypt %I -> %I!%lud\n", 540 vers.raddr, vers.laddr, vers.spi); 541 freeb(bp); 542 return; 543 } 544 545 /* trim packet */ 546 bp->rp += vers.hdrlen + ecb->espivlen; /* toss original IP & ESP hdrs */ 547 bp->wp = bp->rp + payload; 548 if(ecb->header) { 549 /* assume Userhdrlen < Esp4hdrlen < Esp6hdrlen */ 550 bp->rp -= Userhdrlen; 551 uh = (Userhdr*)bp->rp; 552 memset(uh, 0, Userhdrlen); 553 uh->nexthdr = nexthdr; 554 } 555 556 /* ingress filtering here? */ 557 558 if(qfull(c->rq)){ 559 netlog(f, Logesp, "esp: qfull %I -> %I.%uld\n", vers.raddr, 560 vers.laddr, vers.spi); 561 freeblist(bp); 562 }else { 563 // print("esp: pass up: %uld\n", BLEN(bp)); 564 qpass(c->rq, bp); /* pass packet up the read queue */ 565 } 566 567 qunlock(c); 568 } 569 570 char* 571 espctl(Conv *c, char **f, int n) 572 { 573 Espcb *ecb = c->ptcl; 574 char *e = nil; 575 576 if(strcmp(f[0], "esp") == 0) 577 e = setalg(ecb, f, n, espalg); 578 else if(strcmp(f[0], "ah") == 0) 579 e = setalg(ecb, f, n, ahalg); 580 else if(strcmp(f[0], "header") == 0) 581 ecb->header = 1; 582 else if(strcmp(f[0], "noheader") == 0) 583 ecb->header = 0; 584 else 585 e = "unknown control request"; 586 return e; 587 } 588 589 /* called from icmp(v6) for unreachable hosts, time exceeded, etc. */ 590 void 591 espadvise(Proto *esp, Block *bp, char *msg) 592 { 593 Conv *c; 594 Versdep vers; 595 596 getverslens(pktipvers(esp->f, &bp), &vers); 597 getpktspiaddrs(bp->rp, &vers); 598 599 qlock(esp); 600 c = convlookup(esp, vers.spi); 601 if(c != nil) { 602 qhangup(c->rq, msg); 603 qhangup(c->wq, msg); 604 } 605 qunlock(esp); 606 freeblist(bp); 607 } 608 609 int 610 espstats(Proto *esp, char *buf, int len) 611 { 612 Esppriv *upriv; 613 614 upriv = esp->priv; 615 return snprint(buf, len, "%lud %lud\n", 616 upriv->in, 617 upriv->inerrors); 618 } 619 620 static int 621 esplocal(Conv *c, char *buf, int len) 622 { 623 Espcb *ecb = c->ptcl; 624 int n; 625 626 qlock(c); 627 if(ecb->incoming) 628 n = snprint(buf, len, "%I!%uld\n", c->laddr, ecb->spi); 629 else 630 n = snprint(buf, len, "%I\n", c->laddr); 631 qunlock(c); 632 return n; 633 } 634 635 static int 636 espremote(Conv *c, char *buf, int len) 637 { 638 Espcb *ecb = c->ptcl; 639 int n; 640 641 qlock(c); 642 if(ecb->incoming) 643 n = snprint(buf, len, "%I\n", c->raddr); 644 else 645 n = snprint(buf, len, "%I!%uld\n", c->raddr, ecb->spi); 646 qunlock(c); 647 return n; 648 } 649 650 static Conv* 651 convlookup(Proto *esp, ulong spi) 652 { 653 Conv *c, **p; 654 Espcb *ecb; 655 656 for(p=esp->conv; *p; p++){ 657 c = *p; 658 ecb = c->ptcl; 659 if(ecb->incoming && ecb->spi == spi) 660 return c; 661 } 662 return nil; 663 } 664 665 static char * 666 setalg(Espcb *ecb, char **f, int n, Algorithm *alg) 667 { 668 uchar *key; 669 int c, i, nbyte, nchar; 670 671 if(n < 2) 672 return "bad format"; 673 for(; alg->name; alg++) 674 if(strcmp(f[1], alg->name) == 0) 675 break; 676 if(alg->name == nil) 677 return "unknown algorithm"; 678 679 if(n != 3) 680 return "bad format"; 681 nbyte = (alg->keylen + 7) >> 3; 682 nchar = strlen(f[2]); 683 for(i=0; i<nchar; i++) { 684 c = f[2][i]; 685 if(c >= '0' && c <= '9') 686 f[2][i] -= '0'; 687 else if(c >= 'a' && c <= 'f') 688 f[2][i] -= 'a'-10; 689 else if(c >= 'A' && c <= 'F') 690 f[2][i] -= 'A'-10; 691 else 692 return "bad character in key"; 693 } 694 key = smalloc(nbyte); 695 for(i=0; i<nchar && i*2<nbyte; i++) { 696 c = f[2][nchar-i-1]; 697 if(i&1) 698 c <<= 4; 699 key[i>>1] |= c; 700 } 701 702 alg->init(ecb, alg->name, key, alg->keylen); 703 free(key); 704 return nil; 705 } 706 707 708 /* 709 * null encryption 710 */ 711 712 static int 713 nullcipher(Espcb*, uchar*, int) 714 { 715 return 1; 716 } 717 718 static void 719 nullespinit(Espcb *ecb, char *name, uchar*, unsigned) 720 { 721 ecb->espalg = name; 722 ecb->espblklen = 1; 723 ecb->espivlen = 0; 724 ecb->cipher = nullcipher; 725 } 726 727 static int 728 nullauth(Espcb*, uchar*, int, uchar*) 729 { 730 return 1; 731 } 732 733 static void 734 nullahinit(Espcb *ecb, char *name, uchar*, unsigned) 735 { 736 ecb->ahalg = name; 737 ecb->ahblklen = 1; 738 ecb->ahlen = 0; 739 ecb->auth = nullauth; 740 } 741 742 743 /* 744 * sha1 745 */ 746 747 static void 748 seanq_hmac_sha1(uchar hash[SHA1dlen], uchar *t, long tlen, uchar *key, long klen) 749 { 750 int i; 751 uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[SHA1dlen]; 752 DigestState *digest; 753 754 memset(ipad, 0x36, Hmacblksz); 755 memset(opad, 0x5c, Hmacblksz); 756 ipad[Hmacblksz] = opad[Hmacblksz] = 0; 757 for(i = 0; i < klen; i++){ 758 ipad[i] ^= key[i]; 759 opad[i] ^= key[i]; 760 } 761 digest = sha1(ipad, Hmacblksz, nil, nil); 762 sha1(t, tlen, innerhash, digest); 763 digest = sha1(opad, Hmacblksz, nil, nil); 764 sha1(innerhash, SHA1dlen, hash, digest); 765 } 766 767 static int 768 shaauth(Espcb *ecb, uchar *t, int tlen, uchar *auth) 769 { 770 int r; 771 uchar hash[SHA1dlen]; 772 773 memset(hash, 0, SHA1dlen); 774 seanq_hmac_sha1(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128)); 775 r = memcmp(auth, hash, ecb->ahlen) == 0; 776 memmove(auth, hash, ecb->ahlen); 777 return r; 778 } 779 780 static void 781 shaahinit(Espcb *ecb, char *name, uchar *key, unsigned klen) 782 { 783 if(klen != 128) 784 panic("shaahinit: bad keylen"); 785 klen /= BI2BY; 786 787 ecb->ahalg = name; 788 ecb->ahblklen = 1; 789 ecb->ahlen = BITS2BYTES(96); 790 ecb->auth = shaauth; 791 ecb->ahstate = smalloc(klen); 792 memmove(ecb->ahstate, key, klen); 793 } 794 795 796 /* 797 * aes 798 */ 799 800 /* ah_aes_xcbc_mac_96, rfc3566 */ 801 static int 802 aesahauth(Espcb *ecb, uchar *t, int tlen, uchar *auth) 803 { 804 int r; 805 uchar hash[AESdlen]; 806 807 memset(hash, 0, AESdlen); 808 ecb->ds = hmac_aes(t, tlen, hash, BITS2BYTES(96), (uchar*)ecb->ahstate, 809 ecb->ds); 810 r = memcmp(auth, hash, ecb->ahlen) == 0; 811 memmove(auth, hash, ecb->ahlen); 812 return r; 813 } 814 815 static void 816 aesahinit(Espcb *ecb, char *name, uchar *key, unsigned klen) 817 { 818 if(klen != 128) 819 panic("aesahinit: keylen not 128"); 820 klen /= BI2BY; 821 822 ecb->ahalg = name; 823 ecb->ahblklen = 1; 824 ecb->ahlen = BITS2BYTES(96); 825 ecb->auth = aesahauth; 826 ecb->ahstate = smalloc(klen); 827 memmove(ecb->ahstate, key, klen); 828 } 829 830 static int 831 aescbccipher(Espcb *ecb, uchar *p, int n) /* 128-bit blocks */ 832 { 833 uchar tmp[AESbsize], q[AESbsize]; 834 uchar *pp, *tp, *ip, *eip, *ep; 835 AESstate *ds = ecb->espstate; 836 837 ep = p + n; 838 if(ecb->incoming) { 839 memmove(ds->ivec, p, AESbsize); 840 p += AESbsize; 841 while(p < ep){ 842 memmove(tmp, p, AESbsize); 843 aes_decrypt(ds->dkey, ds->rounds, p, q); 844 memmove(p, q, AESbsize); 845 tp = tmp; 846 ip = ds->ivec; 847 for(eip = ip + AESbsize; ip < eip; ){ 848 *p++ ^= *ip; 849 *ip++ = *tp++; 850 } 851 } 852 } else { 853 memmove(p, ds->ivec, AESbsize); 854 for(p += AESbsize; p < ep; p += AESbsize){ 855 pp = p; 856 ip = ds->ivec; 857 for(eip = ip + AESbsize; ip < eip; ) 858 *pp++ ^= *ip++; 859 aes_encrypt(ds->ekey, ds->rounds, p, q); 860 memmove(ds->ivec, q, AESbsize); 861 memmove(p, q, AESbsize); 862 } 863 } 864 return 1; 865 } 866 867 static void 868 aescbcespinit(Espcb *ecb, char *name, uchar *k, unsigned n) 869 { 870 uchar key[Aeskeysz], ivec[Aeskeysz]; 871 int i; 872 873 n = BITS2BYTES(n); 874 if(n > Aeskeysz) 875 n = Aeskeysz; 876 memset(key, 0, sizeof(key)); 877 memmove(key, k, n); 878 for(i = 0; i < Aeskeysz; i++) 879 ivec[i] = nrand(256); 880 ecb->espalg = name; 881 ecb->espblklen = Aesblk; 882 ecb->espivlen = Aesblk; 883 ecb->cipher = aescbccipher; 884 ecb->espstate = smalloc(sizeof(AESstate)); 885 setupAESstate(ecb->espstate, key, n /* keybytes */, ivec); 886 } 887 888 static int 889 aesctrcipher(Espcb *ecb, uchar *p, int n) /* 128-bit blocks */ 890 { 891 uchar tmp[AESbsize], q[AESbsize]; 892 uchar *pp, *tp, *ip, *eip, *ep; 893 AESstate *ds = ecb->espstate; 894 895 ep = p + n; 896 if(ecb->incoming) { 897 memmove(ds->ivec, p, AESbsize); 898 p += AESbsize; 899 while(p < ep){ 900 memmove(tmp, p, AESbsize); 901 aes_decrypt(ds->dkey, ds->rounds, p, q); 902 memmove(p, q, AESbsize); 903 tp = tmp; 904 ip = ds->ivec; 905 for(eip = ip + AESbsize; ip < eip; ){ 906 *p++ ^= *ip; 907 *ip++ = *tp++; 908 } 909 } 910 } else { 911 memmove(p, ds->ivec, AESbsize); 912 for(p += AESbsize; p < ep; p += AESbsize){ 913 pp = p; 914 ip = ds->ivec; 915 for(eip = ip + AESbsize; ip < eip; ) 916 *pp++ ^= *ip++; 917 aes_encrypt(ds->ekey, ds->rounds, p, q); 918 memmove(ds->ivec, q, AESbsize); 919 memmove(p, q, AESbsize); 920 } 921 } 922 return 1; 923 } 924 925 static void 926 aesctrespinit(Espcb *ecb, char *name, uchar *k, unsigned n) 927 { 928 uchar key[Aesblk], ivec[Aesblk]; 929 int i; 930 931 n = BITS2BYTES(n); 932 if(n > Aeskeysz) 933 n = Aeskeysz; 934 memset(key, 0, sizeof(key)); 935 memmove(key, k, n); 936 for(i = 0; i < Aesblk; i++) 937 ivec[i] = nrand(256); 938 ecb->espalg = name; 939 ecb->espblklen = Aesblk; 940 ecb->espivlen = Aesblk; 941 ecb->cipher = aesctrcipher; 942 ecb->espstate = smalloc(sizeof(AESstate)); 943 setupAESstate(ecb->espstate, key, n /* keybytes */, ivec); 944 } 945 946 947 /* 948 * md5 949 */ 950 951 static void 952 seanq_hmac_md5(uchar hash[MD5dlen], uchar *t, long tlen, uchar *key, long klen) 953 { 954 int i; 955 uchar ipad[Hmacblksz+1], opad[Hmacblksz+1], innerhash[MD5dlen]; 956 DigestState *digest; 957 958 memset(ipad, 0x36, Hmacblksz); 959 memset(opad, 0x5c, Hmacblksz); 960 ipad[Hmacblksz] = opad[Hmacblksz] = 0; 961 for(i = 0; i < klen; i++){ 962 ipad[i] ^= key[i]; 963 opad[i] ^= key[i]; 964 } 965 digest = md5(ipad, Hmacblksz, nil, nil); 966 md5(t, tlen, innerhash, digest); 967 digest = md5(opad, Hmacblksz, nil, nil); 968 md5(innerhash, MD5dlen, hash, digest); 969 } 970 971 static int 972 md5auth(Espcb *ecb, uchar *t, int tlen, uchar *auth) 973 { 974 uchar hash[MD5dlen]; 975 int r; 976 977 memset(hash, 0, MD5dlen); 978 seanq_hmac_md5(hash, t, tlen, (uchar*)ecb->ahstate, BITS2BYTES(128)); 979 r = memcmp(auth, hash, ecb->ahlen) == 0; 980 memmove(auth, hash, ecb->ahlen); 981 return r; 982 } 983 984 static void 985 md5ahinit(Espcb *ecb, char *name, uchar *key, unsigned klen) 986 { 987 if(klen != 128) 988 panic("md5ahinit: bad keylen"); 989 klen = BITS2BYTES(klen); 990 ecb->ahalg = name; 991 ecb->ahblklen = 1; 992 ecb->ahlen = BITS2BYTES(96); 993 ecb->auth = md5auth; 994 ecb->ahstate = smalloc(klen); 995 memmove(ecb->ahstate, key, klen); 996 } 997 998 999 /* 1000 * des, single and triple 1001 */ 1002 1003 static int 1004 descipher(Espcb *ecb, uchar *p, int n) 1005 { 1006 DESstate *ds = ecb->espstate; 1007 1008 if(ecb->incoming) { 1009 memmove(ds->ivec, p, Desblk); 1010 desCBCdecrypt(p + Desblk, n - Desblk, ds); 1011 } else { 1012 memmove(p, ds->ivec, Desblk); 1013 desCBCencrypt(p + Desblk, n - Desblk, ds); 1014 } 1015 return 1; 1016 } 1017 1018 static int 1019 des3cipher(Espcb *ecb, uchar *p, int n) 1020 { 1021 DES3state *ds = ecb->espstate; 1022 1023 if(ecb->incoming) { 1024 memmove(ds->ivec, p, Desblk); 1025 des3CBCdecrypt(p + Desblk, n - Desblk, ds); 1026 } else { 1027 memmove(p, ds->ivec, Desblk); 1028 des3CBCencrypt(p + Desblk, n - Desblk, ds); 1029 } 1030 return 1; 1031 } 1032 1033 static void 1034 desespinit(Espcb *ecb, char *name, uchar *k, unsigned n) 1035 { 1036 uchar key[Desblk], ivec[Desblk]; 1037 int i; 1038 1039 n = BITS2BYTES(n); 1040 if(n > Desblk) 1041 n = Desblk; 1042 memset(key, 0, sizeof(key)); 1043 memmove(key, k, n); 1044 for(i = 0; i < Desblk; i++) 1045 ivec[i] = nrand(256); 1046 ecb->espalg = name; 1047 ecb->espblklen = Desblk; 1048 ecb->espivlen = Desblk; 1049 1050 ecb->cipher = descipher; 1051 ecb->espstate = smalloc(sizeof(DESstate)); 1052 setupDESstate(ecb->espstate, key, ivec); 1053 } 1054 1055 static void 1056 des3espinit(Espcb *ecb, char *name, uchar *k, unsigned n) 1057 { 1058 uchar key[3][Desblk], ivec[Desblk]; 1059 int i; 1060 1061 n = BITS2BYTES(n); 1062 if(n > Des3keysz) 1063 n = Des3keysz; 1064 memset(key, 0, sizeof(key)); 1065 memmove(key, k, n); 1066 for(i = 0; i < Desblk; i++) 1067 ivec[i] = nrand(256); 1068 ecb->espalg = name; 1069 ecb->espblklen = Desblk; 1070 ecb->espivlen = Desblk; 1071 1072 ecb->cipher = des3cipher; 1073 ecb->espstate = smalloc(sizeof(DES3state)); 1074 setupDES3state(ecb->espstate, key, ivec); 1075 } 1076 1077 1078 /* 1079 * interfacing to devip 1080 */ 1081 void 1082 espinit(Fs *fs) 1083 { 1084 Proto *esp; 1085 1086 esp = smalloc(sizeof(Proto)); 1087 esp->priv = smalloc(sizeof(Esppriv)); 1088 esp->name = "esp"; 1089 esp->connect = espconnect; 1090 esp->announce = nil; 1091 esp->ctl = espctl; 1092 esp->state = espstate; 1093 esp->create = espcreate; 1094 esp->close = espclose; 1095 esp->rcv = espiput; 1096 esp->advise = espadvise; 1097 esp->stats = espstats; 1098 esp->local = esplocal; 1099 esp->remote = espremote; 1100 esp->ipproto = IP_ESPPROTO; 1101 esp->nc = Nchans; 1102 esp->ptclsize = sizeof(Espcb); 1103 1104 Fsproto(fs, esp); 1105 } 1106