1 /* $OpenBSD: ip_ah.c,v 1.92 2008/09/15 21:46:01 chl Exp $ */ 2 /* 3 * The authors of this code are John Ioannidis (ji@tla.org), 4 * Angelos D. Keromytis (kermit@csd.uch.gr) and 5 * Niels Provos (provos@physnet.uni-hamburg.de). 6 * 7 * The original version of this code was written by John Ioannidis 8 * for BSD/OS in Athens, Greece, in November 1995. 9 * 10 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 11 * by Angelos D. Keromytis. 12 * 13 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 14 * and Niels Provos. 15 * 16 * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist. 17 * 18 * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, 19 * Angelos D. Keromytis and Niels Provos. 20 * Copyright (c) 1999 Niklas Hallqvist. 21 * Copyright (c) 2001 Angelos D. Keromytis. 22 * 23 * Permission to use, copy, and modify this software with or without fee 24 * is hereby granted, provided that this entire notice is included in 25 * all copies of any software which is or includes a copy or 26 * modification of this software. 27 * You may use this code under the GNU public license if you so wish. Please 28 * contribute changes back to the authors under this freer than GPL license 29 * so that we may further the use of strong encryption without limitations to 30 * all. 31 * 32 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 33 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 34 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 35 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 36 * PURPOSE. 37 */ 38 39 #include "pfsync.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/mbuf.h> 44 #include <sys/socket.h> 45 46 #include <net/if.h> 47 #include <net/bpf.h> 48 49 #ifdef INET 50 #include <netinet/in.h> 51 #include <netinet/in_systm.h> 52 #include <netinet/ip.h> 53 #include <netinet/ip_var.h> 54 #endif /* INET */ 55 56 #ifdef INET6 57 #ifndef INET 58 #include <netinet/in.h> 59 #endif /* INET */ 60 #include <netinet/ip6.h> 61 #endif /* INET6 */ 62 63 #include <netinet/ip_ipsp.h> 64 #include <netinet/ip_ah.h> 65 #include <net/pfkeyv2.h> 66 #include <net/if_enc.h> 67 68 #if NPFSYNC > 0 69 #include <net/pfvar.h> 70 #include <net/if_pfsync.h> 71 #endif /* NPFSYNC > 0 */ 72 73 #include <crypto/cryptodev.h> 74 #include <crypto/xform.h> 75 76 #include "bpfilter.h" 77 78 #ifdef ENCDEBUG 79 #define DPRINTF(x) if (encdebug) printf x 80 #else 81 #define DPRINTF(x) 82 #endif 83 84 struct ahstat ahstat; 85 86 /* 87 * ah_attach() is called from the transformation initialization code. 88 */ 89 int 90 ah_attach() 91 { 92 return 0; 93 } 94 95 /* 96 * ah_init() is called when an SPI is being set up. 97 */ 98 int 99 ah_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii) 100 { 101 struct auth_hash *thash = NULL; 102 struct cryptoini cria; 103 104 /* Authentication operation. */ 105 switch (ii->ii_authalg) { 106 case SADB_AALG_MD5HMAC: 107 thash = &auth_hash_hmac_md5_96; 108 break; 109 110 case SADB_AALG_SHA1HMAC: 111 thash = &auth_hash_hmac_sha1_96; 112 break; 113 114 case SADB_X_AALG_RIPEMD160HMAC: 115 thash = &auth_hash_hmac_ripemd_160_96; 116 break; 117 118 case SADB_X_AALG_SHA2_256: 119 thash = &auth_hash_hmac_sha2_256_96; 120 break; 121 122 case SADB_X_AALG_SHA2_384: 123 thash = &auth_hash_hmac_sha2_384_96; 124 break; 125 126 case SADB_X_AALG_SHA2_512: 127 thash = &auth_hash_hmac_sha2_512_96; 128 break; 129 130 case SADB_X_AALG_MD5: 131 thash = &auth_hash_key_md5; 132 break; 133 134 case SADB_X_AALG_SHA1: 135 thash = &auth_hash_key_sha1; 136 break; 137 138 default: 139 DPRINTF(("ah_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg)); 140 return EINVAL; 141 } 142 143 if (ii->ii_authkeylen != thash->keysize && thash->keysize != 0) { 144 DPRINTF(("ah_init(): keylength %d doesn't match algorithm " 145 "%s keysize (%d)\n", ii->ii_authkeylen, thash->name, 146 thash->keysize)); 147 return EINVAL; 148 } 149 150 tdbp->tdb_xform = xsp; 151 tdbp->tdb_authalgxform = thash; 152 tdbp->tdb_bitmap = 0; 153 tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL; 154 155 DPRINTF(("ah_init(): initialized TDB with hash algorithm %s\n", 156 thash->name)); 157 158 tdbp->tdb_amxkeylen = ii->ii_authkeylen; 159 tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA, M_WAITOK); 160 161 bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen); 162 163 /* Initialize crypto session. */ 164 bzero(&cria, sizeof(cria)); 165 cria.cri_alg = tdbp->tdb_authalgxform->type; 166 cria.cri_klen = ii->ii_authkeylen * 8; 167 cria.cri_key = ii->ii_authkey; 168 169 return crypto_newsession(&tdbp->tdb_cryptoid, &cria, 0); 170 } 171 172 /* 173 * Paranoia. 174 */ 175 int 176 ah_zeroize(struct tdb *tdbp) 177 { 178 int err; 179 180 if (tdbp->tdb_amxkey) { 181 bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen); 182 free(tdbp->tdb_amxkey, M_XDATA); 183 tdbp->tdb_amxkey = NULL; 184 } 185 186 err = crypto_freesession(tdbp->tdb_cryptoid); 187 tdbp->tdb_cryptoid = 0; 188 return err; 189 } 190 191 /* 192 * Massage IPv4/IPv6 headers for AH processing. 193 */ 194 int 195 ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out) 196 { 197 struct mbuf *m = *m0; 198 unsigned char *ptr; 199 int off, count; 200 201 #ifdef INET 202 struct ip *ip; 203 #endif /* INET */ 204 205 #ifdef INET6 206 struct ip6_ext *ip6e; 207 struct ip6_hdr ip6; 208 int ad, alloc, nxt; 209 #endif /* INET6 */ 210 211 switch (proto) { 212 #ifdef INET 213 case AF_INET: 214 /* 215 * This is the least painful way of dealing with IPv4 header 216 * and option processing -- just make sure they're in 217 * contiguous memory. 218 */ 219 *m0 = m = m_pullup(m, skip); 220 if (m == NULL) { 221 DPRINTF(("ah_massage_headers(): m_pullup() failed\n")); 222 ahstat.ahs_hdrops++; 223 return ENOBUFS; 224 } 225 226 /* Fix the IP header */ 227 ip = mtod(m, struct ip *); 228 ip->ip_tos = 0; 229 ip->ip_ttl = 0; 230 ip->ip_sum = 0; 231 232 /* 233 * On input, fix ip_len which has been byte-swapped 234 * at ip_input(). 235 */ 236 if (alg == CRYPTO_MD5_KPDK || alg == CRYPTO_SHA1_KPDK) 237 ip->ip_off &= htons(IP_DF); 238 else 239 ip->ip_off = 0; 240 241 ptr = mtod(m, unsigned char *) + sizeof(struct ip); 242 243 /* IPv4 option processing */ 244 for (off = sizeof(struct ip); off < skip;) { 245 if (ptr[off] == IPOPT_EOL || ptr[off] == IPOPT_NOP || 246 off + 1 < skip) 247 ; 248 else { 249 DPRINTF(("ah_massage_headers(): illegal IPv4 " 250 "option length for option %d\n", 251 ptr[off])); 252 253 ahstat.ahs_hdrops++; 254 m_freem(m); 255 return EINVAL; 256 } 257 258 switch (ptr[off]) { 259 case IPOPT_EOL: 260 off = skip; /* End the loop. */ 261 break; 262 263 case IPOPT_NOP: 264 off++; 265 break; 266 267 case IPOPT_SECURITY: /* 0x82 */ 268 case 0x85: /* Extended security. */ 269 case 0x86: /* Commercial security. */ 270 case 0x94: /* Router alert */ 271 case 0x95: /* RFC1770 */ 272 /* Sanity check for option length. */ 273 if (ptr[off + 1] < 2) { 274 DPRINTF(("ah_massage_headers(): " 275 "illegal IPv4 option length for " 276 "option %d\n", ptr[off])); 277 278 ahstat.ahs_hdrops++; 279 m_freem(m); 280 return EINVAL; 281 } 282 283 off += ptr[off + 1]; 284 break; 285 286 case IPOPT_LSRR: 287 case IPOPT_SSRR: 288 /* Sanity check for option length. */ 289 if (ptr[off + 1] < 2) { 290 DPRINTF(("ah_massage_headers(): " 291 "illegal IPv4 option length for " 292 "option %d\n", ptr[off])); 293 294 ahstat.ahs_hdrops++; 295 m_freem(m); 296 return EINVAL; 297 } 298 299 /* 300 * On output, if we have either of the 301 * source routing options, we should 302 * swap the destination address of the 303 * IP header with the last address 304 * specified in the option, as that is 305 * what the destination's IP header 306 * will look like. 307 */ 308 if (out) 309 bcopy(ptr + off + ptr[off + 1] - 310 sizeof(struct in_addr), 311 &(ip->ip_dst), sizeof(struct in_addr)); 312 313 /* FALLTHROUGH */ 314 default: 315 /* Sanity check for option length. */ 316 if (ptr[off + 1] < 2) { 317 DPRINTF(("ah_massage_headers(): " 318 "illegal IPv4 option length for " 319 "option %d\n", ptr[off])); 320 ahstat.ahs_hdrops++; 321 m_freem(m); 322 return EINVAL; 323 } 324 325 /* Zeroize all other options. */ 326 count = ptr[off + 1]; 327 bcopy(ipseczeroes, ptr, count); 328 off += count; 329 break; 330 } 331 332 /* Sanity check. */ 333 if (off > skip) { 334 DPRINTF(("ah_massage_headers(): malformed " 335 "IPv4 options header\n")); 336 337 ahstat.ahs_hdrops++; 338 m_freem(m); 339 return EINVAL; 340 } 341 } 342 343 break; 344 #endif /* INET */ 345 346 #ifdef INET6 347 case AF_INET6: /* Ugly... */ 348 /* Copy and "cook" the IPv6 header. */ 349 m_copydata(m, 0, sizeof(ip6), (caddr_t) &ip6); 350 351 /* We don't do IPv6 Jumbograms. */ 352 if (ip6.ip6_plen == 0) { 353 DPRINTF(("ah_massage_headers(): unsupported IPv6 " 354 "jumbogram")); 355 ahstat.ahs_hdrops++; 356 m_freem(m); 357 return EMSGSIZE; 358 } 359 360 ip6.ip6_flow = 0; 361 ip6.ip6_hlim = 0; 362 ip6.ip6_vfc &= ~IPV6_VERSION_MASK; 363 ip6.ip6_vfc |= IPV6_VERSION; 364 365 /* Scoped address handling. */ 366 if (IN6_IS_SCOPE_EMBED(&ip6.ip6_src)) 367 ip6.ip6_src.s6_addr16[1] = 0; 368 if (IN6_IS_SCOPE_EMBED(&ip6.ip6_dst)) 369 ip6.ip6_dst.s6_addr16[1] = 0; 370 371 /* Done with IPv6 header. */ 372 m_copyback(m, 0, sizeof(struct ip6_hdr), &ip6); 373 374 /* Let's deal with the remaining headers (if any). */ 375 if (skip - sizeof(struct ip6_hdr) > 0) { 376 if (m->m_len <= skip) { 377 ptr = malloc(skip - sizeof(struct ip6_hdr), 378 M_XDATA, M_NOWAIT); 379 if (ptr == NULL) { 380 DPRINTF(("ah_massage_headers(): failed to allocate memory for IPv6 headers\n")); 381 ahstat.ahs_hdrops++; 382 m_freem(m); 383 return ENOBUFS; 384 } 385 386 /* 387 * Copy all the protocol headers after 388 * the IPv6 header. 389 */ 390 m_copydata(m, sizeof(struct ip6_hdr), 391 skip - sizeof(struct ip6_hdr), ptr); 392 alloc = 1; 393 } else { 394 /* No need to allocate memory. */ 395 ptr = mtod(m, unsigned char *) + 396 sizeof(struct ip6_hdr); 397 alloc = 0; 398 } 399 } else 400 break; 401 402 nxt = ip6.ip6_nxt & 0xff; /* Next header type. */ 403 404 for (off = 0; off < skip - sizeof(struct ip6_hdr);) { 405 switch (nxt) { 406 case IPPROTO_HOPOPTS: 407 case IPPROTO_DSTOPTS: 408 ip6e = (struct ip6_ext *) (ptr + off); 409 410 /* 411 * Process the mutable/immutable 412 * options -- borrows heavily from the 413 * KAME code. 414 */ 415 for (count = off + sizeof(struct ip6_ext); 416 count < off + ((ip6e->ip6e_len + 1) << 3);) { 417 if (ptr[count] == IP6OPT_PAD1) { 418 count++; 419 continue; /* Skip padding. */ 420 } 421 422 /* Sanity check. */ 423 if (count > off + 424 ((ip6e->ip6e_len + 1) << 3)) { 425 ahstat.ahs_hdrops++; 426 m_freem(m); 427 428 /* Free, if we allocated. */ 429 if (alloc) 430 free(ptr, M_XDATA); 431 return EINVAL; 432 } 433 434 ad = ptr[count + 1]; 435 436 /* If mutable option, zeroize. */ 437 if (ptr[count] & IP6OPT_MUTABLE) 438 bcopy(ipseczeroes, ptr + count, 439 ptr[count + 1]); 440 441 count += ad; 442 443 /* Sanity check. */ 444 if (count > 445 skip - sizeof(struct ip6_hdr)) { 446 ahstat.ahs_hdrops++; 447 m_freem(m); 448 449 /* Free, if we allocated. */ 450 if (alloc) 451 free(ptr, M_XDATA); 452 return EINVAL; 453 } 454 } 455 456 /* Advance. */ 457 off += ((ip6e->ip6e_len + 1) << 3); 458 nxt = ip6e->ip6e_nxt; 459 break; 460 461 case IPPROTO_ROUTING: 462 /* 463 * Always include routing headers in 464 * computation. 465 */ 466 { 467 struct ip6_rthdr *rh; 468 469 ip6e = (struct ip6_ext *) (ptr + off); 470 rh = (struct ip6_rthdr *)(ptr + off); 471 /* 472 * must adjust content to make it look like 473 * its final form (as seen at the final 474 * destination). 475 * we only know how to massage type 0 routing 476 * header. 477 */ 478 if (out && rh->ip6r_type == IPV6_RTHDR_TYPE_0) { 479 struct ip6_rthdr0 *rh0; 480 struct in6_addr *addr, finaldst; 481 int i; 482 483 rh0 = (struct ip6_rthdr0 *)rh; 484 addr = (struct in6_addr *)(rh0 + 1); 485 486 for (i = 0; i < rh0->ip6r0_segleft; i++) 487 if (IN6_IS_SCOPE_EMBED(&addr[i])) 488 addr[i].s6_addr16[1] = 0; 489 490 finaldst = addr[rh0->ip6r0_segleft - 1]; 491 ovbcopy(&addr[0], &addr[1], 492 sizeof(struct in6_addr) * 493 (rh0->ip6r0_segleft - 1)); 494 495 m_copydata(m, 0, sizeof(ip6), 496 (caddr_t)&ip6); 497 addr[0] = ip6.ip6_dst; 498 ip6.ip6_dst = finaldst; 499 m_copyback(m, 0, sizeof(ip6), &ip6); 500 501 rh0->ip6r0_segleft = 0; 502 } 503 504 /* advance */ 505 off += ((ip6e->ip6e_len + 1) << 3); 506 nxt = ip6e->ip6e_nxt; 507 break; 508 } 509 510 default: 511 DPRINTF(("ah_massage_headers(): unexpected " 512 "IPv6 header type %d\n", off)); 513 if (alloc) 514 free(ptr, M_XDATA); 515 ahstat.ahs_hdrops++; 516 m_freem(m); 517 return EINVAL; 518 } 519 } 520 521 /* Copyback and free, if we allocated. */ 522 if (alloc) { 523 m_copyback(m, sizeof(struct ip6_hdr), 524 skip - sizeof(struct ip6_hdr), ptr); 525 free(ptr, M_XDATA); 526 } 527 528 break; 529 #endif /* INET6 */ 530 } 531 532 return 0; 533 } 534 535 /* 536 * ah_input() gets called to verify that an input packet 537 * passes authentication. 538 */ 539 int 540 ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) 541 { 542 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; 543 struct tdb_crypto *tc; 544 struct m_tag *mtag; 545 u_int32_t btsx; 546 u_int8_t hl; 547 int rplen; 548 549 struct cryptodesc *crda = NULL; 550 struct cryptop *crp; 551 552 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) 553 rplen = AH_FLENGTH + sizeof(u_int32_t); 554 else 555 rplen = AH_FLENGTH; 556 557 /* Save the AH header, we use it throughout. */ 558 m_copydata(m, skip + offsetof(struct ah, ah_hl), sizeof(u_int8_t), 559 (caddr_t) &hl); 560 561 /* Replay window checking, if applicable. */ 562 if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) { 563 m_copydata(m, skip + offsetof(struct ah, ah_rpl), 564 sizeof(u_int32_t), (caddr_t) &btsx); 565 btsx = ntohl(btsx); 566 567 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl), 568 tdb->tdb_wnd, &(tdb->tdb_bitmap), 0)) { 569 case 0: /* All's well. */ 570 break; 571 572 case 1: 573 DPRINTF(("ah_input(): replay counter wrapped for " 574 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 575 ntohl(tdb->tdb_spi))); 576 577 ahstat.ahs_wrap++; 578 m_freem(m); 579 return ENOBUFS; 580 581 case 2: 582 case 3: 583 DPRINTF(("ah_input(): duplicate packet received in " 584 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 585 ntohl(tdb->tdb_spi))); 586 587 m_freem(m); 588 return ENOBUFS; 589 590 default: 591 DPRINTF(("ah_input(): bogus value from " 592 "checkreplaywindow32() in SA %s/%08x\n", 593 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 594 595 ahstat.ahs_replay++; 596 m_freem(m); 597 return ENOBUFS; 598 } 599 } 600 601 /* Verify AH header length. */ 602 if (hl * sizeof(u_int32_t) != ahx->authsize + rplen - AH_FLENGTH) { 603 DPRINTF(("ah_input(): bad authenticator length %d for packet " 604 "in SA %s/%08x\n", hl * sizeof(u_int32_t), 605 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 606 607 ahstat.ahs_badauthl++; 608 m_freem(m); 609 return EACCES; 610 } 611 612 /* Update the counters. */ 613 tdb->tdb_cur_bytes += 614 (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t)); 615 ahstat.ahs_ibytes += (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t)); 616 617 /* Hard expiration. */ 618 if (tdb->tdb_flags & TDBF_BYTES && 619 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { 620 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 621 tdb_delete(tdb); 622 m_freem(m); 623 return ENXIO; 624 } 625 626 /* Notify on expiration. */ 627 if (tdb->tdb_flags & TDBF_SOFT_BYTES && 628 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { 629 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 630 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking. */ 631 } 632 633 /* Get crypto descriptors. */ 634 crp = crypto_getreq(1); 635 if (crp == NULL) { 636 m_freem(m); 637 DPRINTF(("ah_input(): failed to acquire crypto " 638 "descriptors\n")); 639 ahstat.ahs_crypto++; 640 return ENOBUFS; 641 } 642 643 crda = crp->crp_desc; 644 645 crda->crd_skip = 0; 646 crda->crd_len = m->m_pkthdr.len; 647 crda->crd_inject = skip + rplen; 648 649 /* Authentication operation. */ 650 crda->crd_alg = ahx->type; 651 crda->crd_key = tdb->tdb_amxkey; 652 crda->crd_klen = tdb->tdb_amxkeylen * 8; 653 654 #ifdef notyet 655 /* Find out if we've already done crypto. */ 656 for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL); 657 mtag != NULL; 658 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) { 659 struct tdb_ident *tdbi; 660 661 tdbi = (struct tdb_ident *) (mtag + 1); 662 if (tdbi->proto == tdb->tdb_sproto && 663 tdbi->spi == tdb->tdb_spi && 664 !bcmp(&tdbi->dst, &tdb->tdb_dst, 665 sizeof(union sockaddr_union))) 666 break; 667 } 668 #else 669 mtag = NULL; 670 #endif 671 672 /* Allocate IPsec-specific opaque crypto info. */ 673 if (mtag == NULL) 674 tc = malloc(sizeof(*tc) + skip + rplen + ahx->authsize, M_XDATA, 675 M_NOWAIT | M_ZERO); 676 else /* Hash verification has already been done successfully. */ 677 tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO); 678 if (tc == NULL) { 679 m_freem(m); 680 crypto_freereq(crp); 681 DPRINTF(("ah_input(): failed to allocate tdb_crypto\n")); 682 ahstat.ahs_crypto++; 683 return ENOBUFS; 684 } 685 686 /* Only save information if crypto processing is needed. */ 687 if (mtag == NULL) { 688 /* 689 * Save the authenticator, the skipped portion of the packet, 690 * and the AH header. 691 */ 692 m_copydata(m, 0, skip + rplen + ahx->authsize, 693 (caddr_t) (tc + 1)); 694 695 /* Zeroize the authenticator on the packet. */ 696 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes); 697 698 /* "Massage" the packet headers for crypto processing. */ 699 if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, 700 skip, ahx->type, 0)) != 0) { 701 /* mbuf will be free'd by callee. */ 702 free(tc, M_XDATA); 703 crypto_freereq(crp); 704 return btsx; 705 } 706 } 707 708 /* Crypto operation descriptor. */ 709 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 710 crp->crp_flags = CRYPTO_F_IMBUF; 711 crp->crp_buf = (caddr_t) m; 712 crp->crp_callback = (int (*) (struct cryptop *)) ah_input_cb; 713 crp->crp_sid = tdb->tdb_cryptoid; 714 crp->crp_opaque = (caddr_t) tc; 715 716 /* These are passed as-is to the callback. */ 717 tc->tc_skip = skip; 718 tc->tc_protoff = protoff; 719 tc->tc_spi = tdb->tdb_spi; 720 tc->tc_proto = tdb->tdb_sproto; 721 tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified. */ 722 bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union)); 723 724 if (mtag == NULL) 725 return crypto_dispatch(crp); 726 else 727 return ah_input_cb(crp); 728 } 729 730 /* 731 * AH input callback, called directly by the crypto driver. 732 */ 733 int 734 ah_input_cb(void *op) 735 { 736 int s, roff, rplen, error, skip, protoff; 737 unsigned char calc[AH_ALEN_MAX]; 738 struct mbuf *m1, *m0, *m; 739 struct auth_hash *ahx; 740 struct tdb_crypto *tc; 741 struct cryptop *crp; 742 struct m_tag *mtag; 743 struct tdb *tdb; 744 u_int32_t btsx; 745 u_int8_t prot; 746 caddr_t ptr; 747 748 crp = (struct cryptop *) op; 749 750 tc = (struct tdb_crypto *) crp->crp_opaque; 751 skip = tc->tc_skip; 752 protoff = tc->tc_protoff; 753 mtag = (struct m_tag *) tc->tc_ptr; 754 755 m = (struct mbuf *) crp->crp_buf; 756 if (m == NULL) { 757 /* Shouldn't happen... */ 758 free(tc, M_XDATA); 759 crypto_freereq(crp); 760 ahstat.ahs_crypto++; 761 DPRINTF(("ah_input_cb(): bogus returned buffer from " 762 "crypto\n")); 763 return (EINVAL); 764 } 765 766 s = spltdb(); 767 768 tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto); 769 if (tdb == NULL) { 770 free(tc, M_XDATA); 771 ahstat.ahs_notdb++; 772 DPRINTF(("ah_input_cb(): TDB is expired while in crypto")); 773 error = EPERM; 774 goto baddone; 775 } 776 777 ahx = (struct auth_hash *) tdb->tdb_authalgxform; 778 779 /* Check for crypto errors. */ 780 if (crp->crp_etype) { 781 if (crp->crp_etype == EAGAIN) { 782 /* Reset the session ID */ 783 if (tdb->tdb_cryptoid != 0) 784 tdb->tdb_cryptoid = crp->crp_sid; 785 splx(s); 786 return crypto_dispatch(crp); 787 } 788 free(tc, M_XDATA); 789 ahstat.ahs_noxform++; 790 DPRINTF(("ah_input_cb(): crypto error %d\n", crp->crp_etype)); 791 error = crp->crp_etype; 792 goto baddone; 793 } else { 794 crypto_freereq(crp); /* No longer needed. */ 795 crp = NULL; 796 } 797 798 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) 799 rplen = AH_FLENGTH + sizeof(u_int32_t); 800 else 801 rplen = AH_FLENGTH; 802 803 /* Copy authenticator off the packet. */ 804 m_copydata(m, skip + rplen, ahx->authsize, calc); 805 806 /* 807 * If we have an mtag, we don't need to verify the authenticator -- 808 * it has been verified by an IPsec-aware NIC. 809 */ 810 if (mtag == NULL) { 811 ptr = (caddr_t) (tc + 1); 812 813 /* Verify authenticator. */ 814 if (bcmp(ptr + skip + rplen, calc, ahx->authsize)) { 815 free(tc, M_XDATA); 816 817 DPRINTF(("ah_input(): authentication failed for " 818 "packet in SA %s/%08x\n", 819 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 820 821 ahstat.ahs_badauth++; 822 error = EACCES; 823 goto baddone; 824 } 825 826 /* Fix the Next Protocol field. */ 827 ((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip]; 828 829 /* Copyback the saved (uncooked) network headers. */ 830 m_copyback(m, 0, skip, ptr); 831 } else { 832 /* Fix the Next Protocol field. */ 833 m_copydata(m, skip, sizeof(u_int8_t), &prot); 834 m_copyback(m, protoff, sizeof(u_int8_t), &prot); 835 } 836 837 free(tc, M_XDATA); 838 839 /* Replay window checking, if applicable. */ 840 if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) { 841 m_copydata(m, skip + offsetof(struct ah, ah_rpl), 842 sizeof(u_int32_t), (caddr_t) &btsx); 843 btsx = ntohl(btsx); 844 845 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl), 846 tdb->tdb_wnd, &(tdb->tdb_bitmap), 1)) { 847 case 0: /* All's well. */ 848 #if NPFSYNC > 0 849 pfsync_update_tdb(tdb,0); 850 #endif 851 break; 852 853 case 1: 854 DPRINTF(("ah_input(): replay counter wrapped for " 855 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 856 ntohl(tdb->tdb_spi))); 857 858 ahstat.ahs_wrap++; 859 error = ENOBUFS; 860 goto baddone; 861 862 case 2: 863 case 3: 864 DPRINTF(("ah_input_cb(): duplicate packet received in " 865 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 866 ntohl(tdb->tdb_spi))); 867 868 error = ENOBUFS; 869 goto baddone; 870 871 default: 872 DPRINTF(("ah_input_cb(): bogus value from " 873 "checkreplaywindow32() in SA %s/%08x\n", 874 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 875 876 ahstat.ahs_replay++; 877 error = ENOBUFS; 878 goto baddone; 879 } 880 } 881 882 /* Record the beginning of the AH header. */ 883 m1 = m_getptr(m, skip, &roff); 884 if (m1 == NULL) { 885 ahstat.ahs_hdrops++; 886 splx(s); 887 m_freem(m); 888 889 DPRINTF(("ah_input(): bad mbuf chain for packet in SA " 890 "%s/%08x\n", ipsp_address(tdb->tdb_dst), 891 ntohl(tdb->tdb_spi))); 892 893 return EINVAL; 894 } 895 896 /* Remove the AH header from the mbuf. */ 897 if (roff == 0) { 898 /* 899 * The AH header was conveniently at the beginning of 900 * the mbuf. 901 */ 902 m_adj(m1, rplen + ahx->authsize); 903 if (!(m1->m_flags & M_PKTHDR)) 904 m->m_pkthdr.len -= rplen + ahx->authsize; 905 } else 906 if (roff + rplen + ahx->authsize >= m1->m_len) { 907 /* 908 * Part or all of the AH header is at the end 909 * of this mbuf, so first let's remove the 910 * remainder of the AH header from the 911 * beginning of the remainder of the mbuf 912 * chain, if any. 913 */ 914 if (roff + rplen + ahx->authsize > m1->m_len) { 915 /* Adjust the next mbuf by the remainder. */ 916 m_adj(m1->m_next, roff + rplen + 917 ahx->authsize - m1->m_len); 918 919 /* 920 * The second mbuf is guaranteed not 921 * to have a pkthdr... 922 */ 923 m->m_pkthdr.len -= 924 (roff + rplen + ahx->authsize - m1->m_len); 925 } 926 927 /* Now, let's unlink the mbuf chain for a second... */ 928 m0 = m1->m_next; 929 m1->m_next = NULL; 930 931 /* 932 * ...and trim the end of the first part of 933 * the chain...sick 934 */ 935 m_adj(m1, -(m1->m_len - roff)); 936 if (!(m1->m_flags & M_PKTHDR)) 937 m->m_pkthdr.len -= (m1->m_len - roff); 938 939 /* Finally, let's relink. */ 940 m1->m_next = m0; 941 } else { 942 /* 943 * The AH header lies in the "middle" of the 944 * mbuf...do an overlapping copy of the 945 * remainder of the mbuf over the ESP header. 946 */ 947 bcopy(mtod(m1, u_char *) + roff + rplen + 948 ahx->authsize, mtod(m1, u_char *) + roff, 949 m1->m_len - (roff + rplen + ahx->authsize)); 950 m1->m_len -= rplen + ahx->authsize; 951 m->m_pkthdr.len -= rplen + ahx->authsize; 952 } 953 954 error = ipsec_common_input_cb(m, tdb, skip, protoff, mtag); 955 splx(s); 956 return (error); 957 958 baddone: 959 splx(s); 960 961 if (m != NULL) 962 m_freem(m); 963 964 if (crp != NULL) 965 crypto_freereq(crp); 966 967 return (error); 968 } 969 970 /* 971 * AH output routine, called by ipsp_process_packet(). 972 */ 973 int 974 ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, 975 int protoff) 976 { 977 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; 978 struct cryptodesc *crda; 979 struct tdb_crypto *tc; 980 struct mbuf *mo, *mi; 981 struct cryptop *crp; 982 u_int16_t iplen; 983 int len, rplen; 984 u_int8_t prot; 985 struct ah *ah; 986 #if NBPFILTER > 0 987 struct ifnet *ifn = &(encif[0].sc_if); 988 989 ifn->if_opackets++; 990 ifn->if_obytes += m->m_pkthdr.len; 991 992 if (ifn->if_bpf) { 993 struct enchdr hdr; 994 995 bzero (&hdr, sizeof(hdr)); 996 997 hdr.af = tdb->tdb_dst.sa.sa_family; 998 hdr.spi = tdb->tdb_spi; 999 hdr.flags |= M_AUTH | M_AUTH_AH; 1000 1001 bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, ENC_HDRLEN, m, 1002 BPF_DIRECTION_OUT); 1003 } 1004 #endif 1005 1006 ahstat.ahs_output++; 1007 1008 /* 1009 * Check for replay counter wrap-around in automatic (not 1010 * manual) keying. 1011 */ 1012 if ((tdb->tdb_rpl == 0) && (tdb->tdb_wnd > 0) && 1013 (!(tdb->tdb_flags & TDBF_NOREPLAY))) { 1014 DPRINTF(("ah_output(): SA %s/%08x should have expired\n", 1015 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 1016 m_freem(m); 1017 ahstat.ahs_wrap++; 1018 return EINVAL; 1019 } 1020 1021 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) 1022 rplen = AH_FLENGTH + sizeof(u_int32_t); 1023 else 1024 rplen = AH_FLENGTH; 1025 1026 switch (tdb->tdb_dst.sa.sa_family) { 1027 #ifdef INET 1028 case AF_INET: 1029 /* Check for IP maximum packet size violations. */ 1030 if (rplen + ahx->authsize + m->m_pkthdr.len > IP_MAXPACKET) { 1031 DPRINTF(("ah_output(): packet in SA %s/%08x got too " 1032 "big\n", 1033 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 1034 m_freem(m); 1035 ahstat.ahs_toobig++; 1036 return EMSGSIZE; 1037 } 1038 break; 1039 #endif /* INET */ 1040 1041 #ifdef INET6 1042 case AF_INET6: 1043 /* Check for IPv6 maximum packet size violations. */ 1044 if (rplen + ahx->authsize + m->m_pkthdr.len > IPV6_MAXPACKET) { 1045 DPRINTF(("ah_output(): packet in SA %s/%08x " 1046 "got too big\n", ipsp_address(tdb->tdb_dst), 1047 ntohl(tdb->tdb_spi))); 1048 m_freem(m); 1049 ahstat.ahs_toobig++; 1050 return EMSGSIZE; 1051 } 1052 break; 1053 #endif /* INET6 */ 1054 1055 default: 1056 DPRINTF(("ah_output(): unknown/unsupported protocol " 1057 "family %d, SA %s/%08x\n", tdb->tdb_dst.sa.sa_family, 1058 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 1059 m_freem(m); 1060 ahstat.ahs_nopf++; 1061 return EPFNOSUPPORT; 1062 } 1063 1064 /* Update the counters. */ 1065 tdb->tdb_cur_bytes += m->m_pkthdr.len - skip; 1066 ahstat.ahs_obytes += m->m_pkthdr.len - skip; 1067 1068 /* Hard expiration. */ 1069 if (tdb->tdb_flags & TDBF_BYTES && 1070 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { 1071 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 1072 tdb_delete(tdb); 1073 m_freem(m); 1074 return EINVAL; 1075 } 1076 1077 /* Notify on expiration. */ 1078 if (tdb->tdb_flags & TDBF_SOFT_BYTES && 1079 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { 1080 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 1081 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */ 1082 } 1083 1084 /* 1085 * Loop through mbuf chain; if we find a readonly mbuf, 1086 * replace the rest of the chain. 1087 */ 1088 mo = NULL; 1089 mi = m; 1090 while (mi != NULL && !M_READONLY(mi)) { 1091 mo = mi; 1092 mi = mi->m_next; 1093 } 1094 1095 if (mi != NULL) { 1096 /* Replace the rest of the mbuf chain. */ 1097 struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT); 1098 1099 if (n == NULL) { 1100 ahstat.ahs_hdrops++; 1101 m_freem(m); 1102 return ENOBUFS; 1103 } 1104 1105 if (mo != NULL) 1106 mo->m_next = n; 1107 else 1108 m = n; 1109 1110 m_freem(mi); 1111 } 1112 1113 /* Inject AH header. */ 1114 mi = m_inject(m, skip, rplen + ahx->authsize, M_DONTWAIT); 1115 if (mi == NULL) { 1116 DPRINTF(("ah_output(): failed to inject AH header for SA " 1117 "%s/%08x\n", ipsp_address(tdb->tdb_dst), 1118 ntohl(tdb->tdb_spi))); 1119 1120 m_freem(m); 1121 ahstat.ahs_hdrops++; 1122 return ENOBUFS; 1123 } 1124 1125 /* 1126 * The AH header is guaranteed by m_inject() to be in 1127 * contiguous memory, at the beginning of the returned mbuf. 1128 */ 1129 ah = mtod(mi, struct ah *); 1130 1131 /* Initialize the AH header. */ 1132 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nh); 1133 ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH) / sizeof(u_int32_t); 1134 ah->ah_rv = 0; 1135 ah->ah_spi = tdb->tdb_spi; 1136 1137 /* Zeroize authenticator. */ 1138 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes); 1139 1140 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) { 1141 ah->ah_rpl = htonl(tdb->tdb_rpl++); 1142 #if NPFSYNC > 0 1143 pfsync_update_tdb(tdb,1); 1144 #endif 1145 } 1146 1147 /* Get crypto descriptors. */ 1148 crp = crypto_getreq(1); 1149 if (crp == NULL) { 1150 m_freem(m); 1151 DPRINTF(("ah_output(): failed to acquire crypto " 1152 "descriptors\n")); 1153 ahstat.ahs_crypto++; 1154 return ENOBUFS; 1155 } 1156 1157 crda = crp->crp_desc; 1158 1159 crda->crd_skip = 0; 1160 crda->crd_inject = skip + rplen; 1161 crda->crd_len = m->m_pkthdr.len; 1162 1163 /* Authentication operation. */ 1164 crda->crd_alg = ahx->type; 1165 crda->crd_key = tdb->tdb_amxkey; 1166 crda->crd_klen = tdb->tdb_amxkeylen * 8; 1167 1168 /* Allocate IPsec-specific opaque crypto info. */ 1169 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) 1170 tc = malloc(sizeof(*tc) + skip, M_XDATA, M_NOWAIT | M_ZERO); 1171 else 1172 tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO); 1173 if (tc == NULL) { 1174 m_freem(m); 1175 crypto_freereq(crp); 1176 DPRINTF(("ah_output(): failed to allocate tdb_crypto\n")); 1177 ahstat.ahs_crypto++; 1178 return ENOBUFS; 1179 } 1180 1181 /* Save the skipped portion of the packet. */ 1182 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) { 1183 m_copydata(m, 0, skip, (caddr_t) (tc + 1)); 1184 1185 /* 1186 * Fix IP header length on the header used for 1187 * authentication. We don't need to fix the original 1188 * header length as it will be fixed by our caller. 1189 */ 1190 switch (tdb->tdb_dst.sa.sa_family) { 1191 #ifdef INET 1192 case AF_INET: 1193 bcopy(((caddr_t)(tc + 1)) + 1194 offsetof(struct ip, ip_len), 1195 (caddr_t) &iplen, sizeof(u_int16_t)); 1196 iplen = htons(ntohs(iplen) + rplen + ahx->authsize); 1197 m_copyback(m, offsetof(struct ip, ip_len), 1198 sizeof(u_int16_t), &iplen); 1199 break; 1200 #endif /* INET */ 1201 1202 #ifdef INET6 1203 case AF_INET6: 1204 bcopy(((caddr_t)(tc + 1)) + 1205 offsetof(struct ip6_hdr, ip6_plen), 1206 (caddr_t) &iplen, sizeof(u_int16_t)); 1207 iplen = htons(ntohs(iplen) + rplen + ahx->authsize); 1208 m_copyback(m, offsetof(struct ip6_hdr, ip6_plen), 1209 sizeof(u_int16_t), &iplen); 1210 break; 1211 #endif /* INET6 */ 1212 } 1213 1214 /* Fix the Next Header field in saved header. */ 1215 ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH; 1216 1217 /* Update the Next Protocol field in the IP header. */ 1218 prot = IPPROTO_AH; 1219 m_copyback(m, protoff, sizeof(u_int8_t), &prot); 1220 1221 /* "Massage" the packet headers for crypto processing. */ 1222 if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, 1223 skip, ahx->type, 1)) != 0) { 1224 /* mbuf will be free'd by callee. */ 1225 free(tc, M_XDATA); 1226 crypto_freereq(crp); 1227 return len; 1228 } 1229 } else { 1230 /* Update the Next Protocol field in the IP header. */ 1231 prot = IPPROTO_AH; 1232 m_copyback(m, protoff, sizeof(u_int8_t), &prot); 1233 } 1234 1235 /* Crypto operation descriptor. */ 1236 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 1237 crp->crp_flags = CRYPTO_F_IMBUF; 1238 crp->crp_buf = (caddr_t) m; 1239 crp->crp_callback = (int (*) (struct cryptop *)) ah_output_cb; 1240 crp->crp_sid = tdb->tdb_cryptoid; 1241 crp->crp_opaque = (caddr_t) tc; 1242 1243 /* These are passed as-is to the callback. */ 1244 tc->tc_skip = skip; 1245 tc->tc_protoff = protoff; 1246 tc->tc_spi = tdb->tdb_spi; 1247 tc->tc_proto = tdb->tdb_sproto; 1248 bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union)); 1249 1250 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) 1251 return crypto_dispatch(crp); 1252 else 1253 return ah_output_cb(crp); 1254 } 1255 1256 /* 1257 * AH output callback, called directly from the crypto handler. 1258 */ 1259 int 1260 ah_output_cb(void *op) 1261 { 1262 int skip, error; 1263 struct tdb_crypto *tc; 1264 struct cryptop *crp; 1265 struct tdb *tdb; 1266 struct mbuf *m; 1267 caddr_t ptr; 1268 int err, s; 1269 1270 crp = (struct cryptop *) op; 1271 tc = (struct tdb_crypto *) crp->crp_opaque; 1272 skip = tc->tc_skip; 1273 ptr = (caddr_t) (tc + 1); 1274 1275 m = (struct mbuf *) crp->crp_buf; 1276 if (m == NULL) { 1277 /* Shouldn't happen... */ 1278 free(tc, M_XDATA); 1279 crypto_freereq(crp); 1280 ahstat.ahs_crypto++; 1281 DPRINTF(("ah_output_cb(): bogus returned buffer from " 1282 "crypto\n")); 1283 return (EINVAL); 1284 } 1285 1286 s = spltdb(); 1287 1288 tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto); 1289 if (tdb == NULL) { 1290 free(tc, M_XDATA); 1291 ahstat.ahs_notdb++; 1292 DPRINTF(("ah_output_cb(): TDB is expired while in crypto\n")); 1293 error = EPERM; 1294 goto baddone; 1295 } 1296 1297 /* Check for crypto errors. */ 1298 if (crp->crp_etype) { 1299 if (crp->crp_etype == EAGAIN) { 1300 /* Reset the session ID */ 1301 if (tdb->tdb_cryptoid != 0) 1302 tdb->tdb_cryptoid = crp->crp_sid; 1303 splx(s); 1304 return crypto_dispatch(crp); 1305 } 1306 free(tc, M_XDATA); 1307 ahstat.ahs_noxform++; 1308 DPRINTF(("ah_output_cb(): crypto error %d\n", crp->crp_etype)); 1309 error = crp->crp_etype; 1310 goto baddone; 1311 } 1312 1313 /* 1314 * Copy original headers (with the new protocol number) back 1315 * in place. 1316 */ 1317 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) 1318 m_copyback(m, 0, skip, ptr); 1319 1320 free(tc, M_XDATA); 1321 1322 /* No longer needed. */ 1323 crypto_freereq(crp); 1324 1325 err = ipsp_process_done(m, tdb); 1326 splx(s); 1327 return err; 1328 1329 baddone: 1330 splx(s); 1331 1332 if (m != NULL) 1333 m_freem(m); 1334 1335 crypto_freereq(crp); 1336 1337 return error; 1338 } 1339