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