1 /* $OpenBSD: ip_ah.c,v 1.99 2011/01/11 15:42:05 deraadt 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_128; 120 break; 121 122 case SADB_X_AALG_SHA2_384: 123 thash = &auth_hash_hmac_sha2_384_192; 124 break; 125 126 case SADB_X_AALG_SHA2_512: 127 thash = &auth_hash_hmac_sha2_512_256; 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 explicit_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, M_NOWAIT); 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 M_NOWAIT); 501 502 rh0->ip6r0_segleft = 0; 503 } 504 505 /* advance */ 506 off += ((ip6e->ip6e_len + 1) << 3); 507 nxt = ip6e->ip6e_nxt; 508 break; 509 } 510 511 default: 512 DPRINTF(("ah_massage_headers(): unexpected " 513 "IPv6 header type %d\n", off)); 514 if (alloc) 515 free(ptr, M_XDATA); 516 ahstat.ahs_hdrops++; 517 m_freem(m); 518 return EINVAL; 519 } 520 } 521 522 /* Copyback and free, if we allocated. */ 523 if (alloc) { 524 m_copyback(m, sizeof(struct ip6_hdr), 525 skip - sizeof(struct ip6_hdr), ptr, M_NOWAIT); 526 free(ptr, M_XDATA); 527 } 528 529 break; 530 #endif /* INET6 */ 531 } 532 533 return 0; 534 } 535 536 /* 537 * ah_input() gets called to verify that an input packet 538 * passes authentication. 539 */ 540 int 541 ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) 542 { 543 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; 544 struct tdb_crypto *tc; 545 struct m_tag *mtag; 546 u_int32_t btsx; 547 u_int8_t hl; 548 int rplen; 549 550 struct cryptodesc *crda = NULL; 551 struct cryptop *crp; 552 553 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) 554 rplen = AH_FLENGTH + sizeof(u_int32_t); 555 else 556 rplen = AH_FLENGTH; 557 558 /* Save the AH header, we use it throughout. */ 559 m_copydata(m, skip + offsetof(struct ah, ah_hl), sizeof(u_int8_t), 560 (caddr_t) &hl); 561 562 /* Replay window checking, if applicable. */ 563 if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) { 564 m_copydata(m, skip + offsetof(struct ah, ah_rpl), 565 sizeof(u_int32_t), (caddr_t) &btsx); 566 btsx = ntohl(btsx); 567 568 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl), 569 tdb->tdb_wnd, &(tdb->tdb_bitmap), 0)) { 570 case 0: /* All's well. */ 571 break; 572 573 case 1: 574 DPRINTF(("ah_input(): replay counter wrapped for " 575 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 576 ntohl(tdb->tdb_spi))); 577 578 ahstat.ahs_wrap++; 579 m_freem(m); 580 return ENOBUFS; 581 582 case 2: 583 case 3: 584 DPRINTF(("ah_input(): duplicate packet received in " 585 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 586 ntohl(tdb->tdb_spi))); 587 588 m_freem(m); 589 return ENOBUFS; 590 591 default: 592 DPRINTF(("ah_input(): bogus value from " 593 "checkreplaywindow32() in SA %s/%08x\n", 594 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 595 596 ahstat.ahs_replay++; 597 m_freem(m); 598 return ENOBUFS; 599 } 600 } 601 602 /* Verify AH header length. */ 603 if (hl * sizeof(u_int32_t) != ahx->authsize + rplen - AH_FLENGTH) { 604 DPRINTF(("ah_input(): bad authenticator length %d for packet " 605 "in SA %s/%08x\n", hl * sizeof(u_int32_t), 606 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 607 608 ahstat.ahs_badauthl++; 609 m_freem(m); 610 return EACCES; 611 } 612 613 /* Update the counters. */ 614 tdb->tdb_cur_bytes += 615 (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t)); 616 ahstat.ahs_ibytes += (m->m_pkthdr.len - skip - hl * sizeof(u_int32_t)); 617 618 /* Hard expiration. */ 619 if (tdb->tdb_flags & TDBF_BYTES && 620 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { 621 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 622 tdb_delete(tdb); 623 m_freem(m); 624 return ENXIO; 625 } 626 627 /* Notify on expiration. */ 628 if (tdb->tdb_flags & TDBF_SOFT_BYTES && 629 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { 630 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 631 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking. */ 632 } 633 634 /* Get crypto descriptors. */ 635 crp = crypto_getreq(1); 636 if (crp == NULL) { 637 m_freem(m); 638 DPRINTF(("ah_input(): failed to acquire crypto " 639 "descriptors\n")); 640 ahstat.ahs_crypto++; 641 return ENOBUFS; 642 } 643 644 crda = crp->crp_desc; 645 646 crda->crd_skip = 0; 647 crda->crd_len = m->m_pkthdr.len; 648 crda->crd_inject = skip + rplen; 649 650 /* Authentication operation. */ 651 crda->crd_alg = ahx->type; 652 crda->crd_key = tdb->tdb_amxkey; 653 crda->crd_klen = tdb->tdb_amxkeylen * 8; 654 655 #ifdef notyet 656 /* Find out if we've already done crypto. */ 657 for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL); 658 mtag != NULL; 659 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) { 660 struct tdb_ident *tdbi; 661 662 tdbi = (struct tdb_ident *) (mtag + 1); 663 if (tdbi->proto == tdb->tdb_sproto && 664 tdbi->spi == tdb->tdb_spi && 665 tdbi->rdomain == tdb->tdb_rdomain && 666 !bcmp(&tdbi->dst, &tdb->tdb_dst, 667 sizeof(union sockaddr_union))) 668 break; 669 } 670 #else 671 mtag = NULL; 672 #endif 673 674 /* Allocate IPsec-specific opaque crypto info. */ 675 if (mtag == NULL) 676 tc = malloc(sizeof(*tc) + skip + rplen + ahx->authsize, M_XDATA, 677 M_NOWAIT | M_ZERO); 678 else /* Hash verification has already been done successfully. */ 679 tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO); 680 if (tc == NULL) { 681 m_freem(m); 682 crypto_freereq(crp); 683 DPRINTF(("ah_input(): failed to allocate tdb_crypto\n")); 684 ahstat.ahs_crypto++; 685 return ENOBUFS; 686 } 687 688 /* Only save information if crypto processing is needed. */ 689 if (mtag == NULL) { 690 /* 691 * Save the authenticator, the skipped portion of the packet, 692 * and the AH header. 693 */ 694 m_copydata(m, 0, skip + rplen + ahx->authsize, 695 (caddr_t) (tc + 1)); 696 697 /* Zeroize the authenticator on the packet. */ 698 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, 699 M_NOWAIT); 700 701 /* "Massage" the packet headers for crypto processing. */ 702 if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, 703 skip, ahx->type, 0)) != 0) { 704 /* mbuf will be free'd by callee. */ 705 free(tc, M_XDATA); 706 crypto_freereq(crp); 707 return btsx; 708 } 709 } 710 711 /* Crypto operation descriptor. */ 712 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 713 crp->crp_flags = CRYPTO_F_IMBUF; 714 crp->crp_buf = (caddr_t) m; 715 crp->crp_callback = (int (*) (struct cryptop *)) ah_input_cb; 716 crp->crp_sid = tdb->tdb_cryptoid; 717 crp->crp_opaque = (caddr_t) tc; 718 719 /* These are passed as-is to the callback. */ 720 tc->tc_skip = skip; 721 tc->tc_protoff = protoff; 722 tc->tc_spi = tdb->tdb_spi; 723 tc->tc_proto = tdb->tdb_sproto; 724 tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified. */ 725 tc->tc_rdomain = tdb->tdb_rdomain; 726 bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union)); 727 728 if (mtag == NULL) 729 return crypto_dispatch(crp); 730 else 731 return ah_input_cb(crp); 732 } 733 734 /* 735 * AH input callback, called directly by the crypto driver. 736 */ 737 int 738 ah_input_cb(void *op) 739 { 740 int s, roff, rplen, error, skip, protoff; 741 unsigned char calc[AH_ALEN_MAX]; 742 struct mbuf *m1, *m0, *m; 743 struct auth_hash *ahx; 744 struct tdb_crypto *tc; 745 struct cryptop *crp; 746 struct m_tag *mtag; 747 struct tdb *tdb; 748 u_int32_t btsx; 749 u_int8_t prot; 750 caddr_t ptr; 751 752 crp = (struct cryptop *) op; 753 754 tc = (struct tdb_crypto *) crp->crp_opaque; 755 skip = tc->tc_skip; 756 protoff = tc->tc_protoff; 757 mtag = (struct m_tag *) tc->tc_ptr; 758 759 m = (struct mbuf *) crp->crp_buf; 760 if (m == NULL) { 761 /* Shouldn't happen... */ 762 free(tc, M_XDATA); 763 crypto_freereq(crp); 764 ahstat.ahs_crypto++; 765 DPRINTF(("ah_input_cb(): bogus returned buffer from " 766 "crypto\n")); 767 return (EINVAL); 768 } 769 770 s = spltdb(); 771 772 tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto); 773 if (tdb == NULL) { 774 free(tc, M_XDATA); 775 ahstat.ahs_notdb++; 776 DPRINTF(("ah_input_cb(): TDB is expired while in crypto")); 777 error = EPERM; 778 goto baddone; 779 } 780 781 ahx = (struct auth_hash *) tdb->tdb_authalgxform; 782 783 /* Check for crypto errors. */ 784 if (crp->crp_etype) { 785 if (crp->crp_etype == EAGAIN) { 786 /* Reset the session ID */ 787 if (tdb->tdb_cryptoid != 0) 788 tdb->tdb_cryptoid = crp->crp_sid; 789 splx(s); 790 return crypto_dispatch(crp); 791 } 792 free(tc, M_XDATA); 793 ahstat.ahs_noxform++; 794 DPRINTF(("ah_input_cb(): crypto error %d\n", crp->crp_etype)); 795 error = crp->crp_etype; 796 goto baddone; 797 } else { 798 crypto_freereq(crp); /* No longer needed. */ 799 crp = NULL; 800 } 801 802 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) 803 rplen = AH_FLENGTH + sizeof(u_int32_t); 804 else 805 rplen = AH_FLENGTH; 806 807 /* Copy authenticator off the packet. */ 808 m_copydata(m, skip + rplen, ahx->authsize, calc); 809 810 /* 811 * If we have an mtag, we don't need to verify the authenticator -- 812 * it has been verified by an IPsec-aware NIC. 813 */ 814 if (mtag == NULL) { 815 ptr = (caddr_t) (tc + 1); 816 817 /* Verify authenticator. */ 818 if (timingsafe_bcmp(ptr + skip + rplen, calc, ahx->authsize)) { 819 free(tc, M_XDATA); 820 821 DPRINTF(("ah_input(): authentication failed for " 822 "packet in SA %s/%08x\n", 823 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 824 825 ahstat.ahs_badauth++; 826 error = EACCES; 827 goto baddone; 828 } 829 830 /* Fix the Next Protocol field. */ 831 ((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip]; 832 833 /* Copyback the saved (uncooked) network headers. */ 834 m_copyback(m, 0, skip, ptr, M_NOWAIT); 835 } else { 836 /* Fix the Next Protocol field. */ 837 m_copydata(m, skip, sizeof(u_int8_t), &prot); 838 m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT); 839 } 840 841 free(tc, M_XDATA); 842 843 /* Replay window checking, if applicable. */ 844 if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) { 845 m_copydata(m, skip + offsetof(struct ah, ah_rpl), 846 sizeof(u_int32_t), (caddr_t) &btsx); 847 btsx = ntohl(btsx); 848 849 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl), 850 tdb->tdb_wnd, &(tdb->tdb_bitmap), 1)) { 851 case 0: /* All's well. */ 852 #if NPFSYNC > 0 853 pfsync_update_tdb(tdb,0); 854 #endif 855 break; 856 857 case 1: 858 DPRINTF(("ah_input(): replay counter wrapped for " 859 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 860 ntohl(tdb->tdb_spi))); 861 862 ahstat.ahs_wrap++; 863 error = ENOBUFS; 864 goto baddone; 865 866 case 2: 867 case 3: 868 DPRINTF(("ah_input_cb(): duplicate packet received in " 869 "SA %s/%08x\n", ipsp_address(tdb->tdb_dst), 870 ntohl(tdb->tdb_spi))); 871 872 error = ENOBUFS; 873 goto baddone; 874 875 default: 876 DPRINTF(("ah_input_cb(): bogus value from " 877 "checkreplaywindow32() in SA %s/%08x\n", 878 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 879 880 ahstat.ahs_replay++; 881 error = ENOBUFS; 882 goto baddone; 883 } 884 } 885 886 /* Record the beginning of the AH header. */ 887 m1 = m_getptr(m, skip, &roff); 888 if (m1 == NULL) { 889 ahstat.ahs_hdrops++; 890 splx(s); 891 m_freem(m); 892 893 DPRINTF(("ah_input(): bad mbuf chain for packet in SA " 894 "%s/%08x\n", ipsp_address(tdb->tdb_dst), 895 ntohl(tdb->tdb_spi))); 896 897 return EINVAL; 898 } 899 900 /* Remove the AH header from the mbuf. */ 901 if (roff == 0) { 902 /* 903 * The AH header was conveniently at the beginning of 904 * the mbuf. 905 */ 906 m_adj(m1, rplen + ahx->authsize); 907 if (!(m1->m_flags & M_PKTHDR)) 908 m->m_pkthdr.len -= rplen + ahx->authsize; 909 } else 910 if (roff + rplen + ahx->authsize >= m1->m_len) { 911 /* 912 * Part or all of the AH header is at the end 913 * of this mbuf, so first let's remove the 914 * remainder of the AH header from the 915 * beginning of the remainder of the mbuf 916 * chain, if any. 917 */ 918 if (roff + rplen + ahx->authsize > m1->m_len) { 919 /* Adjust the next mbuf by the remainder. */ 920 m_adj(m1->m_next, roff + rplen + 921 ahx->authsize - m1->m_len); 922 923 /* 924 * The second mbuf is guaranteed not 925 * to have a pkthdr... 926 */ 927 m->m_pkthdr.len -= 928 (roff + rplen + ahx->authsize - m1->m_len); 929 } 930 931 /* Now, let's unlink the mbuf chain for a second... */ 932 m0 = m1->m_next; 933 m1->m_next = NULL; 934 935 /* 936 * ...and trim the end of the first part of 937 * the chain...sick 938 */ 939 m_adj(m1, -(m1->m_len - roff)); 940 if (!(m1->m_flags & M_PKTHDR)) 941 m->m_pkthdr.len -= (m1->m_len - roff); 942 943 /* Finally, let's relink. */ 944 m1->m_next = m0; 945 } else { 946 /* 947 * The AH header lies in the "middle" of the 948 * mbuf...do an overlapping copy of the 949 * remainder of the mbuf over the ESP header. 950 */ 951 bcopy(mtod(m1, u_char *) + roff + rplen + 952 ahx->authsize, mtod(m1, u_char *) + roff, 953 m1->m_len - (roff + rplen + ahx->authsize)); 954 m1->m_len -= rplen + ahx->authsize; 955 m->m_pkthdr.len -= rplen + ahx->authsize; 956 } 957 958 error = ipsec_common_input_cb(m, tdb, skip, protoff, mtag); 959 splx(s); 960 return (error); 961 962 baddone: 963 splx(s); 964 965 if (m != NULL) 966 m_freem(m); 967 968 if (crp != NULL) 969 crypto_freereq(crp); 970 971 return (error); 972 } 973 974 /* 975 * AH output routine, called by ipsp_process_packet(). 976 */ 977 int 978 ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, 979 int protoff) 980 { 981 struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; 982 struct cryptodesc *crda; 983 struct tdb_crypto *tc; 984 struct mbuf *mo, *mi; 985 struct cryptop *crp; 986 u_int16_t iplen; 987 int len, rplen; 988 u_int8_t prot; 989 struct ah *ah; 990 #if NBPFILTER > 0 991 struct ifnet *encif; 992 993 if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL) { 994 encif->if_opackets++; 995 encif->if_obytes += m->m_pkthdr.len; 996 997 if (encif->if_bpf) { 998 struct enchdr hdr; 999 1000 bzero (&hdr, sizeof(hdr)); 1001 1002 hdr.af = tdb->tdb_dst.sa.sa_family; 1003 hdr.spi = tdb->tdb_spi; 1004 hdr.flags |= M_AUTH | M_AUTH_AH; 1005 1006 bpf_mtap_hdr(encif->if_bpf, (char *)&hdr, 1007 ENC_HDRLEN, m, BPF_DIRECTION_OUT); 1008 } 1009 } 1010 #endif 1011 1012 ahstat.ahs_output++; 1013 1014 /* 1015 * Check for replay counter wrap-around in automatic (not 1016 * manual) keying. 1017 */ 1018 if ((tdb->tdb_rpl == 0) && (tdb->tdb_wnd > 0) && 1019 (!(tdb->tdb_flags & TDBF_NOREPLAY))) { 1020 DPRINTF(("ah_output(): SA %s/%08x should have expired\n", 1021 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 1022 m_freem(m); 1023 ahstat.ahs_wrap++; 1024 return EINVAL; 1025 } 1026 1027 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) 1028 rplen = AH_FLENGTH + sizeof(u_int32_t); 1029 else 1030 rplen = AH_FLENGTH; 1031 1032 switch (tdb->tdb_dst.sa.sa_family) { 1033 #ifdef INET 1034 case AF_INET: 1035 /* Check for IP maximum packet size violations. */ 1036 if (rplen + ahx->authsize + m->m_pkthdr.len > IP_MAXPACKET) { 1037 DPRINTF(("ah_output(): packet in SA %s/%08x got too " 1038 "big\n", 1039 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 1040 m_freem(m); 1041 ahstat.ahs_toobig++; 1042 return EMSGSIZE; 1043 } 1044 break; 1045 #endif /* INET */ 1046 1047 #ifdef INET6 1048 case AF_INET6: 1049 /* Check for IPv6 maximum packet size violations. */ 1050 if (rplen + ahx->authsize + m->m_pkthdr.len > IPV6_MAXPACKET) { 1051 DPRINTF(("ah_output(): packet in SA %s/%08x " 1052 "got too big\n", ipsp_address(tdb->tdb_dst), 1053 ntohl(tdb->tdb_spi))); 1054 m_freem(m); 1055 ahstat.ahs_toobig++; 1056 return EMSGSIZE; 1057 } 1058 break; 1059 #endif /* INET6 */ 1060 1061 default: 1062 DPRINTF(("ah_output(): unknown/unsupported protocol " 1063 "family %d, SA %s/%08x\n", tdb->tdb_dst.sa.sa_family, 1064 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 1065 m_freem(m); 1066 ahstat.ahs_nopf++; 1067 return EPFNOSUPPORT; 1068 } 1069 1070 /* Update the counters. */ 1071 tdb->tdb_cur_bytes += m->m_pkthdr.len - skip; 1072 ahstat.ahs_obytes += m->m_pkthdr.len - skip; 1073 1074 /* Hard expiration. */ 1075 if (tdb->tdb_flags & TDBF_BYTES && 1076 tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { 1077 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD); 1078 tdb_delete(tdb); 1079 m_freem(m); 1080 return EINVAL; 1081 } 1082 1083 /* Notify on expiration. */ 1084 if (tdb->tdb_flags & TDBF_SOFT_BYTES && 1085 tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { 1086 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); 1087 tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */ 1088 } 1089 1090 /* 1091 * Loop through mbuf chain; if we find a readonly mbuf, 1092 * replace the rest of the chain. 1093 */ 1094 mo = NULL; 1095 mi = m; 1096 while (mi != NULL && !M_READONLY(mi)) { 1097 mo = mi; 1098 mi = mi->m_next; 1099 } 1100 1101 if (mi != NULL) { 1102 /* Replace the rest of the mbuf chain. */ 1103 struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT); 1104 1105 if (n == NULL) { 1106 ahstat.ahs_hdrops++; 1107 m_freem(m); 1108 return ENOBUFS; 1109 } 1110 1111 if (mo != NULL) 1112 mo->m_next = n; 1113 else 1114 m = n; 1115 1116 m_freem(mi); 1117 } 1118 1119 /* Inject AH header. */ 1120 mi = m_inject(m, skip, rplen + ahx->authsize, M_DONTWAIT); 1121 if (mi == NULL) { 1122 DPRINTF(("ah_output(): failed to inject AH header for SA " 1123 "%s/%08x\n", ipsp_address(tdb->tdb_dst), 1124 ntohl(tdb->tdb_spi))); 1125 1126 m_freem(m); 1127 ahstat.ahs_hdrops++; 1128 return ENOBUFS; 1129 } 1130 1131 /* 1132 * The AH header is guaranteed by m_inject() to be in 1133 * contiguous memory, at the beginning of the returned mbuf. 1134 */ 1135 ah = mtod(mi, struct ah *); 1136 1137 /* Initialize the AH header. */ 1138 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nh); 1139 ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH) / sizeof(u_int32_t); 1140 ah->ah_rv = 0; 1141 ah->ah_spi = tdb->tdb_spi; 1142 1143 /* Zeroize authenticator. */ 1144 m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes, M_NOWAIT); 1145 1146 if (!(tdb->tdb_flags & TDBF_NOREPLAY)) { 1147 ah->ah_rpl = htonl(tdb->tdb_rpl++); 1148 #if NPFSYNC > 0 1149 pfsync_update_tdb(tdb,1); 1150 #endif 1151 } 1152 1153 /* Get crypto descriptors. */ 1154 crp = crypto_getreq(1); 1155 if (crp == NULL) { 1156 m_freem(m); 1157 DPRINTF(("ah_output(): failed to acquire crypto " 1158 "descriptors\n")); 1159 ahstat.ahs_crypto++; 1160 return ENOBUFS; 1161 } 1162 1163 crda = crp->crp_desc; 1164 1165 crda->crd_skip = 0; 1166 crda->crd_inject = skip + rplen; 1167 crda->crd_len = m->m_pkthdr.len; 1168 1169 /* Authentication operation. */ 1170 crda->crd_alg = ahx->type; 1171 crda->crd_key = tdb->tdb_amxkey; 1172 crda->crd_klen = tdb->tdb_amxkeylen * 8; 1173 1174 /* Allocate IPsec-specific opaque crypto info. */ 1175 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) 1176 tc = malloc(sizeof(*tc) + skip, M_XDATA, M_NOWAIT | M_ZERO); 1177 else 1178 tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO); 1179 if (tc == NULL) { 1180 m_freem(m); 1181 crypto_freereq(crp); 1182 DPRINTF(("ah_output(): failed to allocate tdb_crypto\n")); 1183 ahstat.ahs_crypto++; 1184 return ENOBUFS; 1185 } 1186 1187 /* Save the skipped portion of the packet. */ 1188 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) { 1189 m_copydata(m, 0, skip, (caddr_t) (tc + 1)); 1190 1191 /* 1192 * Fix IP header length on the header used for 1193 * authentication. We don't need to fix the original 1194 * header length as it will be fixed by our caller. 1195 */ 1196 switch (tdb->tdb_dst.sa.sa_family) { 1197 #ifdef INET 1198 case AF_INET: 1199 bcopy(((caddr_t)(tc + 1)) + 1200 offsetof(struct ip, ip_len), 1201 (caddr_t) &iplen, sizeof(u_int16_t)); 1202 iplen = htons(ntohs(iplen) + rplen + ahx->authsize); 1203 m_copyback(m, offsetof(struct ip, ip_len), 1204 sizeof(u_int16_t), &iplen, M_NOWAIT); 1205 break; 1206 #endif /* INET */ 1207 1208 #ifdef INET6 1209 case AF_INET6: 1210 bcopy(((caddr_t)(tc + 1)) + 1211 offsetof(struct ip6_hdr, ip6_plen), 1212 (caddr_t) &iplen, sizeof(u_int16_t)); 1213 iplen = htons(ntohs(iplen) + rplen + ahx->authsize); 1214 m_copyback(m, offsetof(struct ip6_hdr, ip6_plen), 1215 sizeof(u_int16_t), &iplen, M_NOWAIT); 1216 break; 1217 #endif /* INET6 */ 1218 } 1219 1220 /* Fix the Next Header field in saved header. */ 1221 ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH; 1222 1223 /* Update the Next Protocol field in the IP header. */ 1224 prot = IPPROTO_AH; 1225 m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT); 1226 1227 /* "Massage" the packet headers for crypto processing. */ 1228 if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, 1229 skip, ahx->type, 1)) != 0) { 1230 /* mbuf will be free'd by callee. */ 1231 free(tc, M_XDATA); 1232 crypto_freereq(crp); 1233 return len; 1234 } 1235 } else { 1236 /* Update the Next Protocol field in the IP header. */ 1237 prot = IPPROTO_AH; 1238 m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT); 1239 } 1240 1241 /* Crypto operation descriptor. */ 1242 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 1243 crp->crp_flags = CRYPTO_F_IMBUF; 1244 crp->crp_buf = (caddr_t) m; 1245 crp->crp_callback = (int (*) (struct cryptop *)) ah_output_cb; 1246 crp->crp_sid = tdb->tdb_cryptoid; 1247 crp->crp_opaque = (caddr_t) tc; 1248 1249 /* These are passed as-is to the callback. */ 1250 tc->tc_skip = skip; 1251 tc->tc_protoff = protoff; 1252 tc->tc_spi = tdb->tdb_spi; 1253 tc->tc_proto = tdb->tdb_sproto; 1254 tc->tc_rdomain = tdb->tdb_rdomain; 1255 bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union)); 1256 1257 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) 1258 return crypto_dispatch(crp); 1259 else 1260 return ah_output_cb(crp); 1261 } 1262 1263 /* 1264 * AH output callback, called directly from the crypto handler. 1265 */ 1266 int 1267 ah_output_cb(void *op) 1268 { 1269 int skip, error; 1270 struct tdb_crypto *tc; 1271 struct cryptop *crp; 1272 struct tdb *tdb; 1273 struct mbuf *m; 1274 caddr_t ptr; 1275 int err, s; 1276 1277 crp = (struct cryptop *) op; 1278 tc = (struct tdb_crypto *) crp->crp_opaque; 1279 skip = tc->tc_skip; 1280 ptr = (caddr_t) (tc + 1); 1281 1282 m = (struct mbuf *) crp->crp_buf; 1283 if (m == NULL) { 1284 /* Shouldn't happen... */ 1285 free(tc, M_XDATA); 1286 crypto_freereq(crp); 1287 ahstat.ahs_crypto++; 1288 DPRINTF(("ah_output_cb(): bogus returned buffer from " 1289 "crypto\n")); 1290 return (EINVAL); 1291 } 1292 1293 s = spltdb(); 1294 1295 tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto); 1296 if (tdb == NULL) { 1297 free(tc, M_XDATA); 1298 ahstat.ahs_notdb++; 1299 DPRINTF(("ah_output_cb(): TDB is expired while in crypto\n")); 1300 error = EPERM; 1301 goto baddone; 1302 } 1303 1304 /* Check for crypto errors. */ 1305 if (crp->crp_etype) { 1306 if (crp->crp_etype == EAGAIN) { 1307 /* Reset the session ID */ 1308 if (tdb->tdb_cryptoid != 0) 1309 tdb->tdb_cryptoid = crp->crp_sid; 1310 splx(s); 1311 return crypto_dispatch(crp); 1312 } 1313 free(tc, M_XDATA); 1314 ahstat.ahs_noxform++; 1315 DPRINTF(("ah_output_cb(): crypto error %d\n", crp->crp_etype)); 1316 error = crp->crp_etype; 1317 goto baddone; 1318 } 1319 1320 /* 1321 * Copy original headers (with the new protocol number) back 1322 * in place. 1323 */ 1324 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) 1325 m_copyback(m, 0, skip, ptr, M_NOWAIT); 1326 1327 free(tc, M_XDATA); 1328 1329 /* No longer needed. */ 1330 crypto_freereq(crp); 1331 1332 err = ipsp_process_done(m, tdb); 1333 splx(s); 1334 return err; 1335 1336 baddone: 1337 splx(s); 1338 1339 if (m != NULL) 1340 m_freem(m); 1341 1342 crypto_freereq(crp); 1343 1344 return error; 1345 } 1346