1 /* $OpenBSD: ipsec_output.c,v 1.41 2008/08/26 12:19:01 henning Exp $ */ 2 /* 3 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) 4 * 5 * Copyright (c) 2000-2001 Angelos D. Keromytis. 6 * 7 * Permission to use, copy, and modify this software with or without fee 8 * is hereby granted, provided that this entire notice is included in 9 * all copies of any software which is or includes a copy or 10 * modification of this software. 11 * You may use this code under the GNU public license if you so wish. Please 12 * contribute changes back to the authors under this freer than GPL license 13 * so that we may further the use of strong encryption without limitations to 14 * all. 15 * 16 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 18 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 19 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 20 * PURPOSE. 21 */ 22 23 #include "pf.h" 24 25 #include <sys/param.h> 26 #include <sys/systm.h> 27 #include <sys/mbuf.h> 28 #include <sys/socket.h> 29 #include <sys/kernel.h> 30 31 #include <net/if.h> 32 #include <net/route.h> 33 34 #if NPF > 0 35 #include <net/pfvar.h> 36 #endif 37 38 #ifdef INET 39 #include <netinet/in.h> 40 #include <netinet/in_systm.h> 41 #include <netinet/ip.h> 42 #include <netinet/in_pcb.h> 43 #include <netinet/ip_var.h> 44 #endif /* INET */ 45 46 #ifdef INET6 47 #ifndef INET 48 #include <netinet/in.h> 49 #endif 50 #include <netinet6/in6_var.h> 51 #endif /* INET6 */ 52 53 #include <netinet/udp.h> 54 #include <netinet/ip_ipsp.h> 55 #include <netinet/ip_ah.h> 56 #include <netinet/ip_esp.h> 57 #include <netinet/ip_ipcomp.h> 58 #include <crypto/xform.h> 59 60 #ifdef ENCDEBUG 61 #define DPRINTF(x) if (encdebug) printf x 62 #else 63 #define DPRINTF(x) 64 #endif 65 66 int udpencap_enable = 1; /* enabled by default */ 67 int udpencap_port = 4500; /* triggers decapsulation */ 68 69 /* 70 * Loop over a tdb chain, taking into consideration protocol tunneling. The 71 * fourth argument is set if the first encapsulation header is already in 72 * place. 73 */ 74 int 75 ipsp_process_packet(struct mbuf *m, struct tdb *tdb, int af, int tunalready) 76 { 77 struct timeval tv; 78 int i, off, error; 79 struct mbuf *mp; 80 #ifdef INET6 81 struct ip6_ext ip6e; 82 int nxt; 83 int dstopt = 0; 84 #endif 85 86 #ifdef INET 87 int setdf = 0; 88 struct ip *ip; 89 #endif /* INET */ 90 #ifdef INET6 91 struct ip6_hdr *ip6; 92 #endif /* INET6 */ 93 94 /* Check that the transform is allowed by the administrator. */ 95 if ((tdb->tdb_sproto == IPPROTO_ESP && !esp_enable) || 96 (tdb->tdb_sproto == IPPROTO_AH && !ah_enable) || 97 (tdb->tdb_sproto == IPPROTO_IPCOMP && !ipcomp_enable)) { 98 DPRINTF(("ipsp_process_packet(): IPsec outbound packet " 99 "dropped due to policy (check your sysctls)\n")); 100 m_freem(m); 101 return EHOSTUNREACH; 102 } 103 104 /* Sanity check. */ 105 if (!tdb->tdb_xform) { 106 DPRINTF(("ipsp_process_packet(): uninitialized TDB\n")); 107 m_freem(m); 108 return EHOSTUNREACH; 109 } 110 111 /* Check if the SPI is invalid. */ 112 if (tdb->tdb_flags & TDBF_INVALID) { 113 DPRINTF(("ipsp_process_packet(): attempt to use invalid " 114 "SA %s/%08x/%u\n", ipsp_address(tdb->tdb_dst), 115 ntohl(tdb->tdb_spi), tdb->tdb_sproto)); 116 m_freem(m); 117 return ENXIO; 118 } 119 120 /* Check that the network protocol is supported */ 121 switch (tdb->tdb_dst.sa.sa_family) { 122 #ifdef INET 123 case AF_INET: 124 break; 125 #endif /* INET */ 126 127 #ifdef INET6 128 case AF_INET6: 129 break; 130 #endif /* INET6 */ 131 132 default: 133 DPRINTF(("ipsp_process_packet(): attempt to use " 134 "SA %s/%08x/%u for protocol family %d\n", 135 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi), 136 tdb->tdb_sproto, tdb->tdb_dst.sa.sa_family)); 137 m_freem(m); 138 return ENXIO; 139 } 140 141 /* 142 * Register first use if applicable, setup relevant expiration timer. 143 */ 144 if (tdb->tdb_first_use == 0) { 145 tdb->tdb_first_use = time_second; 146 147 tv.tv_usec = 0; 148 149 tv.tv_sec = tdb->tdb_first_use + tdb->tdb_exp_first_use; 150 if (tdb->tdb_flags & TDBF_FIRSTUSE) 151 timeout_add(&tdb->tdb_first_tmo, 152 hzto(&tv)); 153 154 tv.tv_sec = tdb->tdb_first_use + tdb->tdb_soft_first_use; 155 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) 156 timeout_add(&tdb->tdb_sfirst_tmo, 157 hzto(&tv)); 158 } 159 160 /* 161 * Check for tunneling if we don't have the first header in place. 162 * When doing Ethernet-over-IP, we are handed an already-encapsulated 163 * frame, so we don't need to re-encapsulate. 164 */ 165 if (tunalready == 0) { 166 /* 167 * If the target protocol family is different, we know we'll be 168 * doing tunneling. 169 */ 170 if (af == tdb->tdb_dst.sa.sa_family) { 171 #ifdef INET 172 if (af == AF_INET) 173 i = sizeof(struct ip); 174 #endif /* INET */ 175 176 #ifdef INET6 177 if (af == AF_INET6) 178 i = sizeof(struct ip6_hdr); 179 #endif /* INET6 */ 180 181 /* Bring the network header in the first mbuf. */ 182 if (m->m_len < i) { 183 if ((m = m_pullup(m, i)) == NULL) 184 return ENOBUFS; 185 } 186 187 #ifdef INET 188 if (af == AF_INET) { 189 ip = mtod(m, struct ip *); 190 191 /* 192 * This is not a bridge packet, remember if we 193 * had IP_DF. 194 */ 195 setdf = ip->ip_off & htons(IP_DF); 196 } 197 #endif /* INET */ 198 199 #ifdef INET6 200 if (af == AF_INET6) 201 ip6 = mtod(m, struct ip6_hdr *); 202 #endif /* INET6 */ 203 } 204 205 /* Do the appropriate encapsulation, if necessary. */ 206 if ((tdb->tdb_dst.sa.sa_family != af) || /* PF mismatch */ 207 (tdb->tdb_flags & TDBF_TUNNELING) || /* Tunneling needed */ 208 (tdb->tdb_xform->xf_type == XF_IP4) || /* ditto */ 209 #ifdef INET 210 ((tdb->tdb_dst.sa.sa_family == AF_INET) && 211 (tdb->tdb_dst.sin.sin_addr.s_addr != INADDR_ANY) && 212 (tdb->tdb_dst.sin.sin_addr.s_addr != ip->ip_dst.s_addr)) || 213 #endif /* INET */ 214 #ifdef INET6 215 ((tdb->tdb_dst.sa.sa_family == AF_INET6) && 216 (!IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr)) && 217 (!IN6_ARE_ADDR_EQUAL(&tdb->tdb_dst.sin6.sin6_addr, 218 &ip6->ip6_dst))) || 219 #endif /* INET6 */ 220 0) { 221 #ifdef INET 222 /* Fix IPv4 header checksum and length. */ 223 if (af == AF_INET) { 224 if (m->m_len < sizeof(struct ip)) 225 if ((m = m_pullup(m, 226 sizeof(struct ip))) == NULL) 227 return ENOBUFS; 228 229 ip = mtod(m, struct ip *); 230 ip->ip_len = htons(m->m_pkthdr.len); 231 ip->ip_sum = 0; 232 ip->ip_sum = in_cksum(m, ip->ip_hl << 2); 233 } 234 #endif /* INET */ 235 236 #ifdef INET6 237 /* Fix IPv6 header payload length. */ 238 if (af == AF_INET6) { 239 if (m->m_len < sizeof(struct ip6_hdr)) 240 if ((m = m_pullup(m, 241 sizeof(struct ip6_hdr))) == NULL) 242 return ENOBUFS; 243 244 if (m->m_pkthdr.len - sizeof(*ip6) > 245 IPV6_MAXPACKET) { 246 /* No jumbogram support. */ 247 m_freem(m); 248 return ENXIO; /*?*/ 249 } 250 ip6 = mtod(m, struct ip6_hdr *); 251 ip6->ip6_plen = htons(m->m_pkthdr.len 252 - sizeof(*ip6)); 253 } 254 #endif /* INET6 */ 255 256 /* Encapsulate -- the last two arguments are unused. */ 257 error = ipip_output(m, tdb, &mp, 0, 0); 258 if ((mp == NULL) && (!error)) 259 error = EFAULT; 260 if (error) { 261 if (mp) { 262 m_freem(mp); 263 mp = NULL; 264 } 265 return error; 266 } 267 268 m = mp; 269 mp = NULL; 270 271 #ifdef INET 272 if (tdb->tdb_dst.sa.sa_family == AF_INET && setdf) { 273 if (m->m_len < sizeof(struct ip)) 274 if ((m = m_pullup(m, 275 sizeof(struct ip))) == NULL) 276 return ENOBUFS; 277 278 ip = mtod(m, struct ip *); 279 ip->ip_off |= htons(IP_DF); 280 } 281 #endif 282 283 /* Remember that we appended a tunnel header. */ 284 tdb->tdb_flags |= TDBF_USEDTUNNEL; 285 } 286 287 /* We may be done with this TDB */ 288 if (tdb->tdb_xform->xf_type == XF_IP4) 289 return ipsp_process_done(m, tdb); 290 } else { 291 /* 292 * If this is just an IP-IP TDB and we're told there's 293 * already an encapsulation header, move on. 294 */ 295 if (tdb->tdb_xform->xf_type == XF_IP4) 296 return ipsp_process_done(m, tdb); 297 } 298 299 /* Extract some information off the headers. */ 300 switch (tdb->tdb_dst.sa.sa_family) { 301 #ifdef INET 302 case AF_INET: 303 ip = mtod(m, struct ip *); 304 i = ip->ip_hl << 2; 305 off = offsetof(struct ip, ip_p); 306 break; 307 #endif /* INET */ 308 309 #ifdef INET6 310 case AF_INET6: 311 ip6 = mtod(m, struct ip6_hdr *); 312 i = sizeof(struct ip6_hdr); 313 off = offsetof(struct ip6_hdr, ip6_nxt); 314 nxt = ip6->ip6_nxt; 315 /* 316 * chase mbuf chain to find the appropriate place to 317 * put AH/ESP/IPcomp header. 318 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload] 319 */ 320 do { 321 switch (nxt) { 322 case IPPROTO_AH: 323 case IPPROTO_ESP: 324 case IPPROTO_IPCOMP: 325 /* 326 * we should not skip security header added 327 * beforehand. 328 */ 329 goto exitip6loop; 330 331 case IPPROTO_HOPOPTS: 332 case IPPROTO_DSTOPTS: 333 case IPPROTO_ROUTING: 334 /* 335 * if we see 2nd destination option header, 336 * we should stop there. 337 */ 338 if (nxt == IPPROTO_DSTOPTS && dstopt) 339 goto exitip6loop; 340 341 if (nxt == IPPROTO_DSTOPTS) { 342 /* 343 * seen 1st or 2nd destination option. 344 * next time we see one, it must be 2nd. 345 */ 346 dstopt = 1; 347 } else if (nxt == IPPROTO_ROUTING) { 348 /* 349 * if we see destionation option next 350 * time, it must be dest2. 351 */ 352 dstopt = 2; 353 } 354 355 /* skip this header */ 356 m_copydata(m, i, sizeof(ip6e), (caddr_t)&ip6e); 357 nxt = ip6e.ip6e_nxt; 358 off = i + offsetof(struct ip6_ext, ip6e_nxt); 359 /* 360 * we will never see nxt == IPPROTO_AH 361 * so it is safe to omit AH case. 362 */ 363 i += (ip6e.ip6e_len + 1) << 3; 364 break; 365 default: 366 goto exitip6loop; 367 } 368 } while (i < m->m_pkthdr.len); 369 exitip6loop:; 370 break; 371 #endif /* INET6 */ 372 } 373 374 /* Non expansion policy for IPCOMP */ 375 if (tdb->tdb_sproto == IPPROTO_IPCOMP) { 376 if ((m->m_pkthdr.len - i) < tdb->tdb_compalgxform->minlen) { 377 extern struct ipcompstat ipcompstat; 378 379 /* No need to compress, leave the packet untouched */ 380 ipcompstat.ipcomps_minlen++; 381 return ipsp_process_done(m, tdb); 382 } 383 } 384 385 /* Invoke the IPsec transform. */ 386 return (*(tdb->tdb_xform->xf_output))(m, tdb, NULL, i, off); 387 } 388 389 /* 390 * Called by the IPsec output transform callbacks, to transmit the packet 391 * or do further processing, as necessary. 392 */ 393 int 394 ipsp_process_done(struct mbuf *m, struct tdb *tdb) 395 { 396 #ifdef INET 397 struct ip *ip; 398 #endif /* INET */ 399 400 #ifdef INET6 401 struct ip6_hdr *ip6; 402 #endif /* INET6 */ 403 404 struct tdb_ident *tdbi; 405 struct m_tag *mtag; 406 407 tdb->tdb_last_used = time_second; 408 409 if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0) { 410 struct mbuf *mi; 411 struct udphdr *uh; 412 413 if (!udpencap_enable || !udpencap_port) { 414 m_freem(m); 415 return ENXIO; 416 } 417 mi = m_inject(m, sizeof(struct ip), sizeof(struct udphdr), 418 M_DONTWAIT); 419 if (mi == NULL) { 420 m_freem(m); 421 return ENOMEM; 422 } 423 uh = mtod(mi, struct udphdr *); 424 uh->uh_sport = uh->uh_dport = htons(udpencap_port); 425 if (tdb->tdb_udpencap_port) 426 uh->uh_dport = tdb->tdb_udpencap_port; 427 428 uh->uh_ulen = htons(m->m_pkthdr.len - sizeof(struct ip)); 429 uh->uh_sum = 0; 430 espstat.esps_udpencout++; 431 } 432 433 switch (tdb->tdb_dst.sa.sa_family) { 434 #ifdef INET 435 case AF_INET: 436 /* Fix the header length, for AH processing. */ 437 ip = mtod(m, struct ip *); 438 ip->ip_len = htons(m->m_pkthdr.len); 439 if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0) 440 ip->ip_p = IPPROTO_UDP; 441 break; 442 #endif /* INET */ 443 444 #ifdef INET6 445 case AF_INET6: 446 /* Fix the header length, for AH processing. */ 447 if (m->m_pkthdr.len < sizeof(*ip6)) { 448 m_freem(m); 449 return ENXIO; 450 } 451 if (m->m_pkthdr.len - sizeof(*ip6) > IPV6_MAXPACKET) { 452 /* No jumbogram support. */ 453 m_freem(m); 454 return ENXIO; 455 } 456 ip6 = mtod(m, struct ip6_hdr *); 457 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); 458 if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0) 459 ip6->ip6_nxt = IPPROTO_UDP; 460 break; 461 #endif /* INET6 */ 462 463 default: 464 m_freem(m); 465 DPRINTF(("ipsp_process_done(): unknown protocol family (%d)\n", 466 tdb->tdb_dst.sa.sa_family)); 467 return ENXIO; 468 } 469 470 /* 471 * Add a record of what we've done or what needs to be done to the 472 * packet. 473 */ 474 if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) 475 mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE, 476 sizeof(struct tdb_ident), 477 M_NOWAIT); 478 else 479 mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, 480 sizeof(struct tdb_ident), M_NOWAIT); 481 482 if (mtag == NULL) { 483 m_freem(m); 484 DPRINTF(("ipsp_process_done(): could not allocate packet " 485 "tag\n")); 486 return ENOMEM; 487 } 488 489 tdbi = (struct tdb_ident *)(mtag + 1); 490 bcopy(&tdb->tdb_dst, &tdbi->dst, sizeof(union sockaddr_union)); 491 tdbi->proto = tdb->tdb_sproto; 492 tdbi->spi = tdb->tdb_spi; 493 494 m_tag_prepend(m, mtag); 495 496 /* If there's another (bundled) TDB to apply, do so. */ 497 if (tdb->tdb_onext) 498 return ipsp_process_packet(m, tdb->tdb_onext, 499 tdb->tdb_dst.sa.sa_family, 0); 500 501 #if NPF > 0 502 /* Add pf tag if requested. */ 503 if (pf_tag_packet(m, tdb->tdb_tag, -1)) 504 DPRINTF(("failed to tag ipsec packet\n")); 505 pf_pkt_addr_changed(m); 506 #endif 507 508 /* 509 * We're done with IPsec processing, transmit the packet using the 510 * appropriate network protocol (IP or IPv6). SPD lookup will be 511 * performed again there. 512 */ 513 switch (tdb->tdb_dst.sa.sa_family) { 514 #ifdef INET 515 case AF_INET: 516 return ip_output(m, (void *)NULL, (void *)NULL, IP_RAWOUTPUT, (void *)NULL, (void *)NULL); 517 #endif /* INET */ 518 519 #ifdef INET6 520 case AF_INET6: 521 /* 522 * We don't need massage, IPv6 header fields are always in 523 * net endian. 524 */ 525 return ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 526 #endif /* INET6 */ 527 } 528 return EINVAL; /* Not reached. */ 529 } 530 531 ssize_t 532 ipsec_hdrsz(struct tdb *tdbp) 533 { 534 ssize_t adjust; 535 536 switch (tdbp->tdb_sproto) { 537 case IPPROTO_IPIP: 538 adjust = 0; 539 break; 540 541 case IPPROTO_ESP: 542 if (tdbp->tdb_encalgxform == NULL) 543 return (-1); 544 545 /* Header length */ 546 if (tdbp->tdb_flags & TDBF_NOREPLAY) 547 adjust = sizeof(u_int32_t) + tdbp->tdb_ivlen; 548 else 549 adjust = 2 * sizeof(u_int32_t) + tdbp->tdb_ivlen; 550 if (tdbp->tdb_flags & TDBF_UDPENCAP) 551 adjust += sizeof(struct udphdr); 552 /* Authenticator */ 553 if (tdbp->tdb_authalgxform != NULL) 554 adjust += AH_HMAC_HASHLEN; 555 /* Padding */ 556 adjust += tdbp->tdb_encalgxform->blocksize; 557 break; 558 559 case IPPROTO_AH: 560 if (tdbp->tdb_authalgxform == NULL) 561 return (-1); 562 563 if (!(tdbp->tdb_flags & TDBF_NOREPLAY)) 564 adjust = AH_FLENGTH + sizeof(u_int32_t); 565 else 566 adjust = AH_FLENGTH; 567 adjust += tdbp->tdb_authalgxform->authsize; 568 break; 569 570 default: 571 return (-1); 572 } 573 574 if (!(tdbp->tdb_flags & TDBF_TUNNELING) && 575 !(tdbp->tdb_flags & TDBF_USEDTUNNEL)) 576 return (adjust); 577 578 switch (tdbp->tdb_dst.sa.sa_family) { 579 #ifdef INET 580 case AF_INET: 581 adjust += sizeof(struct ip); 582 break; 583 #endif /* INET */ 584 #ifdef INET6 585 case AF_INET6: 586 adjust += sizeof(struct ip6_hdr); 587 break; 588 #endif /* INET6 */ 589 } 590 591 return (adjust); 592 } 593 594 void 595 ipsec_adjust_mtu(struct mbuf *m, u_int32_t mtu) 596 { 597 struct tdb_ident *tdbi; 598 struct tdb *tdbp; 599 struct m_tag *mtag; 600 ssize_t adjust; 601 int s; 602 603 s = spltdb(); 604 605 for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL); mtag; 606 mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, mtag)) { 607 tdbi = (struct tdb_ident *)(mtag + 1); 608 tdbp = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto); 609 if (tdbp == NULL) 610 break; 611 612 if ((adjust = ipsec_hdrsz(tdbp)) == -1) 613 break; 614 615 mtu -= adjust; 616 tdbp->tdb_mtu = mtu; 617 tdbp->tdb_mtutimeout = time_second + ip_mtudisc_timeout; 618 DPRINTF(("ipsec_adjust_mtu: " 619 "spi %08x mtu %d adjust %d mbuf %p\n", 620 ntohl(tdbp->tdb_spi), tdbp->tdb_mtu, 621 adjust, m)); 622 } 623 624 splx(s); 625 } 626