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