ipsec_input.c revision 170797
1/* $FreeBSD: head/sys/netipsec/ipsec_input.c 170797 2007-06-15 22:23:33Z bz $ */ 2/* $OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $ */ 3/*- 4 * The authors of this code are John Ioannidis (ji@tla.org), 5 * Angelos D. Keromytis (kermit@csd.uch.gr) and 6 * Niels Provos (provos@physnet.uni-hamburg.de). 7 * 8 * This code was written by John Ioannidis for BSD/OS in Athens, Greece, 9 * in November 1995. 10 * 11 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 12 * by Angelos D. Keromytis. 13 * 14 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 15 * and Niels Provos. 16 * 17 * Additional features in 1999 by Angelos D. Keromytis. 18 * 19 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, 20 * Angelos D. Keromytis and Niels Provos. 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/* 40 * IPsec input processing. 41 */ 42 43#include "opt_inet.h" 44#include "opt_inet6.h" 45#include "opt_ipsec.h" 46#include "opt_enc.h" 47 48#include <sys/param.h> 49#include <sys/systm.h> 50#include <sys/malloc.h> 51#include <sys/mbuf.h> 52#include <sys/domain.h> 53#include <sys/protosw.h> 54#include <sys/socket.h> 55#include <sys/errno.h> 56#include <sys/syslog.h> 57 58#include <net/if.h> 59#include <net/route.h> 60#include <net/netisr.h> 61 62#include <netinet/in.h> 63#include <netinet/in_systm.h> 64#include <netinet/ip.h> 65#include <netinet/ip_var.h> 66#include <netinet/in_var.h> 67 68#include <netinet/ip6.h> 69#ifdef INET6 70#include <netinet6/ip6_var.h> 71#endif 72#include <netinet/in_pcb.h> 73#ifdef INET6 74#include <netinet/icmp6.h> 75#endif 76 77#include <netipsec/ipsec.h> 78#ifdef INET6 79#include <netipsec/ipsec6.h> 80#endif 81#include <netipsec/ah_var.h> 82#include <netipsec/esp.h> 83#include <netipsec/esp_var.h> 84#include <netipsec/ipcomp_var.h> 85 86#include <netipsec/key.h> 87#include <netipsec/keydb.h> 88 89#include <netipsec/xform.h> 90#include <netinet6/ip6protosw.h> 91 92#include <machine/in_cksum.h> 93#include <machine/stdarg.h> 94 95#define IPSEC_ISTAT(p,x,y,z) ((p) == IPPROTO_ESP ? (x)++ : \ 96 (p) == IPPROTO_AH ? (y)++ : (z)++) 97 98static void ipsec4_common_ctlinput(int, struct sockaddr *, void *, int); 99 100/* 101 * ipsec_common_input gets called when an IPsec-protected packet 102 * is received by IPv4 or IPv6. It's job is to find the right SA 103 * and call the appropriate transform. The transform callback 104 * takes care of further processing (like ingress filtering). 105 */ 106static int 107ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto) 108{ 109 union sockaddr_union dst_address; 110 struct secasvar *sav; 111 u_int32_t spi; 112 int error; 113 114 IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input, 115 ipcompstat.ipcomps_input); 116 117 IPSEC_ASSERT(m != NULL, ("null packet")); 118 119 IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH || 120 sproto == IPPROTO_IPCOMP, 121 ("unexpected security protocol %u", sproto)); 122 123 if ((sproto == IPPROTO_ESP && !esp_enable) || 124 (sproto == IPPROTO_AH && !ah_enable) || 125 (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) { 126 m_freem(m); 127 IPSEC_ISTAT(sproto, espstat.esps_pdrops, ahstat.ahs_pdrops, 128 ipcompstat.ipcomps_pdrops); 129 return EOPNOTSUPP; 130 } 131 132 if (m->m_pkthdr.len - skip < 2 * sizeof (u_int32_t)) { 133 m_freem(m); 134 IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops, 135 ipcompstat.ipcomps_hdrops); 136 DPRINTF(("%s: packet too small\n", __func__)); 137 return EINVAL; 138 } 139 140 /* Retrieve the SPI from the relevant IPsec header */ 141 if (sproto == IPPROTO_ESP) 142 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi); 143 else if (sproto == IPPROTO_AH) 144 m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t), 145 (caddr_t) &spi); 146 else if (sproto == IPPROTO_IPCOMP) { 147 u_int16_t cpi; 148 m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), 149 (caddr_t) &cpi); 150 spi = ntohl(htons(cpi)); 151 } 152 153 /* 154 * Find the SA and (indirectly) call the appropriate 155 * kernel crypto routine. The resulting mbuf chain is a valid 156 * IP packet ready to go through input processing. 157 */ 158 bzero(&dst_address, sizeof (dst_address)); 159 dst_address.sa.sa_family = af; 160 switch (af) { 161#ifdef INET 162 case AF_INET: 163 dst_address.sin.sin_len = sizeof(struct sockaddr_in); 164 m_copydata(m, offsetof(struct ip, ip_dst), 165 sizeof(struct in_addr), 166 (caddr_t) &dst_address.sin.sin_addr); 167 break; 168#endif /* INET */ 169#ifdef INET6 170 case AF_INET6: 171 dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6); 172 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst), 173 sizeof(struct in6_addr), 174 (caddr_t) &dst_address.sin6.sin6_addr); 175 break; 176#endif /* INET6 */ 177 default: 178 DPRINTF(("%s: unsupported protocol family %u\n", __func__, af)); 179 m_freem(m); 180 IPSEC_ISTAT(sproto, espstat.esps_nopf, ahstat.ahs_nopf, 181 ipcompstat.ipcomps_nopf); 182 return EPFNOSUPPORT; 183 } 184 185 /* NB: only pass dst since key_allocsa follows RFC2401 */ 186 sav = KEY_ALLOCSA(&dst_address, sproto, spi); 187 if (sav == NULL) { 188 DPRINTF(("%s: no key association found for SA %s/%08lx/%u\n", 189 __func__, ipsec_address(&dst_address), 190 (u_long) ntohl(spi), sproto)); 191 IPSEC_ISTAT(sproto, espstat.esps_notdb, ahstat.ahs_notdb, 192 ipcompstat.ipcomps_notdb); 193 m_freem(m); 194 return ENOENT; 195 } 196 197 if (sav->tdb_xform == NULL) { 198 DPRINTF(("%s: attempted to use uninitialized SA %s/%08lx/%u\n", 199 __func__, ipsec_address(&dst_address), 200 (u_long) ntohl(spi), sproto)); 201 IPSEC_ISTAT(sproto, espstat.esps_noxform, ahstat.ahs_noxform, 202 ipcompstat.ipcomps_noxform); 203 KEY_FREESAV(&sav); 204 m_freem(m); 205 return ENXIO; 206 } 207 208 /* 209 * Call appropriate transform and return -- callback takes care of 210 * everything else. 211 */ 212 error = (*sav->tdb_xform->xf_input)(m, sav, skip, protoff); 213 KEY_FREESAV(&sav); 214 return error; 215} 216 217#ifdef INET 218/* 219 * Common input handler for IPv4 AH, ESP, and IPCOMP. 220 */ 221int 222ipsec4_common_input(struct mbuf *m, ...) 223{ 224 va_list ap; 225 int off, nxt; 226 227 va_start(ap, m); 228 off = va_arg(ap, int); 229 nxt = va_arg(ap, int); 230 va_end(ap); 231 232 return ipsec_common_input(m, off, offsetof(struct ip, ip_p), 233 AF_INET, nxt); 234} 235 236void 237ah4_input(struct mbuf *m, int off) 238{ 239 ipsec4_common_input(m, off, IPPROTO_AH); 240} 241void 242ah4_ctlinput(int cmd, struct sockaddr *sa, void *v) 243{ 244 if (sa->sa_family == AF_INET && 245 sa->sa_len == sizeof(struct sockaddr_in)) 246 ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_AH); 247} 248 249void 250esp4_input(struct mbuf *m, int off) 251{ 252 ipsec4_common_input(m, off, IPPROTO_ESP); 253} 254void 255esp4_ctlinput(int cmd, struct sockaddr *sa, void *v) 256{ 257 if (sa->sa_family == AF_INET && 258 sa->sa_len == sizeof(struct sockaddr_in)) 259 ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_ESP); 260} 261 262void 263ipcomp4_input(struct mbuf *m, int off) 264{ 265 ipsec4_common_input(m, off, IPPROTO_IPCOMP); 266} 267 268/* 269 * IPsec input callback for INET protocols. 270 * This routine is called as the transform callback. 271 * Takes care of filtering and other sanity checks on 272 * the processed packet. 273 */ 274int 275ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, 276 int skip, int protoff, struct m_tag *mt) 277{ 278 int prot, af, sproto; 279 struct ip *ip; 280 struct m_tag *mtag; 281 struct tdb_ident *tdbi; 282 struct secasindex *saidx; 283 int error; 284#ifdef INET6 285#ifdef notyet 286 char ip6buf[INET6_ADDRSTRLEN]; 287#endif 288#endif 289 290 IPSEC_SPLASSERT_SOFTNET(__func__); 291 292 IPSEC_ASSERT(m != NULL, ("null mbuf")); 293 IPSEC_ASSERT(sav != NULL, ("null SA")); 294 IPSEC_ASSERT(sav->sah != NULL, ("null SAH")); 295 saidx = &sav->sah->saidx; 296 af = saidx->dst.sa.sa_family; 297 IPSEC_ASSERT(af == AF_INET, ("unexpected af %u", af)); 298 sproto = saidx->proto; 299 IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH || 300 sproto == IPPROTO_IPCOMP, 301 ("unexpected security protocol %u", sproto)); 302 303 /* Sanity check */ 304 if (m == NULL) { 305 DPRINTF(("%s: null mbuf", __func__)); 306 IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr, 307 ipcompstat.ipcomps_badkcr); 308 KEY_FREESAV(&sav); 309 return EINVAL; 310 } 311 312 if (skip != 0) { 313 /* Fix IPv4 header */ 314 if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) { 315 DPRINTF(("%s: processing failed for SA %s/%08lx\n", 316 __func__, ipsec_address(&sav->sah->saidx.dst), 317 (u_long) ntohl(sav->spi))); 318 IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops, 319 ipcompstat.ipcomps_hdrops); 320 error = ENOBUFS; 321 goto bad; 322 } 323 324 ip = mtod(m, struct ip *); 325 ip->ip_len = htons(m->m_pkthdr.len); 326 ip->ip_off = htons(ip->ip_off); 327 ip->ip_sum = 0; 328 ip->ip_sum = in_cksum(m, ip->ip_hl << 2); 329 } else { 330 ip = mtod(m, struct ip *); 331 } 332 prot = ip->ip_p; 333 334#ifdef notyet 335 /* IP-in-IP encapsulation */ 336 if (prot == IPPROTO_IPIP) { 337 struct ip ipn; 338 339 if (m->m_pkthdr.len - skip < sizeof(struct ip)) { 340 IPSEC_ISTAT(sproto, espstat.esps_hdrops, 341 ahstat.ahs_hdrops, 342 ipcompstat.ipcomps_hdrops); 343 error = EINVAL; 344 goto bad; 345 } 346 /* ipn will now contain the inner IPv4 header */ 347 m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), 348 (caddr_t) &ipn); 349 350 /* XXX PROXY address isn't recorded in SAH */ 351 /* 352 * Check that the inner source address is the same as 353 * the proxy address, if available. 354 */ 355 if ((saidx->proxy.sa.sa_family == AF_INET && 356 saidx->proxy.sin.sin_addr.s_addr != 357 INADDR_ANY && 358 ipn.ip_src.s_addr != 359 saidx->proxy.sin.sin_addr.s_addr) || 360 (saidx->proxy.sa.sa_family != AF_INET && 361 saidx->proxy.sa.sa_family != 0)) { 362 363 DPRINTF(("%s: inner source address %s doesn't " 364 "correspond to expected proxy source %s, " 365 "SA %s/%08lx\n", __func__, 366 inet_ntoa4(ipn.ip_src), 367 ipsp_address(saidx->proxy), 368 ipsp_address(saidx->dst), 369 (u_long) ntohl(sav->spi))); 370 371 IPSEC_ISTAT(sproto, espstat.esps_pdrops, 372 ahstat.ahs_pdrops, 373 ipcompstat.ipcomps_pdrops); 374 error = EACCES; 375 goto bad; 376 } 377 } 378#ifdef INET6 379 /* IPv6-in-IP encapsulation. */ 380 if (prot == IPPROTO_IPV6) { 381 struct ip6_hdr ip6n; 382 383 if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { 384 IPSEC_ISTAT(sproto, espstat.esps_hdrops, 385 ahstat.ahs_hdrops, 386 ipcompstat.ipcomps_hdrops); 387 error = EINVAL; 388 goto bad; 389 } 390 /* ip6n will now contain the inner IPv6 header. */ 391 m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), 392 (caddr_t) &ip6n); 393 394 /* 395 * Check that the inner source address is the same as 396 * the proxy address, if available. 397 */ 398 if ((saidx->proxy.sa.sa_family == AF_INET6 && 399 !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) && 400 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, 401 &saidx->proxy.sin6.sin6_addr)) || 402 (saidx->proxy.sa.sa_family != AF_INET6 && 403 saidx->proxy.sa.sa_family != 0)) { 404 405 DPRINTF(("%s: inner source address %s doesn't " 406 "correspond to expected proxy source %s, " 407 "SA %s/%08lx\n", __func__, 408 ip6_sprintf(ip6buf, &ip6n.ip6_src), 409 ipsec_address(&saidx->proxy), 410 ipsec_address(&saidx->dst), 411 (u_long) ntohl(sav->spi))); 412 413 IPSEC_ISTAT(sproto, espstat.esps_pdrops, 414 ahstat.ahs_pdrops, 415 ipcompstat.ipcomps_pdrops); 416 error = EACCES; 417 goto bad; 418 } 419 } 420#endif /* INET6 */ 421#endif /*XXX*/ 422 423 /* 424 * Record what we've done to the packet (under what SA it was 425 * processed). If we've been passed an mtag, it means the packet 426 * was already processed by an ethernet/crypto combo card and 427 * thus has a tag attached with all the right information, but 428 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to 429 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type. 430 */ 431 if (mt == NULL && sproto != IPPROTO_IPCOMP) { 432 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE, 433 sizeof(struct tdb_ident), M_NOWAIT); 434 if (mtag == NULL) { 435 DPRINTF(("%s: failed to get tag\n", __func__)); 436 IPSEC_ISTAT(sproto, espstat.esps_hdrops, 437 ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops); 438 error = ENOMEM; 439 goto bad; 440 } 441 442 tdbi = (struct tdb_ident *)(mtag + 1); 443 bcopy(&saidx->dst, &tdbi->dst, saidx->dst.sa.sa_len); 444 tdbi->proto = sproto; 445 tdbi->spi = sav->spi; 446 447 m_tag_prepend(m, mtag); 448 } else if (mt != NULL) { 449 mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE; 450 /* XXX do we need to mark m_flags??? */ 451 } 452 453 key_sa_recordxfer(sav, m); /* record data transfer */ 454 455#ifdef DEV_ENC 456 /* 457 * Pass the mbuf to enc0 for bpf and pfil. We will filter the IPIP 458 * packet later after it has been decapsulated. 459 */ 460 ipsec_bpf(m, sav, AF_INET); 461 462 if (prot != IPPROTO_IPIP) 463 if ((error = ipsec_filter(&m, 1)) != 0) 464 return (error); 465#endif 466 467 /* 468 * Re-dispatch via software interrupt. 469 */ 470 if ((error = netisr_queue(NETISR_IP, m))) { 471 IPSEC_ISTAT(sproto, espstat.esps_qfull, ahstat.ahs_qfull, 472 ipcompstat.ipcomps_qfull); 473 474 DPRINTF(("%s: queue full; proto %u packet dropped\n", 475 __func__, sproto)); 476 return error; 477 } 478 return 0; 479bad: 480 m_freem(m); 481 return error; 482} 483 484void 485ipsec4_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto) 486{ 487 /* XXX nothing just yet */ 488} 489#endif /* INET */ 490 491#ifdef INET6 492/* IPv6 AH wrapper. */ 493int 494ipsec6_common_input(struct mbuf **mp, int *offp, int proto) 495{ 496 int l = 0; 497 int protoff; 498 struct ip6_ext ip6e; 499 500 if (*offp < sizeof(struct ip6_hdr)) { 501 DPRINTF(("%s: bad offset %u\n", __func__, *offp)); 502 return IPPROTO_DONE; 503 } else if (*offp == sizeof(struct ip6_hdr)) { 504 protoff = offsetof(struct ip6_hdr, ip6_nxt); 505 } else { 506 /* Chase down the header chain... */ 507 protoff = sizeof(struct ip6_hdr); 508 509 do { 510 protoff += l; 511 m_copydata(*mp, protoff, sizeof(ip6e), 512 (caddr_t) &ip6e); 513 514 if (ip6e.ip6e_nxt == IPPROTO_AH) 515 l = (ip6e.ip6e_len + 2) << 2; 516 else 517 l = (ip6e.ip6e_len + 1) << 3; 518 IPSEC_ASSERT(l > 0, ("l went zero or negative")); 519 } while (protoff + l < *offp); 520 521 /* Malformed packet check */ 522 if (protoff + l != *offp) { 523 DPRINTF(("%s: bad packet header chain, protoff %u, " 524 "l %u, off %u\n", __func__, protoff, l, *offp)); 525 IPSEC_ISTAT(proto, espstat.esps_hdrops, 526 ahstat.ahs_hdrops, 527 ipcompstat.ipcomps_hdrops); 528 m_freem(*mp); 529 *mp = NULL; 530 return IPPROTO_DONE; 531 } 532 protoff += offsetof(struct ip6_ext, ip6e_nxt); 533 } 534 (void) ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto); 535 return IPPROTO_DONE; 536} 537 538/* 539 * IPsec input callback, called by the transform callback. Takes care of 540 * filtering and other sanity checks on the processed packet. 541 */ 542int 543ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff, 544 struct m_tag *mt) 545{ 546 int prot, af, sproto; 547 struct ip6_hdr *ip6; 548 struct m_tag *mtag; 549 struct tdb_ident *tdbi; 550 struct secasindex *saidx; 551 int nxt; 552 u_int8_t nxt8; 553 int error, nest; 554#ifdef notyet 555 char ip6buf[INET6_ADDRSTRLEN]; 556#endif 557 558 IPSEC_ASSERT(m != NULL, ("null mbuf")); 559 IPSEC_ASSERT(sav != NULL, ("null SA")); 560 IPSEC_ASSERT(sav->sah != NULL, ("null SAH")); 561 saidx = &sav->sah->saidx; 562 af = saidx->dst.sa.sa_family; 563 IPSEC_ASSERT(af == AF_INET6, ("unexpected af %u", af)); 564 sproto = saidx->proto; 565 IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH || 566 sproto == IPPROTO_IPCOMP, 567 ("unexpected security protocol %u", sproto)); 568 569 /* Sanity check */ 570 if (m == NULL) { 571 DPRINTF(("%s: null mbuf", __func__)); 572 IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr, 573 ipcompstat.ipcomps_badkcr); 574 error = EINVAL; 575 goto bad; 576 } 577 578 /* Fix IPv6 header */ 579 if (m->m_len < sizeof(struct ip6_hdr) && 580 (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 581 582 DPRINTF(("%s: processing failed for SA %s/%08lx\n", 583 __func__, ipsec_address(&sav->sah->saidx.dst), 584 (u_long) ntohl(sav->spi))); 585 586 IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops, 587 ipcompstat.ipcomps_hdrops); 588 error = EACCES; 589 goto bad; 590 } 591 592 ip6 = mtod(m, struct ip6_hdr *); 593 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); 594 595 /* Save protocol */ 596 m_copydata(m, protoff, 1, (unsigned char *) &prot); 597 598#ifdef notyet 599#ifdef INET 600 /* IP-in-IP encapsulation */ 601 if (prot == IPPROTO_IPIP) { 602 struct ip ipn; 603 604 if (m->m_pkthdr.len - skip < sizeof(struct ip)) { 605 IPSEC_ISTAT(sproto, espstat.esps_hdrops, 606 ahstat.ahs_hdrops, 607 ipcompstat.ipcomps_hdrops); 608 error = EINVAL; 609 goto bad; 610 } 611 /* ipn will now contain the inner IPv4 header */ 612 m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn); 613 614 /* 615 * Check that the inner source address is the same as 616 * the proxy address, if available. 617 */ 618 if ((saidx->proxy.sa.sa_family == AF_INET && 619 saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY && 620 ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) || 621 (saidx->proxy.sa.sa_family != AF_INET && 622 saidx->proxy.sa.sa_family != 0)) { 623 624 DPRINTF(("%s: inner source address %s doesn't " 625 "correspond to expected proxy source %s, " 626 "SA %s/%08lx\n", __func__, 627 inet_ntoa4(ipn.ip_src), 628 ipsec_address(&saidx->proxy), 629 ipsec_address(&saidx->dst), 630 (u_long) ntohl(sav->spi))); 631 632 IPSEC_ISTATsproto, (espstat.esps_pdrops, 633 ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops); 634 error = EACCES; 635 goto bad; 636 } 637 } 638#endif /* INET */ 639 640 /* IPv6-in-IP encapsulation */ 641 if (prot == IPPROTO_IPV6) { 642 struct ip6_hdr ip6n; 643 644 if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { 645 IPSEC_ISTAT(sproto, espstat.esps_hdrops, 646 ahstat.ahs_hdrops, 647 ipcompstat.ipcomps_hdrops); 648 error = EINVAL; 649 goto bad; 650 } 651 /* ip6n will now contain the inner IPv6 header. */ 652 m_copydata(m, skip, sizeof(struct ip6_hdr), 653 (caddr_t) &ip6n); 654 655 /* 656 * Check that the inner source address is the same as 657 * the proxy address, if available. 658 */ 659 if ((saidx->proxy.sa.sa_family == AF_INET6 && 660 !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) && 661 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, 662 &saidx->proxy.sin6.sin6_addr)) || 663 (saidx->proxy.sa.sa_family != AF_INET6 && 664 saidx->proxy.sa.sa_family != 0)) { 665 666 DPRINTF(("%s: inner source address %s doesn't " 667 "correspond to expected proxy source %s, " 668 "SA %s/%08lx\n", __func__, 669 ip6_sprintf(ip6buf, &ip6n.ip6_src), 670 ipsec_address(&saidx->proxy), 671 ipsec_address(&saidx->dst), 672 (u_long) ntohl(sav->spi))); 673 674 IPSEC_ISTAT(sproto, espstat.esps_pdrops, 675 ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops); 676 error = EACCES; 677 goto bad; 678 } 679 } 680#endif /*XXX*/ 681 682 /* 683 * Record what we've done to the packet (under what SA it was 684 * processed). If we've been passed an mtag, it means the packet 685 * was already processed by an ethernet/crypto combo card and 686 * thus has a tag attached with all the right information, but 687 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to 688 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type. 689 */ 690 if (mt == NULL && sproto != IPPROTO_IPCOMP) { 691 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE, 692 sizeof(struct tdb_ident), M_NOWAIT); 693 if (mtag == NULL) { 694 DPRINTF(("%s: failed to get tag\n", __func__)); 695 IPSEC_ISTAT(sproto, espstat.esps_hdrops, 696 ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops); 697 error = ENOMEM; 698 goto bad; 699 } 700 701 tdbi = (struct tdb_ident *)(mtag + 1); 702 bcopy(&saidx->dst, &tdbi->dst, sizeof(union sockaddr_union)); 703 tdbi->proto = sproto; 704 tdbi->spi = sav->spi; 705 706 m_tag_prepend(m, mtag); 707 } else { 708 if (mt != NULL) 709 mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE; 710 /* XXX do we need to mark m_flags??? */ 711 } 712 713 key_sa_recordxfer(sav, m); 714 715 /* Retrieve new protocol */ 716 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8); 717 718 /* 719 * See the end of ip6_input for this logic. 720 * IPPROTO_IPV[46] case will be processed just like other ones 721 */ 722 nest = 0; 723 nxt = nxt8; 724 while (nxt != IPPROTO_DONE) { 725 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { 726 ip6stat.ip6s_toomanyhdr++; 727 error = EINVAL; 728 goto bad; 729 } 730 731 /* 732 * Protection against faulty packet - there should be 733 * more sanity checks in header chain processing. 734 */ 735 if (m->m_pkthdr.len < skip) { 736 ip6stat.ip6s_tooshort++; 737 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 738 error = EINVAL; 739 goto bad; 740 } 741 /* 742 * Enforce IPsec policy checking if we are seeing last header. 743 * note that we do not visit this with protocols with pcb layer 744 * code - like udp/tcp/raw ip. 745 */ 746 if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && 747 ipsec6_in_reject(m, NULL)) { 748 error = EINVAL; 749 goto bad; 750 } 751 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt); 752 } 753 return 0; 754bad: 755 if (m) 756 m_freem(m); 757 return error; 758} 759 760void 761esp6_ctlinput(int cmd, struct sockaddr *sa, void *d) 762{ 763 if (sa->sa_family != AF_INET6 || 764 sa->sa_len != sizeof(struct sockaddr_in6)) 765 return; 766 if ((unsigned)cmd >= PRC_NCMDS) 767 return; 768 769 /* if the parameter is from icmp6, decode it. */ 770 if (d != NULL) { 771 struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d; 772 struct mbuf *m = ip6cp->ip6c_m; 773 int off = ip6cp->ip6c_off; 774 775 struct ip6ctlparam ip6cp1; 776 777 /* 778 * Notify the error to all possible sockets via pfctlinput2. 779 * Since the upper layer information (such as protocol type, 780 * source and destination ports) is embedded in the encrypted 781 * data and might have been cut, we can't directly call 782 * an upper layer ctlinput function. However, the pcbnotify 783 * function will consider source and destination addresses 784 * as well as the flow info value, and may be able to find 785 * some PCB that should be notified. 786 * Although pfctlinput2 will call esp6_ctlinput(), there is 787 * no possibility of an infinite loop of function calls, 788 * because we don't pass the inner IPv6 header. 789 */ 790 bzero(&ip6cp1, sizeof(ip6cp1)); 791 ip6cp1.ip6c_src = ip6cp->ip6c_src; 792 pfctlinput2(cmd, sa, (void *)&ip6cp1); 793 794 /* 795 * Then go to special cases that need ESP header information. 796 * XXX: We assume that when ip6 is non NULL, 797 * M and OFF are valid. 798 */ 799 800 if (cmd == PRC_MSGSIZE) { 801 struct secasvar *sav; 802 u_int32_t spi; 803 int valid; 804 805 /* check header length before using m_copydata */ 806 if (m->m_pkthdr.len < off + sizeof (struct esp)) 807 return; 808 m_copydata(m, off + offsetof(struct esp, esp_spi), 809 sizeof(u_int32_t), (caddr_t) &spi); 810 /* 811 * Check to see if we have a valid SA corresponding to 812 * the address in the ICMP message payload. 813 */ 814 sav = KEY_ALLOCSA((union sockaddr_union *)sa, 815 IPPROTO_ESP, spi); 816 valid = (sav != NULL); 817 if (sav) 818 KEY_FREESAV(&sav); 819 820 /* XXX Further validation? */ 821 822 /* 823 * Depending on whether the SA is "valid" and 824 * routing table size (mtudisc_{hi,lo}wat), we will: 825 * - recalcurate the new MTU and create the 826 * corresponding routing entry, or 827 * - ignore the MTU change notification. 828 */ 829 icmp6_mtudisc_update(ip6cp, valid); 830 } 831 } else { 832 /* we normally notify any pcb here */ 833 } 834} 835#endif /* INET6 */ 836