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