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